Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
decrypt.cpp
1 
2 /***************************************************************************
3  * decrypt.cpp - WorldInfo decryption routine
4  *
5  * Created: Thu May 03 15:54:24 2007
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/exceptions/software.h>
25 #include <netcomm/worldinfo/decrypt.h>
26 #ifdef HAVE_LIBCRYPTO
27 # include <openssl/evp.h>
28 #else
29 # include <cstring>
30 #endif
31 
32 namespace fawkes {
33 
34 /** @class MessageDecryptionException <netcomm/worldinfo/decrypt.h>
35  * Message decryption failed.
36  * This exception shall be thrown if there was a problem decrypting a
37  * world info message.
38  * @ingroup NetComm
39  */
40 
41 /** Constructor.
42  * @param msg message
43  */
45  : Exception(msg)
46 {
47 }
48 
49 
50 /** @class WorldInfoMessageDecryptor <netcomm/worldinfo/decrypt.h>
51  * WorldInfo message decryptor.
52  * This class is used to decrypt world info message after they have been
53  * received.
54  *
55  * This is the opposite part of WorldInfoMessageEncryptor.
56  *
57  * This implementation uses OpenSSL for the AES encryption (in fact it uses the
58  * accompanying libcrypto that comes with OpenSSL, not libopenssl itself). It is
59  * almost everywhere available and easy to use.
60  *
61  * @see WorldInfoMessageEncryptor
62  * @ingroup NetComm
63  * @author Tim Niemueller
64  */
65 
66 
67 /** Constructor.
68  * @param key encryption key
69  * @param iv initialisation vector
70  */
71 WorldInfoMessageDecryptor::WorldInfoMessageDecryptor(const unsigned char *key, const unsigned char *iv)
72 {
73  plain_buffer = NULL;
74  plain_buffer_length = 0;
75  crypt_buffer = NULL;
76  crypt_buffer_length = 0;
77 
78  this->key = key;
79  this->iv = iv;
80 }
81 
82 
83 /** Empty destructor. */
85 {
86 }
87 
88 
89 /** Set plain buffer.
90  * This is the destination buffer to which the decrypted plain text is written.
91  * @param buffer plain text buffer
92  * @param buffer_length plain text buffer length
93  */
94 void
95 WorldInfoMessageDecryptor::set_plain_buffer(void *buffer, size_t buffer_length)
96 {
97  plain_buffer = buffer;
98  plain_buffer_length = buffer_length;
99 }
100 
101 
102 /** Set crypted buffer.
103  * This is the source buffer which is decrypted.
104  * @param buffer crypted text buffer
105  * @param buffer_length crypted text buffer length
106  */
107 void
108 WorldInfoMessageDecryptor::set_crypt_buffer(void *buffer, size_t buffer_length)
109 {
110  crypt_buffer = buffer;
111  crypt_buffer_length = buffer_length;
112 }
113 
114 
115 /** Decrypt.
116  * Do the decryption.
117  * @return size of the plain text message.
118  */
119 size_t
121 {
122  if ( (plain_buffer == NULL) || (plain_buffer_length == 0) ||
123  (crypt_buffer == NULL) || (crypt_buffer_length == 0) ) {
124  throw MissingParameterException("Buffer(s) not set for decryption");
125  }
126 
127 #ifdef HAVE_LIBCRYPTO
128  EVP_CIPHER_CTX ctx;
129  if ( ! EVP_DecryptInit(&ctx, EVP_aes_128_ecb(), key, iv) ) {
130  throw MessageDecryptionException("Could not initialize cipher context");
131  }
132 
133  int outl = plain_buffer_length;
134  if ( ! EVP_DecryptUpdate(&ctx,
135  (unsigned char *)plain_buffer, &outl,
136  (unsigned char *)crypt_buffer, crypt_buffer_length) ) {
137  throw MessageDecryptionException("DecryptUpdate failed");
138  }
139 
140  int plen = 0;
141  if ( ! EVP_DecryptFinal(&ctx, (unsigned char *)plain_buffer + outl, &plen) ) {
142  throw MessageDecryptionException("DecryptFinal failed");
143  }
144  outl += plen;
145 
146  return outl;
147 #else
148  // Plain-text copy-through for debugging.
149  memcpy(plain_buffer, crypt_buffer, crypt_buffer_length);
150  return crypt_buffer_length;
151 #endif
152 }
153 
154 } // end namespace fawkes