summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Dittberner <jandd@cacert.org>2016-05-17 20:08:49 +0200
committerJan Dittberner <jandd@cacert.org>2016-05-17 20:08:49 +0200
commitc544e4a07da86201b31623a6edec6662dfd1a1ff (patch)
treea3dc63842c3d1c865c0fd20ec4df9b85adc1461a
parent813fe1c9e2d0707d4e1ae6e4d87b24f92f55b99b (diff)
downloadcacert-infradocs-c544e4a07da86201b31623a6edec6662dfd1a1ff.tar.gz
cacert-infradocs-c544e4a07da86201b31623a6edec6662dfd1a1ff.tar.xz
cacert-infradocs-c544e4a07da86201b31623a6edec6662dfd1a1ff.zip
Add pyx509/pyasn1 based tool to create sslcert directives
-rw-r--r--.gitignore5
-rwxr-xr-xtools/sslcert.py108
-rw-r--r--tools/tool-requirements.txt4
3 files changed, 115 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 47dc4ed..7638b3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
*.pyc
*.pyo
.*.swp
+.ropeproject/
.swp
-venv/
_build/
-.ropeproject/
+py2venv/
+venv/
diff --git a/tools/sslcert.py b/tools/sslcert.py
new file mode 100755
index 0000000..dbdd49f
--- /dev/null
+++ b/tools/sslcert.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python2
+
+from __future__ import print_function
+
+from datetime import datetime
+from hashlib import sha1
+import argparse
+import os.path
+
+from pyasn1_modules import pem
+from pyx509.pkcs7.asn1_models.X509_certificate import Certificate
+from pyx509.pkcs7_models import X509Certificate
+from pyx509.pkcs7.asn1_models.decoder_workarounds import decode
+
+
+ALTNAME_MAP = (
+ ('dNSName', 'DNS'),
+ ('rfc822Name', 'EMAIL'),
+ ('iPAddress', 'IP')
+)
+
+
+def x509_parse(derData):
+ """Decodes certificate.
+ @param derData: DER-encoded certificate string
+ @returns: pkcs7_models.X509Certificate
+ """
+ cert = decode(derData, asn1Spec=Certificate())[0]
+ x509cert = X509Certificate(cert)
+ return x509cert
+
+
+def get_altnames(cert):
+ altnames = cert.tbsCertificate.subjAltNameExt.value.values
+ retval = []
+ for typ, data in [(field[1], altnames[field[0]]) for field in ALTNAME_MAP]:
+ for item in sorted(data):
+ retval.append("{typ}:{item}".format(typ=typ, item=item))
+ return ", ".join(retval)
+
+
+def get_serial(cert):
+ serial = "%X" % cert.tbsCertificate.serial_number
+ return "0" * (len(serial) % 2) + serial
+
+
+def get_expiration(cert):
+ return datetime.strptime(
+ cert.tbsCertificate.validity.valid_to, '%Y%m%d%H%M%SZ'
+ ).strftime('%b %d %Y %H:%M:%S GMT')
+
+
+def get_sha1fp(certdata):
+ hexhash = sha1(certdata).hexdigest().upper()
+ return ":".join([hexhash[i:i+2] for i in range(0, len(hexhash), 2)])
+
+
+def get_issuer(cert):
+ return cert.tbsCertificate.issuer.get_attributes()['CN'][0]
+
+
+def get_subject(cert):
+ return cert.tbsCertificate.subject.get_attributes()['CN'][0]
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description=(
+ 'Create an sslcert directive from data taken from a PEM encoded '
+ 'X.509 certificate file and its corresponding PEM encoded RSA key '
+ 'file.'))
+ parser.add_argument(
+ 'cert', metavar='CERT', type=open,
+ help='PEM encoded X.509 certficate file')
+ parser.add_argument(
+ '--key', metavar='KEY', type=open,
+ help='PEM encoded RSA private key', default=None)
+ args = parser.parse_args()
+
+ certpem = pem.readPemFromFile(args.cert)
+ certpath = os.path.abspath(args.cert.name)
+ if args.key:
+ haskey = True
+ keypem = pem.readPemFromFile(args.key)
+ keypath = os.path.abspath(args.key.name)
+ else:
+ keypath = 'TODO: define key path'
+
+ cert = x509_parse(certpem)
+ data = {
+ 'altnames': get_altnames(cert),
+ 'certfile': certpath,
+ 'keyfile': keypath,
+ 'serial': get_serial(cert),
+ 'expiration': get_expiration(cert),
+ 'sha1fp': get_sha1fp(certpem),
+ 'issuer': get_issuer(cert),
+ 'subject': get_subject(cert),
+ }
+ print(""".. sslcert:: {subject}
+ :altnames: {altnames}
+ :certfile: {certfile}
+ :keyfile: {keyfile}
+ :serial: {serial}
+ :expiration: {expiration}
+ :sha1fp: {sha1fp}
+ :issuer: {issuer}
+""".format(**data))
diff --git a/tools/tool-requirements.txt b/tools/tool-requirements.txt
new file mode 100644
index 0000000..dea6235
--- /dev/null
+++ b/tools/tool-requirements.txt
@@ -0,0 +1,4 @@
+pkg-resources==0.0.0
+pyasn1==0.1.9
+pyasn1-modules==0.0.8
+git+https://github.com/hiviah/pyx509@a35702c3d514c96d75a1c3498307a16991cdd0d3#egg=pyx509