decrypt.cpp

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

Generated on Tue Feb 22 13:32:28 2011 for Fawkes API by  doxygen 1.4.7