openssl 2.1.3 → 3.1.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 +302 -1
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +77 -62
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +59 -43
- data/ext/openssl/ossl.c +110 -64
- data/ext/openssl/ossl.h +33 -10
- data/ext/openssl/ossl_asn1.c +51 -13
- data/ext/openssl/ossl_bn.c +275 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +39 -31
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +25 -60
- data/ext/openssl/ossl_engine.c +18 -27
- data/ext/openssl/ossl_hmac.c +60 -145
- data/ext/openssl/ossl_kdf.c +14 -22
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -64
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +45 -78
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1295 -178
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +130 -340
- data/ext/openssl/ossl_pkey_dsa.c +100 -405
- data/ext/openssl/ossl_pkey_ec.c +192 -335
- data/ext/openssl/ossl_pkey_rsa.c +110 -489
- data/ext/openssl/ossl_rand.c +2 -32
- data/ext/openssl/ossl_ssl.c +556 -442
- data/ext/openssl/ossl_ssl_session.c +28 -29
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509cert.c +169 -13
- data/ext/openssl/ossl_x509crl.c +13 -10
- data/ext/openssl/ossl_x509ext.c +15 -2
- data/ext/openssl/ossl_x509name.c +15 -4
- data/ext/openssl/ossl_x509req.c +13 -10
- data/ext/openssl/ossl_x509revoked.c +3 -3
- data/ext/openssl/ossl_x509store.c +154 -70
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +37 -5
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -12
- 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 +52 -9
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +10 -79
- data/ext/openssl/deprecation.rb +0 -27
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -492
data/ext/openssl/ossl_pkey_ec.c
CHANGED
@@ -47,12 +47,7 @@ VALUE eEC_GROUP;
|
|
47
47
|
VALUE cEC_POINT;
|
48
48
|
VALUE eEC_POINT;
|
49
49
|
|
50
|
-
static ID s_GFp;
|
51
|
-
static ID s_GFp_simple;
|
52
|
-
static ID s_GFp_mont;
|
53
|
-
static ID s_GFp_nist;
|
54
|
-
static ID s_GF2m;
|
55
|
-
static ID s_GF2m_simple;
|
50
|
+
static ID s_GFp, s_GF2m;
|
56
51
|
|
57
52
|
static ID ID_uncompressed;
|
58
53
|
static ID ID_compressed;
|
@@ -63,47 +58,6 @@ static ID id_i_group;
|
|
63
58
|
static VALUE ec_group_new(const EC_GROUP *group);
|
64
59
|
static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group);
|
65
60
|
|
66
|
-
static VALUE ec_instance(VALUE klass, EC_KEY *ec)
|
67
|
-
{
|
68
|
-
EVP_PKEY *pkey;
|
69
|
-
VALUE obj;
|
70
|
-
|
71
|
-
if (!ec) {
|
72
|
-
return Qfalse;
|
73
|
-
}
|
74
|
-
obj = NewPKey(klass);
|
75
|
-
if (!(pkey = EVP_PKEY_new())) {
|
76
|
-
return Qfalse;
|
77
|
-
}
|
78
|
-
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
79
|
-
EVP_PKEY_free(pkey);
|
80
|
-
return Qfalse;
|
81
|
-
}
|
82
|
-
SetPKey(obj, pkey);
|
83
|
-
|
84
|
-
return obj;
|
85
|
-
}
|
86
|
-
|
87
|
-
VALUE ossl_ec_new(EVP_PKEY *pkey)
|
88
|
-
{
|
89
|
-
VALUE obj;
|
90
|
-
|
91
|
-
if (!pkey) {
|
92
|
-
obj = ec_instance(cEC, EC_KEY_new());
|
93
|
-
} else {
|
94
|
-
obj = NewPKey(cEC);
|
95
|
-
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
|
96
|
-
ossl_raise(rb_eTypeError, "Not a EC key!");
|
97
|
-
}
|
98
|
-
SetPKey(obj, pkey);
|
99
|
-
}
|
100
|
-
if (obj == Qfalse) {
|
101
|
-
ossl_raise(eECError, NULL);
|
102
|
-
}
|
103
|
-
|
104
|
-
return obj;
|
105
|
-
}
|
106
|
-
|
107
61
|
/*
|
108
62
|
* Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
|
109
63
|
* representing an OID.
|
@@ -150,16 +104,20 @@ ec_key_new_from_group(VALUE arg)
|
|
150
104
|
static VALUE
|
151
105
|
ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
152
106
|
{
|
107
|
+
EVP_PKEY *pkey;
|
153
108
|
EC_KEY *ec;
|
154
109
|
VALUE obj;
|
155
110
|
|
156
|
-
|
111
|
+
obj = rb_obj_alloc(klass);
|
157
112
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
113
|
+
ec = ec_key_new_from_group(arg);
|
114
|
+
pkey = EVP_PKEY_new();
|
115
|
+
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
116
|
+
EVP_PKEY_free(pkey);
|
117
|
+
EC_KEY_free(ec);
|
118
|
+
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
162
119
|
}
|
120
|
+
RTYPEDDATA_DATA(obj) = pkey;
|
163
121
|
|
164
122
|
if (!EC_KEY_generate_key(ec))
|
165
123
|
ossl_raise(eECError, "EC_KEY_generate_key");
|
@@ -182,81 +140,82 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|
182
140
|
{
|
183
141
|
EVP_PKEY *pkey;
|
184
142
|
EC_KEY *ec;
|
143
|
+
BIO *in;
|
185
144
|
VALUE arg, pass;
|
145
|
+
int type;
|
186
146
|
|
187
|
-
|
188
|
-
if (
|
189
|
-
|
147
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
148
|
+
if (pkey)
|
149
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
190
150
|
|
191
151
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
192
|
-
|
193
152
|
if (NIL_P(arg)) {
|
194
153
|
if (!(ec = EC_KEY_new()))
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
203
|
-
ec = ec_key_new_from_group(arg);
|
204
|
-
} else {
|
205
|
-
BIO *in;
|
154
|
+
ossl_raise(eECError, "EC_KEY_new");
|
155
|
+
goto legacy;
|
156
|
+
}
|
157
|
+
else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
158
|
+
ec = ec_key_new_from_group(arg);
|
159
|
+
goto legacy;
|
160
|
+
}
|
206
161
|
|
207
|
-
|
208
|
-
|
162
|
+
pass = ossl_pem_passwd_value(pass);
|
163
|
+
arg = ossl_to_der_if_possible(arg);
|
164
|
+
in = ossl_obj2bio(&arg);
|
209
165
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
OSSL_BIO_reset(in);
|
217
|
-
ec = d2i_ECPrivateKey_bio(in, NULL);
|
218
|
-
}
|
219
|
-
if (!ec) {
|
220
|
-
OSSL_BIO_reset(in);
|
221
|
-
ec = d2i_EC_PUBKEY_bio(in, NULL);
|
222
|
-
}
|
223
|
-
BIO_free(in);
|
224
|
-
|
225
|
-
if (!ec) {
|
226
|
-
ossl_clear_error();
|
227
|
-
ec = ec_key_new_from_group(arg);
|
228
|
-
}
|
166
|
+
pkey = ossl_pkey_read_generic(in, pass);
|
167
|
+
BIO_free(in);
|
168
|
+
if (!pkey) {
|
169
|
+
ossl_clear_error();
|
170
|
+
ec = ec_key_new_from_group(arg);
|
171
|
+
goto legacy;
|
229
172
|
}
|
230
173
|
|
231
|
-
|
232
|
-
|
233
|
-
|
174
|
+
type = EVP_PKEY_base_id(pkey);
|
175
|
+
if (type != EVP_PKEY_EC) {
|
176
|
+
EVP_PKEY_free(pkey);
|
177
|
+
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
234
178
|
}
|
179
|
+
RTYPEDDATA_DATA(self) = pkey;
|
180
|
+
return self;
|
235
181
|
|
182
|
+
legacy:
|
183
|
+
pkey = EVP_PKEY_new();
|
184
|
+
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
185
|
+
EVP_PKEY_free(pkey);
|
186
|
+
EC_KEY_free(ec);
|
187
|
+
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
188
|
+
}
|
189
|
+
RTYPEDDATA_DATA(self) = pkey;
|
236
190
|
return self;
|
237
191
|
}
|
238
192
|
|
193
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
239
194
|
static VALUE
|
240
195
|
ossl_ec_key_initialize_copy(VALUE self, VALUE other)
|
241
196
|
{
|
242
197
|
EVP_PKEY *pkey;
|
243
198
|
EC_KEY *ec, *ec_new;
|
244
199
|
|
245
|
-
|
246
|
-
if (
|
247
|
-
|
200
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
201
|
+
if (pkey)
|
202
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
248
203
|
GetEC(other, ec);
|
249
204
|
|
250
205
|
ec_new = EC_KEY_dup(ec);
|
251
206
|
if (!ec_new)
|
252
207
|
ossl_raise(eECError, "EC_KEY_dup");
|
253
|
-
|
254
|
-
|
255
|
-
|
208
|
+
|
209
|
+
pkey = EVP_PKEY_new();
|
210
|
+
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) {
|
211
|
+
EC_KEY_free(ec_new);
|
212
|
+
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
256
213
|
}
|
214
|
+
RTYPEDDATA_DATA(self) = pkey;
|
257
215
|
|
258
216
|
return self;
|
259
217
|
}
|
218
|
+
#endif
|
260
219
|
|
261
220
|
/*
|
262
221
|
* call-seq:
|
@@ -268,7 +227,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
|
|
268
227
|
static VALUE
|
269
228
|
ossl_ec_key_get_group(VALUE self)
|
270
229
|
{
|
271
|
-
EC_KEY *ec;
|
230
|
+
OSSL_3_const EC_KEY *ec;
|
272
231
|
const EC_GROUP *group;
|
273
232
|
|
274
233
|
GetEC(self, ec);
|
@@ -289,6 +248,9 @@ ossl_ec_key_get_group(VALUE self)
|
|
289
248
|
static VALUE
|
290
249
|
ossl_ec_key_set_group(VALUE self, VALUE group_v)
|
291
250
|
{
|
251
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
252
|
+
rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
253
|
+
#else
|
292
254
|
EC_KEY *ec;
|
293
255
|
EC_GROUP *group;
|
294
256
|
|
@@ -299,6 +261,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
|
|
299
261
|
ossl_raise(eECError, "EC_KEY_set_group");
|
300
262
|
|
301
263
|
return group_v;
|
264
|
+
#endif
|
302
265
|
}
|
303
266
|
|
304
267
|
/*
|
@@ -309,7 +272,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
|
|
309
272
|
*/
|
310
273
|
static VALUE ossl_ec_key_get_private_key(VALUE self)
|
311
274
|
{
|
312
|
-
EC_KEY *ec;
|
275
|
+
OSSL_3_const EC_KEY *ec;
|
313
276
|
const BIGNUM *bn;
|
314
277
|
|
315
278
|
GetEC(self, ec);
|
@@ -327,6 +290,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self)
|
|
327
290
|
*/
|
328
291
|
static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
|
329
292
|
{
|
293
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
294
|
+
rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
295
|
+
#else
|
330
296
|
EC_KEY *ec;
|
331
297
|
BIGNUM *bn = NULL;
|
332
298
|
|
@@ -340,11 +306,13 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
|
|
340
306
|
case 0:
|
341
307
|
if (bn == NULL)
|
342
308
|
break;
|
309
|
+
/* fallthrough */
|
343
310
|
default:
|
344
311
|
ossl_raise(eECError, "EC_KEY_set_private_key");
|
345
312
|
}
|
346
313
|
|
347
314
|
return private_key;
|
315
|
+
#endif
|
348
316
|
}
|
349
317
|
|
350
318
|
/*
|
@@ -355,7 +323,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
|
|
355
323
|
*/
|
356
324
|
static VALUE ossl_ec_key_get_public_key(VALUE self)
|
357
325
|
{
|
358
|
-
EC_KEY *ec;
|
326
|
+
OSSL_3_const EC_KEY *ec;
|
359
327
|
const EC_POINT *point;
|
360
328
|
|
361
329
|
GetEC(self, ec);
|
@@ -373,6 +341,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self)
|
|
373
341
|
*/
|
374
342
|
static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
|
375
343
|
{
|
344
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
345
|
+
rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
346
|
+
#else
|
376
347
|
EC_KEY *ec;
|
377
348
|
EC_POINT *point = NULL;
|
378
349
|
|
@@ -386,11 +357,13 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
|
|
386
357
|
case 0:
|
387
358
|
if (point == NULL)
|
388
359
|
break;
|
360
|
+
/* fallthrough */
|
389
361
|
default:
|
390
362
|
ossl_raise(eECError, "EC_KEY_set_public_key");
|
391
363
|
}
|
392
364
|
|
393
365
|
return public_key;
|
366
|
+
#endif
|
394
367
|
}
|
395
368
|
|
396
369
|
/*
|
@@ -402,7 +375,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
|
|
402
375
|
*/
|
403
376
|
static VALUE ossl_ec_key_is_public(VALUE self)
|
404
377
|
{
|
405
|
-
EC_KEY *ec;
|
378
|
+
OSSL_3_const EC_KEY *ec;
|
406
379
|
|
407
380
|
GetEC(self, ec);
|
408
381
|
|
@@ -418,73 +391,13 @@ static VALUE ossl_ec_key_is_public(VALUE self)
|
|
418
391
|
*/
|
419
392
|
static VALUE ossl_ec_key_is_private(VALUE self)
|
420
393
|
{
|
421
|
-
EC_KEY *ec;
|
394
|
+
OSSL_3_const EC_KEY *ec;
|
422
395
|
|
423
396
|
GetEC(self, ec);
|
424
397
|
|
425
398
|
return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse;
|
426
399
|
}
|
427
400
|
|
428
|
-
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
|
429
|
-
{
|
430
|
-
EC_KEY *ec;
|
431
|
-
BIO *out;
|
432
|
-
int i = -1;
|
433
|
-
int private = 0;
|
434
|
-
VALUE str;
|
435
|
-
const EVP_CIPHER *cipher = NULL;
|
436
|
-
|
437
|
-
GetEC(self, ec);
|
438
|
-
|
439
|
-
if (EC_KEY_get0_public_key(ec) == NULL)
|
440
|
-
ossl_raise(eECError, "can't export - no public key set");
|
441
|
-
|
442
|
-
if (EC_KEY_check_key(ec) != 1)
|
443
|
-
ossl_raise(eECError, "can't export - EC_KEY_check_key failed");
|
444
|
-
|
445
|
-
if (EC_KEY_get0_private_key(ec))
|
446
|
-
private = 1;
|
447
|
-
|
448
|
-
if (!NIL_P(ciph)) {
|
449
|
-
cipher = ossl_evp_get_cipherbyname(ciph);
|
450
|
-
pass = ossl_pem_passwd_value(pass);
|
451
|
-
}
|
452
|
-
|
453
|
-
if (!(out = BIO_new(BIO_s_mem())))
|
454
|
-
ossl_raise(eECError, "BIO_new(BIO_s_mem())");
|
455
|
-
|
456
|
-
switch(format) {
|
457
|
-
case EXPORT_PEM:
|
458
|
-
if (private) {
|
459
|
-
i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass);
|
460
|
-
} else {
|
461
|
-
i = PEM_write_bio_EC_PUBKEY(out, ec);
|
462
|
-
}
|
463
|
-
|
464
|
-
break;
|
465
|
-
case EXPORT_DER:
|
466
|
-
if (private) {
|
467
|
-
i = i2d_ECPrivateKey_bio(out, ec);
|
468
|
-
} else {
|
469
|
-
i = i2d_EC_PUBKEY_bio(out, ec);
|
470
|
-
}
|
471
|
-
|
472
|
-
break;
|
473
|
-
default:
|
474
|
-
BIO_free(out);
|
475
|
-
ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
|
476
|
-
}
|
477
|
-
|
478
|
-
if (i != 1) {
|
479
|
-
BIO_free(out);
|
480
|
-
ossl_raise(eECError, "outlen=%d", i);
|
481
|
-
}
|
482
|
-
|
483
|
-
str = ossl_membio2str(out);
|
484
|
-
|
485
|
-
return str;
|
486
|
-
}
|
487
|
-
|
488
401
|
/*
|
489
402
|
* call-seq:
|
490
403
|
* key.export([cipher, pass_phrase]) => String
|
@@ -495,11 +408,18 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
|
|
495
408
|
* instance. Note that encryption will only be effective for a private key,
|
496
409
|
* public keys will always be encoded in plain text.
|
497
410
|
*/
|
498
|
-
static VALUE
|
411
|
+
static VALUE
|
412
|
+
ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
|
499
413
|
{
|
500
|
-
|
501
|
-
|
502
|
-
|
414
|
+
OSSL_3_const EC_KEY *ec;
|
415
|
+
|
416
|
+
GetEC(self, ec);
|
417
|
+
if (EC_KEY_get0_public_key(ec) == NULL)
|
418
|
+
ossl_raise(eECError, "can't export - no public key set");
|
419
|
+
if (EC_KEY_get0_private_key(ec))
|
420
|
+
return ossl_pkey_export_traditional(argc, argv, self, 0);
|
421
|
+
else
|
422
|
+
return ossl_pkey_export_spki(self, 0);
|
503
423
|
}
|
504
424
|
|
505
425
|
/*
|
@@ -508,36 +428,19 @@ static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
|
|
508
428
|
*
|
509
429
|
* See the OpenSSL documentation for i2d_ECPrivateKey_bio()
|
510
430
|
*/
|
511
|
-
static VALUE
|
512
|
-
|
513
|
-
return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
|
514
|
-
}
|
515
|
-
|
516
|
-
/*
|
517
|
-
* call-seq:
|
518
|
-
* key.to_text => String
|
519
|
-
*
|
520
|
-
* See the OpenSSL documentation for EC_KEY_print()
|
521
|
-
*/
|
522
|
-
static VALUE ossl_ec_key_to_text(VALUE self)
|
431
|
+
static VALUE
|
432
|
+
ossl_ec_key_to_der(VALUE self)
|
523
433
|
{
|
524
|
-
EC_KEY *ec;
|
525
|
-
BIO *out;
|
526
|
-
VALUE str;
|
434
|
+
OSSL_3_const EC_KEY *ec;
|
527
435
|
|
528
436
|
GetEC(self, ec);
|
529
|
-
if (
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
}
|
536
|
-
str = ossl_membio2str(out);
|
537
|
-
|
538
|
-
return str;
|
437
|
+
if (EC_KEY_get0_public_key(ec) == NULL)
|
438
|
+
ossl_raise(eECError, "can't export - no public key set");
|
439
|
+
if (EC_KEY_get0_private_key(ec))
|
440
|
+
return ossl_pkey_export_traditional(0, NULL, self, 1);
|
441
|
+
else
|
442
|
+
return ossl_pkey_export_spki(self, 1);
|
539
443
|
}
|
540
|
-
|
541
444
|
/*
|
542
445
|
* call-seq:
|
543
446
|
* key.generate_key! => self
|
@@ -554,6 +457,9 @@ static VALUE ossl_ec_key_to_text(VALUE self)
|
|
554
457
|
*/
|
555
458
|
static VALUE ossl_ec_key_generate_key(VALUE self)
|
556
459
|
{
|
460
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
461
|
+
rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
462
|
+
#else
|
557
463
|
EC_KEY *ec;
|
558
464
|
|
559
465
|
GetEC(self, ec);
|
@@ -561,107 +467,53 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
|
|
561
467
|
ossl_raise(eECError, "EC_KEY_generate_key");
|
562
468
|
|
563
469
|
return self;
|
470
|
+
#endif
|
564
471
|
}
|
565
472
|
|
566
473
|
/*
|
567
|
-
*
|
568
|
-
*
|
474
|
+
* call-seq:
|
475
|
+
* key.check_key => true
|
569
476
|
*
|
570
|
-
*
|
477
|
+
* Raises an exception if the key is invalid.
|
571
478
|
*
|
572
|
-
*
|
479
|
+
* See also the man page EVP_PKEY_public_check(3).
|
573
480
|
*/
|
574
481
|
static VALUE ossl_ec_key_check_key(VALUE self)
|
575
482
|
{
|
483
|
+
#ifdef HAVE_EVP_PKEY_CHECK
|
484
|
+
EVP_PKEY *pkey;
|
485
|
+
EVP_PKEY_CTX *pctx;
|
576
486
|
EC_KEY *ec;
|
577
487
|
|
488
|
+
GetPKey(self, pkey);
|
578
489
|
GetEC(self, ec);
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
int buf_len;
|
596
|
-
VALUE str;
|
597
|
-
|
598
|
-
GetEC(self, ec);
|
599
|
-
GetECPoint(pubkey, point);
|
600
|
-
|
601
|
-
/* BUG: need a way to figure out the maximum string size */
|
602
|
-
buf_len = 1024;
|
603
|
-
str = rb_str_new(0, buf_len);
|
604
|
-
/* BUG: take KDF as a block */
|
605
|
-
buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);
|
606
|
-
if (buf_len < 0)
|
607
|
-
ossl_raise(eECError, "ECDH_compute_key");
|
608
|
-
|
609
|
-
rb_str_resize(str, buf_len);
|
610
|
-
|
611
|
-
return str;
|
612
|
-
}
|
613
|
-
|
614
|
-
/* sign_setup */
|
490
|
+
pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
|
491
|
+
if (!pctx)
|
492
|
+
ossl_raise(eECError, "EVP_PKEY_CTX_new");
|
493
|
+
|
494
|
+
if (EC_KEY_get0_private_key(ec) != NULL) {
|
495
|
+
if (EVP_PKEY_check(pctx) != 1) {
|
496
|
+
EVP_PKEY_CTX_free(pctx);
|
497
|
+
ossl_raise(eECError, "EVP_PKEY_check");
|
498
|
+
}
|
499
|
+
}
|
500
|
+
else {
|
501
|
+
if (EVP_PKEY_public_check(pctx) != 1) {
|
502
|
+
EVP_PKEY_CTX_free(pctx);
|
503
|
+
ossl_raise(eECError, "EVP_PKEY_public_check");
|
504
|
+
}
|
505
|
+
}
|
615
506
|
|
616
|
-
|
617
|
-
|
618
|
-
* key.dsa_sign_asn1(data) => String
|
619
|
-
*
|
620
|
-
* See the OpenSSL documentation for ECDSA_sign()
|
621
|
-
*/
|
622
|
-
static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
|
623
|
-
{
|
507
|
+
EVP_PKEY_CTX_free(pctx);
|
508
|
+
#else
|
624
509
|
EC_KEY *ec;
|
625
|
-
unsigned int buf_len;
|
626
|
-
VALUE str;
|
627
510
|
|
628
511
|
GetEC(self, ec);
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
ossl_raise(eECError, "Private EC key needed!");
|
633
|
-
|
634
|
-
str = rb_str_new(0, ECDSA_size(ec));
|
635
|
-
if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
|
636
|
-
ossl_raise(eECError, "ECDSA_sign");
|
637
|
-
rb_str_set_len(str, buf_len);
|
638
|
-
|
639
|
-
return str;
|
640
|
-
}
|
641
|
-
|
642
|
-
/*
|
643
|
-
* call-seq:
|
644
|
-
* key.dsa_verify_asn1(data, sig) => true or false
|
645
|
-
*
|
646
|
-
* See the OpenSSL documentation for ECDSA_verify()
|
647
|
-
*/
|
648
|
-
static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
649
|
-
{
|
650
|
-
EC_KEY *ec;
|
512
|
+
if (EC_KEY_check_key(ec) != 1)
|
513
|
+
ossl_raise(eECError, "EC_KEY_check_key");
|
514
|
+
#endif
|
651
515
|
|
652
|
-
|
653
|
-
StringValue(data);
|
654
|
-
StringValue(sig);
|
655
|
-
|
656
|
-
switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
|
657
|
-
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
|
658
|
-
case 1:
|
659
|
-
return Qtrue;
|
660
|
-
case 0:
|
661
|
-
return Qfalse;
|
662
|
-
default:
|
663
|
-
ossl_raise(eECError, "ECDSA_verify");
|
664
|
-
}
|
516
|
+
return Qtrue;
|
665
517
|
}
|
666
518
|
|
667
519
|
/*
|
@@ -670,7 +522,7 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
|
670
522
|
static void
|
671
523
|
ossl_ec_group_free(void *ptr)
|
672
524
|
{
|
673
|
-
|
525
|
+
EC_GROUP_free(ptr);
|
674
526
|
}
|
675
527
|
|
676
528
|
static const rb_data_type_t ossl_ec_group_type = {
|
@@ -706,20 +558,11 @@ ec_group_new(const EC_GROUP *group)
|
|
706
558
|
* call-seq:
|
707
559
|
* OpenSSL::PKey::EC::Group.new(ec_group)
|
708
560
|
* OpenSSL::PKey::EC::Group.new(pem_or_der_encoded)
|
709
|
-
* OpenSSL::PKey::EC::Group.new(ec_method)
|
710
561
|
* OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)
|
711
562
|
* OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)
|
712
563
|
*
|
713
564
|
* Creates a new EC::Group object.
|
714
565
|
*
|
715
|
-
* _ec_method_ is a symbol that represents an EC_METHOD. Currently the following
|
716
|
-
* are supported:
|
717
|
-
*
|
718
|
-
* * :GFp_simple
|
719
|
-
* * :GFp_mont
|
720
|
-
* * :GFp_nist
|
721
|
-
* * :GF2m_simple
|
722
|
-
*
|
723
566
|
* If the first argument is :GFp or :GF2m, creates a new curve with given
|
724
567
|
* parameters.
|
725
568
|
*/
|
@@ -734,29 +577,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
734
577
|
|
735
578
|
switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
|
736
579
|
case 1:
|
737
|
-
if (
|
738
|
-
const EC_METHOD *method = NULL;
|
739
|
-
ID id = SYM2ID(arg1);
|
740
|
-
|
741
|
-
if (id == s_GFp_simple) {
|
742
|
-
method = EC_GFp_simple_method();
|
743
|
-
} else if (id == s_GFp_mont) {
|
744
|
-
method = EC_GFp_mont_method();
|
745
|
-
} else if (id == s_GFp_nist) {
|
746
|
-
method = EC_GFp_nist_method();
|
747
|
-
#if !defined(OPENSSL_NO_EC2M)
|
748
|
-
} else if (id == s_GF2m_simple) {
|
749
|
-
method = EC_GF2m_simple_method();
|
750
|
-
#endif
|
751
|
-
}
|
752
|
-
|
753
|
-
if (method) {
|
754
|
-
if ((group = EC_GROUP_new(method)) == NULL)
|
755
|
-
ossl_raise(eEC_GROUP, "EC_GROUP_new");
|
756
|
-
} else {
|
757
|
-
ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
|
758
|
-
}
|
759
|
-
} else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
|
580
|
+
if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
|
760
581
|
const EC_GROUP *arg1_group;
|
761
582
|
|
762
583
|
GetECGroup(arg1, arg1_group);
|
@@ -820,8 +641,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
820
641
|
ossl_raise(rb_eArgError, "wrong number of arguments");
|
821
642
|
}
|
822
643
|
|
823
|
-
|
824
|
-
ossl_raise(eEC_GROUP, "");
|
644
|
+
ASSUME(group);
|
825
645
|
RTYPEDDATA_DATA(self) = group;
|
826
646
|
|
827
647
|
return self;
|
@@ -860,10 +680,11 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
|
|
860
680
|
GetECGroup(a, group1);
|
861
681
|
GetECGroup(b, group2);
|
862
682
|
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
683
|
+
switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) {
|
684
|
+
case 0: return Qtrue;
|
685
|
+
case 1: return Qfalse;
|
686
|
+
default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp");
|
687
|
+
}
|
867
688
|
}
|
868
689
|
|
869
690
|
/*
|
@@ -1424,10 +1245,13 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
|
|
1424
1245
|
GetECPoint(b, point2);
|
1425
1246
|
GetECGroup(group_v1, group);
|
1426
1247
|
|
1427
|
-
|
1428
|
-
|
1248
|
+
switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) {
|
1249
|
+
case 0: return Qtrue;
|
1250
|
+
case 1: return Qfalse;
|
1251
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_cmp");
|
1252
|
+
}
|
1429
1253
|
|
1430
|
-
|
1254
|
+
UNREACHABLE;
|
1431
1255
|
}
|
1432
1256
|
|
1433
1257
|
/*
|
@@ -1445,7 +1269,7 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self)
|
|
1445
1269
|
switch (EC_POINT_is_at_infinity(group, point)) {
|
1446
1270
|
case 1: return Qtrue;
|
1447
1271
|
case 0: return Qfalse;
|
1448
|
-
default: ossl_raise(
|
1272
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity");
|
1449
1273
|
}
|
1450
1274
|
|
1451
1275
|
UNREACHABLE;
|
@@ -1466,7 +1290,7 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
|
|
1466
1290
|
switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
|
1467
1291
|
case 1: return Qtrue;
|
1468
1292
|
case 0: return Qfalse;
|
1469
|
-
default: ossl_raise(
|
1293
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve");
|
1470
1294
|
}
|
1471
1295
|
|
1472
1296
|
UNREACHABLE;
|
@@ -1475,6 +1299,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
|
|
1475
1299
|
/*
|
1476
1300
|
* call-seq:
|
1477
1301
|
* point.make_affine! => self
|
1302
|
+
*
|
1303
|
+
* This method is deprecated and should not be used. This is a no-op.
|
1478
1304
|
*/
|
1479
1305
|
static VALUE ossl_ec_point_make_affine(VALUE self)
|
1480
1306
|
{
|
@@ -1484,8 +1310,11 @@ static VALUE ossl_ec_point_make_affine(VALUE self)
|
|
1484
1310
|
GetECPoint(self, point);
|
1485
1311
|
GetECPointGroup(self, group);
|
1486
1312
|
|
1313
|
+
rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated");
|
1314
|
+
#if !OSSL_OPENSSL_PREREQ(3, 0, 0)
|
1487
1315
|
if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
|
1488
|
-
ossl_raise(
|
1316
|
+
ossl_raise(eEC_POINT, "EC_POINT_make_affine");
|
1317
|
+
#endif
|
1489
1318
|
|
1490
1319
|
return self;
|
1491
1320
|
}
|
@@ -1503,7 +1332,7 @@ static VALUE ossl_ec_point_invert(VALUE self)
|
|
1503
1332
|
GetECPointGroup(self, group);
|
1504
1333
|
|
1505
1334
|
if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
|
1506
|
-
ossl_raise(
|
1335
|
+
ossl_raise(eEC_POINT, "EC_POINT_invert");
|
1507
1336
|
|
1508
1337
|
return self;
|
1509
1338
|
}
|
@@ -1521,7 +1350,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
|
|
1521
1350
|
GetECPointGroup(self, group);
|
1522
1351
|
|
1523
1352
|
if (EC_POINT_set_to_infinity(group, point) != 1)
|
1524
|
-
ossl_raise(
|
1353
|
+
ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity");
|
1525
1354
|
|
1526
1355
|
return self;
|
1527
1356
|
}
|
@@ -1562,6 +1391,34 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form)
|
|
1562
1391
|
return str;
|
1563
1392
|
}
|
1564
1393
|
|
1394
|
+
/*
|
1395
|
+
* call-seq:
|
1396
|
+
* point.add(point) => point
|
1397
|
+
*
|
1398
|
+
* Performs elliptic curve point addition.
|
1399
|
+
*/
|
1400
|
+
static VALUE ossl_ec_point_add(VALUE self, VALUE other)
|
1401
|
+
{
|
1402
|
+
EC_POINT *point_self, *point_other, *point_result;
|
1403
|
+
const EC_GROUP *group;
|
1404
|
+
VALUE group_v = rb_attr_get(self, id_i_group);
|
1405
|
+
VALUE result;
|
1406
|
+
|
1407
|
+
GetECPoint(self, point_self);
|
1408
|
+
GetECPoint(other, point_other);
|
1409
|
+
GetECGroup(group_v, group);
|
1410
|
+
|
1411
|
+
result = rb_obj_alloc(cEC_POINT);
|
1412
|
+
ossl_ec_point_initialize(1, &group_v, result);
|
1413
|
+
GetECPoint(result, point_result);
|
1414
|
+
|
1415
|
+
if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) {
|
1416
|
+
ossl_raise(eEC_POINT, "EC_POINT_add");
|
1417
|
+
}
|
1418
|
+
|
1419
|
+
return result;
|
1420
|
+
}
|
1421
|
+
|
1565
1422
|
/*
|
1566
1423
|
* call-seq:
|
1567
1424
|
* point.mul(bn1 [, bn2]) => point
|
@@ -1603,6 +1460,10 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1603
1460
|
if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
|
1604
1461
|
ossl_raise(eEC_POINT, NULL);
|
1605
1462
|
} else {
|
1463
|
+
#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER)
|
1464
|
+
rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \
|
1465
|
+
"supported by this OpenSSL version");
|
1466
|
+
#else
|
1606
1467
|
/*
|
1607
1468
|
* bignums | arg1[0] | arg1[1] | arg1[2] | ...
|
1608
1469
|
* points | self | arg2[0] | arg2[1] | ...
|
@@ -1617,6 +1478,9 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1617
1478
|
if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
|
1618
1479
|
ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");
|
1619
1480
|
|
1481
|
+
rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \
|
1482
|
+
"use #mul(bn) form instead");
|
1483
|
+
|
1620
1484
|
num = RARRAY_LEN(arg1);
|
1621
1485
|
bns_tmp = rb_ary_tmp_new(num);
|
1622
1486
|
bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
|
@@ -1642,6 +1506,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1642
1506
|
|
1643
1507
|
ALLOCV_END(tmp_b);
|
1644
1508
|
ALLOCV_END(tmp_p);
|
1509
|
+
#endif
|
1645
1510
|
}
|
1646
1511
|
|
1647
1512
|
return result;
|
@@ -1682,10 +1547,6 @@ void Init_ossl_ec(void)
|
|
1682
1547
|
|
1683
1548
|
s_GFp = rb_intern("GFp");
|
1684
1549
|
s_GF2m = rb_intern("GF2m");
|
1685
|
-
s_GFp_simple = rb_intern("GFp_simple");
|
1686
|
-
s_GFp_mont = rb_intern("GFp_mont");
|
1687
|
-
s_GFp_nist = rb_intern("GFp_nist");
|
1688
|
-
s_GF2m_simple = rb_intern("GF2m_simple");
|
1689
1550
|
|
1690
1551
|
ID_uncompressed = rb_intern("uncompressed");
|
1691
1552
|
ID_compressed = rb_intern("compressed");
|
@@ -1700,8 +1561,9 @@ void Init_ossl_ec(void)
|
|
1700
1561
|
|
1701
1562
|
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
|
1702
1563
|
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
|
1564
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
1703
1565
|
rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
|
1704
|
-
|
1566
|
+
#endif
|
1705
1567
|
|
1706
1568
|
rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
|
1707
1569
|
rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
|
@@ -1724,15 +1586,9 @@ void Init_ossl_ec(void)
|
|
1724
1586
|
rb_define_alias(cEC, "generate_key", "generate_key!");
|
1725
1587
|
rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
|
1726
1588
|
|
1727
|
-
rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
|
1728
|
-
rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
|
1729
|
-
rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
|
1730
|
-
/* do_sign/do_verify */
|
1731
|
-
|
1732
1589
|
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
|
1733
1590
|
rb_define_alias(cEC, "to_pem", "export");
|
1734
1591
|
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
|
1735
|
-
rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
|
1736
1592
|
|
1737
1593
|
|
1738
1594
|
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
|
@@ -1786,6 +1642,7 @@ void Init_ossl_ec(void)
|
|
1786
1642
|
/* all the other methods */
|
1787
1643
|
|
1788
1644
|
rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1);
|
1645
|
+
rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1);
|
1789
1646
|
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
|
1790
1647
|
|
1791
1648
|
id_i_group = rb_intern("@group");
|