#!/usr/bin/env ruby

# Usage exemple: ./fingerprint twitter.com api.twitter.com ton.twitter.com twitter.com tweetdeck.twitter.com userstream.twitter.com abs.twitter.com psb.twimg.com ton.twing.com video.twimg.com 2> /dev/null
# List of figerprint by domain name

require 'resolv'
require 'openssl'
require 'set'

hosts = Set.new
ips = Set.new
certs = Set.new
subjects = Set.new
cas = Set.new
fps = Set.new
keys = Set.new

resolver = Resolv::DNS.new
ARGV.each do |host|
  $stderr.puts host
  hosts << host
  resolver.each_address(host) do |ip|
    ip = ip.to_s
    ips << ip
    $stderr.puts "  #{ip}"
    tcp_client = TCPSocket.new ip, 443
    ssl_client = OpenSSL::SSL::SSLSocket.new tcp_client
    ssl_client.hostname = host
    ssl_client.connect
    cert = ssl_client.peer_cert
    certs << cert

    subject = cert.subject
    subjects << subject
    $stderr.puts "    CN=#{subject}"

    ca = cert.issuer
    cas << ca
    $stderr.puts "    CA=#{ca}"

    fp = OpenSSL::Digest::SHA256.hexdigest cert.to_der
    fps << fp
    $stderr.puts "    fp=#{fp}"

    key = ::OpenSSL::Digest::SHA256.hexdigest cert.public_key.to_der
    keys << key
    $stderr.puts "    key=#{key}"

    ssl_client.close
  end
end

puts "#{hosts.size} hosts"
hosts.sort.each { |l| puts "  #{l}"}
puts "#{ips.size} IPs"
ips.sort.each { |l| puts "  #{l}"}
puts "#{fps.size} certificates"
fps.sort.each { |l| puts "  #{l}"}
puts "#{cas.size} CAs"
cas.sort.each { |l| puts "  #{l}"}
puts "#{subjects.size} subjects"
subjects.sort.each { |l| puts "  #{l}"}
puts "#{keys.size} keys"
keys.sort.each { |l| puts "  #{l}"}