openssl-custom 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +132 -0
  4. data/History.md +485 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +66 -0
  7. data/ext/openssl/extconf.rb +190 -0
  8. data/ext/openssl/openssl_missing.c +106 -0
  9. data/ext/openssl/openssl_missing.h +257 -0
  10. data/ext/openssl/ossl.c +1282 -0
  11. data/ext/openssl/ossl.h +181 -0
  12. data/ext/openssl/ossl_asn1.c +1878 -0
  13. data/ext/openssl/ossl_asn1.h +62 -0
  14. data/ext/openssl/ossl_bio.c +42 -0
  15. data/ext/openssl/ossl_bio.h +16 -0
  16. data/ext/openssl/ossl_bn.c +1270 -0
  17. data/ext/openssl/ossl_bn.h +26 -0
  18. data/ext/openssl/ossl_cipher.c +1075 -0
  19. data/ext/openssl/ossl_cipher.h +20 -0
  20. data/ext/openssl/ossl_config.c +89 -0
  21. data/ext/openssl/ossl_config.h +19 -0
  22. data/ext/openssl/ossl_digest.c +425 -0
  23. data/ext/openssl/ossl_digest.h +20 -0
  24. data/ext/openssl/ossl_engine.c +567 -0
  25. data/ext/openssl/ossl_engine.h +19 -0
  26. data/ext/openssl/ossl_hmac.c +389 -0
  27. data/ext/openssl/ossl_hmac.h +18 -0
  28. data/ext/openssl/ossl_kdf.c +303 -0
  29. data/ext/openssl/ossl_kdf.h +6 -0
  30. data/ext/openssl/ossl_ns_spki.c +405 -0
  31. data/ext/openssl/ossl_ns_spki.h +19 -0
  32. data/ext/openssl/ossl_ocsp.c +2013 -0
  33. data/ext/openssl/ossl_ocsp.h +23 -0
  34. data/ext/openssl/ossl_pkcs12.c +257 -0
  35. data/ext/openssl/ossl_pkcs12.h +13 -0
  36. data/ext/openssl/ossl_pkcs7.c +1098 -0
  37. data/ext/openssl/ossl_pkcs7.h +36 -0
  38. data/ext/openssl/ossl_pkey.c +673 -0
  39. data/ext/openssl/ossl_pkey.h +241 -0
  40. data/ext/openssl/ossl_pkey_dh.c +650 -0
  41. data/ext/openssl/ossl_pkey_dsa.c +664 -0
  42. data/ext/openssl/ossl_pkey_ec.c +1827 -0
  43. data/ext/openssl/ossl_pkey_rsa.c +966 -0
  44. data/ext/openssl/ossl_rand.c +200 -0
  45. data/ext/openssl/ossl_rand.h +18 -0
  46. data/ext/openssl/ossl_ssl.c +3080 -0
  47. data/ext/openssl/ossl_ssl.h +36 -0
  48. data/ext/openssl/ossl_ssl_session.c +332 -0
  49. data/ext/openssl/ossl_ts.c +1524 -0
  50. data/ext/openssl/ossl_ts.h +16 -0
  51. data/ext/openssl/ossl_x509.c +262 -0
  52. data/ext/openssl/ossl_x509.h +115 -0
  53. data/ext/openssl/ossl_x509attr.c +324 -0
  54. data/ext/openssl/ossl_x509cert.c +846 -0
  55. data/ext/openssl/ossl_x509crl.c +542 -0
  56. data/ext/openssl/ossl_x509ext.c +491 -0
  57. data/ext/openssl/ossl_x509name.c +590 -0
  58. data/ext/openssl/ossl_x509req.c +441 -0
  59. data/ext/openssl/ossl_x509revoked.c +300 -0
  60. data/ext/openssl/ossl_x509store.c +902 -0
  61. data/ext/openssl/ruby_missing.h +24 -0
  62. data/lib/openssl/bn.rb +40 -0
  63. data/lib/openssl/buffering.rb +478 -0
  64. data/lib/openssl/cipher.rb +67 -0
  65. data/lib/openssl/config.rb +501 -0
  66. data/lib/openssl/digest.rb +73 -0
  67. data/lib/openssl/hmac.rb +13 -0
  68. data/lib/openssl/marshal.rb +30 -0
  69. data/lib/openssl/pkcs5.rb +22 -0
  70. data/lib/openssl/pkey.rb +42 -0
  71. data/lib/openssl/ssl.rb +542 -0
  72. data/lib/openssl/version.rb +5 -0
  73. data/lib/openssl/x509.rb +369 -0
  74. data/lib/openssl.rb +38 -0
  75. metadata +196 -0
@@ -0,0 +1,966 @@
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 *e, *d;
30
+
31
+ RSA_get0_key(rsa, NULL, &e, &d);
32
+ return e && d;
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
+ 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()))) {
358
+ ossl_raise(eRSAError, NULL);
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);
367
+ ossl_raise(eRSAError, NULL);
368
+ }
369
+ } else {
370
+ if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
371
+ BIO_free(out);
372
+ ossl_raise(eRSAError, NULL);
373
+ }
374
+ }
375
+ str = ossl_membio2str(out);
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
+ */
386
+ static VALUE
387
+ ossl_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)
405
+ ossl_raise(eRSAError, NULL);
406
+ str = rb_str_new(0, len);
407
+ ptr = (unsigned char *)RSTRING_PTR(str);
408
+ if(i2d_func(rsa, &ptr) < 0)
409
+ ossl_raise(eRSAError, NULL);
410
+ ossl_str_adjust(str, ptr);
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
+ */
423
+ static VALUE
424
+ ossl_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
+ */
455
+ static VALUE
456
+ ossl_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
+ */
487
+ static VALUE
488
+ ossl_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
+ */
521
+ static VALUE
522
+ ossl_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
+ */
580
+ static VALUE
581
+ ossl_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);
641
+ ossl_raise(eRSAError, NULL);
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
+ */
667
+ static VALUE
668
+ ossl_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:
722
+ ossl_clear_error();
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);
734
+ ossl_raise(eRSAError, NULL);
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
+ */
748
+ static VALUE
749
+ ossl_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));
762
+ rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e));
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
+ */
783
+ static VALUE
784
+ ossl_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()))) {
792
+ ossl_raise(eRSAError, NULL);
793
+ }
794
+ if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
795
+ BIO_free(out);
796
+ ossl_raise(eRSAError, NULL);
797
+ }
798
+ str = ossl_membio2str(out);
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
+ */
809
+ static VALUE
810
+ ossl_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);
822
+ ossl_raise(eRSAError, NULL);
823
+ }
824
+ return obj;
825
+ }
826
+
827
+ /*
828
+ * TODO: Test me
829
+
830
+ static VALUE
831
+ ossl_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
+
843
+ static VALUE
844
+ ossl_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
+ */
862
+ OSSL_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
+ */
870
+ OSSL_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
+ */
880
+ OSSL_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
+
887
+ void
888
+ Init_ossl_rsa(void)
889
+ {
890
+ #if 0
891
+ mPKey = rb_define_module_under(mOSSL, "PKey");
892
+ cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
893
+ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
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
+ */
902
+ eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
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
+ */
914
+ cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
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
+
935
+ DEF_OSSL_PKEY_BN(cRSA, rsa, n);
936
+ DEF_OSSL_PKEY_BN(cRSA, rsa, e);
937
+ DEF_OSSL_PKEY_BN(cRSA, rsa, d);
938
+ DEF_OSSL_PKEY_BN(cRSA, rsa, p);
939
+ DEF_OSSL_PKEY_BN(cRSA, rsa, q);
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 */
962
+ void
963
+ Init_ossl_rsa(void)
964
+ {
965
+ }
966
+ #endif /* NO_RSA */