cert.ist certificate chain pinning example Ruby
#!/usr/bin/env ruby -W0 | |
require 'net/http' | |
require 'openssl' | |
require 'json' | |
require 'digest' | |
def validate_cert_for_domain(domain) | |
uri = URI("https://api.cert.ist/#{domain}") | |
response = Net::HTTP.get(uri) | |
parsed = JSON.parse(response) | |
chain = parsed['chain'] | |
full_chain ||= [] | |
chain.each { |certInChain| | |
full_chain << certInChain['pem']['hashes']['sha256'] | |
} | |
http = Net::HTTP.new(domain, 443) | |
http.use_ssl = true | |
http.verify_mode = OpenSSL::SSL::VERIFY_PEER | |
index = 0 | |
http.verify_callback = lambda do |preverify_ok, cert_store| | |
return false unless preverify_ok | |
end_cert = cert_store.chain[index] | |
local_cert_hash = Digest::SHA256.hexdigest(end_cert.to_pem) | |
api_chain_hash = full_chain[index] | |
index += 1 | |
if api_chain_hash.to_s != "" | |
return api_chain_hash == local_cert_hash | |
else | |
# TODO: extra certificate found, figure out what's going on here | |
return true | |
end | |
end | |
_ = http.get '/' | |
puts "Local and cert.ist api certificate chain hashes matched for host: #{domain}" | |
end | |
validate_cert_for_domain('jbird.dev') | |
validate_cert_for_domain('urip.io') | |
validate_cert_for_domain('tilltrump.com') | |
validate_cert_for_domain('asciirange.com') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment