OSDN Git Service

ruby-1.9.1-rc1
[splhack/AndroidRuby.git] / lib / ruby-1.9.1-rc1 / ext / openssl / ossl_pkey_rsa.c
1 /*
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>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 #if !defined(OPENSSL_NO_RSA)
12
13 #include "ossl.h"
14
15 #define GetPKeyRSA(obj, pkey) do { \
16     GetPKey(obj, pkey); \
17     if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \
18         ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
19     } \
20 } while (0)
21
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))
24
25 /*
26  * Classes
27  */
28 VALUE cRSA;
29 VALUE eRSAError;
30
31 /*
32  * Public
33  */
34 static VALUE
35 rsa_instance(VALUE klass, RSA *rsa)
36 {
37     EVP_PKEY *pkey;
38     VALUE obj;
39         
40     if (!rsa) {
41         return Qfalse;
42     }
43     if (!(pkey = EVP_PKEY_new())) {
44         return Qfalse;
45     }
46     if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
47         EVP_PKEY_free(pkey);
48         return Qfalse;
49     }
50     WrapPKey(klass, obj, pkey);
51         
52     return obj;
53 }
54
55 VALUE
56 ossl_rsa_new(EVP_PKEY *pkey)
57 {
58     VALUE obj;
59
60     if (!pkey) {
61         obj = rsa_instance(cRSA, RSA_new());
62     }
63     else {
64         if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
65             ossl_raise(rb_eTypeError, "Not a RSA key!");
66         }
67         WrapPKey(cRSA, obj, pkey);
68     }
69     if (obj == Qfalse) {
70         ossl_raise(eRSAError, NULL);
71     }
72
73     return obj;
74 }
75
76 /*
77  * Private
78  */
79 static RSA *
80 rsa_generate(int size, int exp)
81 {
82     return RSA_generate_key(size, exp,
83             rb_block_given_p() ? ossl_generate_cb : NULL,
84             NULL);
85 }
86
87 /*
88  *  call-seq:
89  *     RSA.generate(size [, exponent]) -> rsa
90  *
91  *  === Parameters
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.
94  *
95  */
96 static VALUE
97 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
98 {
99 /* why does this method exist?  why can't initialize take an optional exponent? */
100     RSA *rsa;
101     VALUE size, exp;
102     VALUE obj;
103
104     rb_scan_args(argc, argv, "11", &size, &exp);
105
106     rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp)); /* err handled by rsa_instance */
107     obj = rsa_instance(klass, rsa);
108
109     if (obj == Qfalse) {
110         RSA_free(rsa);
111         ossl_raise(eRSAError, NULL);
112     }
113
114     return obj;
115 }
116
117 /*
118  *  call-seq:
119  *     RSA.new([size | encoded_key] [, pass]) -> rsa
120  *
121  *  === Parameters
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.
125  *
126  *  === Examples
127  *  * RSA.new(2048) -> rsa 
128  *  * RSA.new(File.read("rsa.pem")) -> rsa
129  *  * RSA.new(File.read("rsa.pem"), "mypassword") -> rsa
130  */
131 static VALUE
132 ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
133 {
134     EVP_PKEY *pkey;
135     RSA *rsa;
136     BIO *in;
137     char *passwd = NULL;
138     VALUE arg, pass;
139         
140     GetPKey(self, pkey);
141     if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
142         rsa = RSA_new();
143     }
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);
147     }
148     else {
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);
153         if (!rsa) {
154             (void)BIO_reset(in);
155             rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
156         }
157         if (!rsa) {
158             (void)BIO_reset(in);
159             rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
160         }
161         if (!rsa) {
162             (void)BIO_reset(in);
163             rsa = d2i_RSAPrivateKey_bio(in, NULL);
164         }
165         if (!rsa) {
166             (void)BIO_reset(in);
167             rsa = d2i_RSAPublicKey_bio(in, NULL);
168         }
169         if (!rsa) {
170             (void)BIO_reset(in);
171             rsa = d2i_RSA_PUBKEY_bio(in, NULL);
172         }
173         BIO_free(in);
174         if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
175     }
176     if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
177         RSA_free(rsa);
178         ossl_raise(eRSAError, NULL);
179     }
180
181     return self;
182 }
183
184 /*
185  *  call-seq:
186  *     rsa.public? -> true
187  *
188  *  The return value is always true since every private key is also a public key.
189  *
190  */
191 static VALUE
192 ossl_rsa_is_public(VALUE self)
193 {
194     EVP_PKEY *pkey;
195
196     GetPKeyRSA(self, pkey);
197     /*
198      * This method should check for n and e.  BUG.
199      */
200     return Qtrue;
201 }
202
203 /*
204  *  call-seq:
205  *     rsa.private? -> true | false
206  *
207  */
208 static VALUE
209 ossl_rsa_is_private(VALUE self)
210 {
211     EVP_PKEY *pkey;
212         
213     GetPKeyRSA(self, pkey);
214     
215     return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
216 }
217
218 /*
219  *  call-seq:
220  *     rsa.to_pem([cipher, pass]) -> aString
221  *
222  *  === Parameters
223  *  * +cipher+ is a Cipher object.
224  *  * +pass+ is a string.
225  *
226  *  === Examples
227  *  * rsa.to_pem -> aString
228  *  * rsa.to_pem(cipher, pass) -> aString
229  */
230 static VALUE
231 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
232 {
233     EVP_PKEY *pkey;
234     BIO *out;
235     const EVP_CIPHER *ciph = NULL;
236     char *passwd = NULL;
237     VALUE cipher, pass, str;
238
239     GetPKeyRSA(self, pkey);
240
241     rb_scan_args(argc, argv, "02", &cipher, &pass);
242
243     if (!NIL_P(cipher)) {
244         ciph = GetCipherPtr(cipher);
245         if (!NIL_P(pass)) {
246             passwd = StringValuePtr(pass);
247         }
248     }
249     if (!(out = BIO_new(BIO_s_mem()))) {
250         ossl_raise(eRSAError, NULL);
251     }
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)) {
255             BIO_free(out);
256             ossl_raise(eRSAError, NULL);
257         }
258     } else {
259         if (!PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa)) {
260             BIO_free(out);
261             ossl_raise(eRSAError, NULL);
262         }
263     }
264     str = ossl_membio2str(out);
265     
266     return str;
267 }
268
269 /*
270  *  call-seq:
271  *     rsa.to_der -> aString
272  *
273  */
274 static VALUE
275 ossl_rsa_to_der(VALUE self)
276 {
277     EVP_PKEY *pkey;
278     int (*i2d_func)_((const RSA*, unsigned char**));
279     unsigned char *p;
280     long len;
281     VALUE str;
282
283     GetPKeyRSA(self, pkey);
284     if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
285         i2d_func = i2d_RSAPrivateKey;
286     else
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);
295
296     return str;
297 }
298
299 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
300
301 /*
302  *  call-seq:
303  *     rsa.public_encrypt(string [, padding]) -> aString
304  *
305  */
306 static VALUE
307 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
308 {
309     EVP_PKEY *pkey;
310     int buf_len, pad;
311     VALUE str, buffer, padding;
312
313     GetPKeyRSA(self, pkey);
314     rb_scan_args(argc, argv, "11", &buffer, &padding);
315     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
316     StringValue(buffer);
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,
320                                  pad);
321     if (buf_len < 0) ossl_raise(eRSAError, NULL);
322     rb_str_set_len(str, buf_len);
323
324     return str;
325 }
326
327 /*
328  *  call-seq:
329  *     rsa.public_decrypt(string [, padding]) -> aString
330  *
331  */
332 static VALUE
333 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
334 {
335     EVP_PKEY *pkey;
336     int buf_len, pad;
337     VALUE str, buffer, padding;
338
339     GetPKeyRSA(self, pkey);
340     rb_scan_args(argc, argv, "11", &buffer, &padding);
341     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
342     StringValue(buffer);
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,
346                                  pad);
347     if (buf_len < 0) ossl_raise(eRSAError, NULL);
348     rb_str_set_len(str, buf_len);
349     
350     return str;
351 }
352
353 /*
354  *  call-seq:
355  *     rsa.private_encrypt(string [, padding]) -> aString
356  *
357  */
358 static VALUE
359 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
360 {
361     EVP_PKEY *pkey;
362     int buf_len, pad;
363     VALUE str, buffer, padding;
364
365     GetPKeyRSA(self, pkey);
366     if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
367         ossl_raise(eRSAError, "private key needed.");
368     }   
369     rb_scan_args(argc, argv, "11", &buffer, &padding);
370     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
371     StringValue(buffer);
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,
375                                   pad);
376     if (buf_len < 0) ossl_raise(eRSAError, NULL);
377     rb_str_set_len(str, buf_len);
378     
379     return str;
380 }
381
382
383 /*
384  *  call-seq:
385  *     rsa.private_decrypt(string [, padding]) -> aString
386  *
387  */
388 static VALUE
389 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
390 {
391     EVP_PKEY *pkey;
392     int buf_len, pad;
393     VALUE str, buffer, padding;
394
395     GetPKeyRSA(self, pkey);
396     if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
397         ossl_raise(eRSAError, "private key needed.");
398     }
399     rb_scan_args(argc, argv, "11", &buffer, &padding);
400     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
401     StringValue(buffer);
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,
405                                   pad);
406     if (buf_len < 0) ossl_raise(eRSAError, NULL);
407     rb_str_set_len(str, buf_len);
408
409     return str;
410 }
411
412 /*
413  *  call-seq:
414  *     rsa.params -> hash
415  *
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)
419  */
420 static VALUE
421 ossl_rsa_get_params(VALUE self)
422 {
423     EVP_PKEY *pkey;
424     VALUE hash;
425
426     GetPKeyRSA(self, pkey);
427
428     hash = rb_hash_new();
429
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));
438     
439     return hash;
440 }
441
442 /*
443  *  call-seq:
444  *     rsa.to_text -> aString
445  *
446  * Prints all parameters of key to buffer
447  * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
448  * Don't use :-)) (It's up to you)
449  */
450 static VALUE
451 ossl_rsa_to_text(VALUE self)
452 {
453     EVP_PKEY *pkey;
454     BIO *out;
455     VALUE str;
456
457     GetPKeyRSA(self, pkey);
458     if (!(out = BIO_new(BIO_s_mem()))) {
459         ossl_raise(eRSAError, NULL);
460     }
461     if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
462         BIO_free(out);
463         ossl_raise(eRSAError, NULL);
464     }
465     str = ossl_membio2str(out);
466
467     return str;
468 }
469
470 /*
471  *  call-seq:
472  *     rsa.public_key -> aRSA
473  *
474  * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY
475  */
476 static VALUE
477 ossl_rsa_to_public_key(VALUE self)
478 {
479     EVP_PKEY *pkey;
480     RSA *rsa;
481     VALUE obj;
482     
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);
487     if (obj == Qfalse) {
488         RSA_free(rsa);
489         ossl_raise(eRSAError, NULL);
490     }
491     return obj;
492 }
493
494 /*
495  * TODO: Test me
496
497 static VALUE
498 ossl_rsa_blinding_on(VALUE self)
499 {
500     EVP_PKEY *pkey;
501     
502     GetPKeyRSA(self, pkey);
503
504     if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
505         ossl_raise(eRSAError, NULL);
506     }
507     return self;
508 }
509
510 static VALUE
511 ossl_rsa_blinding_off(VALUE self)
512 {
513     EVP_PKEY *pkey;
514     
515     GetPKeyRSA(self, pkey);
516     RSA_blinding_off(pkey->pkey.rsa);
517
518     return self;
519 }
520  */
521
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);
530
531 /*
532  * INIT
533  */
534 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
535
536 void
537 Init_ossl_rsa()
538 {
539 #if 0 /* let rdoc know about mOSSL and mPKey */
540     mOSSL = rb_define_module("OpenSSL");
541     mPKey = rb_define_module_under(mOSSL, "PKey");
542 #endif
543
544     eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
545
546     cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
547
548     rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
549     rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
550         
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);
563
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);
572
573     rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
574
575     DefRSAConst(PKCS1_PADDING);
576     DefRSAConst(SSLV23_PADDING);
577     DefRSAConst(NO_PADDING);
578     DefRSAConst(PKCS1_OAEP_PADDING);
579
580 /*
581  * TODO: Test it
582     rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
583     rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
584  */
585 }
586
587 #else /* defined NO_RSA */
588 void
589 Init_ossl_rsa()
590 {
591 }
592 #endif /* NO_RSA */
593