Module: Octobat::CertificateBlacklist

Defined in:
lib/octobat/certificate_blacklist.rb

Constant Summary collapse

BLACKLIST =
{
  "api.stripe.com" => [
    '05c0b3643694470a888c6e7feb5c9e24e823dc53',
  ],
  "revoked.stripe.com" => [
    '5b7dc7fbc98d78bf76d4d4fa6f597a0c901fad5c',
  ]
}

Class Method Summary collapse

Class Method Details

.check_ssl_cert(uri, ca_file) ⇒ Object

Unfortunately the interface to OpenSSL doesn’t make it easy to check the certificate before sending potentially sensitive data on the wire. This approach raises the bar for an attacker significantly.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/octobat/certificate_blacklist.rb', line 25

def self.check_ssl_cert(uri, ca_file)
  uri = URI.parse(uri)

  sock = TCPSocket.new(uri.host, uri.port)
  ctx = OpenSSL::SSL::SSLContext.new
  ctx.set_params(:verify_mode => OpenSSL::SSL::VERIFY_PEER,
                 :ca_file => ca_file)

  socket = OpenSSL::SSL::SSLSocket.new(sock, ctx)
  socket.connect

  certificate = socket.peer_cert.to_der
  fingerprint = Digest::SHA1.hexdigest(certificate)

  if blacklisted_certs = BLACKLIST[uri.host]
    if blacklisted_certs.include?(fingerprint)
      raise APIConnectionError.new(
        "Invalid server certificate. You tried to connect to a server that" \
        "has a revoked SSL certificate, which means we cannot securely send" \
        "data to that server. Please email [email protected] if you need" \
        "help connecting to the correct API server."
      )
    end
  end

  socket.close

  return true
end