Panda3D
 All Classes Functions Variables Enumerations
encrypt_string.cxx
1 // Filename: encrypt_string.cxx
2 // Created by: drose (30Jan07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "encrypt_string.h"
16 
17 #ifdef HAVE_OPENSSL
18 #include "encryptStream.h"
19 #include "virtualFileSystem.h"
20 #include "config_express.h"
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: encrypt_string
24 // Access: Published
25 // Description: Encrypts the indicated source string using the given
26 // password, and the algorithm specified by
27 // encryption-algorithm. Returns the encrypted string.
28 ////////////////////////////////////////////////////////////////////
29 string
30 encrypt_string(const string &source, const string &password,
31  const string &algorithm, int key_length, int iteration_count) {
32  ostringstream dest;
33 
34  {
35  OEncryptStream encrypt;
36  if (!algorithm.empty()) {
37  encrypt.set_algorithm(algorithm);
38  }
39  if (key_length > 0) {
40  encrypt.set_key_length(key_length);
41  }
42  if (iteration_count >= 0) {
43  encrypt.set_iteration_count(iteration_count);
44  }
45  encrypt.open(&dest, false, password);
46  encrypt.write(source.data(), source.length());
47 
48  if (encrypt.fail()) {
49  return string();
50  }
51  }
52 
53  return dest.str();
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: decrypt_string
58 // Access: Published
59 // Description: Decrypts the previously-encrypted string using the
60 // given password (which must be the same password
61 // passed to encrypt()). The return value is the
62 // decrypted string.
63 //
64 // Note that a decryption error, including an incorrect
65 // password, cannot easily be detected, and the return
66 // value may simply be a garbage string.
67 ////////////////////////////////////////////////////////////////////
68 string
69 decrypt_string(const string &source, const string &password) {
70  istringstream source_stream(source);
71  ostringstream dest_stream;
72 
73  if (!decrypt_stream(source_stream, dest_stream, password)) {
74  return string();
75  }
76 
77  return dest_stream.str();
78 }
79 
80 ////////////////////////////////////////////////////////////////////
81 // Function: encrypt_file
82 // Access: Published
83 // Description: Encrypts the data from the source file using the
84 // given password. The source file is read in its
85 // entirety, and the encrypted results are written to
86 // the dest file, overwriting its contents. The return
87 // value is bool on success, or false on failure.
88 ////////////////////////////////////////////////////////////////////
89 EXPCL_PANDAEXPRESS bool
90 encrypt_file(const Filename &source, const Filename &dest, const string &password,
91  const string &algorithm, int key_length, int iteration_count) {
93  Filename source_filename = source;
94  if (!source_filename.is_binary_or_text()) {
95  // The default is binary, if not specified otherwise.
96  source_filename.set_binary();
97  }
98  istream *source_stream = vfs->open_read_file(source_filename, true);
99  if (source_stream == NULL) {
100  express_cat.info() << "Couldn't open file " << source_filename << "\n";
101  return false;
102  }
103 
104  Filename dest_filename = Filename::binary_filename(dest);
105  ostream *dest_stream = vfs->open_write_file(dest_filename, true, true);
106  if (dest_stream == NULL) {
107  express_cat.info() << "Couldn't open file " << dest_filename << "\n";
108  vfs->close_read_file(source_stream);
109  return false;
110  }
111 
112  bool result = encrypt_stream(*source_stream, *dest_stream, password,
113  algorithm, key_length, iteration_count);
114  vfs->close_read_file(source_stream);
115  vfs->close_write_file(dest_stream);
116  return result;
117 }
118 
119 ////////////////////////////////////////////////////////////////////
120 // Function: decrypt_file
121 // Access: Published
122 // Description: Decrypts the data from the source file using the
123 // given password (which must match the same password
124 // passed to encrypt()). The source file is read in its
125 // entirety, and the decrypted results are written to
126 // the dest file, overwriting its contents. The return
127 // value is bool on success, or false on failure.
128 //
129 // Note that a decryption error, including an incorrect
130 // password, cannot easily be detected, and the output
131 // may simply be a garbage string.
132 ////////////////////////////////////////////////////////////////////
133 EXPCL_PANDAEXPRESS bool
134 decrypt_file(const Filename &source, const Filename &dest, const string &password) {
135  Filename source_filename = Filename::binary_filename(source);
137  istream *source_stream = vfs->open_read_file(source_filename, false);
138  if (source_stream == NULL) {
139  express_cat.info() << "Couldn't open file " << source_filename << "\n";
140  return false;
141  }
142 
143  Filename dest_filename = dest;
144  if (!dest_filename.is_binary_or_text()) {
145  // The default is binary, if not specified otherwise.
146  dest_filename.set_binary();
147  }
148  ostream *dest_stream = vfs->open_write_file(dest_filename, true, true);
149  if (dest_stream == NULL) {
150  express_cat.info() << "Couldn't open file " << dest_filename << "\n";
151  vfs->close_read_file(source_stream);
152  return false;
153  }
154 
155  bool result = decrypt_stream(*source_stream, *dest_stream, password);
156  vfs->close_read_file(source_stream);
157  vfs->close_write_file(dest_stream);
158  return result;
159 }
160 
161 ////////////////////////////////////////////////////////////////////
162 // Function: encrypt_stream
163 // Access: Published
164 // Description: Encrypts the data from the source stream using the
165 // given password. The source stream is read from its
166 // current position to the end-of-file, and the
167 // encrypted results are written to the dest stream.
168 // The return value is bool on success, or false on
169 // failure.
170 ////////////////////////////////////////////////////////////////////
171 bool
172 encrypt_stream(istream &source, ostream &dest, const string &password,
173  const string &algorithm, int key_length, int iteration_count) {
174  OEncryptStream encrypt;
175  if (!algorithm.empty()) {
176  encrypt.set_algorithm(algorithm);
177  }
178  if (key_length > 0) {
179  encrypt.set_key_length(key_length);
180  }
181  if (iteration_count >= 0) {
182  encrypt.set_iteration_count(iteration_count);
183  }
184  encrypt.open(&dest, false, password);
185 
186  static const size_t buffer_size = 4096;
187  char buffer[buffer_size];
188 
189  source.read(buffer, buffer_size);
190  size_t count = source.gcount();
191  while (count != 0) {
192  encrypt.write(buffer, count);
193  source.read(buffer, buffer_size);
194  count = source.gcount();
195  }
196  encrypt.close();
197 
198  return (!source.fail() || source.eof()) && (!encrypt.fail());
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function: decrypt_stream
203 // Access: Published
204 // Description: Decrypts the data from the previously-encrypted
205 // source stream using the given password (which must be
206 // the same password passed to encrypt()). The source
207 // stream is read from its current position to the
208 // end-of-file, and the decrypted results are written to
209 // the dest stream. The return value is bool on
210 // success, or false on failure.
211 //
212 // Note that a decryption error, including an incorrect
213 // password, cannot easily be detected, and the output
214 // may simply be a garbage string.
215 ////////////////////////////////////////////////////////////////////
216 bool
217 decrypt_stream(istream &source, ostream &dest, const string &password) {
218  IDecryptStream decrypt(&source, false, password);
219 
220  static const size_t buffer_size = 4096;
221  char buffer[buffer_size];
222 
223  decrypt.read(buffer, buffer_size);
224  size_t count = decrypt.gcount();
225  while (count != 0) {
226  dest.write(buffer, count);
227  decrypt.read(buffer, buffer_size);
228  count = decrypt.gcount();
229  }
230 
231  return (!decrypt.fail() || decrypt.eof()) && (!dest.fail());
232 }
233 
234 #endif // HAVE_OPENSSL
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS&#39;s file system.
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:494
static void close_read_file(istream *stream)
Closes a file opened by a previous call to open_read_file().
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read...
ostream * open_write_file(const Filename &filename, bool auto_wrap, bool truncate)
Convenience function; returns a newly allocated ostream if the file exists and can be written...
static void close_write_file(ostream *stream)
Closes a file opened by a previous call to open_write_file().
bool is_binary_or_text() const
Returns true either is_binary() or is_text() is true; that is, that the filename has been specified a...
Definition: filename.I:534