From cd38f6c5e141f18de1001b36baf3f18162d3d333 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 14 May 2026 00:47:15 +0900 Subject: Merge openssl-4.0.2 The changes can be found at: https://github.com/ruby/openssl/compare/v4.0.1...v4.0.2 --- ext/openssl/History.md | 22 ++++++++++++ ext/openssl/extconf.rb | 3 ++ ext/openssl/lib/openssl/version.rb | 2 +- ext/openssl/openssl.gemspec | 2 +- ext/openssl/openssl_missing.h | 23 ++++++++++++ ext/openssl/ossl.c | 22 +++++++++--- ext/openssl/ossl_asn1.c | 47 +++++++++++++----------- ext/openssl/ossl_bio.c | 6 +++- ext/openssl/ossl_ocsp.c | 5 ++- ext/openssl/ossl_pkey.h | 1 - ext/openssl/ossl_ts.c | 2 +- ext/openssl/ossl_x509.h | 12 +++---- ext/openssl/ossl_x509attr.c | 9 ++--- ext/openssl/ossl_x509cert.c | 12 +++---- ext/openssl/ossl_x509crl.c | 10 +++--- ext/openssl/ossl_x509ext.c | 19 +++++++--- ext/openssl/ossl_x509name.c | 5 +-- ext/openssl/ossl_x509req.c | 4 +-- ext/openssl/ossl_x509revoked.c | 7 ++-- ext/openssl/ossl_x509store.c | 10 +++--- test/openssl/test_ossl.rb | 10 ++++++ test/openssl/test_pkey_rsa.rb | 74 +++++++++++++++++++------------------- test/openssl/test_ssl.rb | 8 +++-- 23 files changed, 203 insertions(+), 112 deletions(-) diff --git a/ext/openssl/History.md b/ext/openssl/History.md index c78c7e4633..ce01b3e0f2 100644 --- a/ext/openssl/History.md +++ b/ext/openssl/History.md @@ -1,3 +1,9 @@ +Version 4.0.2 +============= + +Merged changes in 3.2.4 and 3.3.3. + + Version 4.0.1 ============= @@ -103,6 +109,12 @@ Notable changes [[GitHub #983]](https://github.com/ruby/openssl/pull/983) +Version 3.3.3 +============= + +Merged changes in 3.2.4. + + Version 3.3.2 ============= @@ -191,6 +203,16 @@ And various non-user-visible changes and bug fixes. Please see the commit history for more details. +Version 3.2.4 +============= + +Notable changes +--------------- + +* Add support for OpenSSL 4.0. + [[GitHub #1051]](https://github.com/ruby/openssl/pull/1051) + + Version 3.2.3 ============= diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index a897c86b65..06ed4f6ac3 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -169,6 +169,9 @@ have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h) # added in 3.5.0 have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h) +# added in 4.0.0 +have_func("ASN1_BIT_STRING_set1(NULL, NULL, 0, 0)", "openssl/asn1.h") + Logging::message "=== Checking done. ===\n" # Append flags from environment variables. diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb index 45c150be11..395a720a31 100644 --- a/ext/openssl/lib/openssl/version.rb +++ b/ext/openssl/lib/openssl/version.rb @@ -2,5 +2,5 @@ module OpenSSL # The version string of Ruby/OpenSSL. - VERSION = "4.0.1" + VERSION = "4.0.2" end diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec index c594c6f177..af1775e3b0 100644 --- a/ext/openssl/openssl.gemspec +++ b/ext/openssl/openssl.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |spec| spec.name = "openssl" - spec.version = "4.0.1" + spec.version = "4.0.2" spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"] spec.email = ["ruby-core@ruby-lang.org"] spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby} diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 6592f9ccea..ed3b5b7c0f 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -29,4 +29,27 @@ # define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b) #endif +/* added in 4.0.0 */ +#ifndef HAVE_ASN1_BIT_STRING_SET1 +static inline int +ASN1_BIT_STRING_set1(ASN1_BIT_STRING *bitstr, const uint8_t *data, + size_t length, int unused_bits) +{ + if (length > INT_MAX || !ASN1_STRING_set(bitstr, data, (int)length)) + return 0; + bitstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + bitstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits; + return 1; +} + +static inline int +ASN1_BIT_STRING_get_length(const ASN1_BIT_STRING *bitstr, size_t *length, + int *unused_bits) +{ + *length = bitstr->length; + *unused_bits = bitstr->flags & 0x07; + return 1; +} +#endif + #endif /* _OSSL_OPENSSL_MISSING_H_ */ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 98127fcba0..5716e6f100 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -34,7 +34,11 @@ ossl_##name##_ary2sk0(VALUE ary) \ " of class ##type##"); \ } \ x = dup(val); /* NEED TO DUP */ \ - sk_##type##_push(sk, x); \ + if (!sk_##type##_push(sk, x)) { \ + type##_free(x); \ + sk_##type##_pop_free(sk, type##_free); \ + ossl_raise(eOSSLError, NULL); \ + } \ } \ return (VALUE)sk; \ } \ @@ -523,10 +527,18 @@ ossl_fips_mode_set(VALUE self, VALUE enabled) static VALUE ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) { - const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1); - const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2); - long len1 = RSTRING_LEN(str1); - long len2 = RSTRING_LEN(str2); + const unsigned char *p1; + const unsigned char *p2; + long len1; + long len2; + + StringValue(str1); + StringValue(str2); + + p1 = (const unsigned char *)RSTRING_PTR(str1); + p2 = (const unsigned char *)RSTRING_PTR(str2); + len1 = RSTRING_LEN(str1); + len2 = RSTRING_LEN(str2); if (len1 != len2) { ossl_raise(rb_eArgError, "inputs must be of equal length"); diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 71a87f0463..67c03b7f98 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -130,15 +130,17 @@ asn1integer_to_num(const ASN1_INTEGER *ai) if (!ai) { ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); } + + num = ossl_bn_new(BN_value_one()); + bn = GetBNPtr(num); + if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED) - bn = ASN1_ENUMERATED_to_BN(ai, NULL); + bn = ASN1_ENUMERATED_to_BN(ai, bn); else - bn = ASN1_INTEGER_to_BN(ai, NULL); + bn = ASN1_INTEGER_to_BN(ai, bn); if (!bn) ossl_raise(eOSSLError, NULL); - num = ossl_bn_new(bn); - BN_free(bn); return num; } @@ -226,7 +228,7 @@ obj_to_asn1int(VALUE obj) } static ASN1_BIT_STRING* -obj_to_asn1bstr(VALUE obj, long unused_bits) +obj_to_asn1bstr(VALUE obj, int unused_bits) { ASN1_BIT_STRING *bstr; @@ -234,11 +236,11 @@ obj_to_asn1bstr(VALUE obj, long unused_bits) ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\ "the range 0 to 7"); StringValue(obj); - if(!(bstr = ASN1_BIT_STRING_new())) - ossl_raise(eASN1Error, NULL); - ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj)); - bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ - bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits; + if (!(bstr = ASN1_BIT_STRING_new())) + ossl_raise(eASN1Error, "ASN1_BIT_STRING_new"); + if (!ASN1_BIT_STRING_set1(bstr, (uint8_t *)RSTRING_PTR(obj), + RSTRING_LEN(obj), unused_bits)) + ossl_raise(eASN1Error, "ASN1_BIT_STRING_set1"); return bstr; } @@ -362,22 +364,25 @@ decode_int(unsigned char* der, long length) } static VALUE -decode_bstr(unsigned char* der, long length, long *unused_bits) +decode_bstr(unsigned char* der, long length, int *unused_bits) { ASN1_BIT_STRING *bstr; const unsigned char *p; - long len; + size_t len; VALUE ret; + int state; p = der; - if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - len = bstr->length; - *unused_bits = 0; - if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) - *unused_bits = bstr->flags & 0x07; - ret = rb_str_new((const char *)bstr->data, len); + if (!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) + ossl_raise(eASN1Error, "d2i_ASN1_BIT_STRING"); + if (!ASN1_BIT_STRING_get_length(bstr, &len, unused_bits)) { + ASN1_BIT_STRING_free(bstr); + ossl_raise(eASN1Error, "ASN1_BIT_STRING_get_length"); + } + ret = ossl_str_new((const char *)ASN1_STRING_get0_data(bstr), len, &state); ASN1_BIT_STRING_free(bstr); + if (state) + rb_jump_tag(state); return ret; } @@ -761,7 +766,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, { VALUE value, asn1data; unsigned char *p; - long flag = 0; + int flag = 0; p = *pp; @@ -818,7 +823,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, asn1data = rb_obj_alloc(klass); ossl_asn1_initialize(4, args, asn1data); if(tag == V_ASN1_BIT_STRING){ - rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); + rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag)); } } else { diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index 4edde5091d..cc03c5d5f7 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -32,7 +32,11 @@ ossl_membio2str(BIO *bio) int state; BUF_MEM *buf; - BIO_get_mem_ptr(bio, &buf); + if (BIO_get_mem_ptr(bio, &buf) <= 0) { + BIO_free(bio); + ossl_raise(eOSSLError, "BIO_get_mem_ptr"); + } + ret = ossl_str_new(buf->data, buf->length, &state); BIO_free(bio); if (state) diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index ddb67fcf07..9dd4b466d2 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -922,7 +922,7 @@ ossl_ocspbres_get_status(VALUE self) VALUE ext = rb_ary_new(); int ext_count = OCSP_SINGLERESP_get_ext_count(single); for (int j = 0; j < ext_count; j++) { - X509_EXTENSION *x509ext = OCSP_SINGLERESP_get_ext(single, j); + const X509_EXTENSION *x509ext = OCSP_SINGLERESP_get_ext(single, j); rb_ary_push(ext, ossl_x509ext_new(x509ext)); } rb_ary_push(ary, ext); @@ -1341,7 +1341,6 @@ static VALUE ossl_ocspsres_get_extensions(VALUE self) { OCSP_SINGLERESP *sres; - X509_EXTENSION *ext; int count, i; VALUE ary; @@ -1350,7 +1349,7 @@ ossl_ocspsres_get_extensions(VALUE self) count = OCSP_SINGLERESP_get_ext_count(sres); ary = rb_ary_new2(count); for (i = 0; i < count; i++) { - ext = OCSP_SINGLERESP_get_ext(sres, i); + const X509_EXTENSION *ext = OCSP_SINGLERESP_get_ext(sres, i); rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */ } diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 023361b90f..efba33b752 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -71,7 +71,6 @@ void Init_ossl_dh(void); * EC */ extern VALUE cEC; -VALUE ossl_ec_new(EVP_PKEY *); void Init_ossl_ec(void); #define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \ diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index b31a854a63..393e08acff 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -706,7 +706,7 @@ ossl_ts_resp_get_tsa_certificate(VALUE self) TS_RESP *resp; PKCS7 *p7; PKCS7_SIGNER_INFO *ts_info; - X509 *cert; + const X509 *cert; GetTSResponse(self, resp); if (!(p7 = TS_RESP_get_token(resp))) diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h index d25167ee7b..71932ef1a9 100644 --- a/ext/openssl/ossl_x509.h +++ b/ext/openssl/ossl_x509.h @@ -29,7 +29,7 @@ void Init_ossl_x509(void); */ extern VALUE cX509Attr; -VALUE ossl_x509attr_new(X509_ATTRIBUTE *); +VALUE ossl_x509attr_new(const X509_ATTRIBUTE *); X509_ATTRIBUTE *GetX509AttrPtr(VALUE); void Init_ossl_x509attr(void); @@ -38,7 +38,7 @@ void Init_ossl_x509attr(void); */ extern VALUE cX509Cert; -VALUE ossl_x509_new(X509 *); +VALUE ossl_x509_new(const X509 *); X509 *GetX509CertPtr(VALUE); X509 *DupX509CertPtr(VALUE); void Init_ossl_x509cert(void); @@ -46,7 +46,7 @@ void Init_ossl_x509cert(void); /* * X509CRL */ -VALUE ossl_x509crl_new(X509_CRL *); +VALUE ossl_x509crl_new(const X509_CRL *); X509_CRL *GetX509CRLPtr(VALUE); void Init_ossl_x509crl(void); @@ -55,14 +55,14 @@ void Init_ossl_x509crl(void); */ extern VALUE cX509Ext; -VALUE ossl_x509ext_new(X509_EXTENSION *); +VALUE ossl_x509ext_new(const X509_EXTENSION *); X509_EXTENSION *GetX509ExtPtr(VALUE); void Init_ossl_x509ext(void); /* * X509Name */ -VALUE ossl_x509name_new(X509_NAME *); +VALUE ossl_x509name_new(const X509_NAME *); X509_NAME *GetX509NamePtr(VALUE); void Init_ossl_x509name(void); @@ -77,7 +77,7 @@ void Init_ossl_x509req(void); */ extern VALUE cX509Rev; -VALUE ossl_x509revoked_new(X509_REVOKED *); +VALUE ossl_x509revoked_new(const X509_REVOKED *); X509_REVOKED *DupX509RevokedPtr(VALUE); void Init_ossl_x509revoked(void); diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 4769e56e1e..b0773e7a7d 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -48,13 +48,14 @@ static const rb_data_type_t ossl_x509attr_type = { * Public */ VALUE -ossl_x509attr_new(X509_ATTRIBUTE *attr) +ossl_x509attr_new(const X509_ATTRIBUTE *attr) { X509_ATTRIBUTE *new; VALUE obj; obj = NewX509Attr(cX509Attr); - new = X509_ATTRIBUTE_dup(attr); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_ATTRIBUTE_dup((X509_ATTRIBUTE *)attr); if (!new) ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); SetX509Attr(obj, new); @@ -196,7 +197,7 @@ ossl_x509attr_set_value(VALUE self, VALUE value) ossl_raise(eX509AttrError, "attribute value must be ASN1::Set"); if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */ - ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); + const ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); if (!new_attr) { sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); @@ -240,7 +241,7 @@ ossl_x509attr_get_value(VALUE self) count = X509_ATTRIBUTE_count(attr); for (i = 0; i < count; i++) - sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); + sk_ASN1_TYPE_push(sk, (ASN1_TYPE *)X509_ATTRIBUTE_get0_type(attr, i)); if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) { sk_ASN1_TYPE_free(sk); diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 95679c7d24..de246759ab 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -48,13 +48,14 @@ static const rb_data_type_t ossl_x509_type = { * Public */ VALUE -ossl_x509_new(X509 *x509) +ossl_x509_new(const X509 *x509) { X509 *new; VALUE obj; obj = NewX509(cX509Cert); - new = X509_dup(x509); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_dup((X509 *)x509); if (!new) ossl_raise(eX509CertError, "X509_dup"); SetX509(obj, new); @@ -345,7 +346,7 @@ static VALUE ossl_x509_get_subject(VALUE self) { X509 *x509; - X509_NAME *name; + const X509_NAME *name; GetX509(self, x509); if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ @@ -380,7 +381,7 @@ static VALUE ossl_x509_get_issuer(VALUE self) { X509 *x509; - X509_NAME *name; + const X509_NAME *name; GetX509(self, x509); if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ @@ -603,14 +604,13 @@ ossl_x509_get_extensions(VALUE self) { X509 *x509; int count, i; - X509_EXTENSION *ext; VALUE ary; GetX509(self, x509); count = X509_get_ext_count(x509); ary = rb_ary_new_capa(count); for (i=0; i