|
Ruby 1.9.2p290(2011-07-09revision32553)
|
00001 /* 00002 * $Id: ossl_pkey_rsa.c 31795 2011-05-29 22:49:02Z yugui $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 00005 * All rights reserved. 00006 */ 00007 /* 00008 * This program is licenced under the same licence as Ruby. 00009 * (See the file 'LICENCE'.) 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) { /* PARANOIA? */ \ 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 * Classes 00027 */ 00028 VALUE cRSA; 00029 VALUE eRSAError; 00030 00031 /* 00032 * Public 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 * Private 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 * call-seq: 00089 * RSA.generate(size [, exponent]) -> rsa 00090 * 00091 * === Parameters 00092 * * +size+ is an integer representing the desired key size. Keys smaller than 1024 should be considered insecure. 00093 * * +exponent+ is an odd number normally 3, 17, or 65537. 00094 * 00095 */ 00096 static VALUE 00097 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) 00098 { 00099 /* why does this method exist? why can't initialize take an optional exponent? */ 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)); /* err handled by rsa_instance */ 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 * call-seq: 00119 * RSA.new([size | encoded_key] [, pass]) -> rsa 00120 * 00121 * === Parameters 00122 * * +size+ is an integer representing the desired key size. 00123 * * +encoded_key+ is a string containing PEM or DER encoded key. 00124 * * +pass+ is an optional string with the password to decrypt the encoded key. 00125 * 00126 * === Examples 00127 * * RSA.new(2048) -> rsa 00128 * * RSA.new(File.read("rsa.pem")) -> rsa 00129 * * RSA.new(File.read("rsa.pem"), "mypassword") -> rsa 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 (void)ERR_get_error(); 00156 rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); 00157 } 00158 if (!rsa) { 00159 (void)BIO_reset(in); 00160 (void)ERR_get_error(); 00161 rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); 00162 } 00163 if (!rsa) { 00164 (void)BIO_reset(in); 00165 (void)ERR_get_error(); 00166 rsa = d2i_RSAPrivateKey_bio(in, NULL); 00167 } 00168 if (!rsa) { 00169 (void)BIO_reset(in); 00170 (void)ERR_get_error(); 00171 rsa = d2i_RSAPublicKey_bio(in, NULL); 00172 } 00173 if (!rsa) { 00174 (void)BIO_reset(in); 00175 (void)ERR_get_error(); 00176 rsa = d2i_RSA_PUBKEY_bio(in, NULL); 00177 } 00178 BIO_free(in); 00179 if (!rsa) { 00180 (void)ERR_get_error(); 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 * call-seq: 00194 * rsa.public? -> true 00195 * 00196 * The return value is always true since every private key is also a public key. 00197 * 00198 */ 00199 static VALUE 00200 ossl_rsa_is_public(VALUE self) 00201 { 00202 EVP_PKEY *pkey; 00203 00204 GetPKeyRSA(self, pkey); 00205 /* 00206 * This method should check for n and e. BUG. 00207 */ 00208 return Qtrue; 00209 } 00210 00211 /* 00212 * call-seq: 00213 * rsa.private? -> true | false 00214 * 00215 */ 00216 static VALUE 00217 ossl_rsa_is_private(VALUE self) 00218 { 00219 EVP_PKEY *pkey; 00220 00221 GetPKeyRSA(self, pkey); 00222 00223 return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse; 00224 } 00225 00226 /* 00227 * call-seq: 00228 * rsa.to_pem([cipher, pass]) -> aString 00229 * 00230 * === Parameters 00231 * * +cipher+ is a Cipher object. 00232 * * +pass+ is a string. 00233 * 00234 * === Examples 00235 * * rsa.to_pem -> aString 00236 * * rsa.to_pem(cipher, pass) -> aString 00237 */ 00238 static VALUE 00239 ossl_rsa_export(int argc, VALUE *argv, VALUE self) 00240 { 00241 EVP_PKEY *pkey; 00242 BIO *out; 00243 const EVP_CIPHER *ciph = NULL; 00244 char *passwd = NULL; 00245 VALUE cipher, pass, str; 00246 00247 GetPKeyRSA(self, pkey); 00248 00249 rb_scan_args(argc, argv, "02", &cipher, &pass); 00250 00251 if (!NIL_P(cipher)) { 00252 ciph = GetCipherPtr(cipher); 00253 if (!NIL_P(pass)) { 00254 passwd = StringValuePtr(pass); 00255 } 00256 } 00257 if (!(out = BIO_new(BIO_s_mem()))) { 00258 ossl_raise(eRSAError, NULL); 00259 } 00260 if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) { 00261 if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph, 00262 NULL, 0, ossl_pem_passwd_cb, passwd)) { 00263 BIO_free(out); 00264 ossl_raise(eRSAError, NULL); 00265 } 00266 } else { 00267 if (!PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa)) { 00268 BIO_free(out); 00269 ossl_raise(eRSAError, NULL); 00270 } 00271 } 00272 str = ossl_membio2str(out); 00273 00274 return str; 00275 } 00276 00277 /* 00278 * call-seq: 00279 * rsa.to_der -> aString 00280 * 00281 */ 00282 static VALUE 00283 ossl_rsa_to_der(VALUE self) 00284 { 00285 EVP_PKEY *pkey; 00286 int (*i2d_func)_((const RSA*, unsigned char**)); 00287 unsigned char *p; 00288 long len; 00289 VALUE str; 00290 00291 GetPKeyRSA(self, pkey); 00292 if(RSA_HAS_PRIVATE(pkey->pkey.rsa)) 00293 i2d_func = i2d_RSAPrivateKey; 00294 else 00295 i2d_func = i2d_RSAPublicKey; 00296 if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0) 00297 ossl_raise(eRSAError, NULL); 00298 str = rb_str_new(0, len); 00299 p = (unsigned char *)RSTRING_PTR(str); 00300 if(i2d_func(pkey->pkey.rsa, &p) < 0) 00301 ossl_raise(eRSAError, NULL); 00302 ossl_str_adjust(str, p); 00303 00304 return str; 00305 } 00306 00307 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16) 00308 00309 /* 00310 * call-seq: 00311 * rsa.public_encrypt(string [, padding]) -> aString 00312 * 00313 */ 00314 static VALUE 00315 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self) 00316 { 00317 EVP_PKEY *pkey; 00318 int buf_len, pad; 00319 VALUE str, buffer, padding; 00320 00321 GetPKeyRSA(self, pkey); 00322 rb_scan_args(argc, argv, "11", &buffer, &padding); 00323 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); 00324 StringValue(buffer); 00325 str = rb_str_new(0, ossl_rsa_buf_size(pkey)); 00326 buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer), 00327 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, 00328 pad); 00329 if (buf_len < 0) ossl_raise(eRSAError, NULL); 00330 rb_str_set_len(str, buf_len); 00331 00332 return str; 00333 } 00334 00335 /* 00336 * call-seq: 00337 * rsa.public_decrypt(string [, padding]) -> aString 00338 * 00339 */ 00340 static VALUE 00341 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self) 00342 { 00343 EVP_PKEY *pkey; 00344 int buf_len, pad; 00345 VALUE str, buffer, padding; 00346 00347 GetPKeyRSA(self, pkey); 00348 rb_scan_args(argc, argv, "11", &buffer, &padding); 00349 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); 00350 StringValue(buffer); 00351 str = rb_str_new(0, ossl_rsa_buf_size(pkey)); 00352 buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer), 00353 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, 00354 pad); 00355 if (buf_len < 0) ossl_raise(eRSAError, NULL); 00356 rb_str_set_len(str, buf_len); 00357 00358 return str; 00359 } 00360 00361 /* 00362 * call-seq: 00363 * rsa.private_encrypt(string [, padding]) -> aString 00364 * 00365 */ 00366 static VALUE 00367 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self) 00368 { 00369 EVP_PKEY *pkey; 00370 int buf_len, pad; 00371 VALUE str, buffer, padding; 00372 00373 GetPKeyRSA(self, pkey); 00374 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { 00375 ossl_raise(eRSAError, "private key needed."); 00376 } 00377 rb_scan_args(argc, argv, "11", &buffer, &padding); 00378 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); 00379 StringValue(buffer); 00380 str = rb_str_new(0, ossl_rsa_buf_size(pkey)); 00381 buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer), 00382 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, 00383 pad); 00384 if (buf_len < 0) ossl_raise(eRSAError, NULL); 00385 rb_str_set_len(str, buf_len); 00386 00387 return str; 00388 } 00389 00390 00391 /* 00392 * call-seq: 00393 * rsa.private_decrypt(string [, padding]) -> aString 00394 * 00395 */ 00396 static VALUE 00397 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) 00398 { 00399 EVP_PKEY *pkey; 00400 int buf_len, pad; 00401 VALUE str, buffer, padding; 00402 00403 GetPKeyRSA(self, pkey); 00404 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { 00405 ossl_raise(eRSAError, "private key needed."); 00406 } 00407 rb_scan_args(argc, argv, "11", &buffer, &padding); 00408 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); 00409 StringValue(buffer); 00410 str = rb_str_new(0, ossl_rsa_buf_size(pkey)); 00411 buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer), 00412 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, 00413 pad); 00414 if (buf_len < 0) ossl_raise(eRSAError, NULL); 00415 rb_str_set_len(str, buf_len); 00416 00417 return str; 00418 } 00419 00420 /* 00421 * call-seq: 00422 * rsa.params -> hash 00423 * 00424 * Stores all parameters of key to the hash 00425 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00426 * Don't use :-)) (I's up to you) 00427 */ 00428 static VALUE 00429 ossl_rsa_get_params(VALUE self) 00430 { 00431 EVP_PKEY *pkey; 00432 VALUE hash; 00433 00434 GetPKeyRSA(self, pkey); 00435 00436 hash = rb_hash_new(); 00437 00438 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n)); 00439 rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e)); 00440 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d)); 00441 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p)); 00442 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q)); 00443 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1)); 00444 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1)); 00445 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp)); 00446 00447 return hash; 00448 } 00449 00450 /* 00451 * call-seq: 00452 * rsa.to_text -> aString 00453 * 00454 * Prints all parameters of key to buffer 00455 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00456 * Don't use :-)) (It's up to you) 00457 */ 00458 static VALUE 00459 ossl_rsa_to_text(VALUE self) 00460 { 00461 EVP_PKEY *pkey; 00462 BIO *out; 00463 VALUE str; 00464 00465 GetPKeyRSA(self, pkey); 00466 if (!(out = BIO_new(BIO_s_mem()))) { 00467 ossl_raise(eRSAError, NULL); 00468 } 00469 if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */ 00470 BIO_free(out); 00471 ossl_raise(eRSAError, NULL); 00472 } 00473 str = ossl_membio2str(out); 00474 00475 return str; 00476 } 00477 00478 /* 00479 * call-seq: 00480 * rsa.public_key -> aRSA 00481 * 00482 * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY 00483 */ 00484 static VALUE 00485 ossl_rsa_to_public_key(VALUE self) 00486 { 00487 EVP_PKEY *pkey; 00488 RSA *rsa; 00489 VALUE obj; 00490 00491 GetPKeyRSA(self, pkey); 00492 /* err check performed by rsa_instance */ 00493 rsa = RSAPublicKey_dup(pkey->pkey.rsa); 00494 obj = rsa_instance(CLASS_OF(self), rsa); 00495 if (obj == Qfalse) { 00496 RSA_free(rsa); 00497 ossl_raise(eRSAError, NULL); 00498 } 00499 return obj; 00500 } 00501 00502 /* 00503 * TODO: Test me 00504 00505 static VALUE 00506 ossl_rsa_blinding_on(VALUE self) 00507 { 00508 EVP_PKEY *pkey; 00509 00510 GetPKeyRSA(self, pkey); 00511 00512 if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) { 00513 ossl_raise(eRSAError, NULL); 00514 } 00515 return self; 00516 } 00517 00518 static VALUE 00519 ossl_rsa_blinding_off(VALUE self) 00520 { 00521 EVP_PKEY *pkey; 00522 00523 GetPKeyRSA(self, pkey); 00524 RSA_blinding_off(pkey->pkey.rsa); 00525 00526 return self; 00527 } 00528 */ 00529 00530 OSSL_PKEY_BN(rsa, n) 00531 OSSL_PKEY_BN(rsa, e) 00532 OSSL_PKEY_BN(rsa, d) 00533 OSSL_PKEY_BN(rsa, p) 00534 OSSL_PKEY_BN(rsa, q) 00535 OSSL_PKEY_BN(rsa, dmp1) 00536 OSSL_PKEY_BN(rsa, dmq1) 00537 OSSL_PKEY_BN(rsa, iqmp) 00538 00539 /* 00540 * INIT 00541 */ 00542 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x)) 00543 00544 void 00545 Init_ossl_rsa() 00546 { 00547 #if 0 /* let rdoc know about mOSSL and mPKey */ 00548 mOSSL = rb_define_module("OpenSSL"); 00549 mPKey = rb_define_module_under(mOSSL, "PKey"); 00550 #endif 00551 00552 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError); 00553 00554 cRSA = rb_define_class_under(mPKey, "RSA", cPKey); 00555 00556 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1); 00557 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); 00558 00559 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); 00560 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); 00561 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0); 00562 rb_define_method(cRSA, "export", ossl_rsa_export, -1); 00563 rb_define_alias(cRSA, "to_pem", "export"); 00564 rb_define_alias(cRSA, "to_s", "export"); 00565 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); 00566 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); 00567 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); 00568 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); 00569 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); 00570 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1); 00571 00572 DEF_OSSL_PKEY_BN(cRSA, rsa, n); 00573 DEF_OSSL_PKEY_BN(cRSA, rsa, e); 00574 DEF_OSSL_PKEY_BN(cRSA, rsa, d); 00575 DEF_OSSL_PKEY_BN(cRSA, rsa, p); 00576 DEF_OSSL_PKEY_BN(cRSA, rsa, q); 00577 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1); 00578 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1); 00579 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp); 00580 00581 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0); 00582 00583 DefRSAConst(PKCS1_PADDING); 00584 DefRSAConst(SSLV23_PADDING); 00585 DefRSAConst(NO_PADDING); 00586 DefRSAConst(PKCS1_OAEP_PADDING); 00587 00588 /* 00589 * TODO: Test it 00590 rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); 00591 rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0); 00592 */ 00593 } 00594 00595 #else /* defined NO_RSA */ 00596 void 00597 Init_ossl_rsa() 00598 { 00599 } 00600 #endif /* NO_RSA */ 00601 00602
1.7.3