openssl 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +232 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +61 -46
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +60 -44
  8. data/ext/openssl/ossl.c +112 -66
  9. data/ext/openssl/ossl.h +28 -11
  10. data/ext/openssl/ossl_asn1.c +42 -5
  11. data/ext/openssl/ossl_bn.c +276 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +38 -29
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +31 -62
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +52 -145
  19. data/ext/openssl/ossl_kdf.c +11 -19
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +9 -62
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1255 -178
  27. data/ext/openssl/ossl_pkey.h +40 -77
  28. data/ext/openssl/ossl_pkey_dh.c +125 -335
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +155 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -40
  33. data/ext/openssl/ossl_ssl.c +395 -364
  34. data/ext/openssl/ossl_ssl_session.c +24 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +86 -1
  38. data/ext/openssl/ossl_x509cert.c +166 -10
  39. data/ext/openssl/ossl_x509crl.c +10 -7
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +16 -5
  42. data/ext/openssl/ossl_x509req.c +10 -7
  43. data/ext/openssl/ossl_x509store.c +193 -92
  44. data/lib/openssl/bn.rb +1 -1
  45. data/lib/openssl/buffering.rb +42 -17
  46. data/lib/openssl/cipher.rb +1 -1
  47. data/lib/openssl/digest.rb +10 -12
  48. data/lib/openssl/hmac.rb +78 -0
  49. data/lib/openssl/marshal.rb +30 -0
  50. data/lib/openssl/pkcs5.rb +1 -1
  51. data/lib/openssl/pkey.rb +435 -1
  52. data/lib/openssl/ssl.rb +53 -14
  53. data/lib/openssl/version.rb +5 -0
  54. data/lib/openssl/x509.rb +177 -1
  55. data/lib/openssl.rb +24 -9
  56. metadata +13 -69
  57. data/ext/openssl/deprecation.rb +0 -23
  58. data/ext/openssl/ossl_version.h +0 -15
  59. data/ext/openssl/ruby_missing.h +0 -24
  60. data/lib/openssl/config.rb +0 -474
@@ -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:
@@ -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
  /*
@@ -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
  /*
@@ -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
  /*
@@ -425,66 +398,6 @@ static VALUE ossl_ec_key_is_private(VALUE self)
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,16 @@ 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
+ EC_KEY *ec;
415
+
416
+ GetEC(self, ec);
417
+ if (EC_KEY_get0_private_key(ec))
418
+ return ossl_pkey_export_traditional(argc, argv, self, 0);
419
+ else
420
+ return ossl_pkey_export_spki(self, 0);
503
421
  }
504
422
 
505
423
  /*
@@ -508,36 +426,17 @@ static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
508
426
  *
509
427
  * See the OpenSSL documentation for i2d_ECPrivateKey_bio()
510
428
  */
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)
429
+ static VALUE
430
+ ossl_ec_key_to_der(VALUE self)
523
431
  {
524
432
  EC_KEY *ec;
525
- BIO *out;
526
- VALUE str;
527
433
 
528
434
  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;
435
+ if (EC_KEY_get0_private_key(ec))
436
+ return ossl_pkey_export_traditional(0, NULL, self, 1);
437
+ else
438
+ return ossl_pkey_export_spki(self, 1);
539
439
  }
540
-
541
440
  /*
542
441
  * call-seq:
543
442
  * key.generate_key! => self
@@ -554,6 +453,9 @@ static VALUE ossl_ec_key_to_text(VALUE self)
554
453
  */
555
454
  static VALUE ossl_ec_key_generate_key(VALUE self)
556
455
  {
456
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
457
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
458
+ #else
557
459
  EC_KEY *ec;
558
460
 
559
461
  GetEC(self, ec);
@@ -561,116 +463,50 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
561
463
  ossl_raise(eECError, "EC_KEY_generate_key");
562
464
 
563
465
  return self;
466
+ #endif
564
467
  }
565
468
 
566
469
  /*
567
- * call-seq:
568
- * key.check_key => true
470
+ * call-seq:
471
+ * key.check_key => true
569
472
  *
570
- * Raises an exception if the key is invalid.
473
+ * Raises an exception if the key is invalid.
571
474
  *
572
- * See the OpenSSL documentation for EC_KEY_check_key()
475
+ * See also the man page EVP_PKEY_public_check(3).
573
476
  */
574
477
  static VALUE ossl_ec_key_check_key(VALUE self)
575
478
  {
479
+ #ifdef HAVE_EVP_PKEY_CHECK
480
+ EVP_PKEY *pkey;
481
+ EVP_PKEY_CTX *pctx;
482
+ int ret;
483
+
484
+ GetPKey(self, pkey);
485
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
486
+ if (!pctx)
487
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
488
+ ret = EVP_PKEY_public_check(pctx);
489
+ EVP_PKEY_CTX_free(pctx);
490
+ if (ret != 1)
491
+ ossl_raise(eECError, "EVP_PKEY_public_check");
492
+ #else
576
493
  EC_KEY *ec;
577
494
 
578
495
  GetEC(self, ec);
579
496
  if (EC_KEY_check_key(ec) != 1)
580
497
  ossl_raise(eECError, "EC_KEY_check_key");
498
+ #endif
581
499
 
582
500
  return Qtrue;
583
501
  }
584
502
 
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
- }
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;
651
-
652
- 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");
663
-
664
- UNREACHABLE;
665
- }
666
-
667
503
  /*
668
504
  * OpenSSL::PKey::EC::Group
669
505
  */
670
506
  static void
671
507
  ossl_ec_group_free(void *ptr)
672
508
  {
673
- EC_GROUP_clear_free(ptr);
509
+ EC_GROUP_free(ptr);
674
510
  }
675
511
 
676
512
  static const rb_data_type_t ossl_ec_group_type = {
@@ -706,20 +542,11 @@ ec_group_new(const EC_GROUP *group)
706
542
  * call-seq:
707
543
  * OpenSSL::PKey::EC::Group.new(ec_group)
708
544
  * OpenSSL::PKey::EC::Group.new(pem_or_der_encoded)
709
- * OpenSSL::PKey::EC::Group.new(ec_method)
710
545
  * OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)
711
546
  * OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)
712
547
  *
713
548
  * Creates a new EC::Group object.
714
549
  *
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
550
  * If the first argument is :GFp or :GF2m, creates a new curve with given
724
551
  * parameters.
725
552
  */
@@ -734,29 +561,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
734
561
 
735
562
  switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
736
563
  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)) {
564
+ if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
760
565
  const EC_GROUP *arg1_group;
761
566
 
762
567
  GetECGroup(arg1, arg1_group);
@@ -820,8 +625,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
820
625
  ossl_raise(rb_eArgError, "wrong number of arguments");
821
626
  }
822
627
 
823
- if (group == NULL)
824
- ossl_raise(eEC_GROUP, "");
628
+ ASSUME(group);
825
629
  RTYPEDDATA_DATA(self) = group;
826
630
 
827
631
  return self;
@@ -1475,6 +1279,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
1475
1279
  /*
1476
1280
  * call-seq:
1477
1281
  * point.make_affine! => self
1282
+ *
1283
+ * This method is deprecated and should not be used. This is a no-op.
1478
1284
  */
1479
1285
  static VALUE ossl_ec_point_make_affine(VALUE self)
1480
1286
  {
@@ -1484,8 +1290,11 @@ static VALUE ossl_ec_point_make_affine(VALUE self)
1484
1290
  GetECPoint(self, point);
1485
1291
  GetECPointGroup(self, group);
1486
1292
 
1293
+ rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated");
1294
+ #if !OSSL_OPENSSL_PREREQ(3, 0, 0)
1487
1295
  if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
1488
1296
  ossl_raise(cEC_POINT, "EC_POINT_make_affine");
1297
+ #endif
1489
1298
 
1490
1299
  return self;
1491
1300
  }
@@ -1562,6 +1371,34 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form)
1562
1371
  return str;
1563
1372
  }
1564
1373
 
1374
+ /*
1375
+ * call-seq:
1376
+ * point.add(point) => point
1377
+ *
1378
+ * Performs elliptic curve point addition.
1379
+ */
1380
+ static VALUE ossl_ec_point_add(VALUE self, VALUE other)
1381
+ {
1382
+ EC_POINT *point_self, *point_other, *point_result;
1383
+ const EC_GROUP *group;
1384
+ VALUE group_v = rb_attr_get(self, id_i_group);
1385
+ VALUE result;
1386
+
1387
+ GetECPoint(self, point_self);
1388
+ GetECPoint(other, point_other);
1389
+ GetECGroup(group_v, group);
1390
+
1391
+ result = rb_obj_alloc(cEC_POINT);
1392
+ ossl_ec_point_initialize(1, &group_v, result);
1393
+ GetECPoint(result, point_result);
1394
+
1395
+ if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) {
1396
+ ossl_raise(eEC_POINT, "EC_POINT_add");
1397
+ }
1398
+
1399
+ return result;
1400
+ }
1401
+
1565
1402
  /*
1566
1403
  * call-seq:
1567
1404
  * point.mul(bn1 [, bn2]) => point
@@ -1603,6 +1440,10 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1603
1440
  if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
1604
1441
  ossl_raise(eEC_POINT, NULL);
1605
1442
  } else {
1443
+ #if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER)
1444
+ rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \
1445
+ "supported by this OpenSSL version");
1446
+ #else
1606
1447
  /*
1607
1448
  * bignums | arg1[0] | arg1[1] | arg1[2] | ...
1608
1449
  * points | self | arg2[0] | arg2[1] | ...
@@ -1617,6 +1458,9 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1617
1458
  if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
1618
1459
  ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");
1619
1460
 
1461
+ rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \
1462
+ "use #mul(bn) form instead");
1463
+
1620
1464
  num = RARRAY_LEN(arg1);
1621
1465
  bns_tmp = rb_ary_tmp_new(num);
1622
1466
  bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
@@ -1642,6 +1486,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
1642
1486
 
1643
1487
  ALLOCV_END(tmp_b);
1644
1488
  ALLOCV_END(tmp_p);
1489
+ #endif
1645
1490
  }
1646
1491
 
1647
1492
  return result;
@@ -1682,10 +1527,6 @@ void Init_ossl_ec(void)
1682
1527
 
1683
1528
  s_GFp = rb_intern("GFp");
1684
1529
  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
1530
 
1690
1531
  ID_uncompressed = rb_intern("uncompressed");
1691
1532
  ID_compressed = rb_intern("compressed");
@@ -1700,8 +1541,9 @@ void Init_ossl_ec(void)
1700
1541
 
1701
1542
  rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
1702
1543
  rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
1544
+ #ifndef HAVE_EVP_PKEY_DUP
1703
1545
  rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
1704
- /* copy/dup/cmp */
1546
+ #endif
1705
1547
 
1706
1548
  rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
1707
1549
  rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
@@ -1724,15 +1566,9 @@ void Init_ossl_ec(void)
1724
1566
  rb_define_alias(cEC, "generate_key", "generate_key!");
1725
1567
  rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
1726
1568
 
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
1569
  rb_define_method(cEC, "export", ossl_ec_key_export, -1);
1733
1570
  rb_define_alias(cEC, "to_pem", "export");
1734
1571
  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
1572
 
1737
1573
 
1738
1574
  rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
@@ -1786,6 +1622,7 @@ void Init_ossl_ec(void)
1786
1622
  /* all the other methods */
1787
1623
 
1788
1624
  rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1);
1625
+ rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1);
1789
1626
  rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
1790
1627
 
1791
1628
  id_i_group = rb_intern("@group");