00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(OPENSSL_NO_RSA)
00012
00013 #include "ossl.h"
00014
00015 #define GetPKeyRSA(obj, pkey) do { \
00016 GetPKey((obj), (pkey)); \
00017 if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_RSA) { \
00018 ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
00019 } \
00020 } while (0)
00021
00022 #define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q)
00023 #define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj))
00024
00025
00026
00027
00028 VALUE cRSA;
00029 VALUE eRSAError;
00030
00031
00032
00033
00034 static VALUE
00035 rsa_instance(VALUE klass, RSA *rsa)
00036 {
00037 EVP_PKEY *pkey;
00038 VALUE obj;
00039
00040 if (!rsa) {
00041 return Qfalse;
00042 }
00043 if (!(pkey = EVP_PKEY_new())) {
00044 return Qfalse;
00045 }
00046 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
00047 EVP_PKEY_free(pkey);
00048 return Qfalse;
00049 }
00050 WrapPKey(klass, obj, pkey);
00051
00052 return obj;
00053 }
00054
00055 VALUE
00056 ossl_rsa_new(EVP_PKEY *pkey)
00057 {
00058 VALUE obj;
00059
00060 if (!pkey) {
00061 obj = rsa_instance(cRSA, RSA_new());
00062 }
00063 else {
00064 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
00065 ossl_raise(rb_eTypeError, "Not a RSA key!");
00066 }
00067 WrapPKey(cRSA, obj, pkey);
00068 }
00069 if (obj == Qfalse) {
00070 ossl_raise(eRSAError, NULL);
00071 }
00072
00073 return obj;
00074 }
00075
00076
00077
00078
00079 #if defined(HAVE_RSA_GENERATE_KEY_EX) && HAVE_BN_GENCB
00080 struct rsa_blocking_gen_arg {
00081 RSA *rsa;
00082 BIGNUM *e;
00083 int size;
00084 BN_GENCB *cb;
00085 int result;
00086 };
00087
00088 static void *
00089 rsa_blocking_gen(void *arg)
00090 {
00091 struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg;
00092 gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb);
00093 return 0;
00094 }
00095 #endif
00096
00097 static RSA *
00098 rsa_generate(int size, unsigned long exp)
00099 {
00100 #if defined(HAVE_RSA_GENERATE_KEY_EX) && HAVE_BN_GENCB
00101 int i;
00102 BN_GENCB cb;
00103 struct ossl_generate_cb_arg cb_arg;
00104 struct rsa_blocking_gen_arg gen_arg;
00105 RSA *rsa = RSA_new();
00106 BIGNUM *e = BN_new();
00107
00108 if (!rsa || !e) {
00109 if (e) BN_free(e);
00110 if (rsa) RSA_free(rsa);
00111 return 0;
00112 }
00113 for (i = 0; i < (int)sizeof(exp) * 8; ++i) {
00114 if (exp & (1UL << i)) {
00115 if (BN_set_bit(e, i) == 0) {
00116 BN_free(e);
00117 RSA_free(rsa);
00118 return 0;
00119 }
00120 }
00121 }
00122
00123 memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
00124 if (rb_block_given_p())
00125 cb_arg.yield = 1;
00126 BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg);
00127 gen_arg.rsa = rsa;
00128 gen_arg.e = e;
00129 gen_arg.size = size;
00130 gen_arg.cb = &cb;
00131 if (cb_arg.yield == 1) {
00132
00133 rsa_blocking_gen(&gen_arg);
00134 } else {
00135
00136 rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
00137 }
00138 if (!gen_arg.result) {
00139 BN_free(e);
00140 RSA_free(rsa);
00141 if (cb_arg.state) rb_jump_tag(cb_arg.state);
00142 return 0;
00143 }
00144
00145 BN_free(e);
00146 return rsa;
00147 #else
00148 return RSA_generate_key(size, exp, rb_block_given_p() ? ossl_generate_cb : NULL, NULL);
00149 #endif
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 static VALUE
00162 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
00163 {
00164
00165 RSA *rsa;
00166 VALUE size, exp;
00167 VALUE obj;
00168
00169 rb_scan_args(argc, argv, "11", &size, &exp);
00170
00171 rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp));
00172 obj = rsa_instance(klass, rsa);
00173
00174 if (obj == Qfalse) {
00175 RSA_free(rsa);
00176 ossl_raise(eRSAError, NULL);
00177 }
00178
00179 return obj;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 static VALUE
00203 ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
00204 {
00205 EVP_PKEY *pkey;
00206 RSA *rsa;
00207 BIO *in;
00208 char *passwd = NULL;
00209 VALUE arg, pass;
00210
00211 GetPKey(self, pkey);
00212 if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
00213 rsa = RSA_new();
00214 }
00215 else if (FIXNUM_P(arg)) {
00216 rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass));
00217 if (!rsa) ossl_raise(eRSAError, NULL);
00218 }
00219 else {
00220 if (!NIL_P(pass)) passwd = StringValuePtr(pass);
00221 arg = ossl_to_der_if_possible(arg);
00222 in = ossl_obj2bio(arg);
00223 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
00224 if (!rsa) {
00225 OSSL_BIO_reset(in);
00226 rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
00227 }
00228 if (!rsa) {
00229 OSSL_BIO_reset(in);
00230 rsa = d2i_RSAPrivateKey_bio(in, NULL);
00231 }
00232 if (!rsa) {
00233 OSSL_BIO_reset(in);
00234 rsa = d2i_RSA_PUBKEY_bio(in, NULL);
00235 }
00236 if (!rsa) {
00237 OSSL_BIO_reset(in);
00238 rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
00239 }
00240 if (!rsa) {
00241 OSSL_BIO_reset(in);
00242 rsa = d2i_RSAPublicKey_bio(in, NULL);
00243 }
00244 BIO_free(in);
00245 if (!rsa) {
00246 ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
00247 }
00248 }
00249 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
00250 RSA_free(rsa);
00251 ossl_raise(eRSAError, NULL);
00252 }
00253
00254 return self;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 static VALUE
00265 ossl_rsa_is_public(VALUE self)
00266 {
00267 EVP_PKEY *pkey;
00268
00269 GetPKeyRSA(self, pkey);
00270
00271
00272
00273 return Qtrue;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 static VALUE
00283 ossl_rsa_is_private(VALUE self)
00284 {
00285 EVP_PKEY *pkey;
00286
00287 GetPKeyRSA(self, pkey);
00288
00289 return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 static VALUE
00302 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
00303 {
00304 EVP_PKEY *pkey;
00305 BIO *out;
00306 const EVP_CIPHER *ciph = NULL;
00307 char *passwd = NULL;
00308 VALUE cipher, pass, str;
00309
00310 GetPKeyRSA(self, pkey);
00311
00312 rb_scan_args(argc, argv, "02", &cipher, &pass);
00313
00314 if (!NIL_P(cipher)) {
00315 ciph = GetCipherPtr(cipher);
00316 if (!NIL_P(pass)) {
00317 StringValue(pass);
00318 if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
00319 ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
00320 passwd = RSTRING_PTR(pass);
00321 }
00322 }
00323 if (!(out = BIO_new(BIO_s_mem()))) {
00324 ossl_raise(eRSAError, NULL);
00325 }
00326 if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
00327 if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
00328 NULL, 0, ossl_pem_passwd_cb, passwd)) {
00329 BIO_free(out);
00330 ossl_raise(eRSAError, NULL);
00331 }
00332 } else {
00333 if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
00334 BIO_free(out);
00335 ossl_raise(eRSAError, NULL);
00336 }
00337 }
00338 str = ossl_membio2str(out);
00339
00340 return str;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349 static VALUE
00350 ossl_rsa_to_der(VALUE self)
00351 {
00352 EVP_PKEY *pkey;
00353 int (*i2d_func)_((const RSA*, unsigned char**));
00354 unsigned char *p;
00355 long len;
00356 VALUE str;
00357
00358 GetPKeyRSA(self, pkey);
00359 if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
00360 i2d_func = i2d_RSAPrivateKey;
00361 else
00362 i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
00363 if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
00364 ossl_raise(eRSAError, NULL);
00365 str = rb_str_new(0, len);
00366 p = (unsigned char *)RSTRING_PTR(str);
00367 if(i2d_func(pkey->pkey.rsa, &p) < 0)
00368 ossl_raise(eRSAError, NULL);
00369 ossl_str_adjust(str, p);
00370
00371 return str;
00372 }
00373
00374 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 static VALUE
00385 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
00386 {
00387 EVP_PKEY *pkey;
00388 int buf_len, pad;
00389 VALUE str, buffer, padding;
00390
00391 GetPKeyRSA(self, pkey);
00392 rb_scan_args(argc, argv, "11", &buffer, &padding);
00393 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00394 StringValue(buffer);
00395 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00396 buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00397 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00398 pad);
00399 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00400 rb_str_set_len(str, buf_len);
00401
00402 return str;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 static VALUE
00414 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
00415 {
00416 EVP_PKEY *pkey;
00417 int buf_len, pad;
00418 VALUE str, buffer, padding;
00419
00420 GetPKeyRSA(self, pkey);
00421 rb_scan_args(argc, argv, "11", &buffer, &padding);
00422 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00423 StringValue(buffer);
00424 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00425 buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00426 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00427 pad);
00428 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00429 rb_str_set_len(str, buf_len);
00430
00431 return str;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 static VALUE
00443 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
00444 {
00445 EVP_PKEY *pkey;
00446 int buf_len, pad;
00447 VALUE str, buffer, padding;
00448
00449 GetPKeyRSA(self, pkey);
00450 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00451 ossl_raise(eRSAError, "private key needed.");
00452 }
00453 rb_scan_args(argc, argv, "11", &buffer, &padding);
00454 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00455 StringValue(buffer);
00456 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00457 buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00458 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00459 pad);
00460 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00461 rb_str_set_len(str, buf_len);
00462
00463 return str;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 static VALUE
00475 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
00476 {
00477 EVP_PKEY *pkey;
00478 int buf_len, pad;
00479 VALUE str, buffer, padding;
00480
00481 GetPKeyRSA(self, pkey);
00482 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00483 ossl_raise(eRSAError, "private key needed.");
00484 }
00485 rb_scan_args(argc, argv, "11", &buffer, &padding);
00486 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00487 StringValue(buffer);
00488 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00489 buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00490 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00491 pad);
00492 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00493 rb_str_set_len(str, buf_len);
00494
00495 return str;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 static VALUE
00510 ossl_rsa_get_params(VALUE self)
00511 {
00512 EVP_PKEY *pkey;
00513 VALUE hash;
00514
00515 GetPKeyRSA(self, pkey);
00516
00517 hash = rb_hash_new();
00518
00519 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
00520 rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
00521 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
00522 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
00523 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
00524 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
00525 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
00526 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
00527
00528 return hash;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 static VALUE
00542 ossl_rsa_to_text(VALUE self)
00543 {
00544 EVP_PKEY *pkey;
00545 BIO *out;
00546 VALUE str;
00547
00548 GetPKeyRSA(self, pkey);
00549 if (!(out = BIO_new(BIO_s_mem()))) {
00550 ossl_raise(eRSAError, NULL);
00551 }
00552 if (!RSA_print(out, pkey->pkey.rsa, 0)) {
00553 BIO_free(out);
00554 ossl_raise(eRSAError, NULL);
00555 }
00556 str = ossl_membio2str(out);
00557
00558 return str;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567 static VALUE
00568 ossl_rsa_to_public_key(VALUE self)
00569 {
00570 EVP_PKEY *pkey;
00571 RSA *rsa;
00572 VALUE obj;
00573
00574 GetPKeyRSA(self, pkey);
00575
00576 rsa = RSAPublicKey_dup(pkey->pkey.rsa);
00577 obj = rsa_instance(CLASS_OF(self), rsa);
00578 if (obj == Qfalse) {
00579 RSA_free(rsa);
00580 ossl_raise(eRSAError, NULL);
00581 }
00582 return obj;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 OSSL_PKEY_BN(rsa, n)
00614 OSSL_PKEY_BN(rsa, e)
00615 OSSL_PKEY_BN(rsa, d)
00616 OSSL_PKEY_BN(rsa, p)
00617 OSSL_PKEY_BN(rsa, q)
00618 OSSL_PKEY_BN(rsa, dmp1)
00619 OSSL_PKEY_BN(rsa, dmq1)
00620 OSSL_PKEY_BN(rsa, iqmp)
00621
00622
00623
00624
00625 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
00626
00627 void
00628 Init_ossl_rsa()
00629 {
00630 #if 0
00631 mOSSL = rb_define_module("OpenSSL");
00632 mPKey = rb_define_module_under(mOSSL, "PKey");
00633 #endif
00634
00635
00636
00637
00638
00639
00640
00641 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
00654
00655 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
00656 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
00657
00658 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
00659 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
00660 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
00661 rb_define_method(cRSA, "export", ossl_rsa_export, -1);
00662 rb_define_alias(cRSA, "to_pem", "export");
00663 rb_define_alias(cRSA, "to_s", "export");
00664 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
00665 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
00666 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
00667 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
00668 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
00669 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
00670
00671 DEF_OSSL_PKEY_BN(cRSA, rsa, n);
00672 DEF_OSSL_PKEY_BN(cRSA, rsa, e);
00673 DEF_OSSL_PKEY_BN(cRSA, rsa, d);
00674 DEF_OSSL_PKEY_BN(cRSA, rsa, p);
00675 DEF_OSSL_PKEY_BN(cRSA, rsa, q);
00676 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
00677 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
00678 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
00679
00680 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
00681
00682 DefRSAConst(PKCS1_PADDING);
00683 DefRSAConst(SSLV23_PADDING);
00684 DefRSAConst(NO_PADDING);
00685 DefRSAConst(PKCS1_OAEP_PADDING);
00686
00687
00688
00689
00690
00691
00692 }
00693
00694 #else
00695 void
00696 Init_ossl_rsa()
00697 {
00698 }
00699 #endif
00700
00701