openssl-custom 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 */