Class: AuthorityChecker
- Inherits:
-
Object
- Object
- AuthorityChecker
- Defined in:
- lib/sslackey/authority_checker.rb
Constant Summary collapse
- REVOCATION_RESPONSES =
[:successful, :unknown, :revoked]
Instance Attribute Summary collapse
-
#trusted_certs_file_path ⇒ Object
Returns the value of attribute trusted_certs_file_path.
Class Method Summary collapse
- .parse_authority_info_access(ocsp_string) ⇒ Object
- .parse_crl_distribution_points(crl_string) ⇒ Object
Instance Method Summary collapse
- #create_response_file(file_name) ⇒ Object
- #fetch_crl_content(crl_url) ⇒ Object
- #generate_ocsp_response(issuer_file_path, certificate_file_path, output_file_path, ocsp_url) ⇒ Object
-
#initialize(trusted_certs_path) ⇒ AuthorityChecker
constructor
A new instance of AuthorityChecker.
- #perform_crl_check(certificate, crl_url) ⇒ Object
- #perform_ocsp_check(certificate, issuer_certificate, ocsp_url) ⇒ Object
- #read_ocsp_response(output_file) ⇒ Object
- #validate(certificate, issuer_certificate) ⇒ Object
- #write_certificate_file(certificate, file_name) ⇒ Object
Constructor Details
#initialize(trusted_certs_path) ⇒ AuthorityChecker
Returns a new instance of AuthorityChecker.
6 7 8 9 |
# File 'lib/sslackey/authority_checker.rb', line 6 def initialize(trusted_certs_path) @trusted_certs_file_path = trusted_certs_path end |
Instance Attribute Details
#trusted_certs_file_path ⇒ Object
Returns the value of attribute trusted_certs_file_path.
4 5 6 |
# File 'lib/sslackey/authority_checker.rb', line 4 def trusted_certs_file_path @trusted_certs_file_path end |
Class Method Details
.parse_authority_info_access(ocsp_string) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/sslackey/authority_checker.rb', line 40 def self.(ocsp_string) ocsp_string.each_line do |line| if line.index(/OCSP/) urls = line.scan(/URI:.*/) url = urls[0] url.slice!(/URI:/) return url end end return nil end |
.parse_crl_distribution_points(crl_string) ⇒ Object
52 53 54 55 56 57 58 59 |
# File 'lib/sslackey/authority_checker.rb', line 52 def self.parse_crl_distribution_points(crl_string) crl_string.each_line do |line| urls = line.scan(/URI:.*/) crl_url = urls[0] crl_url.slice!(/URI:/) return crl_url end end |
Instance Method Details
#create_response_file(file_name) ⇒ Object
91 92 93 |
# File 'lib/sslackey/authority_checker.rb', line 91 def create_response_file(file_name) Tempfile.new(file_name) end |
#fetch_crl_content(crl_url) ⇒ Object
106 107 108 |
# File 'lib/sslackey/authority_checker.rb', line 106 def fetch_crl_content(crl_url) `curl -s '#{crl_url}'` end |
#generate_ocsp_response(issuer_file_path, certificate_file_path, output_file_path, ocsp_url) ⇒ Object
72 73 74 |
# File 'lib/sslackey/authority_checker.rb', line 72 def generate_ocsp_response(issuer_file_path, certificate_file_path, output_file_path, ocsp_url) `openssl ocsp -no_nonce -CAfile #{trusted_certs_file_path} -issuer #{issuer_file_path} -cert #{certificate_file_path} -respout #{output_file_path} -url #{ocsp_url}` end |
#perform_crl_check(certificate, crl_url) ⇒ Object
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/sslackey/authority_checker.rb', line 95 def perform_crl_check(certificate, crl_url) content = fetch_crl_content(crl_url) crl = OpenSSL::X509::CRL.new(content) revoked_matches = crl.revoked.select { |elem| elem.serial == certificate.serial } return :revoked unless revoked_matches.empty? :successful end |
#perform_ocsp_check(certificate, issuer_certificate, ocsp_url) ⇒ Object
62 63 64 65 66 67 68 69 70 |
# File 'lib/sslackey/authority_checker.rb', line 62 def perform_ocsp_check(certificate, issuer_certificate, ocsp_url) certificate_file = write_certificate_file(certificate, "provider") issuer_file = write_certificate_file(issuer_certificate, "issuer") output_file = create_response_file("ocsp_output") generate_ocsp_response(issuer_file.path, certificate_file.path, output_file.path, ocsp_url) read_ocsp_response(output_file).to_sym end |
#read_ocsp_response(output_file) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/sslackey/authority_checker.rb', line 76 def read_ocsp_response(output_file) output_file.rewind response = OpenSSL::OCSP::Response.new(output_file.read) output_file.close response.status_string end |
#validate(certificate, issuer_certificate) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/sslackey/authority_checker.rb', line 11 def validate(certificate, issuer_certificate) ocsp_url = nil crl_url = nil certificate.extensions.each do |extension| props = extension.to_h if props["oid"] == "authorityInfoAccess" ocsp_url = AuthorityChecker.(props["value"]) LOGGER.debug("got an ocsp url: #{ocsp_url}") if defined? LOGGER end if props["oid"] == "crlDistributionPoints" crl_url = AuthorityChecker.parse_crl_distribution_points(props["value"]) LOGGER.debug("got an crl url: #{crl_url}") if defined? LOGGER end end if ocsp_url response = perform_ocsp_check(certificate, issuer_certificate, ocsp_url) elsif crl_url response = perform_crl_check(certificate, crl_url) else raise "Could not find valid oscp or crl extension to check against in certificate #{certificate.subject}" end raise "Unknown revocation response #{response}" unless AuthorityChecker::REVOCATION_RESPONSES.include?(response) response end |
#write_certificate_file(certificate, file_name) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/sslackey/authority_checker.rb', line 83 def write_certificate_file(certificate, file_name) file = Tempfile.new(file_name) file.write(certificate) file.rewind file.close file end |