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