commit 6911a3cb2a6657950893edba49748c2a704fa46a Author: David Fifield david@bamsoftware.com Date: Sun Feb 9 02:58:29 2014 -0800
Use mkstemp instead of NamedTemporaryFile.
NamedTemporaryFile can't be reopened by file name on Windows. The precise failure was in ret = ctx.load_verify_locations(ca_file.name) assert ret == 1 The programs that use certificate pinning (flashproxy-reg-appspot, flashproxy-reg-email) were not working on Windows.
This commit is a rediscovery of the same fix that was committed in b3989fda65cb7f32f04369df656600e2655243b9. --- flashproxy-reg-appspot | 4 ++-- flashproxy-reg-email | 4 ++-- flashproxy/keys.py | 12 ++++++------ flashproxy/test/test_keys.py | 17 ++++++++--------- 4 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/flashproxy-reg-appspot b/flashproxy-reg-appspot index db2fdbd..1f12c26 100755 --- a/flashproxy-reg-appspot +++ b/flashproxy-reg-appspot @@ -136,8 +136,8 @@ class PinHTTPSConnection(httplib.HTTPSConnection): ctx = SSL.Context("tlsv1") ctx.set_verify(SSL.verify_peer, 3)
- with temp_cert(PIN_GOOGLE_CA_CERT) as ca_file: - ret = ctx.load_verify_locations(ca_file.name) + with temp_cert(PIN_GOOGLE_CA_CERT) as ca_filename: + ret = ctx.load_verify_locations(ca_filename) assert ret == 1
self.sock = SSL.Connection(ctx, sock) diff --git a/flashproxy-reg-email b/flashproxy-reg-email index 5d38fa5..de67d43 100755 --- a/flashproxy-reg-email +++ b/flashproxy-reg-email @@ -185,7 +185,7 @@ try: ctx = SSL.Context("tlsv1") ctx.set_verify(SSL.verify_peer, 3)
- with temp_cert(PIN_GOOGLE_CA_CERT) as ca_file: + with temp_cert(PIN_GOOGLE_CA_CERT) as ca_filename: # We roll our own initial EHLO/STARTTLS because smtplib.SMTP.starttls # doesn't allow enough certificate validation. code, msg = smtp.docmd("EHLO", EHLO_FQDN) @@ -194,7 +194,7 @@ try: code, msg = smtp.docmd("STARTTLS") if code != 220: raise ValueError("Got code %d after STARTTLS" % code) - ret = ctx.load_verify_locations(ca_file.name) + ret = ctx.load_verify_locations(ca_filename) assert ret == 1
smtp.sock = SSL.Connection(ctx, smtp.sock) diff --git a/flashproxy/keys.py b/flashproxy/keys.py index ff27448..7bf4938 100644 --- a/flashproxy/keys.py +++ b/flashproxy/keys.py @@ -1,3 +1,4 @@ +import os import tempfile
from hashlib import sha1 @@ -74,13 +75,12 @@ class temp_cert(object): """Implements a with-statement over raw certificate data."""
def __init__(self, certdata): - self.fd = tempfile.NamedTemporaryFile(prefix="fp-cert-temp-", suffix=".crt", delete=True) - self.fd.write(certdata) - self.fd.flush() - self.fd.seek(0) + fd, self.path = tempfile.mkstemp(prefix="fp-cert-temp-", suffix=".crt") + os.write(fd, certdata) + os.close(fd)
def __enter__(self): - return self.fd + return self.path
def __exit__(self, type, value, traceback): - self.fd.close() + os.unlink(self.path) diff --git a/flashproxy/test/test_keys.py b/flashproxy/test/test_keys.py index 15c4449..0adff32 100644 --- a/flashproxy/test/test_keys.py +++ b/flashproxy/test/test_keys.py @@ -7,19 +7,18 @@ class TempCertTest(unittest.TestCase):
def test_temp_cert_success(self): fn = None - with temp_cert(PIN_GOOGLE_CA_CERT) as ca_file: - fn = ca_file.name - self.assertTrue(os.path.exists(fn)) - lines = ca_file.readlines() - self.assertIn("-----BEGIN CERTIFICATE-----\n", lines) - self.assertFalse(os.path.exists(fn)) + with temp_cert(PIN_GOOGLE_CA_CERT) as ca_filename: + self.assertTrue(os.path.exists(ca_filename)) + with open(ca_filename) as f: + lines = f.readlines() + self.assertIn("-----BEGIN CERTIFICATE-----\n", lines) + self.assertFalse(os.path.exists(ca_filename))
def test_temp_cert_raise(self): fn = None try: - with temp_cert(PIN_GOOGLE_CA_CERT) as ca_file: - fn = ca_file.name + with temp_cert(PIN_GOOGLE_CA_CERT) as ca_filename: raise ValueError() self.fail() except ValueError: - self.assertFalse(os.path.exists(fn)) + self.assertFalse(os.path.exists(ca_filename))