openssl 3.3.0 → 4.0.1
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 +156 -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 +257 -209
- 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 +176 -146
- data/ext/openssl/ossl_pkey.c +163 -178
- data/ext/openssl/ossl_pkey.h +99 -99
- data/ext/openssl/ossl_pkey_dh.c +32 -67
- data/ext/openssl/ossl_pkey_dsa.c +16 -53
- data/ext/openssl/ossl_pkey_ec.c +181 -237
- data/ext/openssl/ossl_pkey_rsa.c +57 -102
- data/ext/openssl/ossl_provider.c +0 -7
- data/ext/openssl/ossl_rand.c +7 -14
- data/ext/openssl/ossl_ssl.c +544 -393
- 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 -80
- data/lib/openssl/version.rb +2 -1
- data/lib/openssl/x509.rb +9 -0
- data/lib/openssl.rb +9 -6
- metadata +3 -8
- 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)
|
|
@@ -937,20 +960,21 @@ ossl_pkey_export_spki(VALUE self, int to_der)
|
|
|
937
960
|
BIO *bio;
|
|
938
961
|
|
|
939
962
|
GetPKey(self, pkey);
|
|
963
|
+
ossl_pkey_check_public_key(pkey);
|
|
940
964
|
bio = BIO_new(BIO_s_mem());
|
|
941
965
|
if (!bio)
|
|
942
|
-
|
|
966
|
+
ossl_raise(ePKeyError, "BIO_new");
|
|
943
967
|
if (to_der) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
968
|
+
if (!i2d_PUBKEY_bio(bio, pkey)) {
|
|
969
|
+
BIO_free(bio);
|
|
970
|
+
ossl_raise(ePKeyError, "i2d_PUBKEY_bio");
|
|
971
|
+
}
|
|
948
972
|
}
|
|
949
973
|
else {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
974
|
+
if (!PEM_write_bio_PUBKEY(bio, pkey)) {
|
|
975
|
+
BIO_free(bio);
|
|
976
|
+
ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY");
|
|
977
|
+
}
|
|
954
978
|
}
|
|
955
979
|
return ossl_membio2str(bio);
|
|
956
980
|
}
|
|
@@ -985,7 +1009,6 @@ ossl_pkey_public_to_pem(VALUE self)
|
|
|
985
1009
|
return ossl_pkey_export_spki(self, 0);
|
|
986
1010
|
}
|
|
987
1011
|
|
|
988
|
-
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
|
|
989
1012
|
/*
|
|
990
1013
|
* call-seq:
|
|
991
1014
|
* pkey.raw_public_key => string
|
|
@@ -1012,7 +1035,6 @@ ossl_pkey_raw_public_key(VALUE self)
|
|
|
1012
1035
|
|
|
1013
1036
|
return str;
|
|
1014
1037
|
}
|
|
1015
|
-
#endif
|
|
1016
1038
|
|
|
1017
1039
|
/*
|
|
1018
1040
|
* call-seq:
|
|
@@ -1089,7 +1111,7 @@ static VALUE
|
|
|
1089
1111
|
ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
|
|
1090
1112
|
{
|
|
1091
1113
|
EVP_PKEY *pkey;
|
|
1092
|
-
VALUE digest, data, options, sig;
|
|
1114
|
+
VALUE digest, data, options, sig, md_holder;
|
|
1093
1115
|
const EVP_MD *md = NULL;
|
|
1094
1116
|
EVP_MD_CTX *ctx;
|
|
1095
1117
|
EVP_PKEY_CTX *pctx;
|
|
@@ -1099,7 +1121,7 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
|
|
|
1099
1121
|
pkey = GetPrivPKeyPtr(self);
|
|
1100
1122
|
rb_scan_args(argc, argv, "21", &digest, &data, &options);
|
|
1101
1123
|
if (!NIL_P(digest))
|
|
1102
|
-
md =
|
|
1124
|
+
md = ossl_evp_md_fetch(digest, &md_holder);
|
|
1103
1125
|
StringValue(data);
|
|
1104
1126
|
|
|
1105
1127
|
ctx = EVP_MD_CTX_new();
|
|
@@ -1116,7 +1138,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
|
|
|
1116
1138
|
rb_jump_tag(state);
|
|
1117
1139
|
}
|
|
1118
1140
|
}
|
|
1119
|
-
#if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
|
|
1120
1141
|
if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data),
|
|
1121
1142
|
RSTRING_LEN(data)) < 1) {
|
|
1122
1143
|
EVP_MD_CTX_free(ctx);
|
|
@@ -1137,30 +1158,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
|
|
|
1137
1158
|
EVP_MD_CTX_free(ctx);
|
|
1138
1159
|
ossl_raise(ePKeyError, "EVP_DigestSign");
|
|
1139
1160
|
}
|
|
1140
|
-
#else
|
|
1141
|
-
if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
|
|
1142
|
-
EVP_MD_CTX_free(ctx);
|
|
1143
|
-
ossl_raise(ePKeyError, "EVP_DigestSignUpdate");
|
|
1144
|
-
}
|
|
1145
|
-
if (EVP_DigestSignFinal(ctx, NULL, &siglen) < 1) {
|
|
1146
|
-
EVP_MD_CTX_free(ctx);
|
|
1147
|
-
ossl_raise(ePKeyError, "EVP_DigestSignFinal");
|
|
1148
|
-
}
|
|
1149
|
-
if (siglen > LONG_MAX) {
|
|
1150
|
-
EVP_MD_CTX_free(ctx);
|
|
1151
|
-
rb_raise(ePKeyError, "signature would be too large");
|
|
1152
|
-
}
|
|
1153
|
-
sig = ossl_str_new(NULL, (long)siglen, &state);
|
|
1154
|
-
if (state) {
|
|
1155
|
-
EVP_MD_CTX_free(ctx);
|
|
1156
|
-
rb_jump_tag(state);
|
|
1157
|
-
}
|
|
1158
|
-
if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
|
|
1159
|
-
&siglen) < 1) {
|
|
1160
|
-
EVP_MD_CTX_free(ctx);
|
|
1161
|
-
ossl_raise(ePKeyError, "EVP_DigestSignFinal");
|
|
1162
|
-
}
|
|
1163
|
-
#endif
|
|
1164
1161
|
EVP_MD_CTX_free(ctx);
|
|
1165
1162
|
rb_str_set_len(sig, siglen);
|
|
1166
1163
|
return sig;
|
|
@@ -1193,7 +1190,7 @@ static VALUE
|
|
|
1193
1190
|
ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
|
|
1194
1191
|
{
|
|
1195
1192
|
EVP_PKEY *pkey;
|
|
1196
|
-
VALUE digest, sig, data, options;
|
|
1193
|
+
VALUE digest, sig, data, options, md_holder;
|
|
1197
1194
|
const EVP_MD *md = NULL;
|
|
1198
1195
|
EVP_MD_CTX *ctx;
|
|
1199
1196
|
EVP_PKEY_CTX *pctx;
|
|
@@ -1203,7 +1200,7 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
|
|
|
1203
1200
|
rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options);
|
|
1204
1201
|
ossl_pkey_check_public_key(pkey);
|
|
1205
1202
|
if (!NIL_P(digest))
|
|
1206
|
-
md =
|
|
1203
|
+
md = ossl_evp_md_fetch(digest, &md_holder);
|
|
1207
1204
|
StringValue(sig);
|
|
1208
1205
|
StringValue(data);
|
|
1209
1206
|
|
|
@@ -1221,24 +1218,12 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
|
|
|
1221
1218
|
rb_jump_tag(state);
|
|
1222
1219
|
}
|
|
1223
1220
|
}
|
|
1224
|
-
#if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
|
|
1225
1221
|
ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
|
|
1226
1222
|
RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
|
|
1227
1223
|
RSTRING_LEN(data));
|
|
1228
1224
|
EVP_MD_CTX_free(ctx);
|
|
1229
1225
|
if (ret < 0)
|
|
1230
1226
|
ossl_raise(ePKeyError, "EVP_DigestVerify");
|
|
1231
|
-
#else
|
|
1232
|
-
if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
|
|
1233
|
-
EVP_MD_CTX_free(ctx);
|
|
1234
|
-
ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate");
|
|
1235
|
-
}
|
|
1236
|
-
ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
|
|
1237
|
-
RSTRING_LEN(sig));
|
|
1238
|
-
EVP_MD_CTX_free(ctx);
|
|
1239
|
-
if (ret < 0)
|
|
1240
|
-
ossl_raise(ePKeyError, "EVP_DigestVerifyFinal");
|
|
1241
|
-
#endif
|
|
1242
1227
|
if (ret)
|
|
1243
1228
|
return Qtrue;
|
|
1244
1229
|
else {
|
|
@@ -1284,7 +1269,7 @@ static VALUE
|
|
|
1284
1269
|
ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self)
|
|
1285
1270
|
{
|
|
1286
1271
|
EVP_PKEY *pkey;
|
|
1287
|
-
VALUE digest, data, options, sig;
|
|
1272
|
+
VALUE digest, data, options, sig, md_holder;
|
|
1288
1273
|
const EVP_MD *md = NULL;
|
|
1289
1274
|
EVP_PKEY_CTX *ctx;
|
|
1290
1275
|
size_t outlen;
|
|
@@ -1293,7 +1278,7 @@ ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self)
|
|
|
1293
1278
|
GetPKey(self, pkey);
|
|
1294
1279
|
rb_scan_args(argc, argv, "21", &digest, &data, &options);
|
|
1295
1280
|
if (!NIL_P(digest))
|
|
1296
|
-
md =
|
|
1281
|
+
md = ossl_evp_md_fetch(digest, &md_holder);
|
|
1297
1282
|
StringValue(data);
|
|
1298
1283
|
|
|
1299
1284
|
ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
|
|
@@ -1360,7 +1345,7 @@ static VALUE
|
|
|
1360
1345
|
ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self)
|
|
1361
1346
|
{
|
|
1362
1347
|
EVP_PKEY *pkey;
|
|
1363
|
-
VALUE digest, sig, data, options;
|
|
1348
|
+
VALUE digest, sig, data, options, md_holder;
|
|
1364
1349
|
const EVP_MD *md = NULL;
|
|
1365
1350
|
EVP_PKEY_CTX *ctx;
|
|
1366
1351
|
int state, ret;
|
|
@@ -1369,7 +1354,7 @@ ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self)
|
|
|
1369
1354
|
rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options);
|
|
1370
1355
|
ossl_pkey_check_public_key(pkey);
|
|
1371
1356
|
if (!NIL_P(digest))
|
|
1372
|
-
md =
|
|
1357
|
+
md = ossl_evp_md_fetch(digest, &md_holder);
|
|
1373
1358
|
StringValue(sig);
|
|
1374
1359
|
StringValue(data);
|
|
1375
1360
|
|
|
@@ -1423,7 +1408,7 @@ static VALUE
|
|
|
1423
1408
|
ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self)
|
|
1424
1409
|
{
|
|
1425
1410
|
EVP_PKEY *pkey;
|
|
1426
|
-
VALUE digest, sig, options, out;
|
|
1411
|
+
VALUE digest, sig, options, out, md_holder;
|
|
1427
1412
|
const EVP_MD *md = NULL;
|
|
1428
1413
|
EVP_PKEY_CTX *ctx;
|
|
1429
1414
|
int state;
|
|
@@ -1433,7 +1418,7 @@ ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self)
|
|
|
1433
1418
|
rb_scan_args(argc, argv, "21", &digest, &sig, &options);
|
|
1434
1419
|
ossl_pkey_check_public_key(pkey);
|
|
1435
1420
|
if (!NIL_P(digest))
|
|
1436
|
-
md =
|
|
1421
|
+
md = ossl_evp_md_fetch(digest, &md_holder);
|
|
1437
1422
|
StringValue(sig);
|
|
1438
1423
|
|
|
1439
1424
|
ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
|
|
@@ -1673,11 +1658,6 @@ void
|
|
|
1673
1658
|
Init_ossl_pkey(void)
|
|
1674
1659
|
{
|
|
1675
1660
|
#undef rb_intern
|
|
1676
|
-
#if 0
|
|
1677
|
-
mOSSL = rb_define_module("OpenSSL");
|
|
1678
|
-
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
|
1679
|
-
#endif
|
|
1680
|
-
|
|
1681
1661
|
/* Document-module: OpenSSL::PKey
|
|
1682
1662
|
*
|
|
1683
1663
|
* == Asymmetric Public Key Algorithms
|
|
@@ -1733,7 +1713,16 @@ Init_ossl_pkey(void)
|
|
|
1733
1713
|
|
|
1734
1714
|
/* Document-class: OpenSSL::PKey::PKeyError
|
|
1735
1715
|
*
|
|
1736
|
-
*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
|
|
1737
1726
|
*/
|
|
1738
1727
|
ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
|
|
1739
1728
|
|
|
@@ -1751,10 +1740,8 @@ Init_ossl_pkey(void)
|
|
|
1751
1740
|
rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
|
|
1752
1741
|
rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
|
|
1753
1742
|
rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
|
|
1754
|
-
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
|
|
1755
1743
|
rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
|
|
1756
1744
|
rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2);
|
|
1757
|
-
#endif
|
|
1758
1745
|
|
|
1759
1746
|
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
|
|
1760
1747
|
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
|
|
@@ -1770,10 +1757,8 @@ Init_ossl_pkey(void)
|
|
|
1770
1757
|
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
|
|
1771
1758
|
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
|
|
1772
1759
|
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
|
|
1773
|
-
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
|
|
1774
1760
|
rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0);
|
|
1775
1761
|
rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0);
|
|
1776
|
-
#endif
|
|
1777
1762
|
rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1);
|
|
1778
1763
|
|
|
1779
1764
|
rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);
|