openssl 2.2.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +260 -0
  4. data/ext/openssl/extconf.rb +85 -72
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +67 -47
  8. data/ext/openssl/ossl.h +26 -6
  9. data/ext/openssl/ossl_asn1.c +26 -13
  10. data/ext/openssl/ossl_bn.c +278 -142
  11. data/ext/openssl/ossl_bn.h +2 -1
  12. data/ext/openssl/ossl_cipher.c +12 -13
  13. data/ext/openssl/ossl_config.c +412 -41
  14. data/ext/openssl/ossl_config.h +4 -7
  15. data/ext/openssl/ossl_digest.c +15 -11
  16. data/ext/openssl/ossl_engine.c +16 -15
  17. data/ext/openssl/ossl_hmac.c +56 -135
  18. data/ext/openssl/ossl_kdf.c +11 -3
  19. data/ext/openssl/ossl_ocsp.c +5 -53
  20. data/ext/openssl/ossl_pkcs12.c +21 -3
  21. data/ext/openssl/ossl_pkcs7.c +42 -59
  22. data/ext/openssl/ossl_pkey.c +1142 -191
  23. data/ext/openssl/ossl_pkey.h +36 -73
  24. data/ext/openssl/ossl_pkey_dh.c +130 -340
  25. data/ext/openssl/ossl_pkey_dsa.c +100 -405
  26. data/ext/openssl/ossl_pkey_ec.c +163 -335
  27. data/ext/openssl/ossl_pkey_rsa.c +106 -493
  28. data/ext/openssl/ossl_ssl.c +529 -421
  29. data/ext/openssl/ossl_ssl_session.c +28 -29
  30. data/ext/openssl/ossl_ts.c +64 -39
  31. data/ext/openssl/ossl_x509.c +0 -6
  32. data/ext/openssl/ossl_x509cert.c +167 -11
  33. data/ext/openssl/ossl_x509crl.c +13 -10
  34. data/ext/openssl/ossl_x509ext.c +1 -2
  35. data/ext/openssl/ossl_x509name.c +9 -2
  36. data/ext/openssl/ossl_x509req.c +13 -10
  37. data/ext/openssl/ossl_x509revoked.c +3 -3
  38. data/ext/openssl/ossl_x509store.c +193 -90
  39. data/lib/openssl/buffering.rb +10 -1
  40. data/lib/openssl/hmac.rb +65 -0
  41. data/lib/openssl/pkey.rb +429 -0
  42. data/lib/openssl/ssl.rb +13 -8
  43. data/lib/openssl/version.rb +1 -1
  44. data/lib/openssl/x509.rb +22 -0
  45. data/lib/openssl.rb +0 -1
  46. metadata +8 -66
  47. data/ext/openssl/ruby_missing.h +0 -24
  48. data/lib/openssl/config.rb +0 -501
@@ -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
- ec = ec_key_new_from_group(arg);
111
+ obj = rb_obj_alloc(klass);
157
112
 
158
- obj = ec_instance(klass, ec);
159
- if (obj == Qfalse) {
160
- EC_KEY_free(ec);
161
- ossl_raise(eECError, NULL);
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
- GetPKey(self, pkey);
188
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
189
- ossl_raise(eECError, "EC_KEY already initialized");
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
- ossl_raise(eECError, NULL);
196
- } else if (rb_obj_is_kind_of(arg, cEC)) {
197
- EC_KEY *other_ec = NULL;
198
-
199
- GetEC(arg, other_ec);
200
- if (!(ec = EC_KEY_dup(other_ec)))
201
- ossl_raise(eECError, NULL);
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
- ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
211
- if (!ec) {
212
- OSSL_BIO_reset(in);
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
- 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
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
232
- EC_KEY_free(ec);
233
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
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
- GetPKey(self, pkey);
246
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
247
- ossl_raise(eECError, "EC already initialized");
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
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
254
- EC_KEY_free(ec_new);
255
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
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 ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
411
+ static VALUE
412
+ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
499
413
  {
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);
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 ossl_ec_key_to_der(VALUE self)
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 (!(out = BIO_new(BIO_s_mem()))) {
530
- ossl_raise(eECError, "BIO_new(BIO_s_mem())");
531
- }
532
- if (!EC_KEY_print(out, ec, 0)) {
533
- BIO_free(out);
534
- ossl_raise(eECError, "EC_KEY_print");
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
- * call-seq:
568
- * key.check_key => true
474
+ * call-seq:
475
+ * key.check_key => true
569
476
  *
570
- * Raises an exception if the key is invalid.
477
+ * Raises an exception if the key is invalid.
571
478
  *
572
- * See the OpenSSL documentation for EC_KEY_check_key()
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
- if (EC_KEY_check_key(ec) != 1)
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;
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 */
615
-
616
- /*
617
- * call-seq:
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
- {
624
- EC_KEY *ec;
625
- unsigned int buf_len;
626
- VALUE str;
627
-
628
- GetEC(self, ec);
629
- StringValue(data);
630
-
631
- if (EC_KEY_get0_private_key(ec) == NULL)
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
- }
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
+ }
641
506
 
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
- {
507
+ EVP_PKEY_CTX_free(pctx);
508
+ #else
650
509
  EC_KEY *ec;
651
510
 
652
511
  GetEC(self, ec);
653
- StringValue(data);
654
- StringValue(sig);
655
-
656
- switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
657
- case 1: return Qtrue;
658
- case 0: return Qfalse;
659
- default: break;
660
- }
661
-
662
- ossl_raise(eECError, "ECDSA_verify");
512
+ if (EC_KEY_check_key(ec) != 1)
513
+ ossl_raise(eECError, "EC_KEY_check_key");
514
+ #endif
663
515
 
664
- UNREACHABLE;
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
- EC_GROUP_clear_free(ptr);
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 (SYMBOL_P(arg1)) {
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
- if (group == NULL)
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
- if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
864
- return Qfalse;
865
-
866
- return Qtrue;
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
- if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
1428
- return Qfalse;
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
- return Qtrue;
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(cEC_POINT, "EC_POINT_is_at_infinity");
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(cEC_POINT, "EC_POINT_is_on_curve");
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(cEC_POINT, "EC_POINT_make_affine");
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(cEC_POINT, "EC_POINT_invert");
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(cEC_POINT, "EC_POINT_set_to_infinity");
1353
+ ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity");
1525
1354
 
1526
1355
  return self;
1527
1356
  }
@@ -1631,6 +1460,10 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1631
1460
  if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
1632
1461
  ossl_raise(eEC_POINT, NULL);
1633
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
1634
1467
  /*
1635
1468
  * bignums | arg1[0] | arg1[1] | arg1[2] | ...
1636
1469
  * points | self | arg2[0] | arg2[1] | ...
@@ -1645,6 +1478,9 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1645
1478
  if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
1646
1479
  ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");
1647
1480
 
1481
+ rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \
1482
+ "use #mul(bn) form instead");
1483
+
1648
1484
  num = RARRAY_LEN(arg1);
1649
1485
  bns_tmp = rb_ary_tmp_new(num);
1650
1486
  bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
@@ -1670,6 +1506,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1670
1506
 
1671
1507
  ALLOCV_END(tmp_b);
1672
1508
  ALLOCV_END(tmp_p);
1509
+ #endif
1673
1510
  }
1674
1511
 
1675
1512
  return result;
@@ -1710,10 +1547,6 @@ void Init_ossl_ec(void)
1710
1547
 
1711
1548
  s_GFp = rb_intern("GFp");
1712
1549
  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
1550
 
1718
1551
  ID_uncompressed = rb_intern("uncompressed");
1719
1552
  ID_compressed = rb_intern("compressed");
@@ -1728,8 +1561,9 @@ void Init_ossl_ec(void)
1728
1561
 
1729
1562
  rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
1730
1563
  rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
1564
+ #ifndef HAVE_EVP_PKEY_DUP
1731
1565
  rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
1732
- /* copy/dup/cmp */
1566
+ #endif
1733
1567
 
1734
1568
  rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
1735
1569
  rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
@@ -1752,15 +1586,9 @@ void Init_ossl_ec(void)
1752
1586
  rb_define_alias(cEC, "generate_key", "generate_key!");
1753
1587
  rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
1754
1588
 
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
1589
  rb_define_method(cEC, "export", ossl_ec_key_export, -1);
1761
1590
  rb_define_alias(cEC, "to_pem", "export");
1762
1591
  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
1592
 
1765
1593
 
1766
1594
  rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);