Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
ossl_pkey_rsa.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4  * All rights reserved.
5  */
6 /*
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
12 #if !defined(OPENSSL_NO_RSA)
13 
14 #define GetPKeyRSA(obj, pkey) do { \
15  GetPKey((obj), (pkey)); \
16  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { /* PARANOIA? */ \
17  ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
18  } \
19 } while (0)
20 #define GetRSA(obj, rsa) do { \
21  EVP_PKEY *_pkey; \
22  GetPKeyRSA((obj), _pkey); \
23  (rsa) = EVP_PKEY_get0_RSA(_pkey); \
24 } while (0)
25 
26 static inline int
27 RSA_HAS_PRIVATE(RSA *rsa)
28 {
29  const BIGNUM *p, *q;
30 
31  RSA_get0_factors(rsa, &p, &q);
32  return p && q; /* d? why? */
33 }
34 
35 static inline int
36 RSA_PRIVATE(VALUE obj, RSA *rsa)
37 {
38  return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
39 }
40 
41 /*
42  * Classes
43  */
46 
47 /*
48  * Public
49  */
50 static VALUE
51 rsa_instance(VALUE klass, RSA *rsa)
52 {
53  EVP_PKEY *pkey;
54  VALUE obj;
55 
56  if (!rsa) {
57  return Qfalse;
58  }
59  obj = NewPKey(klass);
60  if (!(pkey = EVP_PKEY_new())) {
61  return Qfalse;
62  }
63  if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
64  EVP_PKEY_free(pkey);
65  return Qfalse;
66  }
67  SetPKey(obj, pkey);
68 
69  return obj;
70 }
71 
72 VALUE
73 ossl_rsa_new(EVP_PKEY *pkey)
74 {
75  VALUE obj;
76 
77  if (!pkey) {
78  obj = rsa_instance(cRSA, RSA_new());
79  }
80  else {
81  obj = NewPKey(cRSA);
82  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
83  ossl_raise(rb_eTypeError, "Not a RSA key!");
84  }
85  SetPKey(obj, pkey);
86  }
87  if (obj == Qfalse) {
89  }
90 
91  return obj;
92 }
93 
94 /*
95  * Private
96  */
98  RSA *rsa;
99  BIGNUM *e;
100  int size;
101  BN_GENCB *cb;
102  int result;
103 };
104 
105 static void *
106 rsa_blocking_gen(void *arg)
107 {
108  struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg;
109  gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb);
110  return 0;
111 }
112 
113 static RSA *
114 rsa_generate(int size, unsigned long exp)
115 {
116  int i;
117  struct ossl_generate_cb_arg cb_arg = { 0 };
118  struct rsa_blocking_gen_arg gen_arg;
119  RSA *rsa = RSA_new();
120  BIGNUM *e = BN_new();
121  BN_GENCB *cb = BN_GENCB_new();
122 
123  if (!rsa || !e || !cb) {
124  RSA_free(rsa);
125  BN_free(e);
126  BN_GENCB_free(cb);
127  return NULL;
128  }
129  for (i = 0; i < (int)sizeof(exp) * 8; ++i) {
130  if (exp & (1UL << i)) {
131  if (BN_set_bit(e, i) == 0) {
132  BN_free(e);
133  RSA_free(rsa);
134  BN_GENCB_free(cb);
135  return NULL;
136  }
137  }
138  }
139 
140  if (rb_block_given_p())
141  cb_arg.yield = 1;
142  BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
143  gen_arg.rsa = rsa;
144  gen_arg.e = e;
145  gen_arg.size = size;
146  gen_arg.cb = cb;
147  if (cb_arg.yield == 1) {
148  /* we cannot release GVL when callback proc is supplied */
149  rsa_blocking_gen(&gen_arg);
150  } else {
151  /* there's a chance to unblock */
152  rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
153  }
154 
155  BN_GENCB_free(cb);
156  BN_free(e);
157  if (!gen_arg.result) {
158  RSA_free(rsa);
159  if (cb_arg.state) {
160  /* must clear OpenSSL error stack */
162  rb_jump_tag(cb_arg.state);
163  }
164  return NULL;
165  }
166 
167  return rsa;
168 }
169 
170 /*
171  * call-seq:
172  * RSA.generate(size) => RSA instance
173  * RSA.generate(size, exponent) => RSA instance
174  *
175  * Generates an RSA keypair. _size_ is an integer representing the desired key
176  * size. Keys smaller than 1024 should be considered insecure. _exponent_ is
177  * an odd number normally 3, 17, or 65537.
178  */
179 static VALUE
180 ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
181 {
182 /* why does this method exist? why can't initialize take an optional exponent? */
183  RSA *rsa;
184  VALUE size, exp;
185  VALUE obj;
186 
187  rb_scan_args(argc, argv, "11", &size, &exp);
188 
189  rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); /* err handled by rsa_instance */
190  obj = rsa_instance(klass, rsa);
191 
192  if (obj == Qfalse) {
193  RSA_free(rsa);
195  }
196 
197  return obj;
198 }
199 
200 /*
201  * call-seq:
202  * RSA.new(key_size) => RSA instance
203  * RSA.new(encoded_key) => RSA instance
204  * RSA.new(encoded_key, pass_phrase) => RSA instance
205  *
206  * Generates or loads an RSA keypair. If an integer _key_size_ is given it
207  * represents the desired key size. Keys less than 1024 bits should be
208  * considered insecure.
209  *
210  * A key can instead be loaded from an _encoded_key_ which must be PEM or DER
211  * encoded. A _pass_phrase_ can be used to decrypt the key. If none is given
212  * OpenSSL will prompt for the pass phrase.
213  *
214  * = Examples
215  *
216  * OpenSSL::PKey::RSA.new 2048
217  * OpenSSL::PKey::RSA.new File.read 'rsa.pem'
218  * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
219  */
220 static VALUE
221 ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
222 {
223  EVP_PKEY *pkey;
224  RSA *rsa;
225  BIO *in;
226  VALUE arg, pass;
227 
228  GetPKey(self, pkey);
229  if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
230  rsa = RSA_new();
231  }
232  else if (RB_INTEGER_TYPE_P(arg)) {
233  rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass));
234  if (!rsa) ossl_raise(eRSAError, NULL);
235  }
236  else {
237  pass = ossl_pem_passwd_value(pass);
239  in = ossl_obj2bio(&arg);
240  rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
241  if (!rsa) {
242  OSSL_BIO_reset(in);
243  rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
244  }
245  if (!rsa) {
246  OSSL_BIO_reset(in);
247  rsa = d2i_RSAPrivateKey_bio(in, NULL);
248  }
249  if (!rsa) {
250  OSSL_BIO_reset(in);
251  rsa = d2i_RSA_PUBKEY_bio(in, NULL);
252  }
253  if (!rsa) {
254  OSSL_BIO_reset(in);
255  rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
256  }
257  if (!rsa) {
258  OSSL_BIO_reset(in);
259  rsa = d2i_RSAPublicKey_bio(in, NULL);
260  }
261  BIO_free(in);
262  if (!rsa) {
263  ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
264  }
265  }
266  if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
267  RSA_free(rsa);
269  }
270 
271  return self;
272 }
273 
274 static VALUE
275 ossl_rsa_initialize_copy(VALUE self, VALUE other)
276 {
277  EVP_PKEY *pkey;
278  RSA *rsa, *rsa_new;
279 
280  GetPKey(self, pkey);
281  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
282  ossl_raise(eRSAError, "RSA already initialized");
283  GetRSA(other, rsa);
284 
285  rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa);
286  if (!rsa_new)
287  ossl_raise(eRSAError, "ASN1_dup");
288 
289  EVP_PKEY_assign_RSA(pkey, rsa_new);
290 
291  return self;
292 }
293 
294 /*
295  * call-seq:
296  * rsa.public? => true
297  *
298  * The return value is always +true+ since every private key is also a public
299  * key.
300  */
301 static VALUE
302 ossl_rsa_is_public(VALUE self)
303 {
304  RSA *rsa;
305 
306  GetRSA(self, rsa);
307  /*
308  * This method should check for n and e. BUG.
309  */
310  (void)rsa;
311  return Qtrue;
312 }
313 
314 /*
315  * call-seq:
316  * rsa.private? => true | false
317  *
318  * Does this keypair contain a private key?
319  */
320 static VALUE
321 ossl_rsa_is_private(VALUE self)
322 {
323  RSA *rsa;
324 
325  GetRSA(self, rsa);
326 
327  return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse;
328 }
329 
330 /*
331  * call-seq:
332  * rsa.export([cipher, pass_phrase]) => PEM-format String
333  * rsa.to_pem([cipher, pass_phrase]) => PEM-format String
334  * rsa.to_s([cipher, pass_phrase]) => PEM-format String
335  *
336  * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
337  * given they will be used to encrypt the key. _cipher_ must be an
338  * OpenSSL::Cipher instance.
339  */
340 static VALUE
341 ossl_rsa_export(int argc, VALUE *argv, VALUE self)
342 {
343  RSA *rsa;
344  BIO *out;
345  const EVP_CIPHER *ciph = NULL;
346  VALUE cipher, pass, str;
347 
348  GetRSA(self, rsa);
349 
350  rb_scan_args(argc, argv, "02", &cipher, &pass);
351 
352  if (!NIL_P(cipher)) {
353  ciph = ossl_evp_get_cipherbyname(cipher);
354  pass = ossl_pem_passwd_value(pass);
355  }
356  if (!(out = BIO_new(BIO_s_mem()))) {
358  }
359  if (RSA_HAS_PRIVATE(rsa)) {
360  if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
361  ossl_pem_passwd_cb, (void *)pass)) {
362  BIO_free(out);
364  }
365  } else {
366  if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
367  BIO_free(out);
369  }
370  }
371  str = ossl_membio2str(out);
372 
373  return str;
374 }
375 
376 /*
377  * call-seq:
378  * rsa.to_der => DER-format String
379  *
380  * Outputs this keypair in DER encoding.
381  */
382 static VALUE
383 ossl_rsa_to_der(VALUE self)
384 {
385  RSA *rsa;
386  int (*i2d_func)(const RSA *, unsigned char **);
387  unsigned char *p;
388  long len;
389  VALUE str;
390 
391  GetRSA(self, rsa);
392  if (RSA_HAS_PRIVATE(rsa))
393  i2d_func = i2d_RSAPrivateKey;
394  else
395  i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY;
396  if((len = i2d_func(rsa, NULL)) <= 0)
398  str = rb_str_new(0, len);
399  p = (unsigned char *)RSTRING_PTR(str);
400  if(i2d_func(rsa, &p) < 0)
402  ossl_str_adjust(str, p);
403 
404  return str;
405 }
406 
407 /*
408  * call-seq:
409  * rsa.public_encrypt(string) => String
410  * rsa.public_encrypt(string, padding) => String
411  *
412  * Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING.
413  * The encrypted string output can be decrypted using #private_decrypt.
414  */
415 static VALUE
416 ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
417 {
418  RSA *rsa;
419  const BIGNUM *rsa_n;
420  int buf_len, pad;
421  VALUE str, buffer, padding;
422 
423  GetRSA(self, rsa);
424  RSA_get0_key(rsa, &rsa_n, NULL, NULL);
425  if (!rsa_n)
426  ossl_raise(eRSAError, "incomplete RSA");
427  rb_scan_args(argc, argv, "11", &buffer, &padding);
428  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
429  StringValue(buffer);
430  str = rb_str_new(0, RSA_size(rsa));
431  buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
432  (unsigned char *)RSTRING_PTR(str), rsa, pad);
433  if (buf_len < 0) ossl_raise(eRSAError, NULL);
434  rb_str_set_len(str, buf_len);
435 
436  return str;
437 }
438 
439 /*
440  * call-seq:
441  * rsa.public_decrypt(string) => String
442  * rsa.public_decrypt(string, padding) => String
443  *
444  * Decrypt _string_, which has been encrypted with the private key, with the
445  * public key. _padding_ defaults to PKCS1_PADDING.
446  */
447 static VALUE
448 ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
449 {
450  RSA *rsa;
451  const BIGNUM *rsa_n;
452  int buf_len, pad;
453  VALUE str, buffer, padding;
454 
455  GetRSA(self, rsa);
456  RSA_get0_key(rsa, &rsa_n, NULL, NULL);
457  if (!rsa_n)
458  ossl_raise(eRSAError, "incomplete RSA");
459  rb_scan_args(argc, argv, "11", &buffer, &padding);
460  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
461  StringValue(buffer);
462  str = rb_str_new(0, RSA_size(rsa));
463  buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
464  (unsigned char *)RSTRING_PTR(str), rsa, pad);
465  if (buf_len < 0) ossl_raise(eRSAError, NULL);
466  rb_str_set_len(str, buf_len);
467 
468  return str;
469 }
470 
471 /*
472  * call-seq:
473  * rsa.private_encrypt(string) => String
474  * rsa.private_encrypt(string, padding) => String
475  *
476  * Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING.
477  * The encrypted string output can be decrypted using #public_decrypt.
478  */
479 static VALUE
480 ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
481 {
482  RSA *rsa;
483  const BIGNUM *rsa_n;
484  int buf_len, pad;
485  VALUE str, buffer, padding;
486 
487  GetRSA(self, rsa);
488  RSA_get0_key(rsa, &rsa_n, NULL, NULL);
489  if (!rsa_n)
490  ossl_raise(eRSAError, "incomplete RSA");
491  if (!RSA_PRIVATE(self, rsa))
492  ossl_raise(eRSAError, "private key needed.");
493  rb_scan_args(argc, argv, "11", &buffer, &padding);
494  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
495  StringValue(buffer);
496  str = rb_str_new(0, RSA_size(rsa));
497  buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
498  (unsigned char *)RSTRING_PTR(str), rsa, pad);
499  if (buf_len < 0) ossl_raise(eRSAError, NULL);
500  rb_str_set_len(str, buf_len);
501 
502  return str;
503 }
504 
505 /*
506  * call-seq:
507  * rsa.private_decrypt(string) => String
508  * rsa.private_decrypt(string, padding) => String
509  *
510  * Decrypt _string_, which has been encrypted with the public key, with the
511  * private key. _padding_ defaults to PKCS1_PADDING.
512  */
513 static VALUE
514 ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
515 {
516  RSA *rsa;
517  const BIGNUM *rsa_n;
518  int buf_len, pad;
519  VALUE str, buffer, padding;
520 
521  GetRSA(self, rsa);
522  RSA_get0_key(rsa, &rsa_n, NULL, NULL);
523  if (!rsa_n)
524  ossl_raise(eRSAError, "incomplete RSA");
525  if (!RSA_PRIVATE(self, rsa))
526  ossl_raise(eRSAError, "private key needed.");
527  rb_scan_args(argc, argv, "11", &buffer, &padding);
528  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
529  StringValue(buffer);
530  str = rb_str_new(0, RSA_size(rsa));
531  buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
532  (unsigned char *)RSTRING_PTR(str), rsa, pad);
533  if (buf_len < 0) ossl_raise(eRSAError, NULL);
534  rb_str_set_len(str, buf_len);
535 
536  return str;
537 }
538 
539 /*
540  * call-seq:
541  * rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
542  *
543  * Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns
544  * the calculated signature.
545  *
546  * RSAError will be raised if an error occurs.
547  *
548  * See #verify_pss for the verification operation.
549  *
550  * === Parameters
551  * _digest_::
552  * A String containing the message digest algorithm name.
553  * _data_::
554  * A String. The data to be signed.
555  * _salt_length_::
556  * The length in octets of the salt. Two special values are reserved:
557  * +:digest+ means the digest length, and +:max+ means the maximum possible
558  * length for the combination of the private key and the selected message
559  * digest algorithm.
560  * _mgf1_hash_::
561  * The hash algorithm used in MGF1 (the currently supported mask generation
562  * function (MGF)).
563  *
564  * === Example
565  * data = "Sign me!"
566  * pkey = OpenSSL::PKey::RSA.new(2048)
567  * signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
568  * pub_key = pkey.public_key
569  * puts pub_key.verify_pss("SHA256", signature, data,
570  * salt_length: :auto, mgf1_hash: "SHA256") # => true
571  */
572 static VALUE
573 ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self)
574 {
575  VALUE digest, data, options, kwargs[2], signature;
576  static ID kwargs_ids[2];
577  EVP_PKEY *pkey;
578  EVP_PKEY_CTX *pkey_ctx;
579  const EVP_MD *md, *mgf1md;
580  EVP_MD_CTX *md_ctx;
581  size_t buf_len;
582  int salt_len;
583 
584  if (!kwargs_ids[0]) {
585  kwargs_ids[0] = rb_intern_const("salt_length");
586  kwargs_ids[1] = rb_intern_const("mgf1_hash");
587  }
588  rb_scan_args(argc, argv, "2:", &digest, &data, &options);
589  rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
590  if (kwargs[0] == ID2SYM(rb_intern("max")))
591  salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */
592  else if (kwargs[0] == ID2SYM(rb_intern("digest")))
593  salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
594  else
595  salt_len = NUM2INT(kwargs[0]);
596  mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
597 
598  pkey = GetPrivPKeyPtr(self);
599  buf_len = EVP_PKEY_size(pkey);
600  md = ossl_evp_get_digestbyname(digest);
601  StringValue(data);
602  signature = rb_str_new(NULL, (long)buf_len);
603 
604  md_ctx = EVP_MD_CTX_new();
605  if (!md_ctx)
606  goto err;
607 
608  if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
609  goto err;
610 
611  if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
612  goto err;
613 
614  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
615  goto err;
616 
617  if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
618  goto err;
619 
620  if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
621  goto err;
622 
623  if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1)
624  goto err;
625 
626  rb_str_set_len(signature, (long)buf_len);
627 
628  EVP_MD_CTX_free(md_ctx);
629  return signature;
630 
631  err:
632  EVP_MD_CTX_free(md_ctx);
634 }
635 
636 /*
637  * call-seq:
638  * rsa.verify_pss(digest, signature, data, salt_length:, mgf1_hash:) -> true | false
639  *
640  * Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS).
641  *
642  * The return value is +true+ if the signature is valid, +false+ otherwise.
643  * RSAError will be raised if an error occurs.
644  *
645  * See #sign_pss for the signing operation and an example code.
646  *
647  * === Parameters
648  * _digest_::
649  * A String containing the message digest algorithm name.
650  * _data_::
651  * A String. The data to be signed.
652  * _salt_length_::
653  * The length in octets of the salt. Two special values are reserved:
654  * +:digest+ means the digest length, and +:auto+ means automatically
655  * determining the length based on the signature.
656  * _mgf1_hash_::
657  * The hash algorithm used in MGF1.
658  */
659 static VALUE
660 ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
661 {
662  VALUE digest, signature, data, options, kwargs[2];
663  static ID kwargs_ids[2];
664  EVP_PKEY *pkey;
665  EVP_PKEY_CTX *pkey_ctx;
666  const EVP_MD *md, *mgf1md;
667  EVP_MD_CTX *md_ctx;
668  int result, salt_len;
669 
670  if (!kwargs_ids[0]) {
671  kwargs_ids[0] = rb_intern_const("salt_length");
672  kwargs_ids[1] = rb_intern_const("mgf1_hash");
673  }
674  rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
675  rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
676  if (kwargs[0] == ID2SYM(rb_intern("auto")))
677  salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
678  else if (kwargs[0] == ID2SYM(rb_intern("digest")))
679  salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
680  else
681  salt_len = NUM2INT(kwargs[0]);
682  mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
683 
684  GetPKey(self, pkey);
685  md = ossl_evp_get_digestbyname(digest);
686  StringValue(signature);
687  StringValue(data);
688 
689  md_ctx = EVP_MD_CTX_new();
690  if (!md_ctx)
691  goto err;
692 
693  if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
694  goto err;
695 
696  if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
697  goto err;
698 
699  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
700  goto err;
701 
702  if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
703  goto err;
704 
705  if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
706  goto err;
707 
708  result = EVP_DigestVerifyFinal(md_ctx,
709  (unsigned char *)RSTRING_PTR(signature),
710  RSTRING_LEN(signature));
711 
712  switch (result) {
713  case 0:
715  EVP_MD_CTX_free(md_ctx);
716  return Qfalse;
717  case 1:
718  EVP_MD_CTX_free(md_ctx);
719  return Qtrue;
720  default:
721  goto err;
722  }
723 
724  err:
725  EVP_MD_CTX_free(md_ctx);
727 }
728 
729 /*
730  * call-seq:
731  * rsa.params => hash
732  *
733  * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
734  *
735  * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd',
736  * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'.
737  *
738  * Don't use :-)) (It's up to you)
739  */
740 static VALUE
741 ossl_rsa_get_params(VALUE self)
742 {
743  RSA *rsa;
744  VALUE hash;
745  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
746 
747  GetRSA(self, rsa);
748  RSA_get0_key(rsa, &n, &e, &d);
749  RSA_get0_factors(rsa, &p, &q);
750  RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
751 
752  hash = rb_hash_new();
753  rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n));
754  rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e));
755  rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d));
756  rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
757  rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
758  rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1));
759  rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1));
760  rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp));
761 
762  return hash;
763 }
764 
765 /*
766  * call-seq:
767  * rsa.to_text => String
768  *
769  * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
770  *
771  * Dumps all parameters of a keypair to a String
772  *
773  * Don't use :-)) (It's up to you)
774  */
775 static VALUE
776 ossl_rsa_to_text(VALUE self)
777 {
778  RSA *rsa;
779  BIO *out;
780  VALUE str;
781 
782  GetRSA(self, rsa);
783  if (!(out = BIO_new(BIO_s_mem()))) {
785  }
786  if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
787  BIO_free(out);
789  }
790  str = ossl_membio2str(out);
791 
792  return str;
793 }
794 
795 /*
796  * call-seq:
797  * rsa.public_key -> RSA
798  *
799  * Makes new RSA instance containing the public key from the private key.
800  */
801 static VALUE
802 ossl_rsa_to_public_key(VALUE self)
803 {
804  EVP_PKEY *pkey;
805  RSA *rsa;
806  VALUE obj;
807 
808  GetPKeyRSA(self, pkey);
809  /* err check performed by rsa_instance */
810  rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
811  obj = rsa_instance(rb_obj_class(self), rsa);
812  if (obj == Qfalse) {
813  RSA_free(rsa);
815  }
816  return obj;
817 }
818 
819 /*
820  * TODO: Test me
821 
822 static VALUE
823 ossl_rsa_blinding_on(VALUE self)
824 {
825  RSA *rsa;
826 
827  GetRSA(self, rsa);
828 
829  if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
830  ossl_raise(eRSAError, NULL);
831  }
832  return self;
833 }
834 
835 static VALUE
836 ossl_rsa_blinding_off(VALUE self)
837 {
838  RSA *rsa;
839 
840  GetRSA(self, rsa);
841  RSA_blinding_off(rsa);
842 
843  return self;
844 }
845  */
846 
847 /*
848  * Document-method: OpenSSL::PKey::RSA#set_key
849  * call-seq:
850  * rsa.set_key(n, e, d) -> self
851  *
852  * Sets _n_, _e_, _d_ for the RSA instance.
853  */
854 OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d)
855 /*
856  * Document-method: OpenSSL::PKey::RSA#set_factors
857  * call-seq:
858  * rsa.set_factors(p, q) -> self
859  *
860  * Sets _p_, _q_ for the RSA instance.
861  */
862 OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q)
863 /*
864  * Document-method: OpenSSL::PKey::RSA#set_crt_params
865  * call-seq:
866  * rsa.set_crt_params(dmp1, dmq1, iqmp) -> self
867  *
868  * Sets _dmp1_, _dmq1_, _iqmp_ for the RSA instance. They are calculated by
869  * <tt>d mod (p - 1)</tt>, <tt>d mod (q - 1)</tt> and <tt>q^(-1) mod p</tt>
870  * respectively.
871  */
872 OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp)
873 
874 /*
875  * INIT
876  */
877 #define DefRSAConst(x) rb_define_const(cRSA, #x, INT2NUM(RSA_##x))
878 
879 void
881 {
882 #if 0
886 #endif
887 
888  /* Document-class: OpenSSL::PKey::RSAError
889  *
890  * Generic exception that is raised if an operation on an RSA PKey
891  * fails unexpectedly or in case an instantiation of an instance of RSA
892  * fails due to non-conformant input data.
893  */
895 
896  /* Document-class: OpenSSL::PKey::RSA
897  *
898  * RSA is an asymmetric public key algorithm that has been formalized in
899  * RFC 3447. It is in widespread use in public key infrastructures (PKI)
900  * where certificates (cf. OpenSSL::X509::Certificate) often are issued
901  * on the basis of a public/private RSA key pair. RSA is used in a wide
902  * field of applications such as secure (symmetric) key exchange, e.g.
903  * when establishing a secure TLS/SSL connection. It is also used in
904  * various digital signature schemes.
905  */
907 
908  rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
909  rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
910  rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
911 
912  rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
913  rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
914  rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
915  rb_define_method(cRSA, "export", ossl_rsa_export, -1);
916  rb_define_alias(cRSA, "to_pem", "export");
917  rb_define_alias(cRSA, "to_s", "export");
918  rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
919  rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
920  rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
921  rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
922  rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
923  rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
924  rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
925  rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
926 
932  DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
933  DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
934  DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
935  rb_define_method(cRSA, "set_key", ossl_rsa_set_key, 3);
936  rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2);
937  rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3);
938 
939  rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
940 
941  DefRSAConst(PKCS1_PADDING);
942  DefRSAConst(SSLV23_PADDING);
943  DefRSAConst(NO_PADDING);
944  DefRSAConst(PKCS1_OAEP_PADDING);
945 
946 /*
947  * TODO: Test it
948  rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
949  rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
950  */
951 }
952 
953 #else /* defined NO_RSA */
954 void
955 Init_ossl_rsa(void)
956 {
957 }
958 #endif /* NO_RSA */
rb_get_kwargs
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:1886
ID
unsigned long ID
Definition: ruby.h:103
void
void
Definition: rb_mjit_min_header-2.7.0.h:13273
OSSL_PKEY_BN_DEF3
#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3)
Definition: ossl_pkey.h:210
BN_GENCB_free
#define BN_GENCB_free(cb)
Definition: openssl_missing.h:42
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
rsa_blocking_gen_arg::cb
BN_GENCB * cb
Definition: ossl_pkey_rsa.c:101
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1501
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:797
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:897
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
ossl_to_der_if_possible
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:255
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rsa_blocking_gen_arg::result
int result
Definition: ossl_pkey_rsa.c:102
ossl_membio2str
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:29
NUM2ULONG
#define NUM2ULONG(x)
Definition: ruby.h:689
ePKeyError
VALUE ePKeyError
Definition: ossl_pkey.c:17
rsa_blocking_gen_arg::e
BIGNUM * e
Definition: ossl_pkey_rsa.c:99
VALUE
unsigned long VALUE
Definition: ruby.h:102
ossl_obj2bio
BIO * ossl_obj2bio(volatile VALUE *pobj)
Definition: ossl_bio.c:13
rb_intern
#define rb_intern(str)
rb_intern_const
#define rb_intern_const(str)
Definition: ruby.h:1879
OSSL_BIO_reset
#define OSSL_BIO_reset(bio)
Definition: ossl.h:114
RSTRING_LENINT
#define RSTRING_LENINT(str)
Definition: ruby.h:1017
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
ossl.h
StringValue
use StringValue() instead")))
ossl_clear_error
void ossl_clear_error(void)
Definition: ossl.c:304
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
cPKey
VALUE cPKey
Definition: ossl_pkey.c:16
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
rsa_blocking_gen_arg::size
int size
Definition: ossl_pkey_rsa.c:100
Qfalse
#define Qfalse
Definition: ruby.h:467
rsa_blocking_gen_arg
Definition: ossl_pkey_rsa.c:97
ossl_pem_passwd_cb
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
Definition: ossl.c:177
ossl_str_adjust
#define ossl_str_adjust(str, p)
Definition: ossl.h:86
NULL
#define NULL
Definition: _sdbm.c:101
OSSL_PKEY_BN_DEF2
#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2)
Definition: ossl_pkey.h:217
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:414
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
GetRSA
#define GetRSA(obj, rsa)
Definition: ossl_pkey_rsa.c:20
rsa_blocking_gen_arg::rsa
RSA * rsa
Definition: ossl_pkey_rsa.c:98
DEF_OSSL_PKEY_BN
#define DEF_OSSL_PKEY_BN(class, keytype, name)
Definition: ossl_pkey.h:223
BN_GENCB_new
#define BN_GENCB_new()
Definition: openssl_missing.h:38
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
eRSAError
VALUE eRSAError
Definition: ossl_pkey_rsa.c:45
mOSSL
VALUE mOSSL
Definition: ossl.c:231
ossl_generate_cb_stop
void ossl_generate_cb_stop(void *ptr)
Definition: ossl_pkey.c:72
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:883
ossl_pem_passwd_value
VALUE ossl_pem_passwd_value(VALUE pass)
Definition: ossl.c:151
GetPKey
#define GetPKey(obj, pkey)
Definition: ossl_pkey.h:31
ossl_bn_new
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:58
DefRSAConst
#define DefRSAConst(x)
Definition: ossl_pkey_rsa.c:877
Init_ossl_rsa
void Init_ossl_rsa(void)
Definition: ossl_pkey_rsa.c:880
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
rb_thread_call_without_gvl
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
GetPKeyRSA
#define GetPKeyRSA(obj, pkey)
Definition: ossl_pkey_rsa.c:14
size
int size
Definition: encoding.c:58
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
ossl_generate_cb_arg
Definition: ossl_pkey.h:38
key
key
Definition: openssl_missing.h:181
OSSL_PKEY_IS_PRIVATE
#define OSSL_PKEY_IS_PRIVATE(obj)
Definition: ossl_pkey.h:20
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
EVP_MD_CTX_free
#define EVP_MD_CTX_free
Definition: openssl_missing.h:54
mPKey
VALUE mPKey
Definition: ossl_pkey.c:15
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
cRSA
VALUE cRSA
Definition: ossl_pkey_rsa.c:44
ossl_generate_cb_arg::yield
int yield
Definition: ossl_pkey.h:39
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
exp
double exp(double)
ossl_generate_cb_arg::state
int state
Definition: ossl_pkey.h:41
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2779
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
argc
int argc
Definition: ruby.c:222
err
int err
Definition: win32.c:135
SetPKey
#define SetPKey(obj, pkey)
Definition: ossl_pkey.h:24
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
NewPKey
#define NewPKey(klass)
Definition: ossl_pkey.h:22
Qtrue
#define Qtrue
Definition: ruby.h:468
len
uint8_t len
Definition: escape.c:17
eOSSLError
VALUE eOSSLError
Definition: ossl.c:236
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
RB_INTEGER_TYPE_P
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
ossl_evp_get_cipherbyname
const EVP_CIPHER * ossl_evp_get_cipherbyname(VALUE obj)
Definition: ossl_cipher.c:52
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
GetPrivPKeyPtr
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:239
ossl_evp_get_digestbyname
const EVP_MD * ossl_evp_get_digestbyname(VALUE obj)
Definition: ossl_digest.c:45
ossl_rsa_new
VALUE ossl_rsa_new(EVP_PKEY *pkey)
Definition: ossl_pkey_rsa.c:73
EVP_MD_CTX_new
#define EVP_MD_CTX_new
Definition: openssl_missing.h:50
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
ossl_generate_cb_2
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
Definition: ossl_pkey.c:39