Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
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
26static inline int
27RSA_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
35static inline int
36RSA_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 */
50static VALUE
51rsa_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
73ossl_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;
103};
104
105static void *
106rsa_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
113static RSA *
114rsa_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);
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);
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
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 */
179static VALUE
180ossl_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 */
220static VALUE
221ossl_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));
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
274static VALUE
275ossl_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 */
301static VALUE
302ossl_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 */
320static VALUE
321ossl_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 */
340static VALUE
341ossl_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 */
382static VALUE
383ossl_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)
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 */
415static VALUE
416ossl_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 */
447static VALUE
448ossl_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 */
479static VALUE
480ossl_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 */
513static VALUE
514ossl_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 */
572static VALUE
573ossl_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 */
659static VALUE
660ossl_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 */
740static VALUE
741ossl_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();
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 */
775static VALUE
776ossl_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 */
801static VALUE
802ossl_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
822static VALUE
823ossl_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
835static VALUE
836ossl_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 */
854OSSL_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 */
862OSSL_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 */
872OSSL_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
879void
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 */
954void
955Init_ossl_rsa(void)
956{
957}
958#endif /* NO_RSA */
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
VALUE rb_define_class_under(VALUE, const char *, VALUE)
Defines a class under the namespace of outer.
Definition: class.c:711
VALUE rb_define_module_under(VALUE, const char *)
Definition: class.c:810
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
Definition: class.c:1818
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *)
Definition: class.c:1904
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
VALUE rb_eTypeError
Definition: error.c:924
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:884
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
#define EVP_MD_CTX_free
#define EVP_MD_CTX_new
#define BN_GENCB_new()
#define BN_GENCB_free(cb)
VALUE mOSSL
Definition: ossl.c:231
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
Definition: ossl.c:177
VALUE ossl_pem_passwd_value(VALUE pass)
Definition: ossl.c:151
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:255
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
VALUE eOSSLError
Definition: ossl.c:236
void ossl_clear_error(void)
Definition: ossl.c:304
#define ossl_str_adjust(str, p)
Definition: ossl.h:87
#define OSSL_BIO_reset(bio)
Definition: ossl.h:115
BIO * ossl_obj2bio(volatile VALUE *pobj)
Definition: ossl_bio.c:13
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:29
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:58
const EVP_CIPHER * ossl_evp_get_cipherbyname(VALUE obj)
Definition: ossl_cipher.c:52
const EVP_MD * ossl_evp_get_digestbyname(VALUE obj)
Definition: ossl_digest.c:45
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:239
VALUE cPKey
Definition: ossl_pkey.c:16
VALUE mPKey
Definition: ossl_pkey.c:15
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
Definition: ossl_pkey.c:39
void ossl_generate_cb_stop(void *ptr)
Definition: ossl_pkey.c:72
VALUE ePKeyError
Definition: ossl_pkey.c:17
#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3)
Definition: ossl_pkey.h:210
#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2)
Definition: ossl_pkey.h:217
#define GetPKey(obj, pkey)
Definition: ossl_pkey.h:31
#define SetPKey(obj, pkey)
Definition: ossl_pkey.h:24
#define DEF_OSSL_PKEY_BN(class, keytype, name)
Definition: ossl_pkey.h:223
#define NewPKey(klass)
Definition: ossl_pkey.h:22
#define OSSL_PKEY_IS_PRIVATE(obj)
Definition: ossl_pkey.h:20
#define GetPKeyRSA(obj, pkey)
Definition: ossl_pkey_rsa.c:14
VALUE cRSA
Definition: ossl_pkey_rsa.c:44
#define GetRSA(obj, rsa)
Definition: ossl_pkey_rsa.c:20
void Init_ossl_rsa(void)
VALUE ossl_rsa_new(EVP_PKEY *pkey)
Definition: ossl_pkey_rsa.c:73
#define DefRSAConst(x)
VALUE eRSAError
Definition: ossl_pkey_rsa.c:45
#define rb_str_new2
#define NULL
use StringValue() instead")))
#define RSTRING_LEN(str)
#define NUM2ULONG(x)
const VALUE VALUE obj
#define RSTRING_PTR(str)
#define rb_str_new(str, len)
#define NIL_P(v)
#define ID2SYM(x)
#define RSTRING_LENINT(str)
const char size_t n
#define rb_intern_const(str)
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
unsigned long VALUE
uint32_t i
__inline__ const void *__restrict__ size_t len
#define NUM2INT(x)
void rb_define_singleton_method(VALUE, const char *, VALUE(*)(), int)
#define rb_scan_args(argc, argvp, fmt,...)
#define rb_intern(str)
unsigned int size
#define Qtrue
#define Qfalse
const VALUE * argv
__inline__ int
#define RB_INTEGER_TYPE_P(obj)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
Definition: hash.c:2852
unsigned long ID
double exp(double)
void rb_define_method(VALUE, const char *, VALUE(*)(), int)
VALUE rb_hash_new(void)
Definition: hash.c:1523
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)