From f62db4d8079dce1b412ebef56d053e886a25001b Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Thu, 31 May 2012 16:48:36 -0700 Subject: [PATCH] implement everything except cn, san, and issue --- webserver/CSR.py | 52 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/webserver/CSR.py b/webserver/CSR.py index 6eb05f775..14c033c14 100644 --- a/webserver/CSR.py +++ b/webserver/CSR.py @@ -2,28 +2,50 @@ # use OpenSSL to provide CSR-related operations -import subprocess, tempfile -# we will use tempfile.NamedTemporaryFile() to get tempfiles +import subprocess, tempfile, re +# we can use tempfile.NamedTemporaryFile() to get tempfiles # to pass to OpenSSL subprocesses. def parse(csr): """Is this CSR syntactically valid?""" - return True + out, err = subprocess.Popen(["openssl", "req", "-noout"],shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate(csr) + if not err: + return True + return False + +def modulusbits(key): + """How many bits are in the modulus of this key?""" + out, err = subprocess.Popen(["openssl", "rsa", "-pubin", "-text", "-noout"],shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate(key) + if out and not err: + try: + size = re.search("Public-Key: \(([0-9]+) bit\)", out).groups()[0] + except: + return None + return int(size) + return None def goodkey(csr): """Does this CSR's public key comply with our CA policy?""" - return True + if not parse(csr): return False + bits = modulusbits(pubkey(csr)) + if bits and bits >= 2000: + return True + else: + return False def pubkey(csr): """Get the public key from this CSR.""" - return "" + out, err = subprocess.Popen(["openssl", "req", "-pubkey", "-noout"],shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate(csr) + if out and not err: + return out + return None def cn(csr): """Get the common name from this CSR.""" return "" def san(csr): - """Get the subject alternate names from this CSR.""" + """Get the subjectAltNames from this CSR.""" return [] def can_sign(name): @@ -38,8 +60,24 @@ def can_sign(name): def verify(key, data): """What string was validly signed by this public key? (or None)""" + with tempfile.NamedTemporaryFile() as tmp: + tmp.write(key) + tmp.flush() + out, err = subprocess.Popen(["openssl", "rsautl", "-pubin", "-inkey", tmp.name, "-verify"],shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate(data) + if out and not err: + return out return None def sign(key, data): """Sign this data with this private key. For client-side use.""" - return "" + with tempfile.NamedTemporaryFile() as tmp: + tmp.write(key) + tmp.flush() + out, err = subprocess.Popen(["openssl", "rsautl", "-inkey", tmp.name, "-sign"],shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate(data) + if out and not err: + return out + return None + +def issue(csr): + """Issue the certificate requested by this CSR and return it!""" + return "-----BEGIN CERTIFICATE-----\nThanks for the shrubbery!\n-----END CERTIFICATE-----"