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