diff options
author | Kazuki Yamaguchi <[email protected]> | 2024-07-09 21:15:11 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2024-11-14 11:21:39 +0900 |
commit | 419fb2f3b94d8b7ccb462177667070e13ed9df8a (patch) | |
tree | 851af2166f8b30c72d9d59a2a4b9e9d2b24f9c5f | |
parent | 97be56fc62e942d882ad12ea299240415cdf404f (diff) |
[ruby/openssl] x509: fix handling of multiple URIs in Certificate#crl_uris
The implementation of OpenSSL::X509::Certificate#crl_uris makes the
assumption that each DistributionPoint in the CRL distribution points
extension contains a single general name of type URI. This is not
guaranteed by RFC 5280. A DistributionPoint may contain zero or more
than one URIs.
Let's include all URIs found in the extension. If only non-URI pointers
are found, return nil.
Fixes: https://github.com/ruby/openssl/issues/775
https://github.com/ruby/openssl/commit/71f4fef2fa
-rw-r--r-- | ext/openssl/lib/openssl/x509.rb | 10 | ||||
-rw-r--r-- | test/openssl/test_x509cert.rb | 33 |
2 files changed, 38 insertions, 5 deletions
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb index b66727420e..6459d37b12 100644 --- a/ext/openssl/lib/openssl/x509.rb +++ b/ext/openssl/lib/openssl/x509.rb @@ -122,8 +122,8 @@ module OpenSSL include Helpers # Get the distributionPoint fullName URI from the certificate's CRL - # distribution points extension, as described in RFC5280 Section - # 4.2.1.13 + # distribution points extension, as described in RFC 5280 Section + # 4.2.1.13. # # Returns an array of strings or nil or raises ASN1::ASN1Error. def crl_uris @@ -135,19 +135,19 @@ module OpenSSL raise ASN1::ASN1Error, "invalid extension" end - crl_uris = cdp_asn1.map do |crl_distribution_point| + crl_uris = cdp_asn1.flat_map do |crl_distribution_point| distribution_point = crl_distribution_point.value.find do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 end full_name = distribution_point&.value&.find do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 end - full_name&.value&.find do |v| + full_name&.value&.select do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier end end - crl_uris&.map(&:value) + crl_uris.empty? ? nil : crl_uris.map(&:value) end end diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb index 4263569439..76359552e6 100644 --- a/test/openssl/test_x509cert.rb +++ b/test/openssl/test_x509cert.rb @@ -151,6 +151,39 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase ) end + def test_crl_uris_multiple_general_names + # Single DistributionPoint contains multiple general names of type URI + ef = OpenSSL::X509::ExtensionFactory.new + ef.config = OpenSSL::Config.parse(<<~_cnf_) + [crlDistPts_section] + fullname = URI:http://www.example.com/crl, URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary + _cnf_ + cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil) + ef.subject_certificate = cdp_cert + cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section")) + cdp_cert.sign(@rsa2048, "sha256") + assert_equal( + ["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"], + cdp_cert.crl_uris + ) + end + + def test_crl_uris_no_uris + # The only DistributionPointName is a directoryName + ef = OpenSSL::X509::ExtensionFactory.new + ef.config = OpenSSL::Config.parse(<<~_cnf_) + [crlDistPts_section] + fullname = dirName:dirname_section + [dirname_section] + CN = dirname + _cnf_ + cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil) + ef.subject_certificate = cdp_cert + cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section")) + cdp_cert.sign(@rsa2048, "sha256") + assert_nil(cdp_cert.crl_uris) + end + def test_aia_missing cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil) assert_nil(cert.ca_issuer_uris) |