|
Ruby 1.9.2p180(2011-02-18revision30909)
|
00001 /* 00002 * $Id: ossl_pkey_rsa.c 27440 2010-04-22 08:21:01Z nobu $ 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 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 * call-seq: 00186 * rsa.public? -> true 00187 * 00188 * The return value is always true since every private key is also a public key. 00189 * 00190 */ 00191 static VALUE 00192 ossl_rsa_is_public(VALUE self) 00193 { 00194 EVP_PKEY *pkey; 00195 00196 GetPKeyRSA(self, pkey); 00197 /* 00198 * This method should check for n and e. BUG. 00199 */ 00200 return Qtrue; 00201 } 00202 00203 /* 00204 * call-seq: 00205 * rsa.private? -> true | false 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 * call-seq: 00220 * rsa.to_pem([cipher, pass]) -> aString 00221 * 00222 * === Parameters 00223 * * +cipher+ is a Cipher object. 00224 * * +pass+ is a string. 00225 * 00226 * === Examples 00227 * * rsa.to_pem -> aString 00228 * * rsa.to_pem(cipher, pass) -> aString 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 * call-seq: 00271 * rsa.to_der -> aString 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 * call-seq: 00303 * rsa.public_encrypt(string [, padding]) -> aString 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 * call-seq: 00329 * rsa.public_decrypt(string [, padding]) -> aString 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 * call-seq: 00355 * rsa.private_encrypt(string [, padding]) -> aString 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 * call-seq: 00385 * rsa.private_decrypt(string [, padding]) -> aString 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 * call-seq: 00414 * rsa.params -> hash 00415 * 00416 * Stores all parameters of key to the hash 00417 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00418 * Don't use :-)) (I's up to you) 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 * call-seq: 00444 * rsa.to_text -> aString 00445 * 00446 * Prints all parameters of key to buffer 00447 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00448 * Don't use :-)) (It's up to you) 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)) { /* offset = 0 */ 00462 BIO_free(out); 00463 ossl_raise(eRSAError, NULL); 00464 } 00465 str = ossl_membio2str(out); 00466 00467 return str; 00468 } 00469 00470 /* 00471 * call-seq: 00472 * rsa.public_key -> aRSA 00473 * 00474 * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY 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 /* err check performed by rsa_instance */ 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 * TODO: Test me 00496 00497 static VALUE 00498 ossl_rsa_blinding_on(VALUE self) 00499 { 00500 EVP_PKEY *pkey; 00501 00502 GetPKeyRSA(self, pkey); 00503 00504 if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) { 00505 ossl_raise(eRSAError, NULL); 00506 } 00507 return self; 00508 } 00509 00510 static VALUE 00511 ossl_rsa_blinding_off(VALUE self) 00512 { 00513 EVP_PKEY *pkey; 00514 00515 GetPKeyRSA(self, pkey); 00516 RSA_blinding_off(pkey->pkey.rsa); 00517 00518 return self; 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 * INIT 00533 */ 00534 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x)) 00535 00536 void 00537 Init_ossl_rsa() 00538 { 00539 #if 0 /* let rdoc know about mOSSL and mPKey */ 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 * TODO: Test it 00582 rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); 00583 rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0); 00584 */ 00585 } 00586 00587 #else /* defined NO_RSA */ 00588 void 00589 Init_ossl_rsa() 00590 { 00591 } 00592 #endif /* NO_RSA */ 00593 00594
1.7.3