Skip to content

Instantly share code, notes, and snippets.

@JBirdVegas
Created October 13, 2020 15:41
Show Gist options
  • Save JBirdVegas/238d3df3b72c551360bad6705f258ac0 to your computer and use it in GitHub Desktop.
Save JBirdVegas/238d3df3b72c551360bad6705f258ac0 to your computer and use it in GitHub Desktop.
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