openssl 2.2.1 → 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 +33 -45
- data/History.md +248 -1
- data/README.md +36 -19
- data/ext/openssl/extconf.rb +101 -68
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +128 -237
- data/ext/openssl/ossl.h +31 -12
- data/ext/openssl/ossl_asn1.c +26 -13
- data/ext/openssl/ossl_bn.c +213 -139
- data/ext/openssl/ossl_cipher.c +13 -14
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +10 -10
- data/ext/openssl/ossl_engine.c +17 -16
- data/ext/openssl/ossl_hmac.c +57 -136
- data/ext/openssl/ossl_kdf.c +12 -4
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -59
- data/ext/openssl/ossl_pkcs12.c +22 -4
- data/ext/openssl/ossl_pkcs7.c +45 -62
- data/ext/openssl/ossl_pkey.c +1320 -196
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +152 -347
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +227 -343
- data/ext/openssl/ossl_pkey_rsa.c +159 -491
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_ssl.c +530 -450
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +38 -23
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +168 -12
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +14 -9
- data/ext/openssl/ossl_x509name.c +10 -3
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +166 -75
- data/lib/openssl/buffering.rb +9 -3
- data/lib/openssl/digest.rb +1 -5
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +429 -0
- data/lib/openssl/ssl.rb +22 -17
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +10 -79
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -501
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;
|
206
|
-
|
207
|
-
pass = ossl_pem_passwd_value(pass);
|
208
|
-
in = ossl_obj2bio(&arg);
|
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
|
+
}
|
209
161
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
214
|
-
}
|
215
|
-
if (!ec) {
|
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);
|
162
|
+
pass = ossl_pem_passwd_value(pass);
|
163
|
+
arg = ossl_to_der_if_possible(arg);
|
164
|
+
in = ossl_obj2bio(&arg);
|
224
165
|
|
225
|
-
|
226
|
-
|
227
|
-
|
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,126 +391,112 @@ 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
|
-
|
401
|
+
/*
|
402
|
+
* call-seq:
|
403
|
+
* key.export([cipher, password]) => String
|
404
|
+
* key.to_pem([cipher, password]) => String
|
405
|
+
*
|
406
|
+
* Serializes a private or public key to a PEM-encoding.
|
407
|
+
*
|
408
|
+
* [When the key contains public components only]
|
409
|
+
*
|
410
|
+
* Serializes it into an X.509 SubjectPublicKeyInfo.
|
411
|
+
* The parameters _cipher_ and _password_ are ignored.
|
412
|
+
*
|
413
|
+
* A PEM-encoded key will look like:
|
414
|
+
*
|
415
|
+
* -----BEGIN PUBLIC KEY-----
|
416
|
+
* [...]
|
417
|
+
* -----END PUBLIC KEY-----
|
418
|
+
*
|
419
|
+
* Consider using #public_to_pem instead. This serializes the key into an
|
420
|
+
* X.509 SubjectPublicKeyInfo regardless of whether it is a public key
|
421
|
+
* or a private key.
|
422
|
+
*
|
423
|
+
* [When the key contains private components, and no parameters are given]
|
424
|
+
*
|
425
|
+
* Serializes it into a SEC 1/RFC 5915 ECPrivateKey.
|
426
|
+
*
|
427
|
+
* A PEM-encoded key will look like:
|
428
|
+
*
|
429
|
+
* -----BEGIN EC PRIVATE KEY-----
|
430
|
+
* [...]
|
431
|
+
* -----END EC PRIVATE KEY-----
|
432
|
+
*
|
433
|
+
* [When the key contains private components, and _cipher_ and _password_ are given]
|
434
|
+
*
|
435
|
+
* Serializes it into a SEC 1/RFC 5915 ECPrivateKey
|
436
|
+
* and encrypts it in OpenSSL's traditional PEM encryption format.
|
437
|
+
* _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
|
438
|
+
* instance of OpenSSL::Cipher.
|
439
|
+
*
|
440
|
+
* An encrypted PEM-encoded key will look like:
|
441
|
+
*
|
442
|
+
* -----BEGIN EC PRIVATE KEY-----
|
443
|
+
* Proc-Type: 4,ENCRYPTED
|
444
|
+
* DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
|
445
|
+
*
|
446
|
+
* [...]
|
447
|
+
* -----END EC PRIVATE KEY-----
|
448
|
+
*
|
449
|
+
* Note that this format uses MD5 to derive the encryption key, and hence
|
450
|
+
* will not be available on FIPS-compliant systems.
|
451
|
+
*
|
452
|
+
* <b>This method is kept for compatibility.</b>
|
453
|
+
* This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
|
454
|
+
* required.
|
455
|
+
*
|
456
|
+
* Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
|
457
|
+
* (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
|
458
|
+
*/
|
459
|
+
static VALUE
|
460
|
+
ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
|
429
461
|
{
|
430
|
-
EC_KEY *ec;
|
431
|
-
BIO *out;
|
432
|
-
int i = -1;
|
433
|
-
int private = 0;
|
434
|
-
VALUE str;
|
435
|
-
const EVP_CIPHER *cipher = NULL;
|
462
|
+
OSSL_3_const EC_KEY *ec;
|
436
463
|
|
437
464
|
GetEC(self, ec);
|
438
|
-
|
439
465
|
if (EC_KEY_get0_public_key(ec) == NULL)
|
440
466
|
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
467
|
if (EC_KEY_get0_private_key(ec))
|
446
|
-
|
447
|
-
|
448
|
-
|
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
|
-
/*
|
489
|
-
* call-seq:
|
490
|
-
* key.export([cipher, pass_phrase]) => String
|
491
|
-
* key.to_pem([cipher, pass_phrase]) => String
|
492
|
-
*
|
493
|
-
* Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given
|
494
|
-
* they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher
|
495
|
-
* instance. Note that encryption will only be effective for a private key,
|
496
|
-
* public keys will always be encoded in plain text.
|
497
|
-
*/
|
498
|
-
static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
|
499
|
-
{
|
500
|
-
VALUE cipher, passwd;
|
501
|
-
rb_scan_args(argc, argv, "02", &cipher, &passwd);
|
502
|
-
return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
|
468
|
+
return ossl_pkey_export_traditional(argc, argv, self, 0);
|
469
|
+
else
|
470
|
+
return ossl_pkey_export_spki(self, 0);
|
503
471
|
}
|
504
472
|
|
505
473
|
/*
|
506
474
|
* call-seq:
|
507
475
|
* key.to_der => String
|
508
476
|
*
|
509
|
-
*
|
510
|
-
|
511
|
-
|
512
|
-
{
|
513
|
-
return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
|
514
|
-
}
|
515
|
-
|
516
|
-
/*
|
517
|
-
* call-seq:
|
518
|
-
* key.to_text => String
|
477
|
+
* Serializes a private or public key to a DER-encoding.
|
478
|
+
*
|
479
|
+
* See #to_pem for details.
|
519
480
|
*
|
520
|
-
*
|
481
|
+
* <b>This method is kept for compatibility.</b>
|
482
|
+
* This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
|
483
|
+
* required.
|
484
|
+
*
|
485
|
+
* Consider using #public_to_der or #private_to_der instead.
|
521
486
|
*/
|
522
|
-
static VALUE
|
487
|
+
static VALUE
|
488
|
+
ossl_ec_key_to_der(VALUE self)
|
523
489
|
{
|
524
|
-
EC_KEY *ec;
|
525
|
-
BIO *out;
|
526
|
-
VALUE str;
|
490
|
+
OSSL_3_const EC_KEY *ec;
|
527
491
|
|
528
492
|
GetEC(self, ec);
|
529
|
-
if (
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
}
|
536
|
-
str = ossl_membio2str(out);
|
537
|
-
|
538
|
-
return str;
|
493
|
+
if (EC_KEY_get0_public_key(ec) == NULL)
|
494
|
+
ossl_raise(eECError, "can't export - no public key set");
|
495
|
+
if (EC_KEY_get0_private_key(ec))
|
496
|
+
return ossl_pkey_export_traditional(0, NULL, self, 1);
|
497
|
+
else
|
498
|
+
return ossl_pkey_export_spki(self, 1);
|
539
499
|
}
|
540
|
-
|
541
500
|
/*
|
542
501
|
* call-seq:
|
543
502
|
* key.generate_key! => self
|
@@ -554,6 +513,9 @@ static VALUE ossl_ec_key_to_text(VALUE self)
|
|
554
513
|
*/
|
555
514
|
static VALUE ossl_ec_key_generate_key(VALUE self)
|
556
515
|
{
|
516
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
517
|
+
rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
518
|
+
#else
|
557
519
|
EC_KEY *ec;
|
558
520
|
|
559
521
|
GetEC(self, ec);
|
@@ -561,107 +523,53 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
|
|
561
523
|
ossl_raise(eECError, "EC_KEY_generate_key");
|
562
524
|
|
563
525
|
return self;
|
526
|
+
#endif
|
564
527
|
}
|
565
528
|
|
566
529
|
/*
|
567
|
-
*
|
568
|
-
*
|
530
|
+
* call-seq:
|
531
|
+
* key.check_key => true
|
569
532
|
*
|
570
|
-
*
|
533
|
+
* Raises an exception if the key is invalid.
|
571
534
|
*
|
572
|
-
*
|
535
|
+
* See also the man page EVP_PKEY_public_check(3).
|
573
536
|
*/
|
574
537
|
static VALUE ossl_ec_key_check_key(VALUE self)
|
575
538
|
{
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
ossl_raise(eECError, "EC_KEY_check_key");
|
581
|
-
|
582
|
-
return Qtrue;
|
583
|
-
}
|
584
|
-
|
585
|
-
/*
|
586
|
-
* call-seq:
|
587
|
-
* key.dh_compute_key(pubkey) => String
|
588
|
-
*
|
589
|
-
* See the OpenSSL documentation for ECDH_compute_key()
|
590
|
-
*/
|
591
|
-
static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
|
592
|
-
{
|
593
|
-
EC_KEY *ec;
|
594
|
-
EC_POINT *point;
|
595
|
-
int buf_len;
|
596
|
-
VALUE str;
|
539
|
+
#ifdef HAVE_EVP_PKEY_CHECK
|
540
|
+
EVP_PKEY *pkey;
|
541
|
+
EVP_PKEY_CTX *pctx;
|
542
|
+
const EC_KEY *ec;
|
597
543
|
|
544
|
+
GetPKey(self, pkey);
|
598
545
|
GetEC(self, ec);
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
546
|
+
pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
|
547
|
+
if (!pctx)
|
548
|
+
ossl_raise(eECError, "EVP_PKEY_CTX_new");
|
549
|
+
|
550
|
+
if (EC_KEY_get0_private_key(ec) != NULL) {
|
551
|
+
if (EVP_PKEY_check(pctx) != 1) {
|
552
|
+
EVP_PKEY_CTX_free(pctx);
|
553
|
+
ossl_raise(eECError, "EVP_PKEY_check");
|
554
|
+
}
|
555
|
+
}
|
556
|
+
else {
|
557
|
+
if (EVP_PKEY_public_check(pctx) != 1) {
|
558
|
+
EVP_PKEY_CTX_free(pctx);
|
559
|
+
ossl_raise(eECError, "EVP_PKEY_public_check");
|
560
|
+
}
|
561
|
+
}
|
615
562
|
|
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
|
-
{
|
563
|
+
EVP_PKEY_CTX_free(pctx);
|
564
|
+
#else
|
624
565
|
EC_KEY *ec;
|
625
|
-
unsigned int buf_len;
|
626
|
-
VALUE str;
|
627
566
|
|
628
567
|
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;
|
568
|
+
if (EC_KEY_check_key(ec) != 1)
|
569
|
+
ossl_raise(eECError, "EC_KEY_check_key");
|
570
|
+
#endif
|
651
571
|
|
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
|
-
}
|
572
|
+
return Qtrue;
|
665
573
|
}
|
666
574
|
|
667
575
|
/*
|
@@ -670,7 +578,7 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
|
670
578
|
static void
|
671
579
|
ossl_ec_group_free(void *ptr)
|
672
580
|
{
|
673
|
-
|
581
|
+
EC_GROUP_free(ptr);
|
674
582
|
}
|
675
583
|
|
676
584
|
static const rb_data_type_t ossl_ec_group_type = {
|
@@ -678,7 +586,7 @@ static const rb_data_type_t ossl_ec_group_type = {
|
|
678
586
|
{
|
679
587
|
0, ossl_ec_group_free,
|
680
588
|
},
|
681
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
589
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
682
590
|
};
|
683
591
|
|
684
592
|
static VALUE
|
@@ -706,20 +614,11 @@ ec_group_new(const EC_GROUP *group)
|
|
706
614
|
* call-seq:
|
707
615
|
* OpenSSL::PKey::EC::Group.new(ec_group)
|
708
616
|
* OpenSSL::PKey::EC::Group.new(pem_or_der_encoded)
|
709
|
-
* OpenSSL::PKey::EC::Group.new(ec_method)
|
710
617
|
* OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)
|
711
618
|
* OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)
|
712
619
|
*
|
713
620
|
* Creates a new EC::Group object.
|
714
621
|
*
|
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
622
|
* If the first argument is :GFp or :GF2m, creates a new curve with given
|
724
623
|
* parameters.
|
725
624
|
*/
|
@@ -734,29 +633,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
734
633
|
|
735
634
|
switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
|
736
635
|
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)) {
|
636
|
+
if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
|
760
637
|
const EC_GROUP *arg1_group;
|
761
638
|
|
762
639
|
GetECGroup(arg1, arg1_group);
|
@@ -820,8 +697,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
820
697
|
ossl_raise(rb_eArgError, "wrong number of arguments");
|
821
698
|
}
|
822
699
|
|
823
|
-
|
824
|
-
ossl_raise(eEC_GROUP, "");
|
700
|
+
ASSUME(group);
|
825
701
|
RTYPEDDATA_DATA(self) = group;
|
826
702
|
|
827
703
|
return self;
|
@@ -860,10 +736,11 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
|
|
860
736
|
GetECGroup(a, group1);
|
861
737
|
GetECGroup(b, group2);
|
862
738
|
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
739
|
+
switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) {
|
740
|
+
case 0: return Qtrue;
|
741
|
+
case 1: return Qfalse;
|
742
|
+
default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp");
|
743
|
+
}
|
867
744
|
}
|
868
745
|
|
869
746
|
/*
|
@@ -1294,7 +1171,7 @@ static const rb_data_type_t ossl_ec_point_type = {
|
|
1294
1171
|
{
|
1295
1172
|
0, ossl_ec_point_free,
|
1296
1173
|
},
|
1297
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1174
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1298
1175
|
};
|
1299
1176
|
|
1300
1177
|
static VALUE
|
@@ -1424,10 +1301,13 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
|
|
1424
1301
|
GetECPoint(b, point2);
|
1425
1302
|
GetECGroup(group_v1, group);
|
1426
1303
|
|
1427
|
-
|
1428
|
-
|
1304
|
+
switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) {
|
1305
|
+
case 0: return Qtrue;
|
1306
|
+
case 1: return Qfalse;
|
1307
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_cmp");
|
1308
|
+
}
|
1429
1309
|
|
1430
|
-
|
1310
|
+
UNREACHABLE;
|
1431
1311
|
}
|
1432
1312
|
|
1433
1313
|
/*
|
@@ -1445,7 +1325,7 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self)
|
|
1445
1325
|
switch (EC_POINT_is_at_infinity(group, point)) {
|
1446
1326
|
case 1: return Qtrue;
|
1447
1327
|
case 0: return Qfalse;
|
1448
|
-
default: ossl_raise(
|
1328
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity");
|
1449
1329
|
}
|
1450
1330
|
|
1451
1331
|
UNREACHABLE;
|
@@ -1466,7 +1346,7 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
|
|
1466
1346
|
switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
|
1467
1347
|
case 1: return Qtrue;
|
1468
1348
|
case 0: return Qfalse;
|
1469
|
-
default: ossl_raise(
|
1349
|
+
default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve");
|
1470
1350
|
}
|
1471
1351
|
|
1472
1352
|
UNREACHABLE;
|
@@ -1475,6 +1355,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
|
|
1475
1355
|
/*
|
1476
1356
|
* call-seq:
|
1477
1357
|
* point.make_affine! => self
|
1358
|
+
*
|
1359
|
+
* This method is deprecated and should not be used. This is a no-op.
|
1478
1360
|
*/
|
1479
1361
|
static VALUE ossl_ec_point_make_affine(VALUE self)
|
1480
1362
|
{
|
@@ -1484,8 +1366,11 @@ static VALUE ossl_ec_point_make_affine(VALUE self)
|
|
1484
1366
|
GetECPoint(self, point);
|
1485
1367
|
GetECPointGroup(self, group);
|
1486
1368
|
|
1369
|
+
rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated");
|
1370
|
+
#if !OSSL_OPENSSL_PREREQ(3, 0, 0)
|
1487
1371
|
if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
|
1488
|
-
ossl_raise(
|
1372
|
+
ossl_raise(eEC_POINT, "EC_POINT_make_affine");
|
1373
|
+
#endif
|
1489
1374
|
|
1490
1375
|
return self;
|
1491
1376
|
}
|
@@ -1503,7 +1388,7 @@ static VALUE ossl_ec_point_invert(VALUE self)
|
|
1503
1388
|
GetECPointGroup(self, group);
|
1504
1389
|
|
1505
1390
|
if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
|
1506
|
-
ossl_raise(
|
1391
|
+
ossl_raise(eEC_POINT, "EC_POINT_invert");
|
1507
1392
|
|
1508
1393
|
return self;
|
1509
1394
|
}
|
@@ -1521,7 +1406,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
|
|
1521
1406
|
GetECPointGroup(self, group);
|
1522
1407
|
|
1523
1408
|
if (EC_POINT_set_to_infinity(group, point) != 1)
|
1524
|
-
ossl_raise(
|
1409
|
+
ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity");
|
1525
1410
|
|
1526
1411
|
return self;
|
1527
1412
|
}
|
@@ -1631,6 +1516,10 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1631
1516
|
if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
|
1632
1517
|
ossl_raise(eEC_POINT, NULL);
|
1633
1518
|
} else {
|
1519
|
+
#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER)
|
1520
|
+
rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \
|
1521
|
+
"supported by this OpenSSL version");
|
1522
|
+
#else
|
1634
1523
|
/*
|
1635
1524
|
* bignums | arg1[0] | arg1[1] | arg1[2] | ...
|
1636
1525
|
* points | self | arg2[0] | arg2[1] | ...
|
@@ -1645,6 +1534,9 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1645
1534
|
if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
|
1646
1535
|
ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");
|
1647
1536
|
|
1537
|
+
rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \
|
1538
|
+
"use #mul(bn) form instead");
|
1539
|
+
|
1648
1540
|
num = RARRAY_LEN(arg1);
|
1649
1541
|
bns_tmp = rb_ary_tmp_new(num);
|
1650
1542
|
bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
|
@@ -1670,6 +1562,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1670
1562
|
|
1671
1563
|
ALLOCV_END(tmp_b);
|
1672
1564
|
ALLOCV_END(tmp_p);
|
1565
|
+
#endif
|
1673
1566
|
}
|
1674
1567
|
|
1675
1568
|
return result;
|
@@ -1710,10 +1603,6 @@ void Init_ossl_ec(void)
|
|
1710
1603
|
|
1711
1604
|
s_GFp = rb_intern("GFp");
|
1712
1605
|
s_GF2m = rb_intern("GF2m");
|
1713
|
-
s_GFp_simple = rb_intern("GFp_simple");
|
1714
|
-
s_GFp_mont = rb_intern("GFp_mont");
|
1715
|
-
s_GFp_nist = rb_intern("GFp_nist");
|
1716
|
-
s_GF2m_simple = rb_intern("GF2m_simple");
|
1717
1606
|
|
1718
1607
|
ID_uncompressed = rb_intern("uncompressed");
|
1719
1608
|
ID_compressed = rb_intern("compressed");
|
@@ -1728,8 +1617,9 @@ void Init_ossl_ec(void)
|
|
1728
1617
|
|
1729
1618
|
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
|
1730
1619
|
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
|
1620
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
1731
1621
|
rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
|
1732
|
-
|
1622
|
+
#endif
|
1733
1623
|
|
1734
1624
|
rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
|
1735
1625
|
rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
|
@@ -1752,15 +1642,9 @@ void Init_ossl_ec(void)
|
|
1752
1642
|
rb_define_alias(cEC, "generate_key", "generate_key!");
|
1753
1643
|
rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
|
1754
1644
|
|
1755
|
-
rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
|
1756
|
-
rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
|
1757
|
-
rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
|
1758
|
-
/* do_sign/do_verify */
|
1759
|
-
|
1760
1645
|
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
|
1761
1646
|
rb_define_alias(cEC, "to_pem", "export");
|
1762
1647
|
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
|
1763
|
-
rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
|
1764
1648
|
|
1765
1649
|
|
1766
1650
|
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
|