diff options
author | Bart de Water <bartdewater@gmail.com> | 2019-10-20 16:18:08 -0400 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2019-11-01 10:52:25 +1300 |
commit | 7a622ed7990af25cbdb6266eba06282f6b26f1a5 (patch) | |
tree | 747d8ca60e9d1b8ac1c84d8badca09283ddf8948 | |
parent | 5ae27f5872d8df4253a524b2e857409eb428adcc (diff) | |
download | ruby-openssl-7a622ed7990af25cbdb6266eba06282f6b26f1a5.tar.gz |
Add helper to retrieve CRL URIs from a certificate
-rw-r--r-- | lib/openssl/x509.rb | 34 | ||||
-rw-r--r-- | test/test_x509cert.rb | 16 |
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/openssl/x509.rb b/lib/openssl/x509.rb index 426f99d2..9632d459 100644 --- a/lib/openssl/x509.rb +++ b/lib/openssl/x509.rb @@ -131,6 +131,39 @@ module OpenSSL key_id.nil? ? nil : key_id.value end end + + module CRLDistributionPoints + include Helpers + + # Get the distributionPoint fullName URI from the certificate's CRL + # distribution points extension, as described in RFC5280 Section + # 4.2.1.13 + # + # Returns an array of strings or nil or raises ASN1::ASN1Error. + def crl_uris + ext = find_extension("crlDistributionPoints") + return nil if ext.nil? + + cdp_asn1 = ASN1.decode(ext.value_der) + if cdp_asn1.tag_class != :UNIVERSAL || cdp_asn1.tag != ASN1::SEQUENCE + raise ASN1::ASN1Error "invalid extension" + end + + crl_uris = cdp_asn1.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| + v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier + end + end + + crl_uris&.map(&:value) + end + end end class Name @@ -257,6 +290,7 @@ module OpenSSL include Marshal include Extension::SubjectKeyIdentifier include Extension::AuthorityKeyIdentifier + include Extension::CRLDistributionPoints def pretty_print(q) q.object_group(self) { diff --git a/test/test_x509cert.rb b/test/test_x509cert.rb index 2df28636..f867b68e 100644 --- a/test/test_x509cert.rb +++ b/test/test_x509cert.rb @@ -97,6 +97,22 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase assert_equal(ee1_exts[i].first, ext.oid) assert_equal(ee1_exts[i].last, ext.critical?) } + assert_nil(ee1_cert.crl_uris) + + ef = OpenSSL::X509::ExtensionFactory.new + ef.config = OpenSSL::Config.parse(<<~_cnf_) + [crlDistPts] + URI.1 = http://www.example.com/crl + URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary + _cnf_ + cdp_cert = generate_cert(@ee1, @rsa1024, 3, ca_cert) + ef.subject_certificate = cdp_cert + cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "@crlDistPts")) + cdp_cert.sign(@rsa2048, "sha256") + assert_equal( + ["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"], + cdp_cert.crl_uris + ) no_exts_cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) assert_equal nil, no_exts_cert.authority_key_identifier |