openssl 3.3.2 → 4.0.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +85 -0
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +30 -69
  6. data/ext/openssl/openssl_missing.h +0 -206
  7. data/ext/openssl/ossl.c +280 -301
  8. data/ext/openssl/ossl.h +15 -10
  9. data/ext/openssl/ossl_asn1.c +598 -406
  10. data/ext/openssl/ossl_asn1.h +15 -1
  11. data/ext/openssl/ossl_bio.c +3 -3
  12. data/ext/openssl/ossl_bn.c +286 -291
  13. data/ext/openssl/ossl_cipher.c +252 -203
  14. data/ext/openssl/ossl_cipher.h +10 -1
  15. data/ext/openssl/ossl_config.c +1 -6
  16. data/ext/openssl/ossl_digest.c +74 -43
  17. data/ext/openssl/ossl_digest.h +9 -1
  18. data/ext/openssl/ossl_engine.c +39 -103
  19. data/ext/openssl/ossl_hmac.c +30 -36
  20. data/ext/openssl/ossl_kdf.c +42 -53
  21. data/ext/openssl/ossl_ns_spki.c +31 -37
  22. data/ext/openssl/ossl_ocsp.c +214 -241
  23. data/ext/openssl/ossl_pkcs12.c +26 -26
  24. data/ext/openssl/ossl_pkcs7.c +175 -145
  25. data/ext/openssl/ossl_pkey.c +162 -178
  26. data/ext/openssl/ossl_pkey.h +99 -99
  27. data/ext/openssl/ossl_pkey_dh.c +31 -68
  28. data/ext/openssl/ossl_pkey_dsa.c +15 -54
  29. data/ext/openssl/ossl_pkey_ec.c +179 -237
  30. data/ext/openssl/ossl_pkey_rsa.c +56 -103
  31. data/ext/openssl/ossl_provider.c +0 -7
  32. data/ext/openssl/ossl_rand.c +7 -14
  33. data/ext/openssl/ossl_ssl.c +478 -353
  34. data/ext/openssl/ossl_ssl.h +8 -8
  35. data/ext/openssl/ossl_ssl_session.c +93 -97
  36. data/ext/openssl/ossl_ts.c +81 -127
  37. data/ext/openssl/ossl_x509.c +9 -28
  38. data/ext/openssl/ossl_x509attr.c +33 -54
  39. data/ext/openssl/ossl_x509cert.c +69 -100
  40. data/ext/openssl/ossl_x509crl.c +78 -89
  41. data/ext/openssl/ossl_x509ext.c +45 -66
  42. data/ext/openssl/ossl_x509name.c +63 -88
  43. data/ext/openssl/ossl_x509req.c +55 -62
  44. data/ext/openssl/ossl_x509revoked.c +27 -41
  45. data/ext/openssl/ossl_x509store.c +38 -56
  46. data/lib/openssl/buffering.rb +30 -24
  47. data/lib/openssl/digest.rb +1 -1
  48. data/lib/openssl/pkey.rb +71 -49
  49. data/lib/openssl/ssl.rb +12 -79
  50. data/lib/openssl/version.rb +2 -1
  51. data/lib/openssl/x509.rb +9 -0
  52. data/lib/openssl.rb +9 -6
  53. metadata +1 -3
  54. data/ext/openssl/openssl_missing.c +0 -40
  55. data/lib/openssl/asn1.rb +0 -188
@@ -33,13 +33,13 @@ ossl_evp_pkey_free(void *ptr)
33
33
  const rb_data_type_t ossl_evp_pkey_type = {
34
34
  "OpenSSL/EVP_PKEY",
35
35
  {
36
- 0, ossl_evp_pkey_free,
36
+ 0, ossl_evp_pkey_free,
37
37
  },
38
38
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
39
39
  };
40
40
 
41
41
  static VALUE
42
- pkey_new0(VALUE arg)
42
+ pkey_wrap0(VALUE arg)
43
43
  {
44
44
  EVP_PKEY *pkey = (EVP_PKEY *)arg;
45
45
  VALUE klass, obj;
@@ -65,15 +65,15 @@ pkey_new0(VALUE arg)
65
65
  }
66
66
 
67
67
  VALUE
68
- ossl_pkey_new(EVP_PKEY *pkey)
68
+ ossl_pkey_wrap(EVP_PKEY *pkey)
69
69
  {
70
70
  VALUE obj;
71
71
  int status;
72
72
 
73
- obj = rb_protect(pkey_new0, (VALUE)pkey, &status);
73
+ obj = rb_protect(pkey_wrap0, (VALUE)pkey, &status);
74
74
  if (status) {
75
- EVP_PKEY_free(pkey);
76
- rb_jump_tag(status);
75
+ EVP_PKEY_free(pkey);
76
+ rb_jump_tag(status);
77
77
  }
78
78
 
79
79
  return obj;
@@ -94,7 +94,8 @@ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
94
94
  selection, NULL, NULL);
95
95
  if (!dctx)
96
96
  goto out;
97
- if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb,
97
+ if (selection == EVP_PKEY_KEYPAIR &&
98
+ OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb,
98
99
  ppass) != 1)
99
100
  goto out;
100
101
  while (1) {
@@ -187,23 +188,23 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
187
188
  EVP_PKEY *pkey;
188
189
 
189
190
  if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
190
- goto out;
191
+ goto out;
191
192
  OSSL_BIO_reset(bio);
192
193
  if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass)))
193
- goto out;
194
+ goto out;
194
195
  OSSL_BIO_reset(bio);
195
196
  if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
196
- goto out;
197
+ goto out;
197
198
  OSSL_BIO_reset(bio);
198
199
  /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
199
200
  if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, ppass)))
200
- goto out;
201
+ goto out;
201
202
  OSSL_BIO_reset(bio);
202
203
  if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
203
- goto out;
204
+ goto out;
204
205
  OSSL_BIO_reset(bio);
205
206
  if ((pkey = PEM_read_bio_Parameters(bio, NULL)))
206
- goto out;
207
+ goto out;
207
208
 
208
209
  out:
209
210
  return pkey;
@@ -238,8 +239,8 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
238
239
  pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
239
240
  BIO_free(bio);
240
241
  if (!pkey)
241
- ossl_raise(ePKeyError, "Could not parse PKey");
242
- return ossl_pkey_new(pkey);
242
+ ossl_raise(ePKeyError, "Could not parse PKey");
243
+ return ossl_pkey_wrap(pkey);
243
244
  }
244
245
 
245
246
  static VALUE
@@ -443,7 +444,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam)
443
444
  }
444
445
  }
445
446
 
446
- return ossl_pkey_new(gen_arg.pkey);
447
+ return ossl_pkey_wrap(gen_arg.pkey);
447
448
  }
448
449
 
449
450
  /*
@@ -507,7 +508,7 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self)
507
508
  void
508
509
  ossl_pkey_check_public_key(const EVP_PKEY *pkey)
509
510
  {
510
- #if OSSL_OPENSSL_PREREQ(3, 0, 0)
511
+ #ifdef OSSL_HAVE_IMMUTABLE_PKEY
511
512
  if (EVP_PKEY_missing_parameters(pkey))
512
513
  ossl_raise(ePKeyError, "parameters missing");
513
514
  #else
@@ -515,35 +516,34 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey)
515
516
  const BIGNUM *n, *e, *pubkey;
516
517
 
517
518
  if (EVP_PKEY_missing_parameters(pkey))
518
- ossl_raise(ePKeyError, "parameters missing");
519
+ ossl_raise(ePKeyError, "parameters missing");
519
520
 
520
- /* OpenSSL < 1.1.0 takes non-const pointer */
521
- ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
521
+ ptr = EVP_PKEY_get0(pkey);
522
522
  switch (EVP_PKEY_base_id(pkey)) {
523
523
  case EVP_PKEY_RSA:
524
- RSA_get0_key(ptr, &n, &e, NULL);
525
- if (n && e)
526
- return;
527
- break;
524
+ RSA_get0_key(ptr, &n, &e, NULL);
525
+ if (n && e)
526
+ return;
527
+ break;
528
528
  case EVP_PKEY_DSA:
529
- DSA_get0_key(ptr, &pubkey, NULL);
530
- if (pubkey)
531
- return;
532
- break;
529
+ DSA_get0_key(ptr, &pubkey, NULL);
530
+ if (pubkey)
531
+ return;
532
+ break;
533
533
  case EVP_PKEY_DH:
534
- DH_get0_key(ptr, &pubkey, NULL);
535
- if (pubkey)
536
- return;
537
- break;
534
+ DH_get0_key(ptr, &pubkey, NULL);
535
+ if (pubkey)
536
+ return;
537
+ break;
538
538
  #if !defined(OPENSSL_NO_EC)
539
539
  case EVP_PKEY_EC:
540
- if (EC_KEY_get0_public_key(ptr))
541
- return;
542
- break;
540
+ if (EC_KEY_get0_public_key(ptr))
541
+ return;
542
+ break;
543
543
  #endif
544
544
  default:
545
- /* unsupported type; assuming ok */
546
- return;
545
+ /* unsupported type; assuming ok */
546
+ return;
547
547
  }
548
548
  ossl_raise(ePKeyError, "public key missing");
549
549
  #endif
@@ -610,12 +610,13 @@ static VALUE
610
610
  ossl_pkey_initialize(VALUE self)
611
611
  {
612
612
  if (rb_obj_is_instance_of(self, cPKey)) {
613
- ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
613
+ ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
614
614
  }
615
615
  return self;
616
616
  }
617
617
 
618
618
  #ifdef HAVE_EVP_PKEY_DUP
619
+ /* :nodoc: */
619
620
  static VALUE
620
621
  ossl_pkey_initialize_copy(VALUE self, VALUE other)
621
622
  {
@@ -635,7 +636,29 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other)
635
636
  }
636
637
  #endif
637
638
 
638
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
639
+ #ifndef OSSL_USE_PROVIDER
640
+ static int
641
+ lookup_pkey_type(VALUE type)
642
+ {
643
+ const EVP_PKEY_ASN1_METHOD *ameth;
644
+ int pkey_id;
645
+
646
+ StringValue(type);
647
+ /*
648
+ * XXX: EVP_PKEY_asn1_find_str() looks up a PEM type string. Should we use
649
+ * OBJ_txt2nid() instead (and then somehow check if the NID is an acceptable
650
+ * EVP_PKEY type)?
651
+ * It is probably fine, though, since it can handle all algorithms that
652
+ * support raw keys in 1.1.1: { X25519, X448, ED25519, ED448, HMAC }.
653
+ */
654
+ ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
655
+ if (!ameth)
656
+ ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
657
+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
658
+ return pkey_id;
659
+ }
660
+ #endif
661
+
639
662
  /*
640
663
  * call-seq:
641
664
  * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey
@@ -647,28 +670,27 @@ static VALUE
647
670
  ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
648
671
  {
649
672
  EVP_PKEY *pkey;
650
- const EVP_PKEY_ASN1_METHOD *ameth;
651
- int pkey_id;
652
673
  size_t keylen;
653
674
 
654
- StringValue(type);
655
675
  StringValue(key);
656
- ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
657
- if (!ameth)
658
- ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
659
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
660
-
661
676
  keylen = RSTRING_LEN(key);
662
677
 
678
+ #ifdef OSSL_USE_PROVIDER
679
+ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL,
680
+ (unsigned char *)RSTRING_PTR(key),
681
+ keylen);
682
+ if (!pkey)
683
+ ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex");
684
+ #else
685
+ int pkey_id = lookup_pkey_type(type);
663
686
  pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
664
687
  if (!pkey)
665
688
  ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");
689
+ #endif
666
690
 
667
- return ossl_pkey_new(pkey);
691
+ return ossl_pkey_wrap(pkey);
668
692
  }
669
- #endif
670
693
 
671
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
672
694
  /*
673
695
  * call-seq:
674
696
  * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey
@@ -680,26 +702,26 @@ static VALUE
680
702
  ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
681
703
  {
682
704
  EVP_PKEY *pkey;
683
- const EVP_PKEY_ASN1_METHOD *ameth;
684
- int pkey_id;
685
705
  size_t keylen;
686
706
 
687
- StringValue(type);
688
707
  StringValue(key);
689
- ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
690
- if (!ameth)
691
- ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
692
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
693
-
694
708
  keylen = RSTRING_LEN(key);
695
709
 
710
+ #ifdef OSSL_USE_PROVIDER
711
+ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL,
712
+ (unsigned char *)RSTRING_PTR(key),
713
+ keylen);
714
+ if (!pkey)
715
+ ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex");
716
+ #else
717
+ int pkey_id = lookup_pkey_type(type);
696
718
  pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
697
719
  if (!pkey)
698
720
  ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");
721
+ #endif
699
722
 
700
- return ossl_pkey_new(pkey);
723
+ return ossl_pkey_wrap(pkey);
701
724
  }
702
- #endif
703
725
 
704
726
  /*
705
727
  * call-seq:
@@ -715,6 +737,10 @@ ossl_pkey_oid(VALUE self)
715
737
 
716
738
  GetPKey(self, pkey);
717
739
  nid = EVP_PKEY_id(pkey);
740
+ #ifdef OSSL_USE_PROVIDER
741
+ if (nid == EVP_PKEY_KEYMGMT)
742
+ ossl_raise(ePKeyError, "EVP_PKEY_id");
743
+ #endif
718
744
  return rb_str_new_cstr(OBJ_nid2sn(nid));
719
745
  }
720
746
 
@@ -728,13 +754,23 @@ static VALUE
728
754
  ossl_pkey_inspect(VALUE self)
729
755
  {
730
756
  EVP_PKEY *pkey;
731
- int nid;
732
757
 
733
758
  GetPKey(self, pkey);
734
- nid = EVP_PKEY_id(pkey);
735
- return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>",
736
- rb_class_name(CLASS_OF(self)), (void *)self,
737
- OBJ_nid2sn(nid));
759
+ VALUE str = rb_sprintf("#<%"PRIsVALUE":%p",
760
+ rb_obj_class(self), (void *)self);
761
+ int nid = EVP_PKEY_id(pkey);
762
+ #ifdef OSSL_USE_PROVIDER
763
+ if (nid != EVP_PKEY_KEYMGMT)
764
+ #endif
765
+ rb_str_catf(str, " oid=%s", OBJ_nid2sn(nid));
766
+ #ifdef OSSL_USE_PROVIDER
767
+ rb_str_catf(str, " type_name=%s", EVP_PKEY_get0_type_name(pkey));
768
+ const OSSL_PROVIDER *prov = EVP_PKEY_get0_provider(pkey);
769
+ if (prov)
770
+ rb_str_catf(str, " provider=%s", OSSL_PROVIDER_get0_name(prov));
771
+ #endif
772
+ rb_str_catf(str, ">");
773
+ return str;
738
774
  }
739
775
 
740
776
  /*
@@ -778,44 +814,33 @@ VALUE
778
814
  ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der)
779
815
  {
780
816
  EVP_PKEY *pkey;
781
- VALUE cipher, pass;
817
+ VALUE cipher, pass, cipher_holder;
782
818
  const EVP_CIPHER *enc = NULL;
783
819
  BIO *bio;
784
820
 
785
821
  GetPKey(self, pkey);
786
822
  rb_scan_args(argc, argv, "02", &cipher, &pass);
787
823
  if (!NIL_P(cipher)) {
788
- enc = ossl_evp_get_cipherbyname(cipher);
789
- pass = ossl_pem_passwd_value(pass);
824
+ enc = ossl_evp_cipher_fetch(cipher, &cipher_holder);
825
+ pass = ossl_pem_passwd_value(pass);
790
826
  }
791
827
 
792
828
  bio = BIO_new(BIO_s_mem());
793
829
  if (!bio)
794
- ossl_raise(ePKeyError, "BIO_new");
830
+ ossl_raise(ePKeyError, "BIO_new");
795
831
  if (to_der) {
796
- if (!i2d_PrivateKey_bio(bio, pkey)) {
797
- BIO_free(bio);
798
- ossl_raise(ePKeyError, "i2d_PrivateKey_bio");
799
- }
832
+ if (!i2d_PrivateKey_bio(bio, pkey)) {
833
+ BIO_free(bio);
834
+ ossl_raise(ePKeyError, "i2d_PrivateKey_bio");
835
+ }
800
836
  }
801
837
  else {
802
- #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 5, 0)
803
- if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0,
804
- ossl_pem_passwd_cb,
805
- (void *)pass)) {
806
- #else
807
- char pem_str[80];
808
- const char *aname;
809
-
810
- EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &aname, pkey->ameth);
811
- snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY", aname);
812
- if (!PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, pem_str, bio,
813
- pkey, enc, NULL, 0, ossl_pem_passwd_cb,
814
- (void *)pass)) {
815
- #endif
816
- BIO_free(bio);
817
- ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional");
818
- }
838
+ if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0,
839
+ ossl_pem_passwd_cb,
840
+ (void *)pass)) {
841
+ BIO_free(bio);
842
+ ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional");
843
+ }
819
844
  }
820
845
  return ossl_membio2str(bio);
821
846
  }
@@ -824,37 +849,37 @@ static VALUE
824
849
  do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der)
825
850
  {
826
851
  EVP_PKEY *pkey;
827
- VALUE cipher, pass;
852
+ VALUE cipher, pass, cipher_holder;
828
853
  const EVP_CIPHER *enc = NULL;
829
854
  BIO *bio;
830
855
 
831
856
  GetPKey(self, pkey);
832
857
  rb_scan_args(argc, argv, "02", &cipher, &pass);
833
858
  if (argc > 0) {
834
- /*
835
- * TODO: EncryptedPrivateKeyInfo actually has more options.
836
- * Should they be exposed?
837
- */
838
- enc = ossl_evp_get_cipherbyname(cipher);
839
- pass = ossl_pem_passwd_value(pass);
859
+ /*
860
+ * TODO: EncryptedPrivateKeyInfo actually has more options.
861
+ * Should they be exposed?
862
+ */
863
+ enc = ossl_evp_cipher_fetch(cipher, &cipher_holder);
864
+ pass = ossl_pem_passwd_value(pass);
840
865
  }
841
866
 
842
867
  bio = BIO_new(BIO_s_mem());
843
868
  if (!bio)
844
- ossl_raise(ePKeyError, "BIO_new");
869
+ ossl_raise(ePKeyError, "BIO_new");
845
870
  if (to_der) {
846
- if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0,
847
- ossl_pem_passwd_cb, (void *)pass)) {
848
- BIO_free(bio);
849
- ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio");
850
- }
871
+ if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0,
872
+ ossl_pem_passwd_cb, (void *)pass)) {
873
+ BIO_free(bio);
874
+ ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio");
875
+ }
851
876
  }
852
877
  else {
853
- if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0,
854
- ossl_pem_passwd_cb, (void *)pass)) {
855
- BIO_free(bio);
856
- ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey");
857
- }
878
+ if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0,
879
+ ossl_pem_passwd_cb, (void *)pass)) {
880
+ BIO_free(bio);
881
+ ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey");
882
+ }
858
883
  }
859
884
  return ossl_membio2str(bio);
860
885
  }
@@ -901,7 +926,6 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
901
926
  return do_pkcs8_export(argc, argv, self, 0);
902
927
  }
903
928
 
904
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
905
929
  /*
906
930
  * call-seq:
907
931
  * pkey.raw_private_key => string
@@ -928,7 +952,6 @@ ossl_pkey_raw_private_key(VALUE self)
928
952
 
929
953
  return str;
930
954
  }
931
- #endif
932
955
 
933
956
  VALUE
934
957
  ossl_pkey_export_spki(VALUE self, int to_der)
@@ -940,18 +963,18 @@ ossl_pkey_export_spki(VALUE self, int to_der)
940
963
  ossl_pkey_check_public_key(pkey);
941
964
  bio = BIO_new(BIO_s_mem());
942
965
  if (!bio)
943
- ossl_raise(ePKeyError, "BIO_new");
966
+ ossl_raise(ePKeyError, "BIO_new");
944
967
  if (to_der) {
945
- if (!i2d_PUBKEY_bio(bio, pkey)) {
946
- BIO_free(bio);
947
- ossl_raise(ePKeyError, "i2d_PUBKEY_bio");
948
- }
968
+ if (!i2d_PUBKEY_bio(bio, pkey)) {
969
+ BIO_free(bio);
970
+ ossl_raise(ePKeyError, "i2d_PUBKEY_bio");
971
+ }
949
972
  }
950
973
  else {
951
- if (!PEM_write_bio_PUBKEY(bio, pkey)) {
952
- BIO_free(bio);
953
- ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY");
954
- }
974
+ if (!PEM_write_bio_PUBKEY(bio, pkey)) {
975
+ BIO_free(bio);
976
+ ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY");
977
+ }
955
978
  }
956
979
  return ossl_membio2str(bio);
957
980
  }
@@ -986,7 +1009,6 @@ ossl_pkey_public_to_pem(VALUE self)
986
1009
  return ossl_pkey_export_spki(self, 0);
987
1010
  }
988
1011
 
989
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
990
1012
  /*
991
1013
  * call-seq:
992
1014
  * pkey.raw_public_key => string
@@ -1013,7 +1035,6 @@ ossl_pkey_raw_public_key(VALUE self)
1013
1035
 
1014
1036
  return str;
1015
1037
  }
1016
- #endif
1017
1038
 
1018
1039
  /*
1019
1040
  * call-seq:
@@ -1090,7 +1111,7 @@ static VALUE
1090
1111
  ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
1091
1112
  {
1092
1113
  EVP_PKEY *pkey;
1093
- VALUE digest, data, options, sig;
1114
+ VALUE digest, data, options, sig, md_holder;
1094
1115
  const EVP_MD *md = NULL;
1095
1116
  EVP_MD_CTX *ctx;
1096
1117
  EVP_PKEY_CTX *pctx;
@@ -1100,7 +1121,7 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
1100
1121
  pkey = GetPrivPKeyPtr(self);
1101
1122
  rb_scan_args(argc, argv, "21", &digest, &data, &options);
1102
1123
  if (!NIL_P(digest))
1103
- md = ossl_evp_get_digestbyname(digest);
1124
+ md = ossl_evp_md_fetch(digest, &md_holder);
1104
1125
  StringValue(data);
1105
1126
 
1106
1127
  ctx = EVP_MD_CTX_new();
@@ -1117,7 +1138,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
1117
1138
  rb_jump_tag(state);
1118
1139
  }
1119
1140
  }
1120
- #if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
1121
1141
  if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data),
1122
1142
  RSTRING_LEN(data)) < 1) {
1123
1143
  EVP_MD_CTX_free(ctx);
@@ -1138,30 +1158,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
1138
1158
  EVP_MD_CTX_free(ctx);
1139
1159
  ossl_raise(ePKeyError, "EVP_DigestSign");
1140
1160
  }
1141
- #else
1142
- if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
1143
- EVP_MD_CTX_free(ctx);
1144
- ossl_raise(ePKeyError, "EVP_DigestSignUpdate");
1145
- }
1146
- if (EVP_DigestSignFinal(ctx, NULL, &siglen) < 1) {
1147
- EVP_MD_CTX_free(ctx);
1148
- ossl_raise(ePKeyError, "EVP_DigestSignFinal");
1149
- }
1150
- if (siglen > LONG_MAX) {
1151
- EVP_MD_CTX_free(ctx);
1152
- rb_raise(ePKeyError, "signature would be too large");
1153
- }
1154
- sig = ossl_str_new(NULL, (long)siglen, &state);
1155
- if (state) {
1156
- EVP_MD_CTX_free(ctx);
1157
- rb_jump_tag(state);
1158
- }
1159
- if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
1160
- &siglen) < 1) {
1161
- EVP_MD_CTX_free(ctx);
1162
- ossl_raise(ePKeyError, "EVP_DigestSignFinal");
1163
- }
1164
- #endif
1165
1161
  EVP_MD_CTX_free(ctx);
1166
1162
  rb_str_set_len(sig, siglen);
1167
1163
  return sig;
@@ -1194,7 +1190,7 @@ static VALUE
1194
1190
  ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
1195
1191
  {
1196
1192
  EVP_PKEY *pkey;
1197
- VALUE digest, sig, data, options;
1193
+ VALUE digest, sig, data, options, md_holder;
1198
1194
  const EVP_MD *md = NULL;
1199
1195
  EVP_MD_CTX *ctx;
1200
1196
  EVP_PKEY_CTX *pctx;
@@ -1204,7 +1200,7 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
1204
1200
  rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options);
1205
1201
  ossl_pkey_check_public_key(pkey);
1206
1202
  if (!NIL_P(digest))
1207
- md = ossl_evp_get_digestbyname(digest);
1203
+ md = ossl_evp_md_fetch(digest, &md_holder);
1208
1204
  StringValue(sig);
1209
1205
  StringValue(data);
1210
1206
 
@@ -1222,24 +1218,12 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
1222
1218
  rb_jump_tag(state);
1223
1219
  }
1224
1220
  }
1225
- #if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
1226
1221
  ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
1227
1222
  RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
1228
1223
  RSTRING_LEN(data));
1229
1224
  EVP_MD_CTX_free(ctx);
1230
1225
  if (ret < 0)
1231
1226
  ossl_raise(ePKeyError, "EVP_DigestVerify");
1232
- #else
1233
- if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
1234
- EVP_MD_CTX_free(ctx);
1235
- ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate");
1236
- }
1237
- ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
1238
- RSTRING_LEN(sig));
1239
- EVP_MD_CTX_free(ctx);
1240
- if (ret < 0)
1241
- ossl_raise(ePKeyError, "EVP_DigestVerifyFinal");
1242
- #endif
1243
1227
  if (ret)
1244
1228
  return Qtrue;
1245
1229
  else {
@@ -1285,7 +1269,7 @@ static VALUE
1285
1269
  ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self)
1286
1270
  {
1287
1271
  EVP_PKEY *pkey;
1288
- VALUE digest, data, options, sig;
1272
+ VALUE digest, data, options, sig, md_holder;
1289
1273
  const EVP_MD *md = NULL;
1290
1274
  EVP_PKEY_CTX *ctx;
1291
1275
  size_t outlen;
@@ -1294,7 +1278,7 @@ ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self)
1294
1278
  GetPKey(self, pkey);
1295
1279
  rb_scan_args(argc, argv, "21", &digest, &data, &options);
1296
1280
  if (!NIL_P(digest))
1297
- md = ossl_evp_get_digestbyname(digest);
1281
+ md = ossl_evp_md_fetch(digest, &md_holder);
1298
1282
  StringValue(data);
1299
1283
 
1300
1284
  ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
@@ -1361,7 +1345,7 @@ static VALUE
1361
1345
  ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self)
1362
1346
  {
1363
1347
  EVP_PKEY *pkey;
1364
- VALUE digest, sig, data, options;
1348
+ VALUE digest, sig, data, options, md_holder;
1365
1349
  const EVP_MD *md = NULL;
1366
1350
  EVP_PKEY_CTX *ctx;
1367
1351
  int state, ret;
@@ -1370,7 +1354,7 @@ ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self)
1370
1354
  rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options);
1371
1355
  ossl_pkey_check_public_key(pkey);
1372
1356
  if (!NIL_P(digest))
1373
- md = ossl_evp_get_digestbyname(digest);
1357
+ md = ossl_evp_md_fetch(digest, &md_holder);
1374
1358
  StringValue(sig);
1375
1359
  StringValue(data);
1376
1360
 
@@ -1424,7 +1408,7 @@ static VALUE
1424
1408
  ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self)
1425
1409
  {
1426
1410
  EVP_PKEY *pkey;
1427
- VALUE digest, sig, options, out;
1411
+ VALUE digest, sig, options, out, md_holder;
1428
1412
  const EVP_MD *md = NULL;
1429
1413
  EVP_PKEY_CTX *ctx;
1430
1414
  int state;
@@ -1434,7 +1418,7 @@ ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self)
1434
1418
  rb_scan_args(argc, argv, "21", &digest, &sig, &options);
1435
1419
  ossl_pkey_check_public_key(pkey);
1436
1420
  if (!NIL_P(digest))
1437
- md = ossl_evp_get_digestbyname(digest);
1421
+ md = ossl_evp_md_fetch(digest, &md_holder);
1438
1422
  StringValue(sig);
1439
1423
 
1440
1424
  ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
@@ -1674,11 +1658,6 @@ void
1674
1658
  Init_ossl_pkey(void)
1675
1659
  {
1676
1660
  #undef rb_intern
1677
- #if 0
1678
- mOSSL = rb_define_module("OpenSSL");
1679
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1680
- #endif
1681
-
1682
1661
  /* Document-module: OpenSSL::PKey
1683
1662
  *
1684
1663
  * == Asymmetric Public Key Algorithms
@@ -1734,7 +1713,16 @@ Init_ossl_pkey(void)
1734
1713
 
1735
1714
  /* Document-class: OpenSSL::PKey::PKeyError
1736
1715
  *
1737
- *Raised when errors occur during PKey#sign or PKey#verify.
1716
+ * Raised when errors occur during PKey#sign or PKey#verify.
1717
+ *
1718
+ * Before version 4.0.0, OpenSSL::PKey::PKeyError had the following
1719
+ * subclasses. These subclasses have been removed and the constants are
1720
+ * now defined as aliases of OpenSSL::PKey::PKeyError.
1721
+ *
1722
+ * * OpenSSL::PKey::DHError
1723
+ * * OpenSSL::PKey::DSAError
1724
+ * * OpenSSL::PKey::ECError
1725
+ * * OpenSSL::PKey::RSAError
1738
1726
  */
1739
1727
  ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
1740
1728
 
@@ -1752,10 +1740,8 @@ Init_ossl_pkey(void)
1752
1740
  rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
1753
1741
  rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
1754
1742
  rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
1755
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
1756
1743
  rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
1757
1744
  rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2);
1758
- #endif
1759
1745
 
1760
1746
  rb_define_alloc_func(cPKey, ossl_pkey_alloc);
1761
1747
  rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
@@ -1771,10 +1757,8 @@ Init_ossl_pkey(void)
1771
1757
  rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
1772
1758
  rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
1773
1759
  rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
1774
- #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
1775
1760
  rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0);
1776
1761
  rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0);
1777
- #endif
1778
1762
  rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1);
1779
1763
 
1780
1764
  rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);