00001 #ifndef RSA_CRYPTO_IMPLEMENTATION_FILE
00002 #define RSA_CRYPTO_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "rsa_crypto.h"
00024 #include "ssl_init.h"
00025
00026 #include <basis/byte_array.h>
00027 #include <basis/chaos.h>
00028 #include <basis/function.h>
00029 #include <basis/log_base.h>
00030 #include <basis/packable.h>
00031
00032 #include <openssl/bn.h>
00033 #include <openssl/rsa.h>
00034
00035
00036
00037
00038
00039
00040 #undef LOG
00041 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s)
00042
00043
00044
00045 RSA_crypto::RSA_crypto(int key_size)
00046 : _key(NIL)
00047 {
00048 _key = generate_key(key_size);
00049 }
00050
00051 RSA_crypto::RSA_crypto(const byte_array &key)
00052 : _key(NIL)
00053 {
00054 static_ssl_initializer();
00055 byte_array key_copy = key;
00056 set_key(key_copy);
00057 }
00058
00059 RSA_crypto::RSA_crypto(rsa_st *key)
00060 : _key(NIL)
00061 {
00062 static_ssl_initializer();
00063 set_key(key);
00064 }
00065
00066 RSA_crypto::RSA_crypto(const RSA_crypto &to_copy)
00067 : object_base(),
00068 _key(NIL)
00069 {
00070 static_ssl_initializer();
00071 set_key(to_copy._key);
00072 }
00073
00074 RSA_crypto::~RSA_crypto()
00075 {
00076 RSA_free(_key);
00077 }
00078
00079 const RSA_crypto &RSA_crypto::operator = (const RSA_crypto &to_copy)
00080 {
00081 if (this == &to_copy) return *this;
00082 set_key(to_copy._key);
00083 return *this;
00084 }
00085
00086 rsa_st *RSA_crypto::generate_key(int key_size)
00087 {
00088 FUNCDEF("generate_key");
00089 if (key_size < 4) key_size = 4;
00090 static_ssl_initializer();
00091 rsa_st *to_return = RSA_generate_key(key_size, 65537, NIL, NIL);
00092 if (!to_return) {
00093 continuable_error(static_class_name(), func,
00094 isprintf("failed to generate a key of %d bits.", key_size));
00095 }
00096 return to_return;
00097 }
00098
00099 bool RSA_crypto::check_key(rsa_st *key) { return RSA_check_key(key) == 1; }
00100
00101 bool RSA_crypto::set_key(byte_array &key)
00102 {
00103 FUNCDEF("set_key [byte_array]");
00104 if (!key.length()) return false;
00105 if (_key) RSA_free(_key);
00106 _key = RSA_new();
00107 byte type;
00108 if (!basis::detach(key, type)) return false;
00109 if ( (type != 'r') && (type != 'u') ) return false;
00110
00111 byte_array n;
00112 if (!basis::detach(key, n)) return false;
00113 _key->n = BN_bin2bn(n.access(), n.length(), NIL);
00114 if (!_key->n) return false;
00115 byte_array e;
00116 if (!basis::detach(key, e)) return false;
00117 _key->e = BN_bin2bn(e.access(), e.length(), NIL);
00118 if (!_key->e) return false;
00119 if (type == 'u') return true;
00120
00121
00122 byte_array d;
00123 if (!basis::detach(key, d)) return false;
00124 _key->d = BN_bin2bn(d.access(), d.length(), NIL);
00125 if (!_key->d) return false;
00126 byte_array p;
00127 if (!basis::detach(key, p)) return false;
00128 _key->p = BN_bin2bn(p.access(), p.length(), NIL);
00129 if (!_key->p) return false;
00130 byte_array q;
00131 if (!basis::detach(key, q)) return false;
00132 _key->q = BN_bin2bn(q.access(), q.length(), NIL);
00133 if (!_key->q) return false;
00134 byte_array dmp1;
00135 if (!basis::detach(key, dmp1)) return false;
00136 _key->dmp1 = BN_bin2bn(dmp1.access(), dmp1.length(), NIL);
00137 if (!_key->dmp1) return false;
00138 byte_array dmq1;
00139 if (!basis::detach(key, dmq1)) return false;
00140 _key->dmq1 = BN_bin2bn(dmq1.access(), dmq1.length(), NIL);
00141 if (!_key->dmq1) return false;
00142 byte_array iqmp;
00143 if (!basis::detach(key, iqmp)) return false;
00144 _key->iqmp = BN_bin2bn(iqmp.access(), iqmp.length(), NIL);
00145 if (!_key->iqmp) return false;
00146 int check = RSA_check_key(_key);
00147 if (check != 1) {
00148 continuable_error(static_class_name(), func, "failed to check the private "
00149 "portion of the key!");
00150 return false;
00151 }
00152
00153 return true;
00154 }
00155
00156 bool RSA_crypto::set_key(rsa_st *key)
00157 {
00158 FUNCDEF("set_key [rsa_st]");
00159 if (!key) return NIL;
00160
00161 int check = RSA_check_key(key);
00162 if (check != 1) return false;
00163
00164 if (_key) RSA_free(_key);
00165 _key = RSAPrivateKey_dup(key);
00166 if (!_key) {
00167 continuable_error(static_class_name(), func, "failed to create a "
00168 "duplicate of the key!");
00169 return false;
00170 }
00171 return true;
00172 }
00173
00174 bool RSA_crypto::public_key(byte_array &pubkey) const
00175 {
00176 FUNCDEF("public_key");
00177 if (!_key) return false;
00178 basis::attach(pubkey, byte('u'));
00179
00180 byte_array n(BN_num_bytes(_key->n));
00181 int ret = BN_bn2bin(_key->n, n.access());
00182 byte_array e(BN_num_bytes(_key->e));
00183 ret = BN_bn2bin(_key->e, e.access());
00184
00185 basis::attach(pubkey, n);
00186 basis::attach(pubkey, e);
00187 return true;
00188 }
00189
00190 bool RSA_crypto::private_key(byte_array &privkey) const
00191 {
00192 FUNCDEF("private_key");
00193 if (!_key) return false;
00194 int posn = privkey.length();
00195 bool worked = public_key(privkey);
00196 if (!worked) return false;
00197 privkey[posn] = byte('r');
00198
00199 byte_array d(BN_num_bytes(_key->d));
00200 int ret = BN_bn2bin(_key->d, d.access());
00201 byte_array p(BN_num_bytes(_key->p));
00202 ret = BN_bn2bin(_key->p, p.access());
00203 byte_array q(BN_num_bytes(_key->q));
00204 ret = BN_bn2bin(_key->q, q.access());
00205 byte_array dmp1(BN_num_bytes(_key->dmp1));
00206 ret = BN_bn2bin(_key->dmp1, dmp1.access());
00207 byte_array dmq1(BN_num_bytes(_key->dmq1));
00208 ret = BN_bn2bin(_key->dmq1, dmq1.access());
00209 byte_array iqmp(BN_num_bytes(_key->iqmp));
00210 ret = BN_bn2bin(_key->iqmp, iqmp.access());
00211
00212 basis::attach(privkey, d);
00213 basis::attach(privkey, p);
00214 basis::attach(privkey, q);
00215 basis::attach(privkey, dmp1);
00216 basis::attach(privkey, dmq1);
00217 basis::attach(privkey, iqmp);
00218 return true;
00219 }
00220
00221 bool RSA_crypto::public_encrypt(const byte_array &source,
00222 byte_array &target) const
00223 {
00224 FUNCDEF("public_encrypt");
00225 target.reset();
00226 if (!source.length()) return false;
00227 const int max_chunk = RSA_size(_key) - 12;
00228
00229 byte_array encoded(RSA_size(_key));
00230 for (int i = 0; i < source.length(); i += max_chunk) {
00231 int edge = i + max_chunk - 1;
00232 if (edge > source.last())
00233 edge = source.last();
00234 int next_chunk = edge - i + 1;
00235 RSA_public_encrypt(next_chunk, &source[i],
00236 encoded.access(), _key, RSA_PKCS1_PADDING);
00237 target += encoded;
00238 }
00239 return true;
00240 }
00241
00242 bool RSA_crypto::private_decrypt(const byte_array &source,
00243 byte_array &target) const
00244 {
00245 FUNCDEF("private_decrypt");
00246 target.reset();
00247 if (!source.length()) return false;
00248 const int max_chunk = RSA_size(_key);
00249
00250 byte_array decoded(max_chunk);
00251 for (int i = 0; i < source.length(); i += max_chunk) {
00252 int edge = i + max_chunk - 1;
00253 if (edge > source.last())
00254 edge = source.last();
00255 int next_chunk = edge - i + 1;
00256 int dec_size = RSA_private_decrypt(next_chunk, &source[i],
00257 decoded.access(), _key, RSA_PKCS1_PADDING);
00258 if (dec_size < 0) return false;
00259 decoded.zap(dec_size, decoded.last());
00260 target += decoded;
00261 decoded.reset(max_chunk);
00262 }
00263 return true;
00264 }
00265
00266 bool RSA_crypto::private_encrypt(const byte_array &source,
00267 byte_array &target) const
00268 {
00269 FUNCDEF("private_encrypt");
00270 target.reset();
00271 if (!source.length()) return false;
00272 const int max_chunk = RSA_size(_key) - 12;
00273
00274 byte_array encoded(RSA_size(_key));
00275 for (int i = 0; i < source.length(); i += max_chunk) {
00276 int edge = i + max_chunk - 1;
00277 if (edge > source.last())
00278 edge = source.last();
00279 int next_chunk = edge - i + 1;
00280 RSA_private_encrypt(next_chunk, &source[i],
00281 encoded.access(), _key, RSA_PKCS1_PADDING);
00282 target += encoded;
00283 }
00284 return true;
00285 }
00286
00287 bool RSA_crypto::public_decrypt(const byte_array &source,
00288 byte_array &target) const
00289 {
00290 FUNCDEF("public_decrypt");
00291 target.reset();
00292 if (!source.length()) return false;
00293 const int max_chunk = RSA_size(_key);
00294
00295 byte_array decoded(max_chunk);
00296 for (int i = 0; i < source.length(); i += max_chunk) {
00297 int edge = i + max_chunk - 1;
00298 if (edge > source.last())
00299 edge = source.last();
00300 int next_chunk = edge - i + 1;
00301 int dec_size = RSA_public_decrypt(next_chunk, &source[i],
00302 decoded.access(), _key, RSA_PKCS1_PADDING);
00303 if (dec_size < 0) return false;
00304 decoded.zap(dec_size, decoded.last());
00305 target += decoded;
00306 decoded.reset(max_chunk);
00307 }
00308 return true;
00309 }
00310
00311
00312 #endif //RSA_CRYPTO_IMPLEMENTATION_FILE
00313