source: trunk/locker/sbin/vhostcert @ 2793

Last change on this file since 2793 was 2793, checked in by andersk, 8 years ago
vhostcert: New tool for converting certificate chains to/from LDAP format
  • Property svn:executable set to *
File size: 1.9 KB
Line 
1#!/usr/bin/python
2
3from __future__ import print_function
4
5import base64
6import re
7import sys
8from OpenSSL import crypto
9
10def debug_chain(chain):
11    for i, c in enumerate(chain):
12        print(i, 's:', c.get_subject(), file=sys.stderr)
13        print(i, 'i:', c.get_issuer(), file=sys.stderr)
14    print(file=sys.stderr)
15
16def pem_to_scripts(data):
17    certs = [
18        crypto.load_certificate(crypto.FILETYPE_PEM, m.group(0))
19        for m in
20        re.finditer(
21            b'-----BEGIN CERTIFICATE-----\r?\n.+?\r?\n-----END CERTIFICATE-----',
22            data, re.DOTALL)
23    ]
24
25    # Put the chain in the right order, and delete any self-signed root
26    leaf, = [c for c in certs if not any(
27        c1.get_issuer() == c.get_subject() for c1 in certs)]
28    chain = [leaf]
29    count = 1
30    while True:
31        issuers = [c for c in certs if chain[-1].get_issuer() == c.get_subject()]
32        if not issuers:
33            break
34        issuer, = issuers
35        assert issuer not in chain
36        count += 1
37        if issuer.get_issuer() == issuer.get_subject():
38            break
39        chain.append(issuer)
40    assert count == len(certs)
41
42    debug_chain(chain)
43
44    return b' '.join(base64.b64encode(
45        crypto.dump_certificate(crypto.FILETYPE_ASN1, c)) for c in chain)
46
47def scripts_to_pem(data):
48    chain = [
49        crypto.load_certificate(crypto.FILETYPE_ASN1, base64.b64decode(d))
50        for d in data.split(b' ')
51    ]
52
53    debug_chain(chain)
54
55    return b''.join(crypto.dump_certificate(crypto.FILETYPE_PEM, c) for c in chain)
56
57def __main__():
58    if sys.argv[1:] == ['import']:
59        print(pem_to_scripts(sys.stdin.read().encode()).decode())
60    elif sys.argv[1:] == ['export']:
61        print(scripts_to_pem(sys.stdin.read().encode()).decode(), end='')
62    else:
63        print('usage: {} {import|export}'.format(__file__), file=sys.stderr)
64
65if __name__ == '__main__':
66    sys.exit(__main__())
Note: See TracBrowser for help on using the repository browser.