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 {
45 }
46 
47 /** @class MessageDecryptor <netcomm/crypto/decrypt.h>
48  * Message decryptor.
49  * This class is used to decrypt world info message after they have been
50  * received.
51  *
52  * This is the opposite part of MessageEncryptor.
53  *
54  * This implementation uses OpenSSL for the AES encryption (in fact it uses the
55  * accompanying libcrypto that comes with OpenSSL, not libopenssl itself). It is
56  * almost everywhere available and easy to use.
57  *
58  * @see MessageEncryptor
59  * @ingroup NetComm
60  * @author Tim Niemueller
61  */
62 
63 /** Constructor.
64  * @param key encryption key
65  * @param iv initialisation vector
66  */
67 MessageDecryptor::MessageDecryptor(const unsigned char *key, const unsigned char *iv)
68 {
69  plain_buffer = NULL;
70  plain_buffer_length = 0;
71  crypt_buffer = NULL;
72  crypt_buffer_length = 0;
73 
74  this->key = key;
75  this->iv = iv;
76 }
77 
78 /** Empty destructor. */
80 {
81 }
82 
83 /** Set plain buffer.
84  * This is the destination buffer to which the decrypted plain text is written.
85  * @param buffer plain text buffer
86  * @param buffer_length plain text buffer length
87  */
88 void
89 MessageDecryptor::set_plain_buffer(void *buffer, size_t buffer_length)
90 {
91  plain_buffer = buffer;
92  plain_buffer_length = buffer_length;
93 }
94 
95 /** Set crypted buffer.
96  * This is the source buffer which is decrypted.
97  * @param buffer crypted text buffer
98  * @param buffer_length crypted text buffer length
99  */
100 void
101 MessageDecryptor::set_crypt_buffer(void *buffer, size_t buffer_length)
102 {
103  crypt_buffer = buffer;
104  crypt_buffer_length = buffer_length;
105 }
106 
107 /** Decrypt.
108  * Do the decryption.
109  * @return size of the plain text message.
110  */
111 size_t
113 {
114  if ((plain_buffer == NULL) || (plain_buffer_length == 0) || (crypt_buffer == NULL)
115  || (crypt_buffer_length == 0)) {
116  throw MissingParameterException("Buffer(s) not set for decryption");
117  }
118 
119 #ifdef HAVE_LIBCRYPTO
120  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
121  if (!EVP_DecryptInit(ctx, EVP_aes_128_ecb(), key, iv)) {
122  EVP_CIPHER_CTX_free(ctx);
123  throw MessageDecryptionException("Could not initialize cipher context");
124  }
125 
126  int outl = plain_buffer_length;
127  if (!EVP_DecryptUpdate(ctx,
128  (unsigned char *)plain_buffer,
129  &outl,
130  (unsigned char *)crypt_buffer,
131  crypt_buffer_length)) {
132  EVP_CIPHER_CTX_free(ctx);
133  throw MessageDecryptionException("DecryptUpdate failed");
134  }
135 
136  int plen = 0;
137  if (!EVP_DecryptFinal(ctx, (unsigned char *)plain_buffer + outl, &plen)) {
138  EVP_CIPHER_CTX_free(ctx);
139  throw MessageDecryptionException("DecryptFinal failed");
140  }
141  outl += plen;
142 
143  EVP_CIPHER_CTX_free(ctx);
144  return outl;
145 #else
146  // Plain-text copy-through for debugging.
147  //memcpy(plain_buffer, crypt_buffer, crypt_buffer_length);
148  //return crypt_buffer_length;
149  throw Exception("Decryption support not available");
150 #endif
151 }
152 
153 } // end namespace fawkes
fawkes::MessageDecryptionException::MessageDecryptionException
MessageDecryptionException(const char *msg)
Constructor.
Definition: decrypt.cpp:43
fawkes::MessageDecryptor::MessageDecryptor
MessageDecryptor(const unsigned char *key, const unsigned char *iv)
Constructor.
Definition: decrypt.cpp:67
fawkes::MessageDecryptor::decrypt
size_t decrypt()
Decrypt.
Definition: decrypt.cpp:112
fawkes::MessageDecryptor::set_plain_buffer
void set_plain_buffer(void *buffer, size_t buffer_length)
Set plain buffer.
Definition: decrypt.cpp:89
fawkes
Fawkes library namespace.
fawkes::MissingParameterException
Expected parameter is missing.
Definition: software.h:74
fawkes::MessageDecryptor::set_crypt_buffer
void set_crypt_buffer(void *buffer, size_t buffer_length)
Set crypted buffer.
Definition: decrypt.cpp:101
fawkes::MessageDecryptor::~MessageDecryptor
~MessageDecryptor()
Empty destructor.
Definition: decrypt.cpp:79
fawkes::MessageDecryptionException
Message decryption failed.
Definition: decrypt.h:33
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36