Package: release.debian.org Severity: normal User: release.debian.org@packages.debian.org Usertags: unblock X-Debbugs-Cc: ruby3.1@packages.debian.org Control: affects -1 + src:ruby3.1 Please unblock package ruby3.1 [ Reason ] This release updates the openssl bindings, fixing a few regressions that have been identified. [ Impact ] Without these changes, at least gitlab doesn't work correctly. [ Tests ] I had uploaded this to experimental some time ago, and the pseudo excuses against unstable showed no regressions. [ Risks ] The changes are contained to the implementatin of a few openssl methods. I think the risk is low. I had also tried updating to the new upstream release 3.1.3, which includes this change, but thought that contained too many non-critical changes. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] I'm also attaching the actual patch included in this upload as it is easier to read than the diff-in-diff in the debdiff. unblock ruby3.1/3.1.2-7
diff --git a/debian/changelog b/debian/changelog
index c6bd035fc..54e474d21 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+ruby3.1 (3.1.2-7) unstable; urgency=medium
+
+ * Upload to unstable
+
+ -- Antonio Terceiro <terceiro@debian.org> Sat, 25 Mar 2023 14:20:34 -0300
+
+ruby3.1 (3.1.2-7~exp) experimental; urgency=medium
+
+ * Update openssl extension to to 3.0.1 (Closes: #1032070)
+
+ -- Antonio Terceiro <terceiro@debian.org> Sun, 05 Mar 2023 17:13:36 -0300
+
ruby3.1 (3.1.2-6) unstable; urgency=medium
* Add missing dependencies for pkg-config test
diff --git a/debian/patches/openssl-3.0.1.patch b/debian/patches/openssl-3.0.1.patch
new file mode 100644
index 000000000..0762cb65e
--- /dev/null
+++ b/debian/patches/openssl-3.0.1.patch
@@ -0,0 +1,495 @@
+From: Antonio Terceiro <terceiro@debian.org>
+Date: Sun, 5 Mar 2023 17:09:05 -0300
+Subject: openssl 3.0.1
+
+This is a combination of several patches for openssl extension that fix
+bugs in its version 3.0.0.
+
+Forwarded: not-needed
+---
+ ext/openssl/History.md | 40 +++++++++++++++++++++++++++++++++
+ ext/openssl/extconf.rb | 5 +++--
+ ext/openssl/lib/openssl/pkey.rb | 8 +++++++
+ ext/openssl/lib/openssl/version.rb | 2 +-
+ ext/openssl/openssl.gemspec | 2 +-
+ ext/openssl/ossl_hmac.c | 8 +++++++
+ ext/openssl/ossl_pkey.c | 46 +++++++++++++++++++++++++++++++++++---
+ ext/openssl/ossl_pkey_ec.c | 4 ++++
+ ext/openssl/ossl_x509cert.c | 6 ++---
+ ext/openssl/ossl_x509crl.c | 6 ++---
+ ext/openssl/ossl_x509req.c | 6 ++---
+ ext/openssl/ossl_x509revoked.c | 6 ++---
+ test/openssl/test_hmac.rb | 8 +++++++
+ test/openssl/test_pkey_dsa.rb | 19 ++++++++++++++++
+ test/openssl/test_pkey_ec.rb | 25 +++++++++++++++++++++
+ test/openssl/test_pkey_rsa.rb | 5 +++++
+ test/openssl/test_ssl.rb | 6 +++++
+ 17 files changed, 183 insertions(+), 19 deletions(-)
+
+diff --git a/ext/openssl/History.md b/ext/openssl/History.md
+index 479ec3b..a4f6bd7 100644
+--- a/ext/openssl/History.md
++++ b/ext/openssl/History.md
+@@ -1,3 +1,27 @@
++Version 3.0.1
++=============
++
++Merged changes in 2.1.4 and 2.2.2. Additionally, the following issues are fixed
++by this release.
++
++Bug fixes
++---------
++
++* Add missing type check in OpenSSL::PKey::PKey#sign's optional parameters.
++ [[GitHub #531]](https://github.com/ruby/openssl/pull/531)
++* Work around OpenSSL 3.0's HMAC issues with a zero-length key.
++ [[GitHub #538]](https://github.com/ruby/openssl/pull/538)
++* Fix a regression in OpenSSL::PKey::DSA.generate's default of 'q' size.
++ [[GitHub #483]](https://github.com/ruby/openssl/issues/483)
++ [[GitHub #539]](https://github.com/ruby/openssl/pull/539)
++* Restore OpenSSL::PKey.read's ability to decode "openssl ecparam -genkey"
++ output when linked against OpenSSL 3.0.
++ [[GitHub #535]](https://github.com/ruby/openssl/pull/535)
++ [[GitHub #540]](https://github.com/ruby/openssl/pull/540)
++* Restore error checks in OpenSSL::PKey::EC#{to_der,to_pem}.
++ [[GitHub #541]](https://github.com/ruby/openssl/pull/541)
++
++
+ Version 3.0.0
+ =============
+
+@@ -100,6 +124,12 @@ Notable changes
+ [[GitHub #342]](https://github.com/ruby/openssl/issues/342)
+
+
++Version 2.2.2
++=============
++
++Merged changes in 2.1.4.
++
++
+ Version 2.2.1
+ =============
+
+@@ -194,6 +224,16 @@ Notable changes
+ [[GitHub #297]](https://github.com/ruby/openssl/pull/297)
+
+
++Version 2.1.4
++=============
++
++Bug fixes
++---------
++
++* Do not use pkg-config if --with-openssl-dir option is specified.
++ [[GitHub #486]](https://github.com/ruby/openssl/pull/486)
++
++
+ Version 2.1.3
+ =============
+
+diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
+index fedcb93..d2d7893 100644
+--- a/ext/openssl/extconf.rb
++++ b/ext/openssl/extconf.rb
+@@ -13,7 +13,7 @@
+
+ require "mkmf"
+
+-dir_config("openssl")
++dir_config_given = dir_config("openssl").any?
+ dir_config("kerberos")
+
+ Logging::message "=== OpenSSL for Ruby configurator ===\n"
+@@ -92,7 +92,7 @@ def find_openssl_library
+ end
+
+ Logging::message "=== Checking for required stuff... ===\n"
+-pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h")
++pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h")
+
+ if !pkg_config_found && !find_openssl_library
+ Logging::message "=== Checking for required stuff failed. ===\n"
+@@ -169,6 +169,7 @@ have_func("SSL_CTX_set_post_handshake_auth")
+
+ # added in 1.1.1
+ have_func("EVP_PKEY_check")
++have_func("EVP_PKEY_new_raw_private_key")
+
+ # added in 3.0.0
+ have_func("SSL_set0_tmp_dh_pkey")
+diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
+index c3e0629..d51f066 100644
+--- a/ext/openssl/lib/openssl/pkey.rb
++++ b/ext/openssl/lib/openssl/pkey.rb
+@@ -167,8 +167,16 @@ module OpenSSL::PKey
+ # +size+::
+ # The desired key size in bits.
+ def generate(size, &blk)
++ # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
++ # (2048,256), and (3072,256).
++ #
++ # q size is derived here with compatibility with
++ # DSA_generator_parameters_ex() which previous versions of ruby/openssl
++ # used to call.
++ qsize = size >= 2048 ? 256 : 160
+ dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
+ "dsa_paramgen_bits" => size,
++ "dsa_paramgen_q_bits" => qsize,
+ }, &blk)
+ OpenSSL::PKey.generate_key(dsaparams)
+ end
+diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
+index 5e60604..b9e8444 100644
+--- a/ext/openssl/lib/openssl/version.rb
++++ b/ext/openssl/lib/openssl/version.rb
+@@ -1,5 +1,5 @@
+ # frozen_string_literal: true
+
+ module OpenSSL
+- VERSION = "3.0.0"
++ VERSION = "3.0.1"
+ end
+diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
+index c6cd818..1c13505 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 = "3.0.0"
++ spec.version = "3.0.1"
+ spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
+ spec.email = ["ruby-core@ruby-lang.org"]
+ spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.}
+diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
+index bfe3a74..1a5f471 100644
+--- a/ext/openssl/ossl_hmac.c
++++ b/ext/openssl/ossl_hmac.c
+@@ -97,11 +97,19 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
+
+ GetHMAC(self, ctx);
+ StringValue(key);
++#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
++ pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
++ (unsigned char *)RSTRING_PTR(key),
++ RSTRING_LENINT(key));
++ if (!pkey)
++ ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
++#else
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
+ (unsigned char *)RSTRING_PTR(key),
+ RSTRING_LENINT(key));
+ if (!pkey)
+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
++#endif
+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
+ NULL, pkey) != 1) {
+ EVP_PKEY_free(pkey);
+diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
+index 2a4835a..ee143d6 100644
+--- a/ext/openssl/ossl_pkey.c
++++ b/ext/openssl/ossl_pkey.c
+@@ -99,17 +99,56 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
+ /* First check DER */
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
+ goto out;
++ OSSL_BIO_reset(bio);
+
+ /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */
+- OSSL_BIO_reset(bio);
+ if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
+ goto out;
+- while (OSSL_DECODER_from_bio(dctx, bio) != 1) {
+- if (BIO_eof(bio))
++ /*
++ * First check for private key formats. This is to keep compatibility with
++ * ruby/openssl < 3.0 which decoded the following as a private key.
++ *
++ * $ openssl ecparam -name prime256v1 -genkey -outform PEM
++ * -----BEGIN EC PARAMETERS-----
++ * BggqhkjOPQMBBw==
++ * -----END EC PARAMETERS-----
++ * -----BEGIN EC PRIVATE KEY-----
++ * MHcCAQEEIAG8ugBbA5MHkqnZ9ujQF93OyUfL9tk8sxqM5Wv5tKg5oAoGCCqGSM49
++ * AwEHoUQDQgAEVcjhJfkwqh5C7kGuhAf8XaAjVuG5ADwb5ayg/cJijCgs+GcXeedj
++ * 86avKpGH84DXUlB23C/kPt+6fXYlitUmXQ==
++ * -----END EC PRIVATE KEY-----
++ *
++ * While the first PEM block is a proper encoding of ECParameters, thus
++ * OSSL_DECODER_from_bio() would pick it up, ruby/openssl used to return
++ * the latter instead. Existing applications expect this behavior.
++ *
++ * Note that normally, the input is supposed to contain a single decodable
++ * PEM block only, so this special handling should not create a new problem.
++ */
++ OSSL_DECODER_CTX_set_selection(dctx, EVP_PKEY_KEYPAIR);
++ while (1) {
++ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
+ goto out;
++ if (BIO_eof(bio))
++ break;
+ pos2 = BIO_tell(bio);
+ if (pos2 < 0 || pos2 <= pos)
++ break;
++ ossl_clear_error();
++ pos = pos2;
++ }
++
++ OSSL_BIO_reset(bio);
++ OSSL_DECODER_CTX_set_selection(dctx, 0);
++ while (1) {
++ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
+ goto out;
++ if (BIO_eof(bio))
++ break;
++ pos2 = BIO_tell(bio);
++ if (pos2 < 0 || pos2 <= pos)
++ break;
++ ossl_clear_error();
+ pos = pos2;
+ }
+
+@@ -200,6 +239,7 @@ static VALUE
+ pkey_ctx_apply_options0(VALUE args_v)
+ {
+ VALUE *args = (VALUE *)args_v;
++ Check_Type(args[1], T_HASH);
+
+ rb_block_call(args[1], rb_intern("each"), 0, NULL,
+ pkey_ctx_apply_options_i, args[0]);
+diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
+index dee2154..06d59c2 100644
+--- a/ext/openssl/ossl_pkey_ec.c
++++ b/ext/openssl/ossl_pkey_ec.c
+@@ -414,6 +414,8 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
+ EC_KEY *ec;
+
+ GetEC(self, ec);
++ if (EC_KEY_get0_public_key(ec) == NULL)
++ ossl_raise(eECError, "can't export - no public key set");
+ if (EC_KEY_get0_private_key(ec))
+ return ossl_pkey_export_traditional(argc, argv, self, 0);
+ else
+@@ -432,6 +434,8 @@ ossl_ec_key_to_der(VALUE self)
+ EC_KEY *ec;
+
+ GetEC(self, ec);
++ if (EC_KEY_get0_public_key(ec) == NULL)
++ ossl_raise(eECError, "can't export - no public key set");
+ if (EC_KEY_get0_private_key(ec))
+ return ossl_pkey_export_traditional(0, NULL, self, 1);
+ else
+diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
+index 996f184..9443541 100644
+--- a/ext/openssl/ossl_x509cert.c
++++ b/ext/openssl/ossl_x509cert.c
+@@ -642,12 +642,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
+ OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
+ }
+ GetX509(self, x509);
+- while ((ext = X509_delete_ext(x509, 0)))
+- X509_EXTENSION_free(ext);
++ for (i = X509_get_ext_count(x509); i > 0; i--)
++ X509_EXTENSION_free(X509_delete_ext(x509, 0));
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
+ if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
+- ossl_raise(eX509CertError, NULL);
++ ossl_raise(eX509CertError, "X509_add_ext");
+ }
+ }
+
+diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
+index 863f028..6c1d915 100644
+--- a/ext/openssl/ossl_x509crl.c
++++ b/ext/openssl/ossl_x509crl.c
+@@ -474,12 +474,12 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary)
+ OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
+ }
+ GetX509CRL(self, crl);
+- while ((ext = X509_CRL_delete_ext(crl, 0)))
+- X509_EXTENSION_free(ext);
++ for (i = X509_CRL_get_ext_count(crl); i > 0; i--)
++ X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0));
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */
+ if (!X509_CRL_add_ext(crl, ext, -1)) {
+- ossl_raise(eX509CRLError, NULL);
++ ossl_raise(eX509CRLError, "X509_CRL_add_ext");
+ }
+ }
+
+diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
+index 6eb91e9..77a7d3f 100644
+--- a/ext/openssl/ossl_x509req.c
++++ b/ext/openssl/ossl_x509req.c
+@@ -380,13 +380,13 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary)
+ OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr);
+ }
+ GetX509Req(self, req);
+- while ((attr = X509_REQ_delete_attr(req, 0)))
+- X509_ATTRIBUTE_free(attr);
++ for (i = X509_REQ_get_attr_count(req); i > 0; i--)
++ X509_ATTRIBUTE_free(X509_REQ_delete_attr(req, 0));
+ for (i=0;i<RARRAY_LEN(ary); i++) {
+ item = RARRAY_AREF(ary, i);
+ attr = GetX509AttrPtr(item);
+ if (!X509_REQ_add1_attr(req, attr)) {
+- ossl_raise(eX509ReqError, NULL);
++ ossl_raise(eX509ReqError, "X509_REQ_add1_attr");
+ }
+ }
+ return ary;
+diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c
+index 5fe6853..10b8aa4 100644
+--- a/ext/openssl/ossl_x509revoked.c
++++ b/ext/openssl/ossl_x509revoked.c
+@@ -223,13 +223,13 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
+ OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
+ }
+ GetX509Rev(self, rev);
+- while ((ext = X509_REVOKED_delete_ext(rev, 0)))
+- X509_EXTENSION_free(ext);
++ for (i = X509_REVOKED_get_ext_count(rev); i > 0; i--)
++ X509_EXTENSION_free(X509_REVOKED_delete_ext(rev, 0));
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ item = RARRAY_AREF(ary, i);
+ ext = GetX509ExtPtr(item);
+ if(!X509_REVOKED_add_ext(rev, ext, -1)) {
+- ossl_raise(eX509RevError, NULL);
++ ossl_raise(eX509RevError, "X509_REVOKED_add_ext");
+ }
+ }
+
+diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
+index 47cb371..08b888d 100644
+--- a/test/openssl/test_hmac.rb
++++ b/test/openssl/test_hmac.rb
+@@ -63,6 +63,14 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
+ b64digest = OpenSSL::HMAC.base64digest("MD5", key, "Hi There")
+ assert_equal "kpRyejY4uxwT9I74FYv8nQ==", b64digest
+ end
++
++ def test_zero_length_key
++ # Empty string as the key
++ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "\0"*32, "test")
++ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
++ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "", "test")
++ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
++ end
+ end
+
+ end
+diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
+index 726b7db..de6aa63 100644
+--- a/test/openssl/test_pkey_dsa.rb
++++ b/test/openssl/test_pkey_dsa.rb
+@@ -28,6 +28,25 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
+ end
+ end
+
++ def test_generate
++ # DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the
++ # size of q according to the size of p
++ key1024 = OpenSSL::PKey::DSA.generate(1024)
++ assert_predicate key1024, :private?
++ assert_equal 1024, key1024.p.num_bits
++ assert_equal 160, key1024.q.num_bits
++
++ key2048 = OpenSSL::PKey::DSA.generate(2048)
++ assert_equal 2048, key2048.p.num_bits
++ assert_equal 256, key2048.q.num_bits
++
++ if ENV["OSSL_TEST_ALL"] == "1" # slow
++ key3072 = OpenSSL::PKey::DSA.generate(3072)
++ assert_equal 3072, key3072.p.num_bits
++ assert_equal 256, key3072.q.num_bits
++ end
++ end
++
+ def test_sign_verify
+ dsa512 = Fixtures.pkey("dsa512")
+ data = "Sign me!"
+diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
+index ffe5a94..9a4818d 100644
+--- a/test/openssl/test_pkey_ec.rb
++++ b/test/openssl/test_pkey_ec.rb
+@@ -61,8 +61,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
+ def test_generate_key
+ ec = OpenSSL::PKey::EC.new("prime256v1")
+ assert_equal false, ec.private?
++ assert_raise(OpenSSL::PKey::ECError) { ec.to_der }
+ ec.generate_key!
+ assert_equal true, ec.private?
++ assert_nothing_raised { ec.to_der }
+ end if !openssl?(3, 0, 0)
+
+ def test_marshal
+@@ -199,6 +201,29 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
+ assert_equal pem, p256.export
+ end
+
++ def test_ECPrivateKey_with_parameters
++ p256 = Fixtures.pkey("p256")
++
++ # The format used by "openssl ecparam -name prime256v1 -genkey -outform PEM"
++ #
++ # "EC PARAMETERS" block should be ignored if it is followed by an
++ # "EC PRIVATE KEY" block
++ in_pem = <<~EOF
++ -----BEGIN EC PARAMETERS-----
++ BggqhkjOPQMBBw==
++ -----END EC PARAMETERS-----
++ -----BEGIN EC PRIVATE KEY-----
++ MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
++ AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
++ CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
++ -----END EC PRIVATE KEY-----
++ EOF
++
++ key = OpenSSL::PKey::EC.new(in_pem)
++ assert_same_ec p256, key
++ assert_equal p256.to_der, key.to_der
++ end
++
+ def test_ECPrivateKey_encrypted
+ p256 = Fixtures.pkey("p256")
+ # key = abcdef
+diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
+index 4bb39ed..fa84b76 100644
+--- a/test/openssl/test_pkey_rsa.rb
++++ b/test/openssl/test_pkey_rsa.rb
+@@ -108,6 +108,11 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
+ salt_length: 20, mgf1_hash: "SHA1")
+ # Defaults to PKCS #1 v1.5 padding => verification failure
+ assert_equal false, key.verify("SHA256", sig_pss, data)
++
++ # option type check
++ assert_raise_with_message(TypeError, /expected Hash/) {
++ key.sign("SHA256", data, ["x"])
++ }
+ end
+
+ def test_sign_verify_raw
+diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
+index a7607da..39964bf 100644
+--- a/test/openssl/test_ssl.rb
++++ b/test/openssl/test_ssl.rb
+@@ -676,10 +676,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
+ # buzz.example.net, respectively). ...
+ assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+ create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com'))
++
++ # LibreSSL 3.5.0+ doesn't support other wildcard certificates
++ # (it isn't required to, as RFC states MAY, not MUST)
++ return if libressl?(3, 5, 0)
++
+ assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+ create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com'))
+ assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+ create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com'))
++
+ # Section 6.4.3 of RFC6125 states that client should NOT match identifier
+ # where wildcard is other than left-most label.
+ #
diff --git a/debian/patches/series b/debian/patches/series
index e2febb232..50eaef8ce 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ Fallback-PKG_CONFIG-to-the-configured-pkg-config-always.patch
Honor-the-tool-prefix-against-pkg-config.patch
Fix-for-tzdata-2022g.patch
Merge-CGI-0.3.5.patch
+openssl-3.0.1.patch
From: Antonio Terceiro <terceiro@debian.org>
Date: Sun, 5 Mar 2023 17:09:05 -0300
Subject: openssl 3.0.1
This is a combination of several patches for openssl extension that fix
bugs in its version 3.0.0.
Forwarded: not-needed
---
ext/openssl/History.md | 40 +++++++++++++++++++++++++++++++++
ext/openssl/extconf.rb | 5 +++--
ext/openssl/lib/openssl/pkey.rb | 8 +++++++
ext/openssl/lib/openssl/version.rb | 2 +-
ext/openssl/openssl.gemspec | 2 +-
ext/openssl/ossl_hmac.c | 8 +++++++
ext/openssl/ossl_pkey.c | 46 +++++++++++++++++++++++++++++++++++---
ext/openssl/ossl_pkey_ec.c | 4 ++++
ext/openssl/ossl_x509cert.c | 6 ++---
ext/openssl/ossl_x509crl.c | 6 ++---
ext/openssl/ossl_x509req.c | 6 ++---
ext/openssl/ossl_x509revoked.c | 6 ++---
test/openssl/test_hmac.rb | 8 +++++++
test/openssl/test_pkey_dsa.rb | 19 ++++++++++++++++
test/openssl/test_pkey_ec.rb | 25 +++++++++++++++++++++
test/openssl/test_pkey_rsa.rb | 5 +++++
test/openssl/test_ssl.rb | 6 +++++
17 files changed, 183 insertions(+), 19 deletions(-)
diff --git a/ext/openssl/History.md b/ext/openssl/History.md
index 479ec3b..a4f6bd7 100644
--- a/ext/openssl/History.md
+++ b/ext/openssl/History.md
@@ -1,3 +1,27 @@
+Version 3.0.1
+=============
+
+Merged changes in 2.1.4 and 2.2.2. Additionally, the following issues are fixed
+by this release.
+
+Bug fixes
+---------
+
+* Add missing type check in OpenSSL::PKey::PKey#sign's optional parameters.
+ [[GitHub #531]](https://github.com/ruby/openssl/pull/531)
+* Work around OpenSSL 3.0's HMAC issues with a zero-length key.
+ [[GitHub #538]](https://github.com/ruby/openssl/pull/538)
+* Fix a regression in OpenSSL::PKey::DSA.generate's default of 'q' size.
+ [[GitHub #483]](https://github.com/ruby/openssl/issues/483)
+ [[GitHub #539]](https://github.com/ruby/openssl/pull/539)
+* Restore OpenSSL::PKey.read's ability to decode "openssl ecparam -genkey"
+ output when linked against OpenSSL 3.0.
+ [[GitHub #535]](https://github.com/ruby/openssl/pull/535)
+ [[GitHub #540]](https://github.com/ruby/openssl/pull/540)
+* Restore error checks in OpenSSL::PKey::EC#{to_der,to_pem}.
+ [[GitHub #541]](https://github.com/ruby/openssl/pull/541)
+
+
Version 3.0.0
=============
@@ -100,6 +124,12 @@ Notable changes
[[GitHub #342]](https://github.com/ruby/openssl/issues/342)
+Version 2.2.2
+=============
+
+Merged changes in 2.1.4.
+
+
Version 2.2.1
=============
@@ -194,6 +224,16 @@ Notable changes
[[GitHub #297]](https://github.com/ruby/openssl/pull/297)
+Version 2.1.4
+=============
+
+Bug fixes
+---------
+
+* Do not use pkg-config if --with-openssl-dir option is specified.
+ [[GitHub #486]](https://github.com/ruby/openssl/pull/486)
+
+
Version 2.1.3
=============
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index fedcb93..d2d7893 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -13,7 +13,7 @@
require "mkmf"
-dir_config("openssl")
+dir_config_given = dir_config("openssl").any?
dir_config("kerberos")
Logging::message "=== OpenSSL for Ruby configurator ===\n"
@@ -92,7 +92,7 @@ def find_openssl_library
end
Logging::message "=== Checking for required stuff... ===\n"
-pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h")
+pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h")
if !pkg_config_found && !find_openssl_library
Logging::message "=== Checking for required stuff failed. ===\n"
@@ -169,6 +169,7 @@ have_func("SSL_CTX_set_post_handshake_auth")
# added in 1.1.1
have_func("EVP_PKEY_check")
+have_func("EVP_PKEY_new_raw_private_key")
# added in 3.0.0
have_func("SSL_set0_tmp_dh_pkey")
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index c3e0629..d51f066 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -167,8 +167,16 @@ module OpenSSL::PKey
# +size+::
# The desired key size in bits.
def generate(size, &blk)
+ # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
+ # (2048,256), and (3072,256).
+ #
+ # q size is derived here with compatibility with
+ # DSA_generator_parameters_ex() which previous versions of ruby/openssl
+ # used to call.
+ qsize = size >= 2048 ? 256 : 160
dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
"dsa_paramgen_bits" => size,
+ "dsa_paramgen_q_bits" => qsize,
}, &blk)
OpenSSL::PKey.generate_key(dsaparams)
end
diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
index 5e60604..b9e8444 100644
--- a/ext/openssl/lib/openssl/version.rb
+++ b/ext/openssl/lib/openssl/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module OpenSSL
- VERSION = "3.0.0"
+ VERSION = "3.0.1"
end
diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
index c6cd818..1c13505 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 = "3.0.0"
+ spec.version = "3.0.1"
spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
spec.email = ["ruby-core@ruby-lang.org"]
spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.}
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index bfe3a74..1a5f471 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -97,11 +97,19 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
GetHMAC(self, ctx);
StringValue(key);
+#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
+ pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
+ (unsigned char *)RSTRING_PTR(key),
+ RSTRING_LENINT(key));
+ if (!pkey)
+ ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
+#else
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
(unsigned char *)RSTRING_PTR(key),
RSTRING_LENINT(key));
if (!pkey)
ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
+#endif
if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
NULL, pkey) != 1) {
EVP_PKEY_free(pkey);
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 2a4835a..ee143d6 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -99,17 +99,56 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
/* First check DER */
if (OSSL_DECODER_from_bio(dctx, bio) == 1)
goto out;
+ OSSL_BIO_reset(bio);
/* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */
- OSSL_BIO_reset(bio);
if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
goto out;
- while (OSSL_DECODER_from_bio(dctx, bio) != 1) {
- if (BIO_eof(bio))
+ /*
+ * First check for private key formats. This is to keep compatibility with
+ * ruby/openssl < 3.0 which decoded the following as a private key.
+ *
+ * $ openssl ecparam -name prime256v1 -genkey -outform PEM
+ * -----BEGIN EC PARAMETERS-----
+ * BggqhkjOPQMBBw==
+ * -----END EC PARAMETERS-----
+ * -----BEGIN EC PRIVATE KEY-----
+ * MHcCAQEEIAG8ugBbA5MHkqnZ9ujQF93OyUfL9tk8sxqM5Wv5tKg5oAoGCCqGSM49
+ * AwEHoUQDQgAEVcjhJfkwqh5C7kGuhAf8XaAjVuG5ADwb5ayg/cJijCgs+GcXeedj
+ * 86avKpGH84DXUlB23C/kPt+6fXYlitUmXQ==
+ * -----END EC PRIVATE KEY-----
+ *
+ * While the first PEM block is a proper encoding of ECParameters, thus
+ * OSSL_DECODER_from_bio() would pick it up, ruby/openssl used to return
+ * the latter instead. Existing applications expect this behavior.
+ *
+ * Note that normally, the input is supposed to contain a single decodable
+ * PEM block only, so this special handling should not create a new problem.
+ */
+ OSSL_DECODER_CTX_set_selection(dctx, EVP_PKEY_KEYPAIR);
+ while (1) {
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
goto out;
+ if (BIO_eof(bio))
+ break;
pos2 = BIO_tell(bio);
if (pos2 < 0 || pos2 <= pos)
+ break;
+ ossl_clear_error();
+ pos = pos2;
+ }
+
+ OSSL_BIO_reset(bio);
+ OSSL_DECODER_CTX_set_selection(dctx, 0);
+ while (1) {
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
goto out;
+ if (BIO_eof(bio))
+ break;
+ pos2 = BIO_tell(bio);
+ if (pos2 < 0 || pos2 <= pos)
+ break;
+ ossl_clear_error();
pos = pos2;
}
@@ -200,6 +239,7 @@ static VALUE
pkey_ctx_apply_options0(VALUE args_v)
{
VALUE *args = (VALUE *)args_v;
+ Check_Type(args[1], T_HASH);
rb_block_call(args[1], rb_intern("each"), 0, NULL,
pkey_ctx_apply_options_i, args[0]);
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index dee2154..06d59c2 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -414,6 +414,8 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
EC_KEY *ec;
GetEC(self, ec);
+ if (EC_KEY_get0_public_key(ec) == NULL)
+ ossl_raise(eECError, "can't export - no public key set");
if (EC_KEY_get0_private_key(ec))
return ossl_pkey_export_traditional(argc, argv, self, 0);
else
@@ -432,6 +434,8 @@ ossl_ec_key_to_der(VALUE self)
EC_KEY *ec;
GetEC(self, ec);
+ if (EC_KEY_get0_public_key(ec) == NULL)
+ ossl_raise(eECError, "can't export - no public key set");
if (EC_KEY_get0_private_key(ec))
return ossl_pkey_export_traditional(0, NULL, self, 1);
else
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index 996f184..9443541 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -642,12 +642,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
}
GetX509(self, x509);
- while ((ext = X509_delete_ext(x509, 0)))
- X509_EXTENSION_free(ext);
+ for (i = X509_get_ext_count(x509); i > 0; i--)
+ X509_EXTENSION_free(X509_delete_ext(x509, 0));
for (i=0; i<RARRAY_LEN(ary); i++) {
ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
- ossl_raise(eX509CertError, NULL);
+ ossl_raise(eX509CertError, "X509_add_ext");
}
}
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index 863f028..6c1d915 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -474,12 +474,12 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
}
GetX509CRL(self, crl);
- while ((ext = X509_CRL_delete_ext(crl, 0)))
- X509_EXTENSION_free(ext);
+ for (i = X509_CRL_get_ext_count(crl); i > 0; i--)
+ X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0));
for (i=0; i<RARRAY_LEN(ary); i++) {
ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */
if (!X509_CRL_add_ext(crl, ext, -1)) {
- ossl_raise(eX509CRLError, NULL);
+ ossl_raise(eX509CRLError, "X509_CRL_add_ext");
}
}
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index 6eb91e9..77a7d3f 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -380,13 +380,13 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr);
}
GetX509Req(self, req);
- while ((attr = X509_REQ_delete_attr(req, 0)))
- X509_ATTRIBUTE_free(attr);
+ for (i = X509_REQ_get_attr_count(req); i > 0; i--)
+ X509_ATTRIBUTE_free(X509_REQ_delete_attr(req, 0));
for (i=0;i<RARRAY_LEN(ary); i++) {
item = RARRAY_AREF(ary, i);
attr = GetX509AttrPtr(item);
if (!X509_REQ_add1_attr(req, attr)) {
- ossl_raise(eX509ReqError, NULL);
+ ossl_raise(eX509ReqError, "X509_REQ_add1_attr");
}
}
return ary;
diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c
index 5fe6853..10b8aa4 100644
--- a/ext/openssl/ossl_x509revoked.c
+++ b/ext/openssl/ossl_x509revoked.c
@@ -223,13 +223,13 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
}
GetX509Rev(self, rev);
- while ((ext = X509_REVOKED_delete_ext(rev, 0)))
- X509_EXTENSION_free(ext);
+ for (i = X509_REVOKED_get_ext_count(rev); i > 0; i--)
+ X509_EXTENSION_free(X509_REVOKED_delete_ext(rev, 0));
for (i=0; i<RARRAY_LEN(ary); i++) {
item = RARRAY_AREF(ary, i);
ext = GetX509ExtPtr(item);
if(!X509_REVOKED_add_ext(rev, ext, -1)) {
- ossl_raise(eX509RevError, NULL);
+ ossl_raise(eX509RevError, "X509_REVOKED_add_ext");
}
}
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
index 47cb371..08b888d 100644
--- a/test/openssl/test_hmac.rb
+++ b/test/openssl/test_hmac.rb
@@ -63,6 +63,14 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
b64digest = OpenSSL::HMAC.base64digest("MD5", key, "Hi There")
assert_equal "kpRyejY4uxwT9I74FYv8nQ==", b64digest
end
+
+ def test_zero_length_key
+ # Empty string as the key
+ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "\0"*32, "test")
+ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
+ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "", "test")
+ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
+ end
end
end
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 726b7db..de6aa63 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -28,6 +28,25 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
end
+ def test_generate
+ # DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the
+ # size of q according to the size of p
+ key1024 = OpenSSL::PKey::DSA.generate(1024)
+ assert_predicate key1024, :private?
+ assert_equal 1024, key1024.p.num_bits
+ assert_equal 160, key1024.q.num_bits
+
+ key2048 = OpenSSL::PKey::DSA.generate(2048)
+ assert_equal 2048, key2048.p.num_bits
+ assert_equal 256, key2048.q.num_bits
+
+ if ENV["OSSL_TEST_ALL"] == "1" # slow
+ key3072 = OpenSSL::PKey::DSA.generate(3072)
+ assert_equal 3072, key3072.p.num_bits
+ assert_equal 256, key3072.q.num_bits
+ end
+ end
+
def test_sign_verify
dsa512 = Fixtures.pkey("dsa512")
data = "Sign me!"
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index ffe5a94..9a4818d 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -61,8 +61,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
def test_generate_key
ec = OpenSSL::PKey::EC.new("prime256v1")
assert_equal false, ec.private?
+ assert_raise(OpenSSL::PKey::ECError) { ec.to_der }
ec.generate_key!
assert_equal true, ec.private?
+ assert_nothing_raised { ec.to_der }
end if !openssl?(3, 0, 0)
def test_marshal
@@ -199,6 +201,29 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal pem, p256.export
end
+ def test_ECPrivateKey_with_parameters
+ p256 = Fixtures.pkey("p256")
+
+ # The format used by "openssl ecparam -name prime256v1 -genkey -outform PEM"
+ #
+ # "EC PARAMETERS" block should be ignored if it is followed by an
+ # "EC PRIVATE KEY" block
+ in_pem = <<~EOF
+ -----BEGIN EC PARAMETERS-----
+ BggqhkjOPQMBBw==
+ -----END EC PARAMETERS-----
+ -----BEGIN EC PRIVATE KEY-----
+ MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
+ AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
+ CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
+ -----END EC PRIVATE KEY-----
+ EOF
+
+ key = OpenSSL::PKey::EC.new(in_pem)
+ assert_same_ec p256, key
+ assert_equal p256.to_der, key.to_der
+ end
+
def test_ECPrivateKey_encrypted
p256 = Fixtures.pkey("p256")
# key = abcdef
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 4bb39ed..fa84b76 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -108,6 +108,11 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
salt_length: 20, mgf1_hash: "SHA1")
# Defaults to PKCS #1 v1.5 padding => verification failure
assert_equal false, key.verify("SHA256", sig_pss, data)
+
+ # option type check
+ assert_raise_with_message(TypeError, /expected Hash/) {
+ key.sign("SHA256", data, ["x"])
+ }
end
def test_sign_verify_raw
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index a7607da..39964bf 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -676,10 +676,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# buzz.example.net, respectively). ...
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com'))
+
+ # LibreSSL 3.5.0+ doesn't support other wildcard certificates
+ # (it isn't required to, as RFC states MAY, not MUST)
+ return if libressl?(3, 5, 0)
+
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com'))
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com'))
+
# Section 6.4.3 of RFC6125 states that client should NOT match identifier
# where wildcard is other than left-most label.
#
Attachment:
signature.asc
Description: PGP signature