[tor-commits] [flashproxy/master] Allow multiple public key pins.

dcf at torproject.org dcf at torproject.org
Fri May 31 16:42:40 UTC 2013


commit f04c9ccdff66b53102cfc9f063bec75d6b801fe8
Author: David Fifield <david at bamsoftware.com>
Date:   Fri May 31 09:03:42 2013 -0700

    Allow multiple public key pins.
---
 ChangeLog                            |    2 ++
 facilitator/facilitator-email-poller |   13 ++++++++-----
 flashproxy-reg-appspot               |   13 ++++++++-----
 flashproxy-reg-email                 |   13 ++++++++-----
 4 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a9e92a3..be2ee15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,6 @@
 Changes in version 1.1
+  o Programs that use certificate pins now take a --disable-pin option
+    that causes pins to be ignored.
 
 Changes in version 1.0
   o The facilitator runs on a new domain name fp-facilitator.org. Fixes
diff --git a/facilitator/facilitator-email-poller b/facilitator/facilitator-email-poller
index b70e649..9df7f3b 100755
--- a/facilitator/facilitator-email-poller
+++ b/facilitator/facilitator-email-poller
@@ -55,10 +55,12 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
 -----END CERTIFICATE-----
 """
-# SHA-1 digest of expected public key. See
+# 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 = "63c445c009328b663cdff9cb68f6c523ac7b6c2b".decode("hex")
+PUBKEY_SHA1 = tuple(x.decode("hex") for x in (
+    "63c445c009328b663cdff9cb68f6c523ac7b6c2b",
+))
 
 LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 
@@ -294,9 +296,10 @@ def imap_login():
     pubkey_der = cert.get_pubkey().as_der()
     pubkey_digest = sha1(pubkey_der).digest()
 
-    if pubkey_digest != PUBKEY_SHA1:
-        raise ValueError("Public key does not match pin: got %s but expected %s" %
-            (pubkey_digest.encode("hex"), PUBKEY_SHA1.encode("hex")))
+    if 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))
 
     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 be2fbff..ab65f96 100755
--- a/flashproxy-reg-appspot
+++ b/flashproxy-reg-appspot
@@ -59,10 +59,12 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
 -----END CERTIFICATE-----
 """
-# SHA-1 digest of expected public key. See
+# 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 = "c70ccd442ff4528c603aefef85206fd693990e09".decode("hex")
+PUBKEY_SHA1 = tuple(x.decode("hex") for x in (
+    "c70ccd442ff4528c603aefef85206fd693990e09",
+))
 
 class options(object):
     address_family = socket.AF_UNSPEC
@@ -194,9 +196,10 @@ class PinHTTPSConnection(httplib.HTTPSConnection):
         pubkey_der = cert.get_pubkey().as_der()
         pubkey_digest = sha1(pubkey_der).digest()
 
-        if pubkey_digest != PUBKEY_SHA1:
-            raise ValueError("Public key does not match pin: got %s but expected %s" %
-                (pubkey_digest.encode("hex"), PUBKEY_SHA1.encode("hex")))
+        if 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))
 
 class PinHTTPSHandler(urllib2.HTTPSHandler):
     def https_open(self, req):
diff --git a/flashproxy-reg-email b/flashproxy-reg-email
index edfaff1..90e5264 100755
--- a/flashproxy-reg-email
+++ b/flashproxy-reg-email
@@ -57,10 +57,12 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
 -----END CERTIFICATE-----
 """
-# SHA-1 digest of expected public key. See
+# 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 = "69ba4a72fc198b2203ecdf0c75493e4d5300dac9".decode("hex")
+PUBKEY_SHA1 = tuple(x.decode("hex") for x in (
+    "69ba4a72fc198b2203ecdf0c75493e4d5300dac9",
+))
 
 # Registrations are encrypted with this public key before being emailed. Only
 # the facilitator operators should have the corresponding private key. Given a
@@ -262,9 +264,10 @@ try:
     pubkey_der = cert.get_pubkey().as_der()
     pubkey_digest = sha1(pubkey_der).digest()
 
-    if pubkey_digest != PUBKEY_SHA1:
-        raise ValueError("Public key does not match pin: got %s but expected %s" %
-            (pubkey_digest.encode("hex"), PUBKEY_SHA1.encode("hex")))
+    if 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))
 
     smtp.ehlo(EHLO_FQDN)
 





More information about the tor-commits mailing list