From 22d4559a7aa8a02995796110d15e6970e922455f Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 11 Mar 2012 14:34:17 +1300 Subject: Use PyOpenSSL for certificate generation. We no longer call external OpenSSL commands at all. --- libmproxy/certutils.py | 74 ++++++++++++++++++++++++++++++++++++++------ libmproxy/resources/cert.cnf | 33 -------------------- 2 files changed, 65 insertions(+), 42 deletions(-) delete mode 100644 libmproxy/resources/cert.cnf (limited to 'libmproxy') diff --git a/libmproxy/certutils.py b/libmproxy/certutils.py index 176e7b61..6650486b 100644 --- a/libmproxy/certutils.py +++ b/libmproxy/certutils.py @@ -8,15 +8,7 @@ CERT_SLEEP_TIME = 1 CERT_EXPIRY = str(365 * 3) -def dummy_ca(path): - dirname = os.path.dirname(path) - if not os.path.exists(dirname): - os.makedirs(dirname) - if path.endswith(".pem"): - basename, _ = os.path.splitext(path) - else: - basename = path - +def create_ca(): key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 1024) ca = OpenSSL.crypto.X509() @@ -42,6 +34,19 @@ def dummy_ca(path): subject=ca), ]) ca.sign(key, "sha1") + return key, ca + + +def dummy_ca(path): + dirname = os.path.dirname(path) + if not os.path.exists(dirname): + os.makedirs(dirname) + if path.endswith(".pem"): + basename, _ = os.path.splitext(path) + else: + basename = path + + key, ca = create_ca() # Dump the CA plus private key f = open(path, "w") @@ -76,6 +81,57 @@ def dummy_cert(certdir, ca, commonname, sans): if os.path.exists(certpath): return certpath + ss = [] + for i in sans: + ss.append("DNS: %s"%i) + ss = ", ".join(ss) + + if ca: + raw = file(ca, "r").read() + ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, raw) + key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, raw) + else: + key, ca = create_ca() + + pkey = ca.get_pubkey() + req = OpenSSL.crypto.X509Req() + subj = req.get_subject() + subj.CN = commonname + req.set_pubkey(ca.get_pubkey()) + req.sign(key, "sha1") + if ss: + req.add_extensions([OpenSSL.crypto.X509Extension("subjectAltName", True, ss)]) + + cert = OpenSSL.crypto.X509() + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(60 * 60 * 24 * 30) + cert.set_issuer(ca.get_subject()) + cert.set_subject(req.get_subject()) + if ss: + cert.add_extensions([OpenSSL.crypto.X509Extension("subjectAltName", True, ss)]) + cert.set_pubkey(req.get_pubkey()) + cert.sign(key, "sha1") + + f = open(certpath, "w") + f.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)) + f.close() + + return certpath + + +def dummy_cert_(certdir, ca, commonname, sans): + """ + certdir: Certificate directory. + ca: Path to the certificate authority file, or None. + commonname: Common name for the generated certificate. + + Returns cert path if operation succeeded, None if not. + """ + namehash = hashlib.sha256(commonname).hexdigest() + certpath = os.path.join(certdir, namehash + ".pem") + if os.path.exists(certpath): + return certpath + confpath = os.path.join(certdir, namehash + ".cnf") reqpath = os.path.join(certdir, namehash + ".req") diff --git a/libmproxy/resources/cert.cnf b/libmproxy/resources/cert.cnf deleted file mode 100644 index 4d95f646..00000000 --- a/libmproxy/resources/cert.cnf +++ /dev/null @@ -1,33 +0,0 @@ -[ req ] -prompt = no -distinguished_name = req_distinguished_name -x509_extensions = v3_cert -req_extensions = v3_cert_req - -[ req_distinguished_name ] -organizationName = mitmproxy -commonName = %(commonname)s - -[ v3_ca ] -basicConstraints = critical,CA:true -keyUsage = cRLSign, keyCertSign -nsCertType = sslCA - -[ v3_ca_req ] -basicConstraints = critical,CA:true -keyUsage = cRLSign, keyCertSign -nsCertType = sslCA - -[ v3_cert ] -basicConstraints = CA:false -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -nsCertType = server - -[ v3_cert_req ] -basicConstraints = CA:false -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -nsCertType = server -%(altnames)s - -[ alt_names ] -%(sans)s -- cgit v1.2.3