[tor-commits] [flashproxy/master] Check every certificate's public key, not only the leaf's.
dcf at torproject.org
dcf at torproject.org
Thu Aug 1 03:13:30 UTC 2013
commit e234f31d8c1017672a2000925a0e8ff4f32feda8
Author: David Fifield <david at bamsoftware.com>
Date: Thu Jul 11 15:26:51 2013 -0700
Check every certificate's public key, not only the leaf's.
I put the Chromium kSPKIHash_Google1024 as the only allowed key, as
that's the one I see right now.
---
facilitator/facilitator-email-poller | 29 +++++++++++++++++------------
flashproxy-reg-appspot | 32 +++++++++++++++++---------------
flashproxy-reg-email | 24 +++++++++++++++++-------
3 files changed, 51 insertions(+), 34 deletions(-)
diff --git a/facilitator/facilitator-email-poller b/facilitator/facilitator-email-poller
index a2b5cd6..8b9f10a 100755
--- a/facilitator/facilitator-email-poller
+++ b/facilitator/facilitator-email-poller
@@ -64,9 +64,11 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
# 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 = tuple(x.decode("hex") for x in (
- "63c445c009328b663cdff9cb68f6c523ac7b6c2b",
-))
+PUBKEY_SHA1 = (
+ # https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.h?revision=209003&view=markup
+ # kSPKIHash_Google1024
+ "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd",
+)
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
@@ -362,15 +364,18 @@ def imap_login():
finally:
ca_certs_file.close()
- # Check that the public key is what we expect.
- cert = imap.ssl().get_peer_cert()
- pubkey_der = cert.get_pubkey().as_der()
- pubkey_digest = sha1(pubkey_der).digest()
-
- if options.use_certificate_pin and pubkey_digest not in PUBKEY_SHA1:
- 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" %
- (pubkey_digest.encode("hex"), expected))
+ 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))
log(u"logging in as %s" % options.email_addr)
imap.login(options.email_addr, email_password)
diff --git a/flashproxy-reg-appspot b/flashproxy-reg-appspot
index fc960e9..2ca3467 100755
--- a/flashproxy-reg-appspot
+++ b/flashproxy-reg-appspot
@@ -63,12 +63,11 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
# 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 = tuple(x.decode("hex") for x in (
- "c70ccd442ff4528c603aefef85206fd693990e09",
- "1697e17a8a3317f031721b7b6293cd50643bbbd3",
- "291e750bafedac444486327e50f26f64d840991a",
- "1e3f66cfa0eb03136297fdb238ad6619c30ff375",
-))
+PUBKEY_SHA1 = (
+ # https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.h?revision=209003&view=markup
+ # kSPKIHash_Google1024
+ "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd",
+)
class options(object):
address_family = socket.AF_UNSPEC
@@ -234,15 +233,18 @@ class PinHTTPSConnection(httplib.HTTPSConnection):
self.sock = SSL.Connection(ctx, sock)
self.sock.connect((self.host, self.port))
- # Check that the public key is what we expect.
- cert = self.sock.get_peer_cert()
- pubkey_der = cert.get_pubkey().as_der()
- pubkey_digest = sha1(pubkey_der).digest()
-
- if options.use_certificate_pin and pubkey_digest not in PUBKEY_SHA1:
- 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" %
- (pubkey_digest.encode("hex"), expected))
+ if options.use_certificate_pin:
+ found = []
+ for cert in self.sock.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))
class PinHTTPSHandler(urllib2.HTTPSHandler):
def https_open(self, req):
diff --git a/flashproxy-reg-email b/flashproxy-reg-email
index a3c27ad..6d3f092 100755
--- a/flashproxy-reg-email
+++ b/flashproxy-reg-email
@@ -60,9 +60,11 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
# 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 = tuple(x.decode("hex") for x in (
- "69ba4a72fc198b2203ecdf0c75493e4d5300dac9",
-))
+PUBKEY_SHA1 = (
+ # https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.h?revision=209003&view=markup
+ # kSPKIHash_Google1024
+ "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd",
+)
# Registrations are encrypted with this public key before being emailed. Only
# the facilitator operators should have the corresponding private key. Given a
@@ -284,10 +286,18 @@ try:
smtp.sock.connect_ssl()
smtp.file = smtp.sock.makefile()
- # Check that the public key is what we expect.
- cert = smtp.sock.get_peer_cert()
- pubkey_der = cert.get_pubkey().as_der()
- pubkey_digest = sha1(pubkey_der).digest()
+ if options.use_certificate_pin:
+ found = []
+ for cert in smtp.sock.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))
if options.use_certificate_pin and pubkey_digest not in PUBKEY_SHA1:
expected = "(" + ", ".join(x.encode("hex") for x in PUBKEY_SHA1) + ")"
More information about the tor-commits
mailing list