aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2024-07-09 21:15:11 +0900
committerKazuki Yamaguchi <k@rhe.jp>2024-07-09 21:15:11 +0900
commit0b3f7c173219a8abf508e9b55de66b527a75fdf5 (patch)
tree0f93ffdb673e90d64f882c726d32b50e78f553b1
parentb91aeb7492aab582e091141706efac2797a916aa (diff)
downloadruby-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.rb4
-rw-r--r--test/openssl/test_x509cert.rb33
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)