Panda3D
|
00001 // Filename: encrypt_string.cxx 00002 // Created by: drose (30Jan07) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "encrypt_string.h" 00016 00017 #ifdef HAVE_OPENSSL 00018 #include "encryptStream.h" 00019 #include "virtualFileSystem.h" 00020 #include "config_express.h" 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: encrypt_string 00024 // Access: Published 00025 // Description: Encrypts the indicated source string using the given 00026 // password, and the algorithm specified by 00027 // encryption-algorithm. Returns the encrypted string. 00028 //////////////////////////////////////////////////////////////////// 00029 string 00030 encrypt_string(const string &source, const string &password, 00031 const string &algorithm, int key_length, int iteration_count) { 00032 ostringstream dest; 00033 00034 { 00035 OEncryptStream encrypt; 00036 if (!algorithm.empty()) { 00037 encrypt.set_algorithm(algorithm); 00038 } 00039 if (key_length > 0) { 00040 encrypt.set_key_length(key_length); 00041 } 00042 if (iteration_count >= 0) { 00043 encrypt.set_iteration_count(iteration_count); 00044 } 00045 encrypt.open(&dest, false, password); 00046 encrypt.write(source.data(), source.length()); 00047 00048 if (encrypt.fail()) { 00049 return string(); 00050 } 00051 } 00052 00053 return dest.str(); 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: decrypt_string 00058 // Access: Published 00059 // Description: Decrypts the previously-encrypted string using the 00060 // given password (which must be the same password 00061 // passed to encrypt()). The return value is the 00062 // decrypted string. 00063 // 00064 // Note that a decryption error, including an incorrect 00065 // password, cannot easily be detected, and the return 00066 // value may simply be a garbage string. 00067 //////////////////////////////////////////////////////////////////// 00068 string 00069 decrypt_string(const string &source, const string &password) { 00070 istringstream source_stream(source); 00071 ostringstream dest_stream; 00072 00073 if (!decrypt_stream(source_stream, dest_stream, password)) { 00074 return string(); 00075 } 00076 00077 return dest_stream.str(); 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: encrypt_file 00082 // Access: Published 00083 // Description: Encrypts the data from the source file using the 00084 // given password. The source file is read in its 00085 // entirety, and the encrypted results are written to 00086 // the dest file, overwriting its contents. The return 00087 // value is bool on success, or false on failure. 00088 //////////////////////////////////////////////////////////////////// 00089 EXPCL_PANDAEXPRESS bool 00090 encrypt_file(const Filename &source, const Filename &dest, const string &password, 00091 const string &algorithm, int key_length, int iteration_count) { 00092 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); 00093 Filename source_filename = source; 00094 if (!source_filename.is_binary_or_text()) { 00095 // The default is binary, if not specified otherwise. 00096 source_filename.set_binary(); 00097 } 00098 istream *source_stream = vfs->open_read_file(source_filename, true); 00099 if (source_stream == NULL) { 00100 express_cat.info() << "Couldn't open file " << source_filename << "\n"; 00101 return false; 00102 } 00103 00104 Filename dest_filename = Filename::binary_filename(dest); 00105 ostream *dest_stream = vfs->open_write_file(dest_filename, true, true); 00106 if (dest_stream == NULL) { 00107 express_cat.info() << "Couldn't open file " << dest_filename << "\n"; 00108 vfs->close_read_file(source_stream); 00109 return false; 00110 } 00111 00112 bool result = encrypt_stream(*source_stream, *dest_stream, password, 00113 algorithm, key_length, iteration_count); 00114 vfs->close_read_file(source_stream); 00115 vfs->close_write_file(dest_stream); 00116 return result; 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: decrypt_file 00121 // Access: Published 00122 // Description: Decrypts the data from the source file using the 00123 // given password (which must match the same password 00124 // passed to encrypt()). The source file is read in its 00125 // entirety, and the decrypted results are written to 00126 // the dest file, overwriting its contents. The return 00127 // value is bool on success, or false on failure. 00128 // 00129 // Note that a decryption error, including an incorrect 00130 // password, cannot easily be detected, and the output 00131 // may simply be a garbage string. 00132 //////////////////////////////////////////////////////////////////// 00133 EXPCL_PANDAEXPRESS bool 00134 decrypt_file(const Filename &source, const Filename &dest, const string &password) { 00135 Filename source_filename = Filename::binary_filename(source); 00136 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); 00137 istream *source_stream = vfs->open_read_file(source_filename, false); 00138 if (source_stream == NULL) { 00139 express_cat.info() << "Couldn't open file " << source_filename << "\n"; 00140 return false; 00141 } 00142 00143 Filename dest_filename = dest; 00144 if (!dest_filename.is_binary_or_text()) { 00145 // The default is binary, if not specified otherwise. 00146 dest_filename.set_binary(); 00147 } 00148 ostream *dest_stream = vfs->open_write_file(dest_filename, true, true); 00149 if (dest_stream == NULL) { 00150 express_cat.info() << "Couldn't open file " << dest_filename << "\n"; 00151 vfs->close_read_file(source_stream); 00152 return false; 00153 } 00154 00155 bool result = decrypt_stream(*source_stream, *dest_stream, password); 00156 vfs->close_read_file(source_stream); 00157 vfs->close_write_file(dest_stream); 00158 return result; 00159 } 00160 00161 //////////////////////////////////////////////////////////////////// 00162 // Function: encrypt_stream 00163 // Access: Published 00164 // Description: Encrypts the data from the source stream using the 00165 // given password. The source stream is read from its 00166 // current position to the end-of-file, and the 00167 // encrypted results are written to the dest stream. 00168 // The return value is bool on success, or false on 00169 // failure. 00170 //////////////////////////////////////////////////////////////////// 00171 bool 00172 encrypt_stream(istream &source, ostream &dest, const string &password, 00173 const string &algorithm, int key_length, int iteration_count) { 00174 OEncryptStream encrypt; 00175 if (!algorithm.empty()) { 00176 encrypt.set_algorithm(algorithm); 00177 } 00178 if (key_length > 0) { 00179 encrypt.set_key_length(key_length); 00180 } 00181 if (iteration_count >= 0) { 00182 encrypt.set_iteration_count(iteration_count); 00183 } 00184 encrypt.open(&dest, false, password); 00185 00186 static const size_t buffer_size = 4096; 00187 char buffer[buffer_size]; 00188 00189 source.read(buffer, buffer_size); 00190 size_t count = source.gcount(); 00191 while (count != 0) { 00192 encrypt.write(buffer, count); 00193 source.read(buffer, buffer_size); 00194 count = source.gcount(); 00195 } 00196 encrypt.close(); 00197 00198 return (!source.fail() || source.eof()) && (!encrypt.fail()); 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function: decrypt_stream 00203 // Access: Published 00204 // Description: Decrypts the data from the previously-encrypted 00205 // source stream using the given password (which must be 00206 // the same password passed to encrypt()). The source 00207 // stream is read from its current position to the 00208 // end-of-file, and the decrypted results are written to 00209 // the dest stream. The return value is bool on 00210 // success, or false on failure. 00211 // 00212 // Note that a decryption error, including an incorrect 00213 // password, cannot easily be detected, and the output 00214 // may simply be a garbage string. 00215 //////////////////////////////////////////////////////////////////// 00216 bool 00217 decrypt_stream(istream &source, ostream &dest, const string &password) { 00218 IDecryptStream decrypt(&source, false, password); 00219 00220 static const size_t buffer_size = 4096; 00221 char buffer[buffer_size]; 00222 00223 decrypt.read(buffer, buffer_size); 00224 size_t count = decrypt.gcount(); 00225 while (count != 0) { 00226 dest.write(buffer, count); 00227 decrypt.read(buffer, buffer_size); 00228 count = decrypt.gcount(); 00229 } 00230 00231 return (!decrypt.fail() || decrypt.eof()) && (!dest.fail()); 00232 } 00233 00234 #endif // HAVE_OPENSSL