summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorAndrew Gaffney <agaffney@gentoo.org>2006-05-21 04:48:11 +0000
committerAndrew Gaffney <agaffney@gentoo.org>2006-05-21 04:48:11 +0000
commit00a378891ea77838948738e3b20dd42f3ea3cc2e (patch)
treed9642ee065ce0942498f2624b04baaa78e8fc91d /client
parentupdate to moria.sql. add a svnignore to the templates directory for templates_c (diff)
downloadscire-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.py92
-rwxr-xr-xclient/scirec.py83
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()