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 */
44 VALUE cRSA;
45 VALUE eRSAError;
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) {
88 ossl_raise(eRSAError, NULL);
89 }
90
91 return obj;
92 }
93
94 /*
95 * Private
96 */
97 struct rsa_blocking_gen_arg {
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 */
161 ossl_clear_error();
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);
194 ossl_raise(eRSAError, NULL);
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);
238 arg = ossl_to_der_if_possible(arg);
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);
268 ossl_raise(eRSAError, NULL);
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()))) {
357 ossl_raise(eRSAError, NULL);
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);
363 ossl_raise(eRSAError, NULL);
364 }
365 } else {
366 if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
367 BIO_free(out);
368 ossl_raise(eRSAError, NULL);
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)
397 ossl_raise(eRSAError, NULL);
398 str = rb_str_new(0, len);
399 p = (unsigned char *)RSTRING_PTR(str);
400 if(i2d_func(rsa, &p) < 0)
401 ossl_raise(eRSAError, NULL);
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);
633 ossl_raise(eRSAError, NULL);
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:
714 ossl_clear_error();
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);
726 ossl_raise(eRSAError, NULL);
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()))) {
784 ossl_raise(eRSAError, NULL);
785 }
786 if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
787 BIO_free(out);
788 ossl_raise(eRSAError, NULL);
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);
814 ossl_raise(eRSAError, NULL);
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
880 Init_ossl_rsa(void)
881 {
882 #if 0
883 mPKey = rb_define_module_under(mOSSL, "PKey");
884 cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
885 ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
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 */
894 eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
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 */
906 cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
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
927 DEF_OSSL_PKEY_BN(cRSA, rsa, n);
928 DEF_OSSL_PKEY_BN(cRSA, rsa, e);
929 DEF_OSSL_PKEY_BN(cRSA, rsa, d);
930 DEF_OSSL_PKEY_BN(cRSA, rsa, p);
931 DEF_OSSL_PKEY_BN(cRSA, rsa, q);
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