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
00302 static VALUE
00303 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
00304 {
00305 EVP_PKEY *pkey;
00306 BIO *out;
00307 const EVP_CIPHER *ciph = NULL;
00308 char *passwd = NULL;
00309 VALUE cipher, pass, str;
00310
00311 GetPKeyRSA(self, pkey);
00312
00313 rb_scan_args(argc, argv, "02", &cipher, &pass);
00314
00315 if (!NIL_P(cipher)) {
00316 ciph = GetCipherPtr(cipher);
00317 if (!NIL_P(pass)) {
00318 StringValue(pass);
00319 if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
00320 ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
00321 passwd = RSTRING_PTR(pass);
00322 }
00323 }
00324 if (!(out = BIO_new(BIO_s_mem()))) {
00325 ossl_raise(eRSAError, NULL);
00326 }
00327 if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
00328 if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
00329 NULL, 0, ossl_pem_passwd_cb, passwd)) {
00330 BIO_free(out);
00331 ossl_raise(eRSAError, NULL);
00332 }
00333 } else {
00334 if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
00335 BIO_free(out);
00336 ossl_raise(eRSAError, NULL);
00337 }
00338 }
00339 str = ossl_membio2str(out);
00340
00341 return str;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 static VALUE
00351 ossl_rsa_to_der(VALUE self)
00352 {
00353 EVP_PKEY *pkey;
00354 int (*i2d_func)_((const RSA*, unsigned char**));
00355 unsigned char *p;
00356 long len;
00357 VALUE str;
00358
00359 GetPKeyRSA(self, pkey);
00360 if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
00361 i2d_func = i2d_RSAPrivateKey;
00362 else
00363 i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
00364 if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
00365 ossl_raise(eRSAError, NULL);
00366 str = rb_str_new(0, len);
00367 p = (unsigned char *)RSTRING_PTR(str);
00368 if(i2d_func(pkey->pkey.rsa, &p) < 0)
00369 ossl_raise(eRSAError, NULL);
00370 ossl_str_adjust(str, p);
00371
00372 return str;
00373 }
00374
00375 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 static VALUE
00386 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
00387 {
00388 EVP_PKEY *pkey;
00389 int buf_len, pad;
00390 VALUE str, buffer, padding;
00391
00392 GetPKeyRSA(self, pkey);
00393 rb_scan_args(argc, argv, "11", &buffer, &padding);
00394 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00395 StringValue(buffer);
00396 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00397 buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00398 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00399 pad);
00400 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00401 rb_str_set_len(str, buf_len);
00402
00403 return str;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 static VALUE
00415 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
00416 {
00417 EVP_PKEY *pkey;
00418 int buf_len, pad;
00419 VALUE str, buffer, padding;
00420
00421 GetPKeyRSA(self, pkey);
00422 rb_scan_args(argc, argv, "11", &buffer, &padding);
00423 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00424 StringValue(buffer);
00425 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00426 buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00427 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00428 pad);
00429 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00430 rb_str_set_len(str, buf_len);
00431
00432 return str;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 static VALUE
00444 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
00445 {
00446 EVP_PKEY *pkey;
00447 int buf_len, pad;
00448 VALUE str, buffer, padding;
00449
00450 GetPKeyRSA(self, pkey);
00451 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00452 ossl_raise(eRSAError, "private key needed.");
00453 }
00454 rb_scan_args(argc, argv, "11", &buffer, &padding);
00455 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00456 StringValue(buffer);
00457 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00458 buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00459 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00460 pad);
00461 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00462 rb_str_set_len(str, buf_len);
00463
00464 return str;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 static VALUE
00476 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
00477 {
00478 EVP_PKEY *pkey;
00479 int buf_len, pad;
00480 VALUE str, buffer, padding;
00481
00482 GetPKeyRSA(self, pkey);
00483 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00484 ossl_raise(eRSAError, "private key needed.");
00485 }
00486 rb_scan_args(argc, argv, "11", &buffer, &padding);
00487 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00488 StringValue(buffer);
00489 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00490 buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00491 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00492 pad);
00493 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00494 rb_str_set_len(str, buf_len);
00495
00496 return str;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 static VALUE
00511 ossl_rsa_get_params(VALUE self)
00512 {
00513 EVP_PKEY *pkey;
00514 VALUE hash;
00515
00516 GetPKeyRSA(self, pkey);
00517
00518 hash = rb_hash_new();
00519
00520 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
00521 rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
00522 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
00523 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
00524 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
00525 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
00526 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
00527 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
00528
00529 return hash;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 static VALUE
00543 ossl_rsa_to_text(VALUE self)
00544 {
00545 EVP_PKEY *pkey;
00546 BIO *out;
00547 VALUE str;
00548
00549 GetPKeyRSA(self, pkey);
00550 if (!(out = BIO_new(BIO_s_mem()))) {
00551 ossl_raise(eRSAError, NULL);
00552 }
00553 if (!RSA_print(out, pkey->pkey.rsa, 0)) {
00554 BIO_free(out);
00555 ossl_raise(eRSAError, NULL);
00556 }
00557 str = ossl_membio2str(out);
00558
00559 return str;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 static VALUE
00569 ossl_rsa_to_public_key(VALUE self)
00570 {
00571 EVP_PKEY *pkey;
00572 RSA *rsa;
00573 VALUE obj;
00574
00575 GetPKeyRSA(self, pkey);
00576
00577 rsa = RSAPublicKey_dup(pkey->pkey.rsa);
00578 obj = rsa_instance(CLASS_OF(self), rsa);
00579 if (obj == Qfalse) {
00580 RSA_free(rsa);
00581 ossl_raise(eRSAError, NULL);
00582 }
00583 return obj;
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
00614 OSSL_PKEY_BN(rsa, n)
00615 OSSL_PKEY_BN(rsa, e)
00616 OSSL_PKEY_BN(rsa, d)
00617 OSSL_PKEY_BN(rsa, p)
00618 OSSL_PKEY_BN(rsa, q)
00619 OSSL_PKEY_BN(rsa, dmp1)
00620 OSSL_PKEY_BN(rsa, dmq1)
00621 OSSL_PKEY_BN(rsa, iqmp)
00622
00623
00624
00625
00626 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
00627
00628 void
00629 Init_ossl_rsa()
00630 {
00631 #if 0
00632 mOSSL = rb_define_module("OpenSSL");
00633 mPKey = rb_define_module_under(mOSSL, "PKey");
00634 #endif
00635
00636
00637
00638
00639
00640
00641
00642 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
00655
00656 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
00657 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
00658
00659 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
00660 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
00661 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
00662 rb_define_method(cRSA, "export", ossl_rsa_export, -1);
00663 rb_define_alias(cRSA, "to_pem", "export");
00664 rb_define_alias(cRSA, "to_s", "export");
00665 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
00666 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
00667 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
00668 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
00669 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
00670 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
00671
00672 DEF_OSSL_PKEY_BN(cRSA, rsa, n);
00673 DEF_OSSL_PKEY_BN(cRSA, rsa, e);
00674 DEF_OSSL_PKEY_BN(cRSA, rsa, d);
00675 DEF_OSSL_PKEY_BN(cRSA, rsa, p);
00676 DEF_OSSL_PKEY_BN(cRSA, rsa, q);
00677 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
00678 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
00679 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
00680
00681 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
00682
00683 DefRSAConst(PKCS1_PADDING);
00684 DefRSAConst(SSLV23_PADDING);
00685 DefRSAConst(NO_PADDING);
00686 DefRSAConst(PKCS1_OAEP_PADDING);
00687
00688
00689
00690
00691
00692
00693 }
00694
00695 #else
00696 void
00697 Init_ossl_rsa()
00698 {
00699 }
00700 #endif
00701
00702