Update certificate information for test.cacert.org.
[cacert-infradocs.git] / tools / sslcert.py
1 #!/usr/bin/env python3
2
3 from __future__ import print_function
4
5 import argparse
6 import os.path
7 from hashlib import sha1
8
9 from asn1crypto import pem
10 from cryptography import x509
11 from cryptography.hazmat.backends import default_backend
12 from cryptography.x509.oid import ExtensionOID, NameOID
13
14 ALTNAME_MAP = (
15 (x509.DNSName, 'DNS'),
16 (x509.RFC822Name, 'EMAIL'),
17 (x509.IPAddress, 'IP')
18 )
19
20
21 def get_altnames(cert):
22 altnames = cert.extensions.get_extension_for_oid(
23 ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
24
25 retval = []
26 for altname_type, field_name in ALTNAME_MAP:
27 names = altnames.value.get_values_for_type(altname_type)
28 for item in sorted(names):
29 retval.append("{typ}:{item}".format(typ=field_name, item=item))
30 return ", ".join(retval)
31
32
33 def get_serial(cert):
34 serial = "%X" % cert.serial_number
35 return "0" * (len(serial) % 2) + serial
36
37
38 def get_expiration(cert):
39 return cert.not_valid_after.strftime('%b %d %H:%M:%S %Y GMT')
40
41
42 def get_sha1fp(pem_data):
43 cert_data = pem.unarmor(pem_data)
44 hex_hash = sha1(cert_data[2]).hexdigest().upper()
45 return ":".join([hex_hash[i:i + 2] for i in range(0, len(hex_hash), 2)])
46
47
48 def get_issuer(cert):
49 return cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value
50
51
52 def get_subject(cert):
53 return cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value
54
55
56 if __name__ == '__main__':
57 parser = argparse.ArgumentParser(
58 description=(
59 'Create an sslcert directive from data taken from a PEM encoded '
60 'X.509 certificate file and its corresponding PEM encoded RSA key '
61 'file.'))
62 parser.add_argument(
63 'cert', metavar='CERT', type=argparse.FileType('rb'),
64 help='PEM encoded X.509 certificate file')
65 parser.add_argument(
66 '--key', metavar='KEY', type=argparse.FileType('rb'),
67 help='PEM encoded RSA private key', default=None)
68 parser.add_argument(
69 '--root', metavar='ROOT', type=str,
70 help='Relative root directory for key and cert')
71
72 args = parser.parse_args()
73
74 cert_path = os.path.abspath(args.cert.name)
75 if args.root:
76 cert_path = '/' + os.path.relpath(cert_path, args.root)
77 if args.key:
78 has_key = True
79 key_path = os.path.abspath(args.key.name)
80 if args.root:
81 key_path = '/' + os.path.relpath(key_path, args.root)
82 else:
83 key_path = 'TODO: define key path'
84
85 cert_pem = args.cert.read()
86 certificate = x509.load_pem_x509_certificate(cert_pem, default_backend())
87 data = {
88 'altnames': get_altnames(certificate),
89 'certfile': cert_path,
90 'keyfile': key_path,
91 'serial': get_serial(certificate),
92 'expiration': get_expiration(certificate),
93 'sha1fp': get_sha1fp(cert_pem),
94 'issuer': get_issuer(certificate),
95 'subject': get_subject(certificate),
96 }
97 print(""".. sslcert:: {subject}
98 :altnames: {altnames}
99 :certfile: {certfile}
100 :keyfile: {keyfile}
101 :serial: {serial}
102 :expiration: {expiration}
103 :sha1fp: {sha1fp}
104 :issuer: {issuer}
105 """.format(**data))