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.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/CONTRIBUTING.md +132 -0
- data/History.md +485 -0
- data/LICENSE.txt +56 -0
- data/README.md +66 -0
- data/ext/openssl/extconf.rb +190 -0
- data/ext/openssl/openssl_missing.c +106 -0
- data/ext/openssl/openssl_missing.h +257 -0
- data/ext/openssl/ossl.c +1282 -0
- data/ext/openssl/ossl.h +181 -0
- data/ext/openssl/ossl_asn1.c +1878 -0
- data/ext/openssl/ossl_asn1.h +62 -0
- data/ext/openssl/ossl_bio.c +42 -0
- data/ext/openssl/ossl_bio.h +16 -0
- data/ext/openssl/ossl_bn.c +1270 -0
- data/ext/openssl/ossl_bn.h +26 -0
- data/ext/openssl/ossl_cipher.c +1075 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +89 -0
- data/ext/openssl/ossl_config.h +19 -0
- data/ext/openssl/ossl_digest.c +425 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +567 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +389 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_kdf.c +303 -0
- data/ext/openssl/ossl_kdf.h +6 -0
- data/ext/openssl/ossl_ns_spki.c +405 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +2013 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +257 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs7.c +1098 -0
- data/ext/openssl/ossl_pkcs7.h +36 -0
- data/ext/openssl/ossl_pkey.c +673 -0
- data/ext/openssl/ossl_pkey.h +241 -0
- data/ext/openssl/ossl_pkey_dh.c +650 -0
- data/ext/openssl/ossl_pkey_dsa.c +664 -0
- data/ext/openssl/ossl_pkey_ec.c +1827 -0
- data/ext/openssl/ossl_pkey_rsa.c +966 -0
- data/ext/openssl/ossl_rand.c +200 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +3080 -0
- data/ext/openssl/ossl_ssl.h +36 -0
- data/ext/openssl/ossl_ssl_session.c +332 -0
- data/ext/openssl/ossl_ts.c +1524 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +262 -0
- data/ext/openssl/ossl_x509.h +115 -0
- data/ext/openssl/ossl_x509attr.c +324 -0
- data/ext/openssl/ossl_x509cert.c +846 -0
- data/ext/openssl/ossl_x509crl.c +542 -0
- data/ext/openssl/ossl_x509ext.c +491 -0
- data/ext/openssl/ossl_x509name.c +590 -0
- data/ext/openssl/ossl_x509req.c +441 -0
- data/ext/openssl/ossl_x509revoked.c +300 -0
- data/ext/openssl/ossl_x509store.c +902 -0
- data/ext/openssl/ruby_missing.h +24 -0
- data/lib/openssl/bn.rb +40 -0
- data/lib/openssl/buffering.rb +478 -0
- data/lib/openssl/cipher.rb +67 -0
- data/lib/openssl/config.rb +501 -0
- data/lib/openssl/digest.rb +73 -0
- data/lib/openssl/hmac.rb +13 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +22 -0
- data/lib/openssl/pkey.rb +42 -0
- data/lib/openssl/ssl.rb +542 -0
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +369 -0
- data/lib/openssl.rb +38 -0
- 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 */
|