Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
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 *e, *d;
30
31 RSA_get0_key(rsa, NULL, &e, &d);
32 return e && d;
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);
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) {
243 rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
244 }
245 if (!rsa) {
247 rsa = d2i_RSAPrivateKey_bio(in, NULL);
248 }
249 if (!rsa) {
251 rsa = d2i_RSA_PUBKEY_bio(in, NULL);
252 }
253 if (!rsa) {
255 rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
256 }
257 if (!rsa) {
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 const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
345 BIO *out;
346 const EVP_CIPHER *ciph = NULL;
347 VALUE cipher, pass, str;
348
349 GetRSA(self, rsa);
350
351 rb_scan_args(argc, argv, "02", &cipher, &pass);
352
353 if (!NIL_P(cipher)) {
354 ciph = ossl_evp_get_cipherbyname(cipher);
355 pass = ossl_pem_passwd_value(pass);
356 }
357 if (!(out = BIO_new(BIO_s_mem()))) {
359 }
360 RSA_get0_key(rsa, &n, &e, &d);
361 RSA_get0_factors(rsa, &p, &q);
362 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
363 if (n && e && d && p && q && dmp1 && dmq1 && iqmp) {
364 if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
365 ossl_pem_passwd_cb, (void *)pass)) {
366 BIO_free(out);
368 }
369 } else {
370 if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
371 BIO_free(out);
373 }
374 }
376
377 return str;
378}
379
380/*
381 * call-seq:
382 * rsa.to_der => DER-format String
383 *
384 * Outputs this keypair in DER encoding.
385 */
386static VALUE
387ossl_rsa_to_der(VALUE self)
388{
389 RSA *rsa;
390 const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
391 int (*i2d_func)(const RSA *, unsigned char **);
392 unsigned char *ptr;
393 long len;
394 VALUE str;
395
396 GetRSA(self, rsa);
397 RSA_get0_key(rsa, &n, &e, &d);
398 RSA_get0_factors(rsa, &p, &q);
399 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
400 if (n && e && d && p && q && dmp1 && dmq1 && iqmp)
401 i2d_func = i2d_RSAPrivateKey;
402 else
403 i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY;
404 if((len = i2d_func(rsa, NULL)) <= 0)
406 str = rb_str_new(0, len);
407 ptr = (unsigned char *)RSTRING_PTR(str);
408 if(i2d_func(rsa, &ptr) < 0)
411
412 return str;
413}
414
415/*
416 * call-seq:
417 * rsa.public_encrypt(string) => String
418 * rsa.public_encrypt(string, padding) => String
419 *
420 * Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING.
421 * The encrypted string output can be decrypted using #private_decrypt.
422 */
423static VALUE
424ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
425{
426 RSA *rsa;
427 const BIGNUM *rsa_n;
428 int buf_len, pad;
429 VALUE str, buffer, padding;
430
431 GetRSA(self, rsa);
432 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
433 if (!rsa_n)
434 ossl_raise(eRSAError, "incomplete RSA");
435 rb_scan_args(argc, argv, "11", &buffer, &padding);
436 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
437 StringValue(buffer);
438 str = rb_str_new(0, RSA_size(rsa));
439 buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
440 (unsigned char *)RSTRING_PTR(str), rsa, pad);
441 if (buf_len < 0) ossl_raise(eRSAError, NULL);
442 rb_str_set_len(str, buf_len);
443
444 return str;
445}
446
447/*
448 * call-seq:
449 * rsa.public_decrypt(string) => String
450 * rsa.public_decrypt(string, padding) => String
451 *
452 * Decrypt _string_, which has been encrypted with the private key, with the
453 * public key. _padding_ defaults to PKCS1_PADDING.
454 */
455static VALUE
456ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
457{
458 RSA *rsa;
459 const BIGNUM *rsa_n;
460 int buf_len, pad;
461 VALUE str, buffer, padding;
462
463 GetRSA(self, rsa);
464 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
465 if (!rsa_n)
466 ossl_raise(eRSAError, "incomplete RSA");
467 rb_scan_args(argc, argv, "11", &buffer, &padding);
468 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
469 StringValue(buffer);
470 str = rb_str_new(0, RSA_size(rsa));
471 buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
472 (unsigned char *)RSTRING_PTR(str), rsa, pad);
473 if (buf_len < 0) ossl_raise(eRSAError, NULL);
474 rb_str_set_len(str, buf_len);
475
476 return str;
477}
478
479/*
480 * call-seq:
481 * rsa.private_encrypt(string) => String
482 * rsa.private_encrypt(string, padding) => String
483 *
484 * Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING.
485 * The encrypted string output can be decrypted using #public_decrypt.
486 */
487static VALUE
488ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
489{
490 RSA *rsa;
491 const BIGNUM *rsa_n;
492 int buf_len, pad;
493 VALUE str, buffer, padding;
494
495 GetRSA(self, rsa);
496 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
497 if (!rsa_n)
498 ossl_raise(eRSAError, "incomplete RSA");
499 if (!RSA_PRIVATE(self, rsa))
500 ossl_raise(eRSAError, "private key needed.");
501 rb_scan_args(argc, argv, "11", &buffer, &padding);
502 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
503 StringValue(buffer);
504 str = rb_str_new(0, RSA_size(rsa));
505 buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
506 (unsigned char *)RSTRING_PTR(str), rsa, pad);
507 if (buf_len < 0) ossl_raise(eRSAError, NULL);
508 rb_str_set_len(str, buf_len);
509
510 return str;
511}
512
513/*
514 * call-seq:
515 * rsa.private_decrypt(string) => String
516 * rsa.private_decrypt(string, padding) => String
517 *
518 * Decrypt _string_, which has been encrypted with the public key, with the
519 * private key. _padding_ defaults to PKCS1_PADDING.
520 */
521static VALUE
522ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
523{
524 RSA *rsa;
525 const BIGNUM *rsa_n;
526 int buf_len, pad;
527 VALUE str, buffer, padding;
528
529 GetRSA(self, rsa);
530 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
531 if (!rsa_n)
532 ossl_raise(eRSAError, "incomplete RSA");
533 if (!RSA_PRIVATE(self, rsa))
534 ossl_raise(eRSAError, "private key needed.");
535 rb_scan_args(argc, argv, "11", &buffer, &padding);
536 pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
537 StringValue(buffer);
538 str = rb_str_new(0, RSA_size(rsa));
539 buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
540 (unsigned char *)RSTRING_PTR(str), rsa, pad);
541 if (buf_len < 0) ossl_raise(eRSAError, NULL);
542 rb_str_set_len(str, buf_len);
543
544 return str;
545}
546
547/*
548 * call-seq:
549 * rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
550 *
551 * Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns
552 * the calculated signature.
553 *
554 * RSAError will be raised if an error occurs.
555 *
556 * See #verify_pss for the verification operation.
557 *
558 * === Parameters
559 * _digest_::
560 * A String containing the message digest algorithm name.
561 * _data_::
562 * A String. The data to be signed.
563 * _salt_length_::
564 * The length in octets of the salt. Two special values are reserved:
565 * +:digest+ means the digest length, and +:max+ means the maximum possible
566 * length for the combination of the private key and the selected message
567 * digest algorithm.
568 * _mgf1_hash_::
569 * The hash algorithm used in MGF1 (the currently supported mask generation
570 * function (MGF)).
571 *
572 * === Example
573 * data = "Sign me!"
574 * pkey = OpenSSL::PKey::RSA.new(2048)
575 * signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
576 * pub_key = pkey.public_key
577 * puts pub_key.verify_pss("SHA256", signature, data,
578 * salt_length: :auto, mgf1_hash: "SHA256") # => true
579 */
580static VALUE
581ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self)
582{
583 VALUE digest, data, options, kwargs[2], signature;
584 static ID kwargs_ids[2];
585 EVP_PKEY *pkey;
586 EVP_PKEY_CTX *pkey_ctx;
587 const EVP_MD *md, *mgf1md;
588 EVP_MD_CTX *md_ctx;
589 size_t buf_len;
590 int salt_len;
591
592 if (!kwargs_ids[0]) {
593 kwargs_ids[0] = rb_intern_const("salt_length");
594 kwargs_ids[1] = rb_intern_const("mgf1_hash");
595 }
596 rb_scan_args(argc, argv, "2:", &digest, &data, &options);
597 rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
598 if (kwargs[0] == ID2SYM(rb_intern("max")))
599 salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */
600 else if (kwargs[0] == ID2SYM(rb_intern("digest")))
601 salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
602 else
603 salt_len = NUM2INT(kwargs[0]);
604 mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
605
606 pkey = GetPrivPKeyPtr(self);
607 buf_len = EVP_PKEY_size(pkey);
608 md = ossl_evp_get_digestbyname(digest);
609 StringValue(data);
610 signature = rb_str_new(NULL, (long)buf_len);
611
612 md_ctx = EVP_MD_CTX_new();
613 if (!md_ctx)
614 goto err;
615
616 if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
617 goto err;
618
619 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
620 goto err;
621
622 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
623 goto err;
624
625 if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
626 goto err;
627
628 if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
629 goto err;
630
631 if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1)
632 goto err;
633
634 rb_str_set_len(signature, (long)buf_len);
635
636 EVP_MD_CTX_free(md_ctx);
637 return signature;
638
639 err:
640 EVP_MD_CTX_free(md_ctx);
642}
643
644/*
645 * call-seq:
646 * rsa.verify_pss(digest, signature, data, salt_length:, mgf1_hash:) -> true | false
647 *
648 * Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS).
649 *
650 * The return value is +true+ if the signature is valid, +false+ otherwise.
651 * RSAError will be raised if an error occurs.
652 *
653 * See #sign_pss for the signing operation and an example code.
654 *
655 * === Parameters
656 * _digest_::
657 * A String containing the message digest algorithm name.
658 * _data_::
659 * A String. The data to be signed.
660 * _salt_length_::
661 * The length in octets of the salt. Two special values are reserved:
662 * +:digest+ means the digest length, and +:auto+ means automatically
663 * determining the length based on the signature.
664 * _mgf1_hash_::
665 * The hash algorithm used in MGF1.
666 */
667static VALUE
668ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
669{
670 VALUE digest, signature, data, options, kwargs[2];
671 static ID kwargs_ids[2];
672 EVP_PKEY *pkey;
673 EVP_PKEY_CTX *pkey_ctx;
674 const EVP_MD *md, *mgf1md;
675 EVP_MD_CTX *md_ctx;
676 int result, salt_len;
677
678 if (!kwargs_ids[0]) {
679 kwargs_ids[0] = rb_intern_const("salt_length");
680 kwargs_ids[1] = rb_intern_const("mgf1_hash");
681 }
682 rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
683 rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
684 if (kwargs[0] == ID2SYM(rb_intern("auto")))
685 salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
686 else if (kwargs[0] == ID2SYM(rb_intern("digest")))
687 salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
688 else
689 salt_len = NUM2INT(kwargs[0]);
690 mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
691
692 GetPKey(self, pkey);
693 md = ossl_evp_get_digestbyname(digest);
694 StringValue(signature);
695 StringValue(data);
696
697 md_ctx = EVP_MD_CTX_new();
698 if (!md_ctx)
699 goto err;
700
701 if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
702 goto err;
703
704 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
705 goto err;
706
707 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
708 goto err;
709
710 if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
711 goto err;
712
713 if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
714 goto err;
715
716 result = EVP_DigestVerifyFinal(md_ctx,
717 (unsigned char *)RSTRING_PTR(signature),
718 RSTRING_LEN(signature));
719
720 switch (result) {
721 case 0:
723 EVP_MD_CTX_free(md_ctx);
724 return Qfalse;
725 case 1:
726 EVP_MD_CTX_free(md_ctx);
727 return Qtrue;
728 default:
729 goto err;
730 }
731
732 err:
733 EVP_MD_CTX_free(md_ctx);
735}
736
737/*
738 * call-seq:
739 * rsa.params => hash
740 *
741 * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
742 *
743 * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd',
744 * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'.
745 *
746 * Don't use :-)) (It's up to you)
747 */
748static VALUE
749ossl_rsa_get_params(VALUE self)
750{
751 RSA *rsa;
752 VALUE hash;
753 const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
754
755 GetRSA(self, rsa);
756 RSA_get0_key(rsa, &n, &e, &d);
757 RSA_get0_factors(rsa, &p, &q);
758 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
759
760 hash = rb_hash_new();
761 rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n));
763 rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d));
764 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
765 rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
766 rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1));
767 rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1));
768 rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp));
769
770 return hash;
771}
772
773/*
774 * call-seq:
775 * rsa.to_text => String
776 *
777 * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
778 *
779 * Dumps all parameters of a keypair to a String
780 *
781 * Don't use :-)) (It's up to you)
782 */
783static VALUE
784ossl_rsa_to_text(VALUE self)
785{
786 RSA *rsa;
787 BIO *out;
788 VALUE str;
789
790 GetRSA(self, rsa);
791 if (!(out = BIO_new(BIO_s_mem()))) {
793 }
794 if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
795 BIO_free(out);
797 }
799
800 return str;
801}
802
803/*
804 * call-seq:
805 * rsa.public_key -> RSA
806 *
807 * Makes new RSA instance containing the public key from the private key.
808 */
809static VALUE
810ossl_rsa_to_public_key(VALUE self)
811{
812 EVP_PKEY *pkey;
813 RSA *rsa;
814 VALUE obj;
815
816 GetPKeyRSA(self, pkey);
817 /* err check performed by rsa_instance */
818 rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
819 obj = rsa_instance(rb_obj_class(self), rsa);
820 if (obj == Qfalse) {
821 RSA_free(rsa);
823 }
824 return obj;
825}
826
827/*
828 * TODO: Test me
829
830static VALUE
831ossl_rsa_blinding_on(VALUE self)
832{
833 RSA *rsa;
834
835 GetRSA(self, rsa);
836
837 if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
838 ossl_raise(eRSAError, NULL);
839 }
840 return self;
841}
842
843static VALUE
844ossl_rsa_blinding_off(VALUE self)
845{
846 RSA *rsa;
847
848 GetRSA(self, rsa);
849 RSA_blinding_off(rsa);
850
851 return self;
852}
853 */
854
855/*
856 * Document-method: OpenSSL::PKey::RSA#set_key
857 * call-seq:
858 * rsa.set_key(n, e, d) -> self
859 *
860 * Sets _n_, _e_, _d_ for the RSA instance.
861 */
862OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d)
863/*
864 * Document-method: OpenSSL::PKey::RSA#set_factors
865 * call-seq:
866 * rsa.set_factors(p, q) -> self
867 *
868 * Sets _p_, _q_ for the RSA instance.
869 */
870OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q)
871/*
872 * Document-method: OpenSSL::PKey::RSA#set_crt_params
873 * call-seq:
874 * rsa.set_crt_params(dmp1, dmq1, iqmp) -> self
875 *
876 * Sets _dmp1_, _dmq1_, _iqmp_ for the RSA instance. They are calculated by
877 * <tt>d mod (p - 1)</tt>, <tt>d mod (q - 1)</tt> and <tt>q^(-1) mod p</tt>
878 * respectively.
879 */
880OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp)
881
882/*
883 * INIT
884 */
885#define DefRSAConst(x) rb_define_const(cRSA, #x, INT2NUM(RSA_##x))
886
887void
889{
890#if 0
894#endif
895
896 /* Document-class: OpenSSL::PKey::RSAError
897 *
898 * Generic exception that is raised if an operation on an RSA PKey
899 * fails unexpectedly or in case an instantiation of an instance of RSA
900 * fails due to non-conformant input data.
901 */
903
904 /* Document-class: OpenSSL::PKey::RSA
905 *
906 * RSA is an asymmetric public key algorithm that has been formalized in
907 * RFC 3447. It is in widespread use in public key infrastructures (PKI)
908 * where certificates (cf. OpenSSL::X509::Certificate) often are issued
909 * on the basis of a public/private RSA key pair. RSA is used in a wide
910 * field of applications such as secure (symmetric) key exchange, e.g.
911 * when establishing a secure TLS/SSL connection. It is also used in
912 * various digital signature schemes.
913 */
915
916 rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
917 rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
918 rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
919
920 rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
921 rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
922 rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
923 rb_define_method(cRSA, "export", ossl_rsa_export, -1);
924 rb_define_alias(cRSA, "to_pem", "export");
925 rb_define_alias(cRSA, "to_s", "export");
926 rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
927 rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
928 rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
929 rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
930 rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
931 rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
932 rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
933 rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
934
940 DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
941 DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
942 DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
943 rb_define_method(cRSA, "set_key", ossl_rsa_set_key, 3);
944 rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2);
945 rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3);
946
947 rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
948
949 DefRSAConst(PKCS1_PADDING);
950 DefRSAConst(SSLV23_PADDING);
951 DefRSAConst(NO_PADDING);
952 DefRSAConst(PKCS1_OAEP_PADDING);
953
954/*
955 * TODO: Test it
956 rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
957 rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
958 */
959}
960
961#else /* defined NO_RSA */
962void
963Init_ossl_rsa(void)
964{
965}
966#endif /* NO_RSA */
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
struct RIMemo * ptr
Definition: debug.c:88
string_t out
Definition: enough.c:230
uint8_t len
Definition: escape.c:17
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:797
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:895
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1999
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:935
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:2085
VALUE rb_eTypeError
Definition: error.c:1057
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:921
VALUE rb_cObject
Object class.
Definition: object.c:49
VALUE rb_obj_class(VALUE)
Definition: object.c:245
unsigned in(void *in_desc, z_const unsigned char **buf)
Definition: gun.c:89
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2901
VALUE rb_hash_new(void)
Definition: hash.c:1538
#define rb_str_new2
Definition: string.h:276
#define rb_str_new(str, len)
Definition: string.h:213
void rb_str_set_len(VALUE, long)
Definition: string.c:2842
#define ID2SYM
Definition: symbol.h:44
ID rb_intern(const char *)
Definition: symbol.c:785
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define NUM2INT
Definition: int.h:44
voidpf void uLong size
Definition: ioapi.h:138
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define NUM2ULONG
Definition: long.h:52
#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:89
#define OSSL_BIO_reset(bio)
Definition: ossl.h:116
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:62
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:245
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 NULL
Definition: regenc.h:69
#define StringValue(v)
Definition: rstring.h:50
int argc
Definition: ruby.c:240
char ** argv
Definition: ruby.c:241
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
#define Qtrue
#define Qfalse
#define NIL_P
unsigned long VALUE
Definition: value.h:38
unsigned long ID
Definition: value.h:39
int err
Definition: win32.c:142