Ruby  1.9.3p448(2013-06-27revision41675)
ossl_pkey_rsa.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_pkey_rsa.c 32199 2011-06-22 08:41:08Z emboss $
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  */
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) {
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,
84  NULL);
85 }
86 
87 /*
88  * call-seq:
89  * RSA.generate(size) => RSA instance
90  * RSA.generate(size, exponent) => RSA instance
91  *
92  * Generates an RSA keypair. +size+ is an integer representing the desired key
93  * size. Keys smaller than 1024 should be considered insecure. +exponent+ is
94  * an odd number normally 3, 17, or 65537.
95  */
96 static VALUE
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);
112  }
113 
114  return obj;
115 }
116 
117 /*
118  * call-seq:
119  * RSA.new(key_size) => RSA instance
120  * RSA.new(encoded_key) => RSA instance
121  * RSA.new(encoded_key, pass_phrase) => RSA instance
122  *
123  * Generates or loads an RSA keypair. If an integer +key_size+ is given it
124  * represents the desired key size. Keys less than 1024 bits should be
125  * considered insecure.
126  *
127  * A key can instead be loaded from an +encoded_key+ which must be PEM or DER
128  * encoded. A +pass_phrase+ can be used to decrypt the key. If none is given
129  * OpenSSL will prompt for the pass phrase.
130  *
131  * = Examples
132  *
133  * OpenSSL::PKey::RSA.new 2048
134  * OpenSSL::PKey::RSA.new File.read 'rsa.pem'
135  * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
136  */
137 static VALUE
139 {
140  EVP_PKEY *pkey;
141  RSA *rsa;
142  BIO *in;
143  char *passwd = NULL;
144  VALUE arg, pass;
145 
146  GetPKey(self, pkey);
147  if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
148  rsa = RSA_new();
149  }
150  else if (FIXNUM_P(arg)) {
151  rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
152  if (!rsa) ossl_raise(eRSAError, NULL);
153  }
154  else {
155  if (!NIL_P(pass)) passwd = StringValuePtr(pass);
156  arg = ossl_to_der_if_possible(arg);
157  in = ossl_obj2bio(arg);
158  rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
159  if (!rsa) {
160  OSSL_BIO_reset(in);
161  rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
162  }
163  if (!rsa) {
164  OSSL_BIO_reset(in);
165  rsa = d2i_RSAPrivateKey_bio(in, NULL);
166  }
167  if (!rsa) {
168  OSSL_BIO_reset(in);
169  rsa = d2i_RSA_PUBKEY_bio(in, NULL);
170  }
171  if (!rsa) {
172  OSSL_BIO_reset(in);
173  rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
174  }
175  if (!rsa) {
176  OSSL_BIO_reset(in);
177  rsa = d2i_RSAPublicKey_bio(in, NULL);
178  }
179  BIO_free(in);
180  if (!rsa) {
181  ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
182  }
183  }
184  if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
185  RSA_free(rsa);
187  }
188 
189  return self;
190 }
191 
192 /*
193  * call-seq:
194  * rsa.public? => true
195  *
196  * The return value is always true since every private key is also a public
197  * key.
198  */
199 static VALUE
201 {
202  EVP_PKEY *pkey;
203 
204  GetPKeyRSA(self, pkey);
205  /*
206  * This method should check for n and e. BUG.
207  */
208  return Qtrue;
209 }
210 
211 /*
212  * call-seq:
213  * rsa.private? => true | false
214  *
215  * Does this keypair contain a private key?
216  */
217 static VALUE
219 {
220  EVP_PKEY *pkey;
221 
222  GetPKeyRSA(self, pkey);
223 
224  return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
225 }
226 
227 /*
228  * call-seq:
229  * rsa.to_pem => PEM-format String
230  * rsa.to_pem(cipher, pass_phrase) => PEM-format String
231  *
232  * Outputs this keypair in PEM encoding. If +cipher+ and +pass_phrase+ are
233  * given they will be used to encrypt the key. +cipher+ must be an
234  * OpenSSL::Cipher::Cipher instance.
235  */
236 static VALUE
238 {
239  EVP_PKEY *pkey;
240  BIO *out;
241  const EVP_CIPHER *ciph = NULL;
242  char *passwd = NULL;
243  VALUE cipher, pass, str;
244 
245  GetPKeyRSA(self, pkey);
246 
247  rb_scan_args(argc, argv, "02", &cipher, &pass);
248 
249  if (!NIL_P(cipher)) {
250  ciph = GetCipherPtr(cipher);
251  if (!NIL_P(pass)) {
252  passwd = StringValuePtr(pass);
253  }
254  }
255  if (!(out = BIO_new(BIO_s_mem()))) {
257  }
258  if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
259  if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
260  NULL, 0, ossl_pem_passwd_cb, passwd)) {
261  BIO_free(out);
263  }
264  } else {
265  if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
266  BIO_free(out);
268  }
269  }
270  str = ossl_membio2str(out);
271 
272  return str;
273 }
274 
275 /*
276  * call-seq:
277  * rsa.to_der => DER-format String
278  *
279  * Outputs this keypair in DER encoding.
280  */
281 static VALUE
283 {
284  EVP_PKEY *pkey;
285  int (*i2d_func)_((const RSA*, unsigned char**));
286  unsigned char *p;
287  long len;
288  VALUE str;
289 
290  GetPKeyRSA(self, pkey);
291  if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
292  i2d_func = i2d_RSAPrivateKey;
293  else
294  i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
295  if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
297  str = rb_str_new(0, len);
298  p = (unsigned char *)RSTRING_PTR(str);
299  if(i2d_func(pkey->pkey.rsa, &p) < 0)
301  ossl_str_adjust(str, p);
302 
303  return str;
304 }
305 
306 #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
307 
308 /*
309  * call-seq:
310  * rsa.public_encrypt(string) => String
311  * rsa.public_encrypt(string, padding) => String
312  *
313  * Encrypt +string+ with the public key. +padding+ defaults to PKCS1_PADDING.
314  * The encrypted string output can be decrypted using #private_decrypt.
315  */
316 static VALUE
318 {
319  EVP_PKEY *pkey;
320  int buf_len, pad;
321  VALUE str, buffer, padding;
322 
323  GetPKeyRSA(self, pkey);
324  rb_scan_args(argc, argv, "11", &buffer, &padding);
325  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
326  StringValue(buffer);
327  str = rb_str_new(0, ossl_rsa_buf_size(pkey));
328  buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
329  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
330  pad);
331  if (buf_len < 0) ossl_raise(eRSAError, NULL);
332  rb_str_set_len(str, buf_len);
333 
334  return str;
335 }
336 
337 /*
338  * call-seq:
339  * rsa.public_decrypt(string) => String
340  * rsa.public_decrypt(string, padding) => String
341  *
342  * Decrypt +string+, which has been encrypted with the private key, with the
343  * public key. +padding+ defaults to PKCS1_PADDING.
344  */
345 static VALUE
347 {
348  EVP_PKEY *pkey;
349  int buf_len, pad;
350  VALUE str, buffer, padding;
351 
352  GetPKeyRSA(self, pkey);
353  rb_scan_args(argc, argv, "11", &buffer, &padding);
354  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
355  StringValue(buffer);
356  str = rb_str_new(0, ossl_rsa_buf_size(pkey));
357  buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
358  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
359  pad);
360  if (buf_len < 0) ossl_raise(eRSAError, NULL);
361  rb_str_set_len(str, buf_len);
362 
363  return str;
364 }
365 
366 /*
367  * call-seq:
368  * rsa.private_encrypt(string) => String
369  * rsa.private_encrypt(string, padding) => String
370  *
371  * Encrypt +string+ with the private key. +padding+ defaults to PKCS1_PADDING.
372  * The encrypted string output can be decrypted using #public_decrypt.
373  */
374 static VALUE
376 {
377  EVP_PKEY *pkey;
378  int buf_len, pad;
379  VALUE str, buffer, padding;
380 
381  GetPKeyRSA(self, pkey);
382  if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
383  ossl_raise(eRSAError, "private key needed.");
384  }
385  rb_scan_args(argc, argv, "11", &buffer, &padding);
386  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
387  StringValue(buffer);
388  str = rb_str_new(0, ossl_rsa_buf_size(pkey));
389  buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
390  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
391  pad);
392  if (buf_len < 0) ossl_raise(eRSAError, NULL);
393  rb_str_set_len(str, buf_len);
394 
395  return str;
396 }
397 
398 /*
399  * call-seq:
400  * rsa.private_decrypt(string) => String
401  * rsa.private_decrypt(string, padding) => String
402  *
403  * Decrypt +string+, which has been encrypted with the public key, with the
404  * private key. +padding+ defaults to PKCS1_PADDING.
405  */
406 static VALUE
408 {
409  EVP_PKEY *pkey;
410  int buf_len, pad;
411  VALUE str, buffer, padding;
412 
413  GetPKeyRSA(self, pkey);
414  if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
415  ossl_raise(eRSAError, "private key needed.");
416  }
417  rb_scan_args(argc, argv, "11", &buffer, &padding);
418  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
419  StringValue(buffer);
420  str = rb_str_new(0, ossl_rsa_buf_size(pkey));
421  buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
422  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
423  pad);
424  if (buf_len < 0) ossl_raise(eRSAError, NULL);
425  rb_str_set_len(str, buf_len);
426 
427  return str;
428 }
429 
430 /*
431  * call-seq:
432  * rsa.params => hash
433  *
434  * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
435  *
436  * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd',
437  * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'.
438  *
439  * Don't use :-)) (It's up to you)
440  */
441 static VALUE
443 {
444  EVP_PKEY *pkey;
445  VALUE hash;
446 
447  GetPKeyRSA(self, pkey);
448 
449  hash = rb_hash_new();
450 
451  rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
452  rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
453  rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
454  rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
455  rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
456  rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
457  rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
458  rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
459 
460  return hash;
461 }
462 
463 /*
464  * call-seq:
465  * rsa.to_text => String
466  *
467  * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
468  *
469  * Dumps all parameters of a keypair to a String
470  *
471  * Don't use :-)) (It's up to you)
472  */
473 static VALUE
475 {
476  EVP_PKEY *pkey;
477  BIO *out;
478  VALUE str;
479 
480  GetPKeyRSA(self, pkey);
481  if (!(out = BIO_new(BIO_s_mem()))) {
483  }
484  if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
485  BIO_free(out);
487  }
488  str = ossl_membio2str(out);
489 
490  return str;
491 }
492 
493 /*
494  * call-seq:
495  * rsa.public_key -> RSA
496  *
497  * Makes new RSA instance containing the public key from the private key.
498  */
499 static VALUE
501 {
502  EVP_PKEY *pkey;
503  RSA *rsa;
504  VALUE obj;
505 
506  GetPKeyRSA(self, pkey);
507  /* err check performed by rsa_instance */
508  rsa = RSAPublicKey_dup(pkey->pkey.rsa);
509  obj = rsa_instance(CLASS_OF(self), rsa);
510  if (obj == Qfalse) {
511  RSA_free(rsa);
513  }
514  return obj;
515 }
516 
517 /*
518  * TODO: Test me
519 
520 static VALUE
521 ossl_rsa_blinding_on(VALUE self)
522 {
523  EVP_PKEY *pkey;
524 
525  GetPKeyRSA(self, pkey);
526 
527  if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
528  ossl_raise(eRSAError, NULL);
529  }
530  return self;
531 }
532 
533 static VALUE
534 ossl_rsa_blinding_off(VALUE self)
535 {
536  EVP_PKEY *pkey;
537 
538  GetPKeyRSA(self, pkey);
539  RSA_blinding_off(pkey->pkey.rsa);
540 
541  return self;
542 }
543  */
544 
545 OSSL_PKEY_BN(rsa, n)
546 OSSL_PKEY_BN(rsa, e)
547 OSSL_PKEY_BN(rsa, d)
548 OSSL_PKEY_BN(rsa, p)
549 OSSL_PKEY_BN(rsa, q)
550 OSSL_PKEY_BN(rsa, dmp1)
551 OSSL_PKEY_BN(rsa, dmq1)
552 OSSL_PKEY_BN(rsa, iqmp)
553 
554 /*
555  * INIT
556  */
557 #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
558 
559 void
561 {
562 #if 0
563  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
565 #endif
566 
567  /* Document-class: OpenSSL::PKey::RSAError
568  *
569  * Generic exception that is raised if an operation on an RSA PKey
570  * fails unexpectedly or in case an instantiation of an instance of RSA
571  * fails due to non-conformant input data.
572  */
574 
575  /* Document-class: OpenSSL::PKey::RSA
576  *
577  * RSA is an asymmetric public key algorithm that has been formalized in
578  * RFC 3447. It is in widespread use in public key infrastuctures (PKI)
579  * where certificates (cf. OpenSSL::X509::Certificate) often are issued
580  * on the basis of a public/private RSA key pair. RSA is used in a wide
581  * field of applications such as secure (symmetric) key exchange, e.g.
582  * when establishing a secure TLS/SSL connection. It is also used in
583  * various digital signature schemes.
584  */
586 
588  rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
589 
590  rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
591  rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
592  rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
593  rb_define_method(cRSA, "export", ossl_rsa_export, -1);
594  rb_define_alias(cRSA, "to_pem", "export");
595  rb_define_alias(cRSA, "to_s", "export");
596  rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
597  rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
598  rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
599  rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
600  rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
601  rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
602 
603  DEF_OSSL_PKEY_BN(cRSA, rsa, n);
604  DEF_OSSL_PKEY_BN(cRSA, rsa, e);
605  DEF_OSSL_PKEY_BN(cRSA, rsa, d);
606  DEF_OSSL_PKEY_BN(cRSA, rsa, p);
607  DEF_OSSL_PKEY_BN(cRSA, rsa, q);
608  DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
609  DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
610  DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
611 
613 
614  DefRSAConst(PKCS1_PADDING);
615  DefRSAConst(SSLV23_PADDING);
616  DefRSAConst(NO_PADDING);
617  DefRSAConst(PKCS1_OAEP_PADDING);
618 
619 /*
620  * TODO: Test it
621  rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
622  rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
623  */
624 }
625 
626 #else /* defined NO_RSA */
627 void
629 {
630 }
631 #endif /* NO_RSA */
632 
633