From a3e5e42375968d7c9a4fe84969ebcb3627cdb3c4 Mon Sep 17 00:00:00 2001 From: Zhenchao Li Date: Fri, 6 Aug 2010 21:57:13 +0800 Subject: [PATCH] add code to generate self signed certificates --- src/common/jingle_xtls.py | 91 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/src/common/jingle_xtls.py b/src/common/jingle_xtls.py index 8fe6140e7..1b0e23d84 100644 --- a/src/common/jingle_xtls.py +++ b/src/common/jingle_xtls.py @@ -26,10 +26,14 @@ PYOPENSSL_PRESENT = False try: import OpenSSL PYOPENSSL_PRESENT = True - from OpenSSL import SSL, Context except ImportError: log.info("PyOpenSSL not available") +if PYOPENSSL_PRESENT: + from OpenSSL import SSL + from OpenSSL.SSL import Context + from OpenSSL import crypto + def default_callback(connection, certificate, error_num, depth, return_code): log.info("certificate: %s" % certificate) return return_code @@ -54,3 +58,88 @@ def get_context(fingerprint, verify_cb=None): ctx.load_verify_locations(os.path.expanduser('~/certs/CA.cert')) return ctx +# the following code is partly due to pyopenssl examples + +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 + ST - State or province name + L - Locality name + O - Organization name + OU - Organizational unit name + CN - Common name + emailAddress - 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 make_certs(filepath, CN): + """ + make self signed certificates + filepath : absolute path of certificate file, will be appended the '.pkey' and '.cert' extensions + CN : common name + """ + key = createKeyPair(TYPE_RSA, 1024) + req = createCertRequest(key, CN=CN) + cert = createCertificate(req, (req, key), 0, (0, 60*60*24*365*5)) # five years + open(filepath + '.pkey', 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)) + open(filepath + '.cert', 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + + +if __name__ == '__main__': + make_certs('./selfcert', 'gajim') +