diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2024-07-09 21:15:11 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2024-07-09 21:15:11 +0900 |
commit | 0b3f7c173219a8abf508e9b55de66b527a75fdf5 (patch) | |
tree | 0f93ffdb673e90d64f882c726d32b50e78f553b1 | |
parent | b91aeb7492aab582e091141706efac2797a916aa (diff) | |
download | ruby-openssl-ky/x509cert-crl_uris-fix-nil.tar.gz |
x509: fix handling of multiple URIs in Certificate#crl_urisky/x509cert-crl_uris-fix-nil
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 only contains something
other than a URI, or more than one URI.
Let's include all URIs seen in the extension. If only non-URI pointers
are found, return an empty array.
-rw-r--r-- | lib/openssl/x509.rb | 4 | ||||
-rw-r--r-- | test/openssl/test_x509cert.rb | 33 |
2 files changed, 35 insertions, 2 deletions
diff --git a/lib/openssl/x509.rb b/lib/openssl/x509.rb index b6672742..d5d16cc7 100644 --- a/lib/openssl/x509.rb +++ b/lib/openssl/x509.rb @@ -135,14 +135,14 @@ 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 diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb index 6ad1bcab..8e1cc799 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 DistributionPointName contains multiple general names + 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 + # 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_equal([], cdp_cert.crl_uris) + end + def test_aia_no_aia cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil) assert_nil(cert.ca_issuer_uris) |