Use full year for expiration date
[cacert-infradocs.git] / tools / sslcert.py
1 #!/usr/bin/env python
2
3 from __future__ import print_function
4
5 from datetime import datetime
6 from hashlib import sha1
7 import argparse
8 import os.path
9
10 from pyasn1_modules import pem
11 from pyx509.pkcs7.asn1_models.X509_certificate import Certificate
12 from pyx509.pkcs7_models import X509Certificate
13 from pyx509.pkcs7.asn1_models.decoder_workarounds import decode
14
15
16 ALTNAME_MAP = (
17 ('dNSName', 'DNS'),
18 ('rfc822Name', 'EMAIL'),
19 ('iPAddress', 'IP')
20 )
21
22
23 def x509_parse(derData):
24 """Decodes certificate.
25 @param derData: DER-encoded certificate string
26 @returns: pkcs7_models.X509Certificate
27 """
28 cert = decode(derData, asn1Spec=Certificate())[0]
29 x509cert = X509Certificate(cert)
30 return x509cert
31
32
33 def get_altnames(cert):
34 altnames = cert.tbsCertificate.subjAltNameExt.value.values
35 retval = []
36 for typ, data in [(field[1], altnames[field[0]]) for field in ALTNAME_MAP]:
37 for item in sorted(data):
38 retval.append("{typ}:{item}".format(typ=typ, item=item))
39 return ", ".join(retval)
40
41
42 def get_serial(cert):
43 serial = "%X" % cert.tbsCertificate.serial_number
44 return "0" * (len(serial) % 2) + serial
45
46
47 def get_expiration(cert):
48 return datetime.strptime(
49 cert.tbsCertificate.validity.valid_to, '%Y%m%d%H%M%SZ'
50 ).strftime('%b %d %H:%M:%S %Y GMT')
51
52
53 def get_sha1fp(certdata):
54 hexhash = sha1(certdata).hexdigest().upper()
55 return ":".join([hexhash[i:i+2] for i in range(0, len(hexhash), 2)])
56
57
58 def get_issuer(cert):
59 return cert.tbsCertificate.issuer.get_attributes()['CN'][0]
60
61
62 def get_subject(cert):
63 return cert.tbsCertificate.subject.get_attributes()['CN'][0]
64
65
66 if __name__ == '__main__':
67 parser = argparse.ArgumentParser(
68 description=(
69 'Create an sslcert directive from data taken from a PEM encoded '
70 'X.509 certificate file and its corresponding PEM encoded RSA key '
71 'file.'))
72 parser.add_argument(
73 'cert', metavar='CERT', type=open,
74 help='PEM encoded X.509 certficate file')
75 parser.add_argument(
76 '--key', metavar='KEY', type=open,
77 help='PEM encoded RSA private key', default=None)
78 parser.add_argument(
79 '--root', metavar='ROOT', type=str,
80 help='Relative root directory for key and cert')
81
82 args = parser.parse_args()
83
84 certpem = pem.readPemFromFile(args.cert)
85 certpath = os.path.abspath(args.cert.name)
86 if args.root:
87 certpath = '/' + os.path.relpath(certpath, args.root)
88 if args.key:
89 haskey = True
90 keypem = pem.readPemFromFile(args.key)
91 keypath = os.path.abspath(args.key.name)
92 if args.root:
93 keypath = '/' + os.path.relpath(keypath, args.root)
94 else:
95 keypath = 'TODO: define key path'
96
97 cert = x509_parse(certpem)
98 data = {
99 'altnames': get_altnames(cert),
100 'certfile': certpath,
101 'keyfile': keypath,
102 'serial': get_serial(cert),
103 'expiration': get_expiration(cert),
104 'sha1fp': get_sha1fp(certpem),
105 'issuer': get_issuer(cert),
106 'subject': get_subject(cert),
107 }
108 print(""".. sslcert:: {subject}
109 :altnames: {altnames}
110 :certfile: {certfile}
111 :keyfile: {keyfile}
112 :serial: {serial}
113 :expiration: {expiration}
114 :sha1fp: {sha1fp}
115 :issuer: {issuer}
116 """.format(**data))