
commit 871e4c394dbe81efbe350185624d9ac81fcd5133 Author: Ximin Luo <infinity0@gmx.com> Date: Wed Nov 13 17:28:53 2013 +0000 use common certificate pinning code in facilitator-email-poller --- facilitator/facilitator-email-poller | 63 +++------------------------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/facilitator/facilitator-email-poller b/facilitator/facilitator-email-poller index 0eef115..f30e1cb 100755 --- a/facilitator/facilitator-email-poller +++ b/facilitator/facilitator-email-poller @@ -17,6 +17,7 @@ import tempfile import time from flashproxy import fac +from flashproxy import keys from flashproxy import proc from flashproxy.util import parse_addr_spec @@ -36,45 +37,6 @@ REGISTRATION_AGE_LIMIT = 30 * 60 FACILITATOR_ADDR = ("127.0.0.1", 9002) -# We trust no other CA certificate than this. -# -# To find the certificate to copy here, -# $ strace openssl s_client -connect imap.gmail.com:993 -verify 10 -CApath /etc/ssl/certs 2>&1 | grep /etc/ssl/certs -# stat("/etc/ssl/certs/XXXXXXXX.0", {st_mode=S_IFREG|0644, st_size=YYYY, ...}) = 0 -CA_CERTS = """\ -subject=/C=US/O=Equifax/OU=Equifax Secure Certificate Authority -issuer=/C=US/O=Equifax/OU=Equifax Secure Certificate Authority ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- -""" -# SHA-1 digest of expected public keys. Any of these is valid. See -# http://www.imperialviolet.org/2011/05/04/pinning.html for the reason behind -# hashing the public key, not the entire certificate. -PUBKEY_SHA1 = ( - # https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security... - # kSPKIHash_Google1024 - "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd", - # kSPKIHash_GoogleG2 - "\x43\xda\xd6\x30\xee\x53\xf8\xa9\x80\xca\x6e\xfd\x85\xf4\x6a\xa3\x79\x90\xe0\xea", -) - LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" class options(object): @@ -379,27 +341,12 @@ def imap_loop(imap): def imap_login(): """Make an IMAP connection, check the certificate and public key, and log in.""" - ca_certs_file = tempfile.NamedTemporaryFile(prefix="facilitator-email-poller-", suffix=".crt", delete=True) - try: - ca_certs_file.write(CA_CERTS) - ca_certs_file.flush() - imap = IMAP4_SSL_REQUIRED(imap_addr[0], imap_addr[1], - None, ca_certs_file.name) - finally: - ca_certs_file.close() + with keys.temp_cert(keys.PIN_GOOGLE_CA_CERT) as ca_certs_file: + imap = IMAP4_SSL_REQUIRED( + imap_addr[0], imap_addr[1], None, ca_certs_file.name) if options.use_certificate_pin: - found = [] - for cert in imap.ssl().get_peer_cert_chain(): - pubkey_der = cert.get_pubkey().as_der() - pubkey_digest = sha1(pubkey_der).digest() - if pubkey_digest in PUBKEY_SHA1: - break - found.append(pubkey_digest) - else: - found = "(" + ", ".join(x.encode("hex") for x in found) + ")" - expected = "(" + ", ".join(x.encode("hex") for x in PUBKEY_SHA1) + ")" - raise ValueError("Public key does not match pin: got %s but expected any of %s" % (found, expected)) + keys.check_certificate_pin(imap.ssl(), keys.PIN_GOOGLE_PUBKEY_SHA1) log(u"logging in as %s" % email_addr) imap.login(email_addr, email_password)