MADARA  3.4.1
AESBufferFilter.cpp
Go to the documentation of this file.
1 
2 #ifdef _USE_SSL_
3 
4 #include <algorithm>
5 #include <string.h>
6 #include <openssl/evp.h>
7 #include <openssl/aes.h>
8 #include "AESBufferFilter.h"
9 
10 #include "madara/utility/Utility.h"
11 
13 
15  : key_(new unsigned char[32]), iv_(new unsigned char[16])
16 {
17  memset((void*)key_.get_ptr(), 0, 32);
18  memset((void*)iv_.get_ptr(), 0, 16);
19 }
20 
22  : key_(new unsigned char[32]), iv_(new unsigned char[16])
23 {
24  memcpy(key_.get_ptr(), input.key_.get_ptr(), 32);
25  memset((void*)iv_.get_ptr(), 0, 16);
26 }
27 
29  unsigned char* key, int key_length)
30  : key_(new unsigned char[32]), iv_(new unsigned char[16])
31 {
32  memcpy(key_.get_ptr(), key, std::min(32, key_length));
33  memset((void*)iv_.get_ptr(), 0, 16);
34 }
35 
37 
39 {
40  int i, rounds = 10000;
41 
42  // use a random salt and a zero'd initialization vector
43  int64_t salt = 0x70e4ed2d19a447ef;
44 
45  i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), (unsigned char*)&salt,
46  (unsigned char*)password.c_str(), (int)password.length(), rounds,
47  (unsigned char*)key_.get_ptr(), (unsigned char*)iv_.get_ptr());
48 
49  if (i != 32)
50  {
52  " Unable to initialize 256 bit AES. Only received %d bytes.\n", i);
53 
54  return -1;
55  }
56 
57  return 0;
58 }
59 
61  char* source, int size, int max_size) const
62 {
63  int result = 0;
64 
66  EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
67 
68  int len = 0;
69  int ciphertext_len = 0;
70 
71  // size == plaintext_len
72  size = std::min(size, max_size);
73 
74  // initialize the context
75 
76  EVP_CIPHER_CTX_init(ctx);
77 
78  // init the encryption with our key and IV
79  result = EVP_EncryptInit_ex(
80  ctx, EVP_aes_256_cbc(), NULL, key_.get_ptr(), iv_.get_ptr());
81 
82  if (result != 1)
83  {
85  "AESBufferFilter::encode: Cannot init key/iv. Result=%d.\n", result);
86 
87  return 0;
88  }
89 
90  // encrypt the buffer
91  result = EVP_EncryptUpdate(
92  ctx, (unsigned char*)source, &len, (unsigned char*)source, size);
93 
94  if (result != 1)
95  {
97  "AESBufferFilter::encode: Cannot perform encrypt. Result=%d.\n",
98  result);
99 
100  return 0;
101  }
102 
103  ciphertext_len = len;
104 
106  "AESBufferFilter::encode:EVP_EncryptUpdate:2: len=%d, "
107  "ciphertext_len=%d.\n",
108  len, ciphertext_len);
109 
110  // finalize the encryption with padding
111  result = EVP_EncryptFinal_ex(ctx, (unsigned char*)(source + len), &len);
112 
113  if (result != 1)
114  {
116  "AESBufferFilter::encode: Cannot finalize encrypt. Result=%d.\n",
117  result);
118 
119  return 0;
120  }
121 
122  ciphertext_len += len;
123 
125  "AESBufferFilter::encode:EVP_EncryptFinal_ex: "
126  "len=%d, ciphertext_len=%d.\n",
127  len, ciphertext_len);
128 
129  EVP_CIPHER_CTX_free(ctx);
130 
131  return ciphertext_len;
132 }
133 
135  char* source, int size, int max_size) const
136 {
137  int result = 0;
138 
140  EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
141 
142  int len(0);
143  int plaintext_len(0);
144 
145  // size == cyphertext_len
146  size = std::min(size, max_size);
147 
148  // initialize the context
149  EVP_CIPHER_CTX_init(ctx);
150 
151  result = EVP_DecryptInit_ex(
152  ctx, EVP_aes_256_cbc(), NULL, key_.get_ptr(), iv_.get_ptr());
153 
154  if (result != 1)
155  {
157  "AESBufferFilter::decode: Cannot init key/iv. Result=%d.\n", result);
158 
159  return 0;
160  }
161 
163  "AESBufferFilter::decode:EVP_DecryptUpdate:1: len=%d, size=%d.\n", len,
164  size);
165 
166  result = EVP_DecryptUpdate(
167  ctx, (unsigned char*)source, &len, (unsigned char*)source, size);
168  plaintext_len = len;
169 
170  if (result != 1)
171  {
173  "AESBufferFilter::decode: Cannot perform decrypt. Result=%d.\n",
174  result);
175 
176  return 0;
177  }
178 
180  "AESBufferFilter::decode:EVP_DecryptUpdate:2: len=%d, "
181  "plaintext_len=%d.\n",
182  len, plaintext_len);
183 
184  result = EVP_DecryptFinal_ex(ctx, (unsigned char*)(source + len), &len);
185 
186  if (result != 1)
187  {
189  "AESBufferFilter::decode: Cannot finalize decrypt. Result=%d.\n",
190  result);
191 
192  return 0;
193  }
194 
195  plaintext_len += len;
196 
198  "AESBufferFilter::decode:EVP_DecryptFinal_ex: "
199  "len=%d, plaintext_len=%d.\n",
200  len, plaintext_len);
201 
202  EVP_CIPHER_CTX_free(ctx);
203 
204  return plaintext_len;
205 }
206 
208 {
209  return "ssl";
210 }
211 
217 {
218  return madara::utility::get_uint_version("1.0.0");
219 }
220 
221 #endif // _USE_SSL_
#define madara_logger_ptr_log(loggering, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:41
Encrypts a buffer with 256 bit AES via OpenSSL.
int generate_key(const std::string &password)
Generates a 256 bit key from a password.
utility::ScopedArray< unsigned char > iv_
initialization vector
virtual int encode(char *source, int size, int max_size) const
Encodes the buffer in place using AES encryption.
utility::ScopedArray< unsigned char > key_
the user's cypher key
virtual int decode(char *source, int size, int max_size) const
Decodes the buffer in place using AES encryption.
virtual ~AESBufferFilter()
Destructor.
virtual std::string get_id(void)
Gets the id of the filter.
virtual uint32_t get_version(void)
Gets the version of the filter.
T * get_ptr(void)
get the underlying pointer
Definition: ScopedArray.inl:64
constexpr string_t string
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
uint32_t get_uint_version(const std::string &str_version)
Converts a string version to a uint32.
Definition: Utility.cpp:30