2 * $Id: ossl_pkey_rsa.c 18168 2008-07-22 15:34:23Z nobu $
3 * 'OpenSSL for Ruby' project
4 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
8 * This program is licenced under the same licence as Ruby.
9 * (See the file 'LICENCE'.)
11 #if !defined(OPENSSL_NO_RSA)
15 #define GetPKeyRSA(obj, pkey) do { \
17 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \
18 ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
22 #define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q)
23 #define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj))
35 rsa_instance(VALUE klass, RSA *rsa)
43 if (!(pkey = EVP_PKEY_new())) {
46 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
50 WrapPKey(klass, obj, pkey);
56 ossl_rsa_new(EVP_PKEY *pkey)
61 obj = rsa_instance(cRSA, RSA_new());
64 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
65 ossl_raise(rb_eTypeError, "Not a RSA key!");
67 WrapPKey(cRSA, obj, pkey);
70 ossl_raise(eRSAError, NULL);
80 rsa_generate(int size, int exp)
82 return RSA_generate_key(size, exp,
83 rb_block_given_p() ? ossl_generate_cb : NULL,
89 * RSA.generate(size [, exponent]) -> rsa
92 * * +size+ is an integer representing the desired key size. Keys smaller than 1024 should be considered insecure.
93 * * +exponent+ is an odd number normally 3, 17, or 65537.
97 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
99 /* why does this method exist? why can't initialize take an optional exponent? */
104 rb_scan_args(argc, argv, "11", &size, &exp);
106 rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp)); /* err handled by rsa_instance */
107 obj = rsa_instance(klass, rsa);
111 ossl_raise(eRSAError, NULL);
119 * RSA.new([size | encoded_key] [, pass]) -> rsa
122 * * +size+ is an integer representing the desired key size.
123 * * +encoded_key+ is a string containing PEM or DER encoded key.
124 * * +pass+ is an optional string with the password to decrypt the encoded key.
127 * * RSA.new(2048) -> rsa
128 * * RSA.new(File.read("rsa.pem")) -> rsa
129 * * RSA.new(File.read("rsa.pem"), "mypassword") -> rsa
132 ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
141 if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
144 else if (FIXNUM_P(arg)) {
145 rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
146 if (!rsa) ossl_raise(eRSAError, NULL);
149 if (!NIL_P(pass)) passwd = StringValuePtr(pass);
150 arg = ossl_to_der_if_possible(arg);
151 in = ossl_obj2bio(arg);
152 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
155 rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
159 rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
163 rsa = d2i_RSAPrivateKey_bio(in, NULL);
167 rsa = d2i_RSAPublicKey_bio(in, NULL);
171 rsa = d2i_RSA_PUBKEY_bio(in, NULL);
174 if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
176 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
178 ossl_raise(eRSAError, NULL);
186 * rsa.public? -> true
188 * The return value is always true since every private key is also a public key.
192 ossl_rsa_is_public(VALUE self)
196 GetPKeyRSA(self, pkey);
198 * This method should check for n and e. BUG.
205 * rsa.private? -> true | false
209 ossl_rsa_is_private(VALUE self)
213 GetPKeyRSA(self, pkey);
215 return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
220 * rsa.to_pem([cipher, pass]) -> aString
223 * * +cipher+ is a Cipher object.
224 * * +pass+ is a string.
227 * * rsa.to_pem -> aString
228 * * rsa.to_pem(cipher, pass) -> aString
231 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
235 const EVP_CIPHER *ciph = NULL;
237 VALUE cipher, pass, str;
239 GetPKeyRSA(self, pkey);
241 rb_scan_args(argc, argv, "02", &cipher, &pass);
243 if (!NIL_P(cipher)) {
244 ciph = GetCipherPtr(cipher);
246 passwd = StringValuePtr(pass);
249 if (!(out = BIO_new(BIO_s_mem()))) {
250 ossl_raise(eRSAError, NULL);
252 if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
253 if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
254 NULL, 0, ossl_pem_passwd_cb, passwd)) {
256 ossl_raise(eRSAError, NULL);
259 if (!PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa)) {
261 ossl_raise(eRSAError, NULL);
264 str = ossl_membio2str(out);
271 * rsa.to_der -> aString
275 ossl_rsa_to_der(VALUE self)
278 int (*i2d_func)_((const RSA*, unsigned char**));
283 GetPKeyRSA(self, pkey);
284 if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
285 i2d_func = i2d_RSAPrivateKey;
287 i2d_func = i2d_RSAPublicKey;
288 if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
289 ossl_raise(eRSAError, NULL);
290 str = rb_str_new(0, len);
291 p = (unsigned char *)RSTRING_PTR(str);
292 if(i2d_func(pkey->pkey.rsa, &p) < 0)
293 ossl_raise(eRSAError, NULL);
294 ossl_str_adjust(str, p);
299 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
303 * rsa.public_encrypt(string [, padding]) -> aString
307 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
311 VALUE str, buffer, padding;
313 GetPKeyRSA(self, pkey);
314 rb_scan_args(argc, argv, "11", &buffer, &padding);
315 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
317 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
318 buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
319 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
321 if (buf_len < 0) ossl_raise(eRSAError, NULL);
322 rb_str_set_len(str, buf_len);
329 * rsa.public_decrypt(string [, padding]) -> aString
333 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
337 VALUE str, buffer, padding;
339 GetPKeyRSA(self, pkey);
340 rb_scan_args(argc, argv, "11", &buffer, &padding);
341 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
343 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
344 buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
345 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
347 if (buf_len < 0) ossl_raise(eRSAError, NULL);
348 rb_str_set_len(str, buf_len);
355 * rsa.private_encrypt(string [, padding]) -> aString
359 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
363 VALUE str, buffer, padding;
365 GetPKeyRSA(self, pkey);
366 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
367 ossl_raise(eRSAError, "private key needed.");
369 rb_scan_args(argc, argv, "11", &buffer, &padding);
370 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
372 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
373 buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
374 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
376 if (buf_len < 0) ossl_raise(eRSAError, NULL);
377 rb_str_set_len(str, buf_len);
385 * rsa.private_decrypt(string [, padding]) -> aString
389 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
393 VALUE str, buffer, padding;
395 GetPKeyRSA(self, pkey);
396 if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
397 ossl_raise(eRSAError, "private key needed.");
399 rb_scan_args(argc, argv, "11", &buffer, &padding);
400 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
402 str = rb_str_new(0, ossl_rsa_buf_size(pkey));
403 buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
404 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
406 if (buf_len < 0) ossl_raise(eRSAError, NULL);
407 rb_str_set_len(str, buf_len);
416 * Stores all parameters of key to the hash
417 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
418 * Don't use :-)) (I's up to you)
421 ossl_rsa_get_params(VALUE self)
426 GetPKeyRSA(self, pkey);
428 hash = rb_hash_new();
430 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
431 rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
432 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
433 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
434 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
435 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
436 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
437 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
444 * rsa.to_text -> aString
446 * Prints all parameters of key to buffer
447 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
448 * Don't use :-)) (It's up to you)
451 ossl_rsa_to_text(VALUE self)
457 GetPKeyRSA(self, pkey);
458 if (!(out = BIO_new(BIO_s_mem()))) {
459 ossl_raise(eRSAError, NULL);
461 if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
463 ossl_raise(eRSAError, NULL);
465 str = ossl_membio2str(out);
472 * rsa.public_key -> aRSA
474 * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY
477 ossl_rsa_to_public_key(VALUE self)
483 GetPKeyRSA(self, pkey);
484 /* err check performed by rsa_instance */
485 rsa = RSAPublicKey_dup(pkey->pkey.rsa);
486 obj = rsa_instance(CLASS_OF(self), rsa);
489 ossl_raise(eRSAError, NULL);
498 ossl_rsa_blinding_on(VALUE self)
502 GetPKeyRSA(self, pkey);
504 if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
505 ossl_raise(eRSAError, NULL);
511 ossl_rsa_blinding_off(VALUE self)
515 GetPKeyRSA(self, pkey);
516 RSA_blinding_off(pkey->pkey.rsa);
522 OSSL_PKEY_BN(rsa, n);
523 OSSL_PKEY_BN(rsa, e);
524 OSSL_PKEY_BN(rsa, d);
525 OSSL_PKEY_BN(rsa, p);
526 OSSL_PKEY_BN(rsa, q);
527 OSSL_PKEY_BN(rsa, dmp1);
528 OSSL_PKEY_BN(rsa, dmq1);
529 OSSL_PKEY_BN(rsa, iqmp);
534 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
539 #if 0 /* let rdoc know about mOSSL and mPKey */
540 mOSSL = rb_define_module("OpenSSL");
541 mPKey = rb_define_module_under(mOSSL, "PKey");
544 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
546 cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
548 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
549 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
551 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
552 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
553 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
554 rb_define_method(cRSA, "export", ossl_rsa_export, -1);
555 rb_define_alias(cRSA, "to_pem", "export");
556 rb_define_alias(cRSA, "to_s", "export");
557 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
558 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
559 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
560 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
561 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
562 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
564 DEF_OSSL_PKEY_BN(cRSA, rsa, n);
565 DEF_OSSL_PKEY_BN(cRSA, rsa, e);
566 DEF_OSSL_PKEY_BN(cRSA, rsa, d);
567 DEF_OSSL_PKEY_BN(cRSA, rsa, p);
568 DEF_OSSL_PKEY_BN(cRSA, rsa, q);
569 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
570 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
571 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
573 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
575 DefRSAConst(PKCS1_PADDING);
576 DefRSAConst(SSLV23_PADDING);
577 DefRSAConst(NO_PADDING);
578 DefRSAConst(PKCS1_OAEP_PADDING);
582 rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
583 rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
587 #else /* defined NO_RSA */