openssl 2.1.3 → 3.0.2

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +266 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +46 -38
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +27 -10
  10. data/ext/openssl/ossl_asn1.c +41 -4
  11. data/ext/openssl/ossl_bn.c +251 -134
  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 +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -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 +1295 -178
  27. data/ext/openssl/ossl_pkey.h +35 -72
  28. data/ext/openssl/ossl_pkey_dh.c +124 -334
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +186 -329
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +347 -394
  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 +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +443 -1
  53. data/lib/openssl/ssl.rb +47 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -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,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
+ 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
434
  EC_KEY *ec;
525
- BIO *out;
526
- VALUE str;
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 */
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
- * 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
- {
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
- 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;
512
+ if (EC_KEY_check_key(ec) != 1)
513
+ ossl_raise(eECError, "EC_KEY_check_key");
514
+ #endif
651
515
 
652
- GetEC(self, ec);
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
- 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
  }
@@ -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
- /* copy/dup/cmp */
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");