diff options
author | 2006-05-21 04:48:11 +0000 | |
---|---|---|
committer | 2006-05-21 04:48:11 +0000 | |
commit | 00a378891ea77838948738e3b20dd42f3ea3cc2e (patch) | |
tree | d9642ee065ce0942498f2624b04baaa78e8fc91d /client | |
parent | update to moria.sql. add a svnignore to the templates directory for templates_c (diff) | |
download | scire-00a378891ea77838948738e3b20dd42f3ea3cc2e.tar.gz scire-00a378891ea77838948738e3b20dd42f3ea3cc2e.tar.bz2 scire-00a378891ea77838948738e3b20dd42f3ea3cc2e.zip |
generate cert/key when needed
check server cert's digest against stored digest
svn path=/; revision=75
Diffstat (limited to 'client')
-rw-r--r-- | client/certgen.py | 92 | ||||
-rwxr-xr-x | client/scirec.py | 83 |
2 files changed, 145 insertions, 30 deletions
diff --git a/client/certgen.py b/client/certgen.py new file mode 100644 index 0000000..ffab9c9 --- /dev/null +++ b/client/certgen.py @@ -0,0 +1,92 @@ +# +# certgen.py +# +# Copyright (C) Martin Sjogren and AB Strakt 2001, All rights reserved +# +# $Id$ +# +""" +Certificate generation module. +""" + +from OpenSSL import crypto + +TYPE_RSA = crypto.TYPE_RSA +TYPE_DSA = crypto.TYPE_DSA + +def createKeyPair(type, bits): + """ + Create a public/private key pair. + + Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA + bits - Number of bits to use in the key + Returns: The public/private key pair in a PKey object + """ + pkey = crypto.PKey() + pkey.generate_key(type, bits) + return pkey + +def createCertRequest(pkey, digest="md5", **name): + """ + Create a certificate request. + + Arguments: pkey - The key to associate with the request + digest - Digestion method to use for signing, default is md5 + **name - The name of the subject of the request, possible + arguments are: + C - Country name + SP - State or province name + L - Locality name + O - Organization name + OU - Organizational unit name + CN - Common name + email - E-mail address + Returns: The certificate request in an X509Req object + """ + req = crypto.X509Req() + subj = req.get_subject() + + for (key,value) in name.items(): + setattr(subj, key, value) + + req.set_pubkey(pkey) + req.sign(pkey, digest) + return req + +def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"): + """ + Generate a certificate given a certificate request. + + Arguments: req - Certificate reqeust to use + issuerCert - The certificate of the issuer + issuerKey - The private key of the issuer + serial - Serial number for the certificate + notBefore - Timestamp (relative to now) when the certificate + starts being valid + notAfter - Timestamp (relative to now) when the certificate + stops being valid + digest - Digest method to use for signing, default is md5 + Returns: The signed certificate in an X509 object + """ + cert = crypto.X509() + cert.set_serial_number(serial) + cert.gmtime_adj_notBefore(notBefore) + cert.gmtime_adj_notAfter(notAfter) + cert.set_issuer(issuerCert.get_subject()) + cert.set_subject(req.get_subject()) + cert.set_pubkey(req.get_pubkey()) + cert.sign(issuerKey, digest) + return cert + +def certgen(keytype, keylength, commonname, keyfile, certfile): + key_types = { "RSA": TYPE_RSA, "DSA": TYPE_DSA } + key = createKeyPair(key_types[keytype], keylength) + req = createCertRequest(key, CN=commonname) + cert = createCertificate(req, (req, key), 0, (0, 60*60*24*365*50)) # fifty years + pkey_file = open(keyfile, 'w') + pkey_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)) + pkey_file.close() + cert_file = open(certfile, 'w') + cert_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + cert_file.close() + diff --git a/client/scirec.py b/client/scirec.py index 5a301f9..109d431 100755 --- a/client/scirec.py +++ b/client/scirec.py @@ -1,36 +1,59 @@ #!/usr/bin/python from OpenSSL import SSL +import certgen import sys, os, select, socket -def verify_cb(conn, cert, errnum, depth, ok): - # This obviously has to be updated - print 'Got certificate: %s' % cert.get_subject() - return ok - -# Initialize context -ctx = SSL.Context(SSL.SSLv23_METHOD) -#ctx.set_verify(SSL.VERIFY_PEER, verify_cb) # Demand a certificate -ctx.use_privatekey_file('/tmp/server.pkey') -ctx.use_certificate_file('/tmp/server.cert') -ctx.load_verify_locations('/tmp/CA.cert') - -# Set up client -sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) -sock.connect(('localhost', 9876)) - -while 1: - line = sys.stdin.readline() - if line == '': - break - try: - sock.send(line) - sys.stdout.write(sock.recv(1024)) - sys.stdout.flush() - except SSL.Error: - print 'Connection died unexpectedly' - break - -sock.shutdown() -sock.close() +config_dir = "/tmp" + +def verify_server_cert(conn, cert, errnum, depth, ok): + if not os.path.isfile(config_dir + "/known_servers"): + print "Recording server's cert digest in known_servers" + known_servers_file = open(config_dir + "/known_servers", "w") + known_servers_file.write(cert.digest("sha1") + "\n") + known_servers_file.close() + else: + known_servers_file = open(config_dir + "/known_servers", "r") + known_servers = [x.strip() for x in known_servers_file.readlines()] + known_servers_file.close() + if not cert.digest("sha1") in known_servers: + return False + return True + +def generate_cert_and_key(keytype="RSA", keylength=1024): + # Generate server cert/key + sys.stdout.write("Generating client certificate...") + certgen.certgen(keytype, keylength, "Scire Client", config_dir + '/client.key', config_dir + '/client.cert') + print "done" + +if __name__ == "__main__": + # Check for public/private keypair and generate if they don't exist + if not os.path.isfile(config_dir + "/client.key") or not os.path.isfile(config_dir + "/client.cert"): + generate_cert_and_key() + + # Initialize context + ctx = SSL.Context(SSL.SSLv23_METHOD) + ctx.set_verify(SSL.VERIFY_PEER, verify_server_cert) # Demand a certificate + ctx.use_privatekey_file('/tmp/client.key') + ctx.use_certificate_file('/tmp/client.cert') +# ctx.load_verify_locations('/tmp/CA.cert') + + # Set up client + sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + sock.connect(('localhost', 9876)) + + while 1: + line = sys.stdin.readline() + if line == '': + break + try: + sock.send(line) + sys.stdout.write(sock.recv(1024)) + sys.stdout.flush() + except SSL.Error: + print 'Connection died unexpectedly' + break + + sock.shutdown() + sock.close() |