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/rsa.h>
36 using namespace basis;
37 using namespace loggers;
38 using namespace mathematics;
39 using namespace structures;
43 //#define DEBUG_RSA_CRYPTO
44 // uncomment for noisier version.
46 #ifdef DEBUG_RSA_CRYPTO
48 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
54 SAFE_STATIC(mutex, __single_stepper, )
55 // protects unsafe areas of rsa crypto from access by multiple threads at once.
57 rsa_crypto::rsa_crypto(int key_size)
61 LOG("prior to generating key");
62 _key = generate_key(key_size); // generate_key initializes ssl for us.
63 LOG("after generating key");
66 rsa_crypto::rsa_crypto(const byte_array &key)
69 FUNCDEF("ctor(byte_array)");
70 static_ssl_initializer();
71 byte_array key_copy = key;
72 LOG("prior to set key");
77 rsa_crypto::rsa_crypto(RSA *key)
81 static_ssl_initializer();
82 LOG("prior to set key");
87 rsa_crypto::rsa_crypto(const rsa_crypto &to_copy)
92 static_ssl_initializer();
93 LOG("prior to set key");
94 set_key(to_copy._key);
98 rsa_crypto::~rsa_crypto()
101 LOG("prior to rsa free");
102 auto_synchronizer mutt(__single_stepper());
104 LOG("after rsa free");
107 const rsa_crypto &rsa_crypto::operator = (const rsa_crypto &to_copy)
109 if (this == &to_copy) return *this;
110 set_key(to_copy._key);
114 RSA *rsa_crypto::generate_key(int key_size)
116 FUNCDEF("generate_key");
117 if (key_size < 4) key_size = 4; // laughable lower default.
118 static_ssl_initializer();
119 LOG("into generate key");
120 auto_synchronizer mutt(__single_stepper());
121 RSA *to_return = RSA_generate_key(key_size, 65537, NULL_POINTER, NULL_POINTER);
123 continuable_error(static_class_name(), func,
124 a_sprintf("failed to generate a key of %d bits.", key_size));
126 LOG("after key generated");
130 bool rsa_crypto::check_key(RSA *key)
132 auto_synchronizer mutt(__single_stepper());
133 return RSA_check_key(key) == 1;
136 bool rsa_crypto::set_key(byte_array &key)
138 FUNCDEF("set_key [byte_array]");
139 if (!key.length()) return false;
140 auto_synchronizer mutt(__single_stepper());
141 if (_key) RSA_free(_key);
144 if (!structures::detach(key, type)) return false;
145 if ( (type != 'r') && (type != 'u') ) return false;
146 // get the public key bits first.
148 if (!structures::detach(key, n)) return false;
149 BIGNUM *the_n = BN_bin2bn(n.access(), n.length(), NULL_POINTER);
150 if (!the_n) return false;
152 if (!structures::detach(key, e)) return false;
153 BIGNUM *the_e = BN_bin2bn(e.access(), e.length(), NULL_POINTER);
154 if (!the_e) return false;
157 // done with public key.
159 RSA_set0_key(_key, the_n, the_e, NULL_POINTER);
161 _key->n = the_n; _key->e = the_e;
166 // the rest is for a private key.
168 if (!structures::detach(key, d)) return false;
169 BIGNUM *the_d = BN_bin2bn(d.access(), d.length(), NULL_POINTER);
170 if (!the_d) return false;
173 if (!structures::detach(key, p)) return false;
174 BIGNUM *the_p = BN_bin2bn(p.access(), p.length(), NULL_POINTER);
175 if (!the_p) return false;
177 if (!structures::detach(key, q)) return false;
178 BIGNUM *the_q = BN_bin2bn(q.access(), q.length(), NULL_POINTER);
179 if (!the_q) return false;
181 if (!structures::detach(key, dmp1)) return false;
182 BIGNUM *the_dmp1 = BN_bin2bn(dmp1.access(), dmp1.length(), NULL_POINTER);
183 if (!the_dmp1) return false;
185 if (!structures::detach(key, dmq1)) return false;
186 BIGNUM *the_dmq1 = BN_bin2bn(dmq1.access(), dmq1.length(), NULL_POINTER);
187 if (!the_dmq1) return false;
189 if (!structures::detach(key, iqmp)) return false;
190 BIGNUM *the_iqmp = BN_bin2bn(iqmp.access(), iqmp.length(), NULL_POINTER);
191 if (!the_iqmp) return false;
193 // we can set the n, e and d now.
195 int ret = RSA_set0_key(_key, the_n, the_e, the_d);
196 if (ret != 1) return false;
197 ret = RSA_set0_factors(_key, the_p, the_q);
198 if (ret != 1) return false;
199 ret = RSA_set0_crt_params(_key, the_dmp1, the_dmq1, the_iqmp);
200 if (ret != 1) return false;
202 _key->n = the_n; _key->e = the_e; _key->d = the_d;
203 _key->p = the_p; _key->q = the_q;
204 _key->dmp1 = the_dmp1; _key->dmq1 = the_dmq1; _key->iqmp = the_iqmp;
207 int check = RSA_check_key(_key);
209 continuable_error(static_class_name(), func, "failed to check the private "
210 "portion of the key!");
217 bool rsa_crypto::set_key(RSA *key)
219 FUNCDEF("set_key [RSA]");
220 if (!key) return NULL_POINTER;
221 // test the incoming key.
222 auto_synchronizer mutt(__single_stepper());
223 int check = RSA_check_key(key);
224 if (check != 1) return false;
225 // clean out the old key.
226 if (_key) RSA_free(_key);
227 _key = RSAPrivateKey_dup(key);
229 continuable_error(static_class_name(), func, "failed to create a "
230 "duplicate of the key!");
236 bool rsa_crypto::public_key(byte_array &pubkey) const
238 FUNCDEF("public_key");
239 if (!_key) return false;
240 structures::attach(pubkey, abyte('u')); // signal a public key.
241 // convert the two public portions into binary.
242 BIGNUM **the_n = new BIGNUM *, **the_e = new BIGNUM *, **the_d = new BIGNUM *;
244 RSA_get0_key(_key, (const BIGNUM **)the_n, (const BIGNUM **)the_e, (const BIGNUM **)the_d);
246 *the_n = _key->n; *the_e = _key->e; *the_d = _key->d;
248 byte_array n(BN_num_bytes(*the_n));
249 int ret = BN_bn2bin(*the_n, n.access());
250 byte_array e(BN_num_bytes(*the_e));
251 ret = BN_bn2bin(*the_e, e.access());
252 // pack those two chunks.
253 structures::attach(pubkey, n);
254 structures::attach(pubkey, e);
255 WHACK(the_n); WHACK(the_e); WHACK(the_d);
260 bool rsa_crypto::private_key(byte_array &privkey) const
262 FUNCDEF("private_key");
263 if (!_key) return false;
264 int posn = privkey.length();
265 bool worked = public_key(privkey); // get the public pieces first.
266 if (!worked) return false;
267 privkey[posn] = abyte('r'); // switch public key flag to private.
268 // convert the multiple private portions into binary.
269 //const BIGNUM **the_n = NULL_POINTER, **the_e = NULL_POINTER, **the_d = NULL_POINTER;
270 BIGNUM **the_n = new BIGNUM *, **the_e = new BIGNUM *, **the_d = new BIGNUM *;
271 BIGNUM **the_p = new BIGNUM *, **the_q = new BIGNUM *;
272 BIGNUM **the_dmp1 = new BIGNUM *, **the_dmq1 = new BIGNUM *, **the_iqmp = new BIGNUM *;
274 RSA_get0_key(_key, (const BIGNUM **)the_n, (const BIGNUM **)the_e, (const BIGNUM **)the_d);
275 RSA_get0_factors(_key, (const BIGNUM **)the_p, (const BIGNUM **)the_q);
276 RSA_get0_crt_params(_key, (const BIGNUM **)the_dmp1, (const BIGNUM **)the_dmq1, (const BIGNUM **)the_iqmp);
278 *the_n = _key->n; *the_e = _key->e; *the_d = _key->d;
279 *the_p = _key->p; *the_q = _key->q;
280 *the_dmp1 = _key->dmp1; *the_dmq1 = _key->dmq1; *the_iqmp = _key->iqmp;
282 byte_array d(BN_num_bytes(*the_d));
283 int ret = BN_bn2bin(*the_d, d.access());
284 byte_array p(BN_num_bytes(*the_p));
285 ret = BN_bn2bin(*the_p, p.access());
286 byte_array q(BN_num_bytes(*the_q));
287 ret = BN_bn2bin(*the_q, q.access());
288 byte_array dmp1(BN_num_bytes(*the_dmp1));
289 ret = BN_bn2bin(*the_dmp1, dmp1.access());
290 byte_array dmq1(BN_num_bytes(*the_dmq1));
291 ret = BN_bn2bin(*the_dmq1, dmq1.access());
292 byte_array iqmp(BN_num_bytes(*the_iqmp));
293 ret = BN_bn2bin(*the_iqmp, iqmp.access());
294 // pack all those in now.
295 structures::attach(privkey, d);
296 structures::attach(privkey, p);
297 structures::attach(privkey, q);
298 structures::attach(privkey, dmp1);
299 structures::attach(privkey, dmq1);
300 structures::attach(privkey, iqmp);
304 bool rsa_crypto::public_encrypt(const byte_array &source,
305 byte_array &target) const
307 FUNCDEF("public_encrypt");
309 if (!source.length()) return false;
311 auto_synchronizer mutt(__single_stepper());
312 const int max_chunk = RSA_size(_key) - 12;
314 byte_array encoded(RSA_size(_key));
315 for (int i = 0; i < source.length(); i += max_chunk) {
316 int edge = i + max_chunk - 1;
317 if (edge > source.last())
318 edge = source.last();
319 int next_chunk = edge - i + 1;
320 RSA_public_encrypt(next_chunk, &source[i],
321 encoded.access(), _key, RSA_PKCS1_PADDING);
327 bool rsa_crypto::private_decrypt(const byte_array &source,
328 byte_array &target) const
330 FUNCDEF("private_decrypt");
332 if (!source.length()) return false;
334 auto_synchronizer mutt(__single_stepper());
335 const int max_chunk = RSA_size(_key);
337 byte_array decoded(max_chunk);
338 for (int i = 0; i < source.length(); i += max_chunk) {
339 int edge = i + max_chunk - 1;
340 if (edge > source.last())
341 edge = source.last();
342 int next_chunk = edge - i + 1;
343 int dec_size = RSA_private_decrypt(next_chunk, &source[i],
344 decoded.access(), _key, RSA_PKCS1_PADDING);
345 if (dec_size < 0) return false; // that didn't work.
346 decoded.zap(dec_size, decoded.last());
348 decoded.reset(max_chunk);
353 bool rsa_crypto::private_encrypt(const byte_array &source,
354 byte_array &target) const
356 FUNCDEF("private_encrypt");
358 if (!source.length()) return false;
360 auto_synchronizer mutt(__single_stepper());
361 const int max_chunk = RSA_size(_key) - 12;
363 byte_array encoded(RSA_size(_key));
364 for (int i = 0; i < source.length(); i += max_chunk) {
365 int edge = i + max_chunk - 1;
366 if (edge > source.last())
367 edge = source.last();
368 int next_chunk = edge - i + 1;
369 RSA_private_encrypt(next_chunk, &source[i],
370 encoded.access(), _key, RSA_PKCS1_PADDING);
376 bool rsa_crypto::public_decrypt(const byte_array &source,
377 byte_array &target) const
379 FUNCDEF("public_decrypt");
381 if (!source.length()) return false;
383 auto_synchronizer mutt(__single_stepper());
384 const int max_chunk = RSA_size(_key);
386 byte_array decoded(max_chunk);
387 for (int i = 0; i < source.length(); i += max_chunk) {
388 int edge = i + max_chunk - 1;
389 if (edge > source.last())
390 edge = source.last();
391 int next_chunk = edge - i + 1;
392 int dec_size = RSA_public_decrypt(next_chunk, &source[i],
393 decoded.access(), _key, RSA_PKCS1_PADDING);
394 if (dec_size < 0) return false; // that didn't work.
395 decoded.zap(dec_size, decoded.last());
397 decoded.reset(max_chunk);