2 * Name : RSA public key encryption
3 * Author : Chris Koeritz
5 * Supports public (and private) key encryption and decryption using the
6 * OpenSSL package's support for RSA encryption.
8 * Copyright (c) 2005-$now By Author. This program is free software; you can *
9 * redistribute it and/or modify it under the terms of the GNU General Public *
10 * License as published by the Free Software Foundation; either version 2 of *
11 * the License or (at your option) any later version. This is online at: *
12 * http://www.fsf.org/copyleft/gpl.html *
13 * Please send any updates to: fred@gruntose.com *
16 //note: rsa crypto provides a nice printing method... RSA_print_fp(stdout, private_key, 0);
18 // notes from openssl docs: length to be encrypted in a chunk must be less than
19 // RSA_size(rsa) - 11 for the PKCS #1 v1.5 based padding modes, less than
20 // RSA_size(rsa) - 41 for RSA_PKCS1_OAEP_PADDING and exactly RSA_size(rsa)
21 // for RSA_NO_PADDING.
23 #include "rsa_crypto.h"
26 #include <basis/functions.h>
27 #include <loggers/critical_events.h>
28 #include <loggers/program_wide_logger.h>
29 #include <mathematics/chaos.h>
30 #include <structures/object_packers.h>
31 #include <structures/static_memory_gremlin.h>
33 #include <openssl/bn.h>
34 #include <openssl/err.h>
35 #include <openssl/rsa.h>
37 using namespace basis;
38 using namespace loggers;
39 using namespace mathematics;
40 using namespace structures;
44 //#define DEBUG_RSA_CRYPTO
45 // uncomment for noisier version.
47 #ifdef DEBUG_RSA_CRYPTO
49 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
55 SAFE_STATIC(mutex, __single_stepper, )
56 // protects unsafe areas of rsa crypto from access by multiple threads at once.
58 rsa_crypto::rsa_crypto(int key_size)
62 LOG("prior to generating key");
63 _key = generate_key(key_size); // generate_key initializes ssl for us.
64 LOG("after generating key");
67 rsa_crypto::rsa_crypto(const byte_array &key)
70 FUNCDEF("ctor(byte_array)");
71 static_ssl_initializer();
72 byte_array key_copy = key;
73 LOG("prior to set key");
78 rsa_crypto::rsa_crypto(RSA *key)
82 static_ssl_initializer();
83 LOG("prior to set key");
88 rsa_crypto::rsa_crypto(const rsa_crypto &to_copy)
93 static_ssl_initializer();
94 LOG("prior to set key");
95 set_key(to_copy._key);
99 rsa_crypto::~rsa_crypto()
101 FUNCDEF("destructor");
102 LOG("prior to rsa free");
103 auto_synchronizer mutt(__single_stepper());
105 LOG("after rsa free");
108 const rsa_crypto &rsa_crypto::operator = (const rsa_crypto &to_copy)
110 if (this == &to_copy) return *this;
111 set_key(to_copy._key);
115 RSA *rsa_crypto::generate_key(int key_size)
117 FUNCDEF("generate_key");
118 if (key_size < 4) key_size = 4; // laughable lower default.
119 static_ssl_initializer();
120 LOG("into generate key");
121 auto_synchronizer mutt(__single_stepper());
122 RSA *to_return = RSA_new();
123 BIGNUM *e = BN_new();
124 BN_set_word(e, 65537);
125 //hmmm: only one value of e?
126 int ret = RSA_generate_key_ex(to_return, key_size, e, NULL_POINTER);
128 continuable_error(static_class_name(), func,
129 a_sprintf("failed to generate a key of %d bits: error is %ld.", key_size, ERR_get_error()));
134 LOG("after key generated");
139 bool rsa_crypto::check_key(RSA *key)
141 auto_synchronizer mutt(__single_stepper());
142 return RSA_check_key(key) == 1;
145 bool rsa_crypto::set_key(byte_array &key)
147 FUNCDEF("set_key [byte_array]");
148 if (!key.length()) return false;
149 auto_synchronizer mutt(__single_stepper());
150 if (_key) RSA_free(_key);
153 if (!structures::detach(key, type)) return false;
154 if ( (type != 'r') && (type != 'u') ) return false;
155 // get the public key bits first.
157 if (!structures::detach(key, n)) return false;
158 BIGNUM *the_n = BN_bin2bn(n.access(), n.length(), NULL_POINTER);
159 if (!the_n) return false;
161 if (!structures::detach(key, e)) return false;
162 BIGNUM *the_e = BN_bin2bn(e.access(), e.length(), NULL_POINTER);
163 if (!the_e) return false;
166 // done with public key.
168 RSA_set0_key(_key, the_n, the_e, NULL_POINTER);
170 _key->n = the_n; _key->e = the_e;
175 // the rest is for a private key.
177 if (!structures::detach(key, d)) return false;
178 BIGNUM *the_d = BN_bin2bn(d.access(), d.length(), NULL_POINTER);
179 if (!the_d) return false;
182 if (!structures::detach(key, p)) return false;
183 BIGNUM *the_p = BN_bin2bn(p.access(), p.length(), NULL_POINTER);
184 if (!the_p) return false;
186 if (!structures::detach(key, q)) return false;
187 BIGNUM *the_q = BN_bin2bn(q.access(), q.length(), NULL_POINTER);
188 if (!the_q) return false;
190 if (!structures::detach(key, dmp1)) return false;
191 BIGNUM *the_dmp1 = BN_bin2bn(dmp1.access(), dmp1.length(), NULL_POINTER);
192 if (!the_dmp1) return false;
194 if (!structures::detach(key, dmq1)) return false;
195 BIGNUM *the_dmq1 = BN_bin2bn(dmq1.access(), dmq1.length(), NULL_POINTER);
196 if (!the_dmq1) return false;
198 if (!structures::detach(key, iqmp)) return false;
199 BIGNUM *the_iqmp = BN_bin2bn(iqmp.access(), iqmp.length(), NULL_POINTER);
200 if (!the_iqmp) return false;
202 // we can set the n, e and d now.
204 int ret = RSA_set0_key(_key, the_n, the_e, the_d);
205 if (ret != 1) return false;
206 ret = RSA_set0_factors(_key, the_p, the_q);
207 if (ret != 1) return false;
208 ret = RSA_set0_crt_params(_key, the_dmp1, the_dmq1, the_iqmp);
209 if (ret != 1) return false;
211 _key->n = the_n; _key->e = the_e; _key->d = the_d;
212 _key->p = the_p; _key->q = the_q;
213 _key->dmp1 = the_dmp1; _key->dmq1 = the_dmq1; _key->iqmp = the_iqmp;
216 int check = RSA_check_key(_key);
218 continuable_error(static_class_name(), func, "failed to check the private "
219 "portion of the key!");
226 bool rsa_crypto::set_key(RSA *key)
228 FUNCDEF("set_key [RSA]");
229 if (!key) return NULL_POINTER;
230 // test the incoming key.
231 auto_synchronizer mutt(__single_stepper());
232 int check = RSA_check_key(key);
233 if (check != 1) return false;
234 // clean out the old key.
235 if (_key) RSA_free(_key);
236 _key = RSAPrivateKey_dup(key);
238 continuable_error(static_class_name(), func, "failed to create a "
239 "duplicate of the key!");
245 bool rsa_crypto::public_key(byte_array &pubkey) const
247 FUNCDEF("public_key");
248 if (!_key) return false;
249 structures::attach(pubkey, abyte('u')); // signal a public key.
250 // convert the two public portions into binary.
251 BIGNUM **the_n = new BIGNUM *, **the_e = new BIGNUM *, **the_d = new BIGNUM *;
253 RSA_get0_key(_key, (const BIGNUM **)the_n, (const BIGNUM **)the_e, (const BIGNUM **)the_d);
255 *the_n = _key->n; *the_e = _key->e; *the_d = _key->d;
257 byte_array n(BN_num_bytes(*the_n));
258 int ret = BN_bn2bin(*the_n, n.access());
259 byte_array e(BN_num_bytes(*the_e));
260 ret = BN_bn2bin(*the_e, e.access());
261 // pack those two chunks.
262 structures::attach(pubkey, n);
263 structures::attach(pubkey, e);
264 WHACK(the_n); WHACK(the_e); WHACK(the_d);
269 bool rsa_crypto::private_key(byte_array &privkey) const
271 FUNCDEF("private_key");
272 if (!_key) return false;
273 int posn = privkey.length();
274 bool worked = public_key(privkey); // get the public pieces first.
275 if (!worked) return false;
276 privkey[posn] = abyte('r'); // switch public key flag to private.
277 // convert the multiple private portions into binary.
278 //const BIGNUM **the_n = NULL_POINTER, **the_e = NULL_POINTER, **the_d = NULL_POINTER;
279 BIGNUM **the_n = new BIGNUM *, **the_e = new BIGNUM *, **the_d = new BIGNUM *;
280 BIGNUM **the_p = new BIGNUM *, **the_q = new BIGNUM *;
281 BIGNUM **the_dmp1 = new BIGNUM *, **the_dmq1 = new BIGNUM *, **the_iqmp = new BIGNUM *;
283 RSA_get0_key(_key, (const BIGNUM **)the_n, (const BIGNUM **)the_e, (const BIGNUM **)the_d);
284 RSA_get0_factors(_key, (const BIGNUM **)the_p, (const BIGNUM **)the_q);
285 RSA_get0_crt_params(_key, (const BIGNUM **)the_dmp1, (const BIGNUM **)the_dmq1, (const BIGNUM **)the_iqmp);
287 *the_n = _key->n; *the_e = _key->e; *the_d = _key->d;
288 *the_p = _key->p; *the_q = _key->q;
289 *the_dmp1 = _key->dmp1; *the_dmq1 = _key->dmq1; *the_iqmp = _key->iqmp;
291 byte_array d(BN_num_bytes(*the_d));
292 int ret = BN_bn2bin(*the_d, d.access());
293 byte_array p(BN_num_bytes(*the_p));
294 ret = BN_bn2bin(*the_p, p.access());
295 byte_array q(BN_num_bytes(*the_q));
296 ret = BN_bn2bin(*the_q, q.access());
297 byte_array dmp1(BN_num_bytes(*the_dmp1));
298 ret = BN_bn2bin(*the_dmp1, dmp1.access());
299 byte_array dmq1(BN_num_bytes(*the_dmq1));
300 ret = BN_bn2bin(*the_dmq1, dmq1.access());
301 byte_array iqmp(BN_num_bytes(*the_iqmp));
302 ret = BN_bn2bin(*the_iqmp, iqmp.access());
303 // pack all those in now.
304 structures::attach(privkey, d);
305 structures::attach(privkey, p);
306 structures::attach(privkey, q);
307 structures::attach(privkey, dmp1);
308 structures::attach(privkey, dmq1);
309 structures::attach(privkey, iqmp);
313 bool rsa_crypto::public_encrypt(const byte_array &source,
314 byte_array &target) const
316 FUNCDEF("public_encrypt");
318 if (!source.length()) return false;
320 auto_synchronizer mutt(__single_stepper());
321 const int max_chunk = RSA_size(_key) - 12;
323 byte_array encoded(RSA_size(_key));
324 for (int i = 0; i < source.length(); i += max_chunk) {
325 int edge = i + max_chunk - 1;
326 if (edge > source.last())
327 edge = source.last();
328 int next_chunk = edge - i + 1;
329 RSA_public_encrypt(next_chunk, &source[i],
330 encoded.access(), _key, RSA_PKCS1_PADDING);
336 bool rsa_crypto::private_decrypt(const byte_array &source,
337 byte_array &target) const
339 FUNCDEF("private_decrypt");
341 if (!source.length()) return false;
343 auto_synchronizer mutt(__single_stepper());
344 const int max_chunk = RSA_size(_key);
346 byte_array decoded(max_chunk);
347 for (int i = 0; i < source.length(); i += max_chunk) {
348 int edge = i + max_chunk - 1;
349 if (edge > source.last())
350 edge = source.last();
351 int next_chunk = edge - i + 1;
352 int dec_size = RSA_private_decrypt(next_chunk, &source[i],
353 decoded.access(), _key, RSA_PKCS1_PADDING);
354 if (dec_size < 0) return false; // that didn't work.
355 decoded.zap(dec_size, decoded.last());
357 decoded.reset(max_chunk);
362 bool rsa_crypto::private_encrypt(const byte_array &source,
363 byte_array &target) const
365 FUNCDEF("private_encrypt");
367 if (!source.length()) return false;
369 auto_synchronizer mutt(__single_stepper());
370 const int max_chunk = RSA_size(_key) - 12;
372 byte_array encoded(RSA_size(_key));
373 for (int i = 0; i < source.length(); i += max_chunk) {
374 int edge = i + max_chunk - 1;
375 if (edge > source.last())
376 edge = source.last();
377 int next_chunk = edge - i + 1;
378 RSA_private_encrypt(next_chunk, &source[i],
379 encoded.access(), _key, RSA_PKCS1_PADDING);
385 bool rsa_crypto::public_decrypt(const byte_array &source,
386 byte_array &target) const
388 FUNCDEF("public_decrypt");
390 if (!source.length()) return false;
392 auto_synchronizer mutt(__single_stepper());
393 const int max_chunk = RSA_size(_key);
395 byte_array decoded(max_chunk);
396 for (int i = 0; i < source.length(); i += max_chunk) {
397 int edge = i + max_chunk - 1;
398 if (edge > source.last())
399 edge = source.last();
400 int next_chunk = edge - i + 1;
401 int dec_size = RSA_public_decrypt(next_chunk, &source[i],
402 decoded.access(), _key, RSA_PKCS1_PADDING);
403 if (dec_size < 0) return false; // that didn't work.
404 decoded.zap(dec_size, decoded.last());
406 decoded.reset(max_chunk);