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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +3 -0
- data/History.md +85 -0
- data/README.md +12 -11
- data/ext/openssl/extconf.rb +30 -69
- data/ext/openssl/openssl_missing.h +0 -206
- data/ext/openssl/ossl.c +280 -301
- data/ext/openssl/ossl.h +15 -10
- data/ext/openssl/ossl_asn1.c +598 -406
- data/ext/openssl/ossl_asn1.h +15 -1
- data/ext/openssl/ossl_bio.c +3 -3
- data/ext/openssl/ossl_bn.c +286 -291
- data/ext/openssl/ossl_cipher.c +252 -203
- data/ext/openssl/ossl_cipher.h +10 -1
- data/ext/openssl/ossl_config.c +1 -6
- data/ext/openssl/ossl_digest.c +74 -43
- data/ext/openssl/ossl_digest.h +9 -1
- data/ext/openssl/ossl_engine.c +39 -103
- data/ext/openssl/ossl_hmac.c +30 -36
- data/ext/openssl/ossl_kdf.c +42 -53
- data/ext/openssl/ossl_ns_spki.c +31 -37
- data/ext/openssl/ossl_ocsp.c +214 -241
- data/ext/openssl/ossl_pkcs12.c +26 -26
- data/ext/openssl/ossl_pkcs7.c +175 -145
- data/ext/openssl/ossl_pkey.c +162 -178
- data/ext/openssl/ossl_pkey.h +99 -99
- data/ext/openssl/ossl_pkey_dh.c +31 -68
- data/ext/openssl/ossl_pkey_dsa.c +15 -54
- data/ext/openssl/ossl_pkey_ec.c +179 -237
- data/ext/openssl/ossl_pkey_rsa.c +56 -103
- data/ext/openssl/ossl_provider.c +0 -7
- data/ext/openssl/ossl_rand.c +7 -14
- data/ext/openssl/ossl_ssl.c +478 -353
- data/ext/openssl/ossl_ssl.h +8 -8
- data/ext/openssl/ossl_ssl_session.c +93 -97
- data/ext/openssl/ossl_ts.c +81 -127
- data/ext/openssl/ossl_x509.c +9 -28
- data/ext/openssl/ossl_x509attr.c +33 -54
- data/ext/openssl/ossl_x509cert.c +69 -100
- data/ext/openssl/ossl_x509crl.c +78 -89
- data/ext/openssl/ossl_x509ext.c +45 -66
- data/ext/openssl/ossl_x509name.c +63 -88
- data/ext/openssl/ossl_x509req.c +55 -62
- data/ext/openssl/ossl_x509revoked.c +27 -41
- data/ext/openssl/ossl_x509store.c +38 -56
- data/lib/openssl/buffering.rb +30 -24
- data/lib/openssl/digest.rb +1 -1
- data/lib/openssl/pkey.rb +71 -49
- data/lib/openssl/ssl.rb +12 -79
- data/lib/openssl/version.rb +2 -1
- data/lib/openssl/x509.rb +9 -0
- data/lib/openssl.rb +9 -6
- metadata +1 -3
- data/ext/openssl/openssl_missing.c +0 -40
- data/lib/openssl/asn1.rb +0 -188
data/ext/openssl/ossl_pkey.c
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
68
|
+
ossl_pkey_wrap(EVP_PKEY *pkey)
|
|
69
69
|
{
|
|
70
70
|
VALUE obj;
|
|
71
71
|
int status;
|
|
72
72
|
|
|
73
|
-
obj = rb_protect(
|
|
73
|
+
obj = rb_protect(pkey_wrap0, (VALUE)pkey, &status);
|
|
74
74
|
if (status) {
|
|
75
|
-
|
|
76
|
-
|
|
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 (
|
|
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
|
-
|
|
191
|
+
goto out;
|
|
191
192
|
OSSL_BIO_reset(bio);
|
|
192
193
|
if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass)))
|
|
193
|
-
|
|
194
|
+
goto out;
|
|
194
195
|
OSSL_BIO_reset(bio);
|
|
195
196
|
if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
|
|
196
|
-
|
|
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
|
-
|
|
201
|
+
goto out;
|
|
201
202
|
OSSL_BIO_reset(bio);
|
|
202
203
|
if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
|
|
203
|
-
|
|
204
|
+
goto out;
|
|
204
205
|
OSSL_BIO_reset(bio);
|
|
205
206
|
if ((pkey = PEM_read_bio_Parameters(bio, NULL)))
|
|
206
|
-
|
|
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
|
-
|
|
242
|
-
return
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
519
|
+
ossl_raise(ePKeyError, "parameters missing");
|
|
519
520
|
|
|
520
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
524
|
+
RSA_get0_key(ptr, &n, &e, NULL);
|
|
525
|
+
if (n && e)
|
|
526
|
+
return;
|
|
527
|
+
break;
|
|
528
528
|
case EVP_PKEY_DSA:
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
529
|
+
DSA_get0_key(ptr, &pubkey, NULL);
|
|
530
|
+
if (pubkey)
|
|
531
|
+
return;
|
|
532
|
+
break;
|
|
533
533
|
case EVP_PKEY_DH:
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
541
|
-
|
|
542
|
-
|
|
540
|
+
if (EC_KEY_get0_public_key(ptr))
|
|
541
|
+
return;
|
|
542
|
+
break;
|
|
543
543
|
#endif
|
|
544
544
|
default:
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
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
|
-
|
|
789
|
-
|
|
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
|
-
|
|
830
|
+
ossl_raise(ePKeyError, "BIO_new");
|
|
795
831
|
if (to_der) {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
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
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
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
|
-
|
|
869
|
+
ossl_raise(ePKeyError, "BIO_new");
|
|
845
870
|
if (to_der) {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
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
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
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
|
-
|
|
966
|
+
ossl_raise(ePKeyError, "BIO_new");
|
|
944
967
|
if (to_der) {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
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
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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);
|