openssl 2.1.0 → 3.2.0
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 +4 -4
- data/CONTRIBUTING.md +35 -45
- data/History.md +426 -0
- data/README.md +38 -21
- data/ext/openssl/extconf.rb +132 -72
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +62 -46
- data/ext/openssl/ossl.c +177 -252
- data/ext/openssl/ossl.h +39 -17
- data/ext/openssl/ossl_asn1.c +53 -14
- data/ext/openssl/ossl_bn.c +288 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +42 -32
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +32 -63
- data/ext/openssl/ossl_engine.c +19 -28
- data/ext/openssl/ossl_hmac.c +61 -146
- data/ext/openssl/ossl_kdf.c +15 -23
- data/ext/openssl/ossl_ns_spki.c +2 -2
- data/ext/openssl/ossl_ocsp.c +17 -70
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +23 -4
- data/ext/openssl/ossl_pkcs7.c +49 -81
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1508 -195
- data/ext/openssl/ossl_pkey.h +41 -78
- data/ext/openssl/ossl_pkey_dh.c +153 -348
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +257 -343
- data/ext/openssl/ossl_pkey_rsa.c +166 -490
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +666 -456
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +86 -1
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +170 -14
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +29 -9
- data/ext/openssl/ossl_x509name.c +24 -12
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +205 -96
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +42 -20
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -16
- data/lib/openssl/hmac.rb +78 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +447 -1
- data/lib/openssl/ssl.rb +68 -24
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +18 -71
- data/ext/openssl/deprecation.rb +0 -23
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -474
data/ext/openssl/ossl_pkey_rsa.c
CHANGED
@@ -24,16 +24,16 @@
|
|
24
24
|
} while (0)
|
25
25
|
|
26
26
|
static inline int
|
27
|
-
RSA_HAS_PRIVATE(RSA *rsa)
|
27
|
+
RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa)
|
28
28
|
{
|
29
|
-
const BIGNUM *
|
29
|
+
const BIGNUM *e, *d;
|
30
30
|
|
31
|
-
|
32
|
-
return
|
31
|
+
RSA_get0_key(rsa, NULL, &e, &d);
|
32
|
+
return e && d;
|
33
33
|
}
|
34
34
|
|
35
35
|
static inline int
|
36
|
-
RSA_PRIVATE(VALUE obj, RSA *rsa)
|
36
|
+
RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa)
|
37
37
|
{
|
38
38
|
return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
|
39
39
|
}
|
@@ -44,252 +44,125 @@ RSA_PRIVATE(VALUE obj, RSA *rsa)
|
|
44
44
|
VALUE cRSA;
|
45
45
|
VALUE eRSAError;
|
46
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
47
|
/*
|
95
48
|
* Private
|
96
49
|
*/
|
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
50
|
/*
|
171
51
|
* call-seq:
|
172
|
-
* RSA.
|
173
|
-
* RSA.
|
52
|
+
* RSA.new -> rsa
|
53
|
+
* RSA.new(encoded_key [, password ]) -> rsa
|
54
|
+
* RSA.new(encoded_key) { password } -> rsa
|
55
|
+
* RSA.new(size [, exponent]) -> rsa
|
174
56
|
*
|
175
|
-
* Generates an RSA keypair.
|
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
|
57
|
+
* Generates or loads an \RSA keypair.
|
205
58
|
*
|
206
|
-
*
|
207
|
-
*
|
208
|
-
*
|
59
|
+
* If called without arguments, creates a new instance with no key components
|
60
|
+
* set. They can be set individually by #set_key, #set_factors, and
|
61
|
+
* #set_crt_params.
|
209
62
|
*
|
210
|
-
*
|
211
|
-
*
|
212
|
-
* OpenSSL will prompt for
|
63
|
+
* If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
|
64
|
+
* Note that if _password_ is not specified, but the key is encrypted with a
|
65
|
+
* password, \OpenSSL will prompt for it.
|
66
|
+
* See also OpenSSL::PKey.read which can parse keys of any kind.
|
213
67
|
*
|
214
|
-
*
|
68
|
+
* If called with a number, generates a new key pair. This form works as an
|
69
|
+
* alias of RSA.generate.
|
215
70
|
*
|
71
|
+
* Examples:
|
216
72
|
* OpenSSL::PKey::RSA.new 2048
|
217
73
|
* OpenSSL::PKey::RSA.new File.read 'rsa.pem'
|
218
|
-
* OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my
|
74
|
+
* OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password'
|
219
75
|
*/
|
220
76
|
static VALUE
|
221
77
|
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
222
78
|
{
|
223
79
|
EVP_PKEY *pkey;
|
224
80
|
RSA *rsa;
|
225
|
-
BIO *in;
|
81
|
+
BIO *in = NULL;
|
226
82
|
VALUE arg, pass;
|
83
|
+
int type;
|
227
84
|
|
228
|
-
|
229
|
-
if(
|
85
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
86
|
+
if (pkey)
|
87
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
88
|
+
|
89
|
+
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
90
|
+
rb_scan_args(argc, argv, "02", &arg, &pass);
|
91
|
+
if (argc == 0) {
|
230
92
|
rsa = RSA_new();
|
93
|
+
if (!rsa)
|
94
|
+
ossl_raise(eRSAError, "RSA_new");
|
95
|
+
goto legacy;
|
231
96
|
}
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
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);
|
97
|
+
|
98
|
+
pass = ossl_pem_passwd_value(pass);
|
99
|
+
arg = ossl_to_der_if_possible(arg);
|
100
|
+
in = ossl_obj2bio(&arg);
|
101
|
+
|
102
|
+
/* First try RSAPublicKey format */
|
103
|
+
rsa = d2i_RSAPublicKey_bio(in, NULL);
|
104
|
+
if (rsa)
|
105
|
+
goto legacy;
|
106
|
+
OSSL_BIO_reset(in);
|
107
|
+
rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
108
|
+
if (rsa)
|
109
|
+
goto legacy;
|
110
|
+
OSSL_BIO_reset(in);
|
111
|
+
|
112
|
+
/* Use the generic routine */
|
113
|
+
pkey = ossl_pkey_read_generic(in, pass);
|
114
|
+
BIO_free(in);
|
115
|
+
if (!pkey)
|
116
|
+
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
117
|
+
|
118
|
+
type = EVP_PKEY_base_id(pkey);
|
119
|
+
if (type != EVP_PKEY_RSA) {
|
120
|
+
EVP_PKEY_free(pkey);
|
121
|
+
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
269
122
|
}
|
123
|
+
RTYPEDDATA_DATA(self) = pkey;
|
124
|
+
return self;
|
270
125
|
|
126
|
+
legacy:
|
127
|
+
BIO_free(in);
|
128
|
+
pkey = EVP_PKEY_new();
|
129
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
130
|
+
EVP_PKEY_free(pkey);
|
131
|
+
RSA_free(rsa);
|
132
|
+
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
133
|
+
}
|
134
|
+
RTYPEDDATA_DATA(self) = pkey;
|
271
135
|
return self;
|
272
136
|
}
|
273
137
|
|
138
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
274
139
|
static VALUE
|
275
140
|
ossl_rsa_initialize_copy(VALUE self, VALUE other)
|
276
141
|
{
|
277
142
|
EVP_PKEY *pkey;
|
278
143
|
RSA *rsa, *rsa_new;
|
279
144
|
|
280
|
-
|
281
|
-
if (
|
282
|
-
|
145
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
146
|
+
if (pkey)
|
147
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
283
148
|
GetRSA(other, rsa);
|
284
149
|
|
285
|
-
rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey,
|
150
|
+
rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey,
|
151
|
+
(d2i_of_void *)d2i_RSAPrivateKey,
|
152
|
+
(char *)rsa);
|
286
153
|
if (!rsa_new)
|
287
154
|
ossl_raise(eRSAError, "ASN1_dup");
|
288
155
|
|
289
|
-
|
156
|
+
pkey = EVP_PKEY_new();
|
157
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) {
|
158
|
+
RSA_free(rsa_new);
|
159
|
+
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
160
|
+
}
|
161
|
+
RTYPEDDATA_DATA(self) = pkey;
|
290
162
|
|
291
163
|
return self;
|
292
164
|
}
|
165
|
+
#endif
|
293
166
|
|
294
167
|
/*
|
295
168
|
* call-seq:
|
@@ -301,7 +174,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
|
|
301
174
|
static VALUE
|
302
175
|
ossl_rsa_is_public(VALUE self)
|
303
176
|
{
|
304
|
-
RSA *rsa;
|
177
|
+
OSSL_3_const RSA *rsa;
|
305
178
|
|
306
179
|
GetRSA(self, rsa);
|
307
180
|
/*
|
@@ -320,220 +193,115 @@ ossl_rsa_is_public(VALUE self)
|
|
320
193
|
static VALUE
|
321
194
|
ossl_rsa_is_private(VALUE self)
|
322
195
|
{
|
323
|
-
RSA *rsa;
|
196
|
+
OSSL_3_const RSA *rsa;
|
324
197
|
|
325
198
|
GetRSA(self, rsa);
|
326
199
|
|
327
200
|
return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse;
|
328
201
|
}
|
329
202
|
|
330
|
-
|
331
|
-
|
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)
|
203
|
+
static int
|
204
|
+
can_export_rsaprivatekey(VALUE self)
|
342
205
|
{
|
343
|
-
RSA *rsa;
|
344
|
-
|
345
|
-
const EVP_CIPHER *ciph = NULL;
|
346
|
-
VALUE cipher, pass, str;
|
206
|
+
OSSL_3_const RSA *rsa;
|
207
|
+
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
|
347
208
|
|
348
209
|
GetRSA(self, rsa);
|
349
210
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
ciph = ossl_evp_get_cipherbyname(cipher);
|
354
|
-
pass = ossl_pem_passwd_value(pass);
|
355
|
-
}
|
356
|
-
if (!(out = BIO_new(BIO_s_mem()))) {
|
357
|
-
ossl_raise(eRSAError, NULL);
|
358
|
-
}
|
359
|
-
if (RSA_HAS_PRIVATE(rsa)) {
|
360
|
-
if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
|
361
|
-
ossl_pem_passwd_cb, (void *)pass)) {
|
362
|
-
BIO_free(out);
|
363
|
-
ossl_raise(eRSAError, NULL);
|
364
|
-
}
|
365
|
-
} else {
|
366
|
-
if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
|
367
|
-
BIO_free(out);
|
368
|
-
ossl_raise(eRSAError, NULL);
|
369
|
-
}
|
370
|
-
}
|
371
|
-
str = ossl_membio2str(out);
|
211
|
+
RSA_get0_key(rsa, &n, &e, &d);
|
212
|
+
RSA_get0_factors(rsa, &p, &q);
|
213
|
+
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
|
372
214
|
|
373
|
-
return
|
215
|
+
return n && e && d && p && q && dmp1 && dmq1 && iqmp;
|
374
216
|
}
|
375
217
|
|
376
218
|
/*
|
377
219
|
* call-seq:
|
378
|
-
* rsa.
|
220
|
+
* rsa.export([cipher, password]) => PEM-format String
|
221
|
+
* rsa.to_pem([cipher, password]) => PEM-format String
|
222
|
+
* rsa.to_s([cipher, password]) => PEM-format String
|
223
|
+
*
|
224
|
+
* Serializes a private or public key to a PEM-encoding.
|
225
|
+
*
|
226
|
+
* [When the key contains public components only]
|
227
|
+
*
|
228
|
+
* Serializes it into an X.509 SubjectPublicKeyInfo.
|
229
|
+
* The parameters _cipher_ and _password_ are ignored.
|
230
|
+
*
|
231
|
+
* A PEM-encoded key will look like:
|
232
|
+
*
|
233
|
+
* -----BEGIN PUBLIC KEY-----
|
234
|
+
* [...]
|
235
|
+
* -----END PUBLIC KEY-----
|
236
|
+
*
|
237
|
+
* Consider using #public_to_pem instead. This serializes the key into an
|
238
|
+
* X.509 SubjectPublicKeyInfo regardless of whether the key is a public key
|
239
|
+
* or a private key.
|
240
|
+
*
|
241
|
+
* [When the key contains private components, and no parameters are given]
|
242
|
+
*
|
243
|
+
* Serializes it into a PKCS #1 RSAPrivateKey.
|
244
|
+
*
|
245
|
+
* A PEM-encoded key will look like:
|
246
|
+
*
|
247
|
+
* -----BEGIN RSA PRIVATE KEY-----
|
248
|
+
* [...]
|
249
|
+
* -----END RSA PRIVATE KEY-----
|
250
|
+
*
|
251
|
+
* [When the key contains private components, and _cipher_ and _password_ are given]
|
252
|
+
*
|
253
|
+
* Serializes it into a PKCS #1 RSAPrivateKey
|
254
|
+
* and encrypts it in OpenSSL's traditional PEM encryption format.
|
255
|
+
* _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
|
256
|
+
* instance of OpenSSL::Cipher.
|
257
|
+
*
|
258
|
+
* An encrypted PEM-encoded key will look like:
|
259
|
+
*
|
260
|
+
* -----BEGIN RSA PRIVATE KEY-----
|
261
|
+
* Proc-Type: 4,ENCRYPTED
|
262
|
+
* DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
|
263
|
+
*
|
264
|
+
* [...]
|
265
|
+
* -----END RSA PRIVATE KEY-----
|
266
|
+
*
|
267
|
+
* Note that this format uses MD5 to derive the encryption key, and hence
|
268
|
+
* will not be available on FIPS-compliant systems.
|
269
|
+
*
|
270
|
+
* <b>This method is kept for compatibility.</b>
|
271
|
+
* This should only be used when the PKCS #1 RSAPrivateKey format is required.
|
379
272
|
*
|
380
|
-
*
|
273
|
+
* Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
|
274
|
+
* (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
|
381
275
|
*/
|
382
276
|
static VALUE
|
383
|
-
|
277
|
+
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
|
384
278
|
{
|
385
|
-
|
386
|
-
|
387
|
-
unsigned char *p;
|
388
|
-
long len;
|
389
|
-
VALUE str;
|
390
|
-
|
391
|
-
GetRSA(self, rsa);
|
392
|
-
if (RSA_HAS_PRIVATE(rsa))
|
393
|
-
i2d_func = i2d_RSAPrivateKey;
|
279
|
+
if (can_export_rsaprivatekey(self))
|
280
|
+
return ossl_pkey_export_traditional(argc, argv, self, 0);
|
394
281
|
else
|
395
|
-
|
396
|
-
if((len = i2d_func(rsa, NULL)) <= 0)
|
397
|
-
ossl_raise(eRSAError, NULL);
|
398
|
-
str = rb_str_new(0, len);
|
399
|
-
p = (unsigned char *)RSTRING_PTR(str);
|
400
|
-
if(i2d_func(rsa, &p) < 0)
|
401
|
-
ossl_raise(eRSAError, NULL);
|
402
|
-
ossl_str_adjust(str, p);
|
403
|
-
|
404
|
-
return str;
|
282
|
+
return ossl_pkey_export_spki(self, 0);
|
405
283
|
}
|
406
284
|
|
407
285
|
/*
|
408
286
|
* call-seq:
|
409
|
-
* rsa.
|
410
|
-
* rsa.public_encrypt(string, padding) => String
|
287
|
+
* rsa.to_der => DER-format String
|
411
288
|
*
|
412
|
-
*
|
413
|
-
* The encrypted string output can be decrypted using #private_decrypt.
|
414
|
-
*/
|
415
|
-
static VALUE
|
416
|
-
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
|
417
|
-
{
|
418
|
-
RSA *rsa;
|
419
|
-
const BIGNUM *rsa_n;
|
420
|
-
int buf_len, pad;
|
421
|
-
VALUE str, buffer, padding;
|
422
|
-
|
423
|
-
GetRSA(self, rsa);
|
424
|
-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
|
425
|
-
if (!rsa_n)
|
426
|
-
ossl_raise(eRSAError, "incomplete RSA");
|
427
|
-
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
428
|
-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
429
|
-
StringValue(buffer);
|
430
|
-
str = rb_str_new(0, RSA_size(rsa));
|
431
|
-
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
432
|
-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
433
|
-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
434
|
-
rb_str_set_len(str, buf_len);
|
435
|
-
|
436
|
-
return str;
|
437
|
-
}
|
438
|
-
|
439
|
-
/*
|
440
|
-
* call-seq:
|
441
|
-
* rsa.public_decrypt(string) => String
|
442
|
-
* rsa.public_decrypt(string, padding) => String
|
289
|
+
* Serializes a private or public key to a DER-encoding.
|
443
290
|
*
|
444
|
-
*
|
445
|
-
* public key. _padding_ defaults to PKCS1_PADDING.
|
446
|
-
*/
|
447
|
-
static VALUE
|
448
|
-
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
|
449
|
-
{
|
450
|
-
RSA *rsa;
|
451
|
-
const BIGNUM *rsa_n;
|
452
|
-
int buf_len, pad;
|
453
|
-
VALUE str, buffer, padding;
|
454
|
-
|
455
|
-
GetRSA(self, rsa);
|
456
|
-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
|
457
|
-
if (!rsa_n)
|
458
|
-
ossl_raise(eRSAError, "incomplete RSA");
|
459
|
-
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
460
|
-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
461
|
-
StringValue(buffer);
|
462
|
-
str = rb_str_new(0, RSA_size(rsa));
|
463
|
-
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
464
|
-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
465
|
-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
466
|
-
rb_str_set_len(str, buf_len);
|
467
|
-
|
468
|
-
return str;
|
469
|
-
}
|
470
|
-
|
471
|
-
/*
|
472
|
-
* call-seq:
|
473
|
-
* rsa.private_encrypt(string) => String
|
474
|
-
* rsa.private_encrypt(string, padding) => String
|
291
|
+
* See #to_pem for details.
|
475
292
|
*
|
476
|
-
*
|
477
|
-
*
|
478
|
-
*/
|
479
|
-
static VALUE
|
480
|
-
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
|
481
|
-
{
|
482
|
-
RSA *rsa;
|
483
|
-
const BIGNUM *rsa_n;
|
484
|
-
int buf_len, pad;
|
485
|
-
VALUE str, buffer, padding;
|
486
|
-
|
487
|
-
GetRSA(self, rsa);
|
488
|
-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
|
489
|
-
if (!rsa_n)
|
490
|
-
ossl_raise(eRSAError, "incomplete RSA");
|
491
|
-
if (!RSA_PRIVATE(self, rsa))
|
492
|
-
ossl_raise(eRSAError, "private key needed.");
|
493
|
-
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
494
|
-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
495
|
-
StringValue(buffer);
|
496
|
-
str = rb_str_new(0, RSA_size(rsa));
|
497
|
-
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
498
|
-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
499
|
-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
500
|
-
rb_str_set_len(str, buf_len);
|
501
|
-
|
502
|
-
return str;
|
503
|
-
}
|
504
|
-
|
505
|
-
/*
|
506
|
-
* call-seq:
|
507
|
-
* rsa.private_decrypt(string) => String
|
508
|
-
* rsa.private_decrypt(string, padding) => String
|
293
|
+
* <b>This method is kept for compatibility.</b>
|
294
|
+
* This should only be used when the PKCS #1 RSAPrivateKey format is required.
|
509
295
|
*
|
510
|
-
*
|
511
|
-
* private key. _padding_ defaults to PKCS1_PADDING.
|
296
|
+
* Consider using #public_to_der or #private_to_der instead.
|
512
297
|
*/
|
513
298
|
static VALUE
|
514
|
-
|
299
|
+
ossl_rsa_to_der(VALUE self)
|
515
300
|
{
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
GetRSA(self, rsa);
|
522
|
-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
|
523
|
-
if (!rsa_n)
|
524
|
-
ossl_raise(eRSAError, "incomplete RSA");
|
525
|
-
if (!RSA_PRIVATE(self, rsa))
|
526
|
-
ossl_raise(eRSAError, "private key needed.");
|
527
|
-
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
528
|
-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
529
|
-
StringValue(buffer);
|
530
|
-
str = rb_str_new(0, RSA_size(rsa));
|
531
|
-
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
532
|
-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
533
|
-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
534
|
-
rb_str_set_len(str, buf_len);
|
535
|
-
|
536
|
-
return str;
|
301
|
+
if (can_export_rsaprivatekey(self))
|
302
|
+
return ossl_pkey_export_traditional(0, NULL, self, 1);
|
303
|
+
else
|
304
|
+
return ossl_pkey_export_spki(self, 1);
|
537
305
|
}
|
538
306
|
|
539
307
|
/*
|
@@ -565,7 +333,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
|
|
565
333
|
* data = "Sign me!"
|
566
334
|
* pkey = OpenSSL::PKey::RSA.new(2048)
|
567
335
|
* signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
|
568
|
-
* pub_key = pkey.
|
336
|
+
* pub_key = OpenSSL::PKey.read(pkey.public_to_der)
|
569
337
|
* puts pub_key.verify_pss("SHA256", signature, data,
|
570
338
|
* salt_length: :auto, mgf1_hash: "SHA256") # => true
|
571
339
|
*/
|
@@ -740,7 +508,7 @@ ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
|
|
740
508
|
static VALUE
|
741
509
|
ossl_rsa_get_params(VALUE self)
|
742
510
|
{
|
743
|
-
RSA *rsa;
|
511
|
+
OSSL_3_const RSA *rsa;
|
744
512
|
VALUE hash;
|
745
513
|
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
|
746
514
|
|
@@ -762,88 +530,6 @@ ossl_rsa_get_params(VALUE self)
|
|
762
530
|
return hash;
|
763
531
|
}
|
764
532
|
|
765
|
-
/*
|
766
|
-
* call-seq:
|
767
|
-
* rsa.to_text => String
|
768
|
-
*
|
769
|
-
* THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
|
770
|
-
*
|
771
|
-
* Dumps all parameters of a keypair to a String
|
772
|
-
*
|
773
|
-
* Don't use :-)) (It's up to you)
|
774
|
-
*/
|
775
|
-
static VALUE
|
776
|
-
ossl_rsa_to_text(VALUE self)
|
777
|
-
{
|
778
|
-
RSA *rsa;
|
779
|
-
BIO *out;
|
780
|
-
VALUE str;
|
781
|
-
|
782
|
-
GetRSA(self, rsa);
|
783
|
-
if (!(out = BIO_new(BIO_s_mem()))) {
|
784
|
-
ossl_raise(eRSAError, NULL);
|
785
|
-
}
|
786
|
-
if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
|
787
|
-
BIO_free(out);
|
788
|
-
ossl_raise(eRSAError, NULL);
|
789
|
-
}
|
790
|
-
str = ossl_membio2str(out);
|
791
|
-
|
792
|
-
return str;
|
793
|
-
}
|
794
|
-
|
795
|
-
/*
|
796
|
-
* call-seq:
|
797
|
-
* rsa.public_key -> RSA
|
798
|
-
*
|
799
|
-
* Makes new RSA instance containing the public key from the private key.
|
800
|
-
*/
|
801
|
-
static VALUE
|
802
|
-
ossl_rsa_to_public_key(VALUE self)
|
803
|
-
{
|
804
|
-
EVP_PKEY *pkey;
|
805
|
-
RSA *rsa;
|
806
|
-
VALUE obj;
|
807
|
-
|
808
|
-
GetPKeyRSA(self, pkey);
|
809
|
-
/* err check performed by rsa_instance */
|
810
|
-
rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
|
811
|
-
obj = rsa_instance(rb_obj_class(self), rsa);
|
812
|
-
if (obj == Qfalse) {
|
813
|
-
RSA_free(rsa);
|
814
|
-
ossl_raise(eRSAError, NULL);
|
815
|
-
}
|
816
|
-
return obj;
|
817
|
-
}
|
818
|
-
|
819
|
-
/*
|
820
|
-
* TODO: Test me
|
821
|
-
|
822
|
-
static VALUE
|
823
|
-
ossl_rsa_blinding_on(VALUE self)
|
824
|
-
{
|
825
|
-
RSA *rsa;
|
826
|
-
|
827
|
-
GetRSA(self, rsa);
|
828
|
-
|
829
|
-
if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
|
830
|
-
ossl_raise(eRSAError, NULL);
|
831
|
-
}
|
832
|
-
return self;
|
833
|
-
}
|
834
|
-
|
835
|
-
static VALUE
|
836
|
-
ossl_rsa_blinding_off(VALUE self)
|
837
|
-
{
|
838
|
-
RSA *rsa;
|
839
|
-
|
840
|
-
GetRSA(self, rsa);
|
841
|
-
RSA_blinding_off(rsa);
|
842
|
-
|
843
|
-
return self;
|
844
|
-
}
|
845
|
-
*/
|
846
|
-
|
847
533
|
/*
|
848
534
|
* Document-method: OpenSSL::PKey::RSA#set_key
|
849
535
|
* call-seq:
|
@@ -905,22 +591,17 @@ Init_ossl_rsa(void)
|
|
905
591
|
*/
|
906
592
|
cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
|
907
593
|
|
908
|
-
rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
|
909
594
|
rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
|
595
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
910
596
|
rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
|
597
|
+
#endif
|
911
598
|
|
912
599
|
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
|
913
600
|
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
|
914
|
-
rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
|
915
601
|
rb_define_method(cRSA, "export", ossl_rsa_export, -1);
|
916
602
|
rb_define_alias(cRSA, "to_pem", "export");
|
917
603
|
rb_define_alias(cRSA, "to_s", "export");
|
918
604
|
rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
|
919
|
-
rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
|
920
|
-
rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
|
921
|
-
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
|
922
|
-
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
|
923
|
-
rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
|
924
605
|
rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
|
925
606
|
rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
|
926
607
|
|
@@ -938,11 +619,6 @@ Init_ossl_rsa(void)
|
|
938
619
|
|
939
620
|
rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
|
940
621
|
|
941
|
-
DefRSAConst(PKCS1_PADDING);
|
942
|
-
DefRSAConst(SSLV23_PADDING);
|
943
|
-
DefRSAConst(NO_PADDING);
|
944
|
-
DefRSAConst(PKCS1_OAEP_PADDING);
|
945
|
-
|
946
622
|
/*
|
947
623
|
* TODO: Test it
|
948
624
|
rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
|