Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * decrypt.cpp - WorldInfo decryption routine 00004 * 00005 * Created: Thu May 03 15:54:24 2007 00006 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <core/exceptions/software.h> 00025 #include <netcomm/worldinfo/decrypt.h> 00026 #ifdef HAVE_LIBCRYPTO 00027 # include <openssl/evp.h> 00028 #else 00029 # include <cstring> 00030 #endif 00031 00032 namespace fawkes { 00033 00034 /** @class MessageDecryptionException <netcomm/worldinfo/decrypt.h> 00035 * Message decryption failed. 00036 * This exception shall be thrown if there was a problem decrypting a 00037 * world info message. 00038 * @ingroup NetComm 00039 */ 00040 00041 /** Constructor. 00042 * @param msg message 00043 */ 00044 MessageDecryptionException::MessageDecryptionException(const char *msg) 00045 : Exception(msg) 00046 { 00047 } 00048 00049 00050 /** @class WorldInfoMessageDecryptor <netcomm/worldinfo/decrypt.h> 00051 * WorldInfo message decryptor. 00052 * This class is used to decrypt world info message after they have been 00053 * received. 00054 * 00055 * This is the opposite part of WorldInfoMessageEncryptor. 00056 * 00057 * This implementation uses OpenSSL for the AES encryption (in fact it uses the 00058 * accompanying libcrypto that comes with OpenSSL, not libopenssl itself). It is 00059 * almost everywhere available and easy to use. 00060 * 00061 * @see WorldInfoMessageEncryptor 00062 * @ingroup NetComm 00063 * @author Tim Niemueller 00064 */ 00065 00066 00067 /** Constructor. 00068 * @param key encryption key 00069 * @param iv initialisation vector 00070 */ 00071 WorldInfoMessageDecryptor::WorldInfoMessageDecryptor(const unsigned char *key, const unsigned char *iv) 00072 { 00073 plain_buffer = NULL; 00074 plain_buffer_length = 0; 00075 crypt_buffer = NULL; 00076 crypt_buffer_length = 0; 00077 00078 this->key = key; 00079 this->iv = iv; 00080 } 00081 00082 00083 /** Empty destructor. */ 00084 WorldInfoMessageDecryptor::~WorldInfoMessageDecryptor() 00085 { 00086 } 00087 00088 00089 /** Set plain buffer. 00090 * This is the destination buffer to which the decrypted plain text is written. 00091 * @param buffer plain text buffer 00092 * @param buffer_length plain text buffer length 00093 */ 00094 void 00095 WorldInfoMessageDecryptor::set_plain_buffer(void *buffer, size_t buffer_length) 00096 { 00097 plain_buffer = buffer; 00098 plain_buffer_length = buffer_length; 00099 } 00100 00101 00102 /** Set crypted buffer. 00103 * This is the source buffer which is decrypted. 00104 * @param buffer crypted text buffer 00105 * @param buffer_length crypted text buffer length 00106 */ 00107 void 00108 WorldInfoMessageDecryptor::set_crypt_buffer(void *buffer, size_t buffer_length) 00109 { 00110 crypt_buffer = buffer; 00111 crypt_buffer_length = buffer_length; 00112 } 00113 00114 00115 /** Decrypt. 00116 * Do the decryption. 00117 * @return size of the plain text message. 00118 */ 00119 size_t 00120 WorldInfoMessageDecryptor::decrypt() 00121 { 00122 if ( (plain_buffer == NULL) || (plain_buffer_length == 0) || 00123 (crypt_buffer == NULL) || (crypt_buffer_length == 0) ) { 00124 throw MissingParameterException("Buffer(s) not set for decryption"); 00125 } 00126 00127 #ifdef HAVE_LIBCRYPTO 00128 EVP_CIPHER_CTX ctx; 00129 if ( ! EVP_DecryptInit(&ctx, EVP_aes_128_ecb(), key, iv) ) { 00130 throw MessageDecryptionException("Could not initialize cipher context"); 00131 } 00132 00133 int outl = plain_buffer_length; 00134 if ( ! EVP_DecryptUpdate(&ctx, 00135 (unsigned char *)plain_buffer, &outl, 00136 (unsigned char *)crypt_buffer, crypt_buffer_length) ) { 00137 throw MessageDecryptionException("DecryptUpdate failed"); 00138 } 00139 00140 int plen = 0; 00141 if ( ! EVP_DecryptFinal(&ctx, (unsigned char *)plain_buffer + outl, &plen) ) { 00142 throw MessageDecryptionException("DecryptFinal failed"); 00143 } 00144 outl += plen; 00145 00146 return outl; 00147 #else 00148 // Plain-text copy-through for debugging. 00149 memcpy(plain_buffer, crypt_buffer, crypt_buffer_length); 00150 return crypt_buffer_length; 00151 #endif 00152 } 00153 00154 } // end namespace fawkes