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 static RSA *
00080 rsa_generate(int size, int exp)
00081 {
00082 return RSA_generate_key(size, exp,
00083 rb_block_given_p() ? ossl_generate_cb : NULL,
00084 NULL);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static VALUE
00097 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
00098 {
00099
00100 RSA *rsa;
00101 VALUE size, exp;
00102 VALUE obj;
00103
00104 rb_scan_args(argc, argv, "11", &size, &exp);
00105
00106 rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp));
00107 obj = rsa_instance(klass, rsa);
00108
00109 if (obj == Qfalse) {
00110 RSA_free(rsa);
00111 ossl_raise(eRSAError, NULL);
00112 }
00113
00114 return obj;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 static VALUE
00138 ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
00139 {
00140 EVP_PKEY *pkey;
00141 RSA *rsa;
00142 BIO *in;
00143 char *passwd = NULL;
00144 VALUE arg, pass;
00145
00146 GetPKey(self, pkey);
00147 if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
00148 rsa = RSA_new();
00149 }
00150 else if (FIXNUM_P(arg)) {
00151 rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
00152 if (!rsa) ossl_raise(eRSAError, NULL);
00153 }
00154 else {
00155 if (!NIL_P(pass)) passwd = StringValuePtr(pass);
00156 arg = ossl_to_der_if_possible(arg);
00157 in = ossl_obj2bio(arg);
00158 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
00159 if (!rsa) {
00160 OSSL_BIO_reset(in);
00161 rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
00162 }
00163 if (!rsa) {
00164 OSSL_BIO_reset(in);
00165 rsa = d2i_RSAPrivateKey_bio(in, NULL);
00166 }
00167 if (!rsa) {
00168 OSSL_BIO_reset(in);
00169 rsa = d2i_RSA_PUBKEY_bio(in, NULL);
00170 }
00171 if (!rsa) {
00172 OSSL_BIO_reset(in);
00173 rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
00174 }
00175 if (!rsa) {
00176 OSSL_BIO_reset(in);
00177 rsa = d2i_RSAPublicKey_bio(in, NULL);
00178 }
00179 BIO_free(in);
00180 if (!rsa) {
00181 ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
00182 }
00183 }
00184 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
00185 RSA_free(rsa);
00186 ossl_raise(eRSAError, NULL);
00187 }
00188
00189 return self;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199 static VALUE
00200 ossl_rsa_is_public(VALUE self)
00201 {
00202 EVP_PKEY *pkey;
00203
00204 GetPKeyRSA(self, pkey);
00205
00206
00207
00208 return Qtrue;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 static VALUE
00218 ossl_rsa_is_private(VALUE self)
00219 {
00220 EVP_PKEY *pkey;
00221
00222 GetPKeyRSA(self, pkey);
00223
00224 return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 static VALUE
00237 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
00238 {
00239 EVP_PKEY *pkey;
00240 BIO *out;
00241 const EVP_CIPHER *ciph = NULL;
00242 char *passwd = NULL;
00243 VALUE cipher, pass, str;
00244
00245 GetPKeyRSA(self, pkey);
00246
00247 rb_scan_args(argc, argv, "02", &cipher, &pass);
00248
00249 if (!NIL_P(cipher)) {
00250 ciph = GetCipherPtr(cipher);
00251 if (!NIL_P(pass)) {
00252 passwd = StringValuePtr(pass);
00253 }
00254 }
00255 if (!(out = BIO_new(BIO_s_mem()))) {
00256 ossl_raise(eRSAError, NULL);
00257 }
00258 if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
00259 if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
00260 NULL, 0, ossl_pem_passwd_cb, passwd)) {
00261 BIO_free(out);
00262 ossl_raise(eRSAError, NULL);
00263 }
00264 } else {
00265 if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
00266 BIO_free(out);
00267 ossl_raise(eRSAError, NULL);
00268 }
00269 }
00270 str = ossl_membio2str(out);
00271
00272 return str;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 static VALUE
00282 ossl_rsa_to_der(VALUE self)
00283 {
00284 EVP_PKEY *pkey;
00285 int (*i2d_func)_((const RSA*, unsigned char**));
00286 unsigned char *p;
00287 long len;
00288 VALUE str;
00289
00290 GetPKeyRSA(self, pkey);
00291 if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
00292 i2d_func = i2d_RSAPrivateKey;
00293 else
00294 i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
00295 if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
00296 ossl_raise(eRSAError, NULL);
00297 str = rb_str_new(0, len);
00298 p = (unsigned char *)RSTRING_PTR(str);
00299 if(i2d_func(pkey->pkey.rsa, &p) < 0)
00300 ossl_raise(eRSAError, NULL);
00301 ossl_str_adjust(str, p);
00302
00303 return str;
00304 }
00305
00306 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 static VALUE
00317 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
00318 {
00319 EVP_PKEY *pkey;
00320 int buf_len, pad;
00321 VALUE str, buffer, padding;
00322
00323 GetPKeyRSA(self, pkey);
00324 rb_scan_args(argc, argv, "11", &buffer, &padding);
00325 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00326 StringValue(buffer);
00327 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00328 buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00329 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00330 pad);
00331 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00332 rb_str_set_len(str, buf_len);
00333
00334 return str;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 static VALUE
00346 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
00347 {
00348 EVP_PKEY *pkey;
00349 int buf_len, pad;
00350 VALUE str, buffer, padding;
00351
00352 GetPKeyRSA(self, pkey);
00353 rb_scan_args(argc, argv, "11", &buffer, &padding);
00354 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00355 StringValue(buffer);
00356 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00357 buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00358 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00359 pad);
00360 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00361 rb_str_set_len(str, buf_len);
00362
00363 return str;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 static VALUE
00375 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
00376 {
00377 EVP_PKEY *pkey;
00378 int buf_len, pad;
00379 VALUE str, buffer, padding;
00380
00381 GetPKeyRSA(self, pkey);
00382 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00383 ossl_raise(eRSAError, "private key needed.");
00384 }
00385 rb_scan_args(argc, argv, "11", &buffer, &padding);
00386 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00387 StringValue(buffer);
00388 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00389 buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00390 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00391 pad);
00392 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00393 rb_str_set_len(str, buf_len);
00394
00395 return str;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 static VALUE
00407 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
00408 {
00409 EVP_PKEY *pkey;
00410 int buf_len, pad;
00411 VALUE str, buffer, padding;
00412
00413 GetPKeyRSA(self, pkey);
00414 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
00415 ossl_raise(eRSAError, "private key needed.");
00416 }
00417 rb_scan_args(argc, argv, "11", &buffer, &padding);
00418 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
00419 StringValue(buffer);
00420 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
00421 buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
00422 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
00423 pad);
00424 if (buf_len < 0) ossl_raise(eRSAError, NULL);
00425 rb_str_set_len(str, buf_len);
00426
00427 return str;
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 static VALUE
00442 ossl_rsa_get_params(VALUE self)
00443 {
00444 EVP_PKEY *pkey;
00445 VALUE hash;
00446
00447 GetPKeyRSA(self, pkey);
00448
00449 hash = rb_hash_new();
00450
00451 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
00452 rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
00453 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
00454 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
00455 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
00456 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
00457 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
00458 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
00459
00460 return hash;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 static VALUE
00474 ossl_rsa_to_text(VALUE self)
00475 {
00476 EVP_PKEY *pkey;
00477 BIO *out;
00478 VALUE str;
00479
00480 GetPKeyRSA(self, pkey);
00481 if (!(out = BIO_new(BIO_s_mem()))) {
00482 ossl_raise(eRSAError, NULL);
00483 }
00484 if (!RSA_print(out, pkey->pkey.rsa, 0)) {
00485 BIO_free(out);
00486 ossl_raise(eRSAError, NULL);
00487 }
00488 str = ossl_membio2str(out);
00489
00490 return str;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 static VALUE
00500 ossl_rsa_to_public_key(VALUE self)
00501 {
00502 EVP_PKEY *pkey;
00503 RSA *rsa;
00504 VALUE obj;
00505
00506 GetPKeyRSA(self, pkey);
00507
00508 rsa = RSAPublicKey_dup(pkey->pkey.rsa);
00509 obj = rsa_instance(CLASS_OF(self), rsa);
00510 if (obj == Qfalse) {
00511 RSA_free(rsa);
00512 ossl_raise(eRSAError, NULL);
00513 }
00514 return obj;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 OSSL_PKEY_BN(rsa, n)
00546 OSSL_PKEY_BN(rsa, e)
00547 OSSL_PKEY_BN(rsa, d)
00548 OSSL_PKEY_BN(rsa, p)
00549 OSSL_PKEY_BN(rsa, q)
00550 OSSL_PKEY_BN(rsa, dmp1)
00551 OSSL_PKEY_BN(rsa, dmq1)
00552 OSSL_PKEY_BN(rsa, iqmp)
00553
00554
00555
00556
00557 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
00558
00559 void
00560 Init_ossl_rsa()
00561 {
00562 #if 0
00563 mOSSL = rb_define_module("OpenSSL");
00564 mPKey = rb_define_module_under(mOSSL, "PKey");
00565 #endif
00566
00567
00568
00569
00570
00571
00572
00573 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
00586
00587 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
00588 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
00589
00590 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
00591 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
00592 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
00593 rb_define_method(cRSA, "export", ossl_rsa_export, -1);
00594 rb_define_alias(cRSA, "to_pem", "export");
00595 rb_define_alias(cRSA, "to_s", "export");
00596 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
00597 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
00598 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
00599 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
00600 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
00601 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
00602
00603 DEF_OSSL_PKEY_BN(cRSA, rsa, n);
00604 DEF_OSSL_PKEY_BN(cRSA, rsa, e);
00605 DEF_OSSL_PKEY_BN(cRSA, rsa, d);
00606 DEF_OSSL_PKEY_BN(cRSA, rsa, p);
00607 DEF_OSSL_PKEY_BN(cRSA, rsa, q);
00608 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
00609 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
00610 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
00611
00612 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
00613
00614 DefRSAConst(PKCS1_PADDING);
00615 DefRSAConst(SSLV23_PADDING);
00616 DefRSAConst(NO_PADDING);
00617 DefRSAConst(PKCS1_OAEP_PADDING);
00618
00619
00620
00621
00622
00623
00624 }
00625
00626 #else
00627 void
00628 Init_ossl_rsa()
00629 {
00630 }
00631 #endif
00632
00633