-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathssl_chain_checker.py
More file actions
executable file
·87 lines (80 loc) · 2.69 KB
/
ssl_chain_checker.py
File metadata and controls
executable file
·87 lines (80 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env python3
import argparse
import datetime
import re
import subprocess
import sys
def get_cert_chain_from(filename):
begin_regex = r'^-+?BEGIN CERTIFICATE-+\n$'
end_regex = r'^-+?END CERTIFICATE-+\n?$'
chain = []
try:
with open(filename, 'rb') as f:
begin_seen = False
for line in f:
tline = line.decode()
if begin_seen:
cert.append(line)
r = re.fullmatch(end_regex, tline)
if r is not None:
begin_seen = False
chain.append(cert)
else:
r = re.fullmatch(begin_regex, tline)
if r is not None:
begin_seen = True
cert = [line]
except Exception as e:
print('When processing: {}, returned: {}'.format(filename, e), file=sys.stderr)
return chain
def _parse_openssl_data(lines):
d = {}
for line in lines:
key, data = line.split('=', maxsplit=1)
d[key] = data
return d
def get_openssl_data(cert):
cmd = [
'openssl',
'x509',
'-nameopt',
'RFC2253',
'-noout',
'-issuer',
'-subject',
'-dates',
]
r = subprocess.run(cmd, input=b''.join(cert), capture_output=True)
if r.returncode != 0:
print('{} returned: {}'.format(' '.join(cmd), r.returncode), file=sys.stderr)
return _parse_openssl_data([])
lines = [ l for l in r.stdout.decode('utf8').split('\n') if l ]
return _parse_openssl_data(lines)
def print_openssl_data(cert):
timeformat = '%b %d %H:%M:%S %Y %Z'
expired = 'YES'
if len(cert) == 0:
return
now = datetime.datetime.utcnow()
not_before = datetime.datetime.strptime(cert['notBefore'], timeformat)
not_after = datetime.datetime.strptime(cert['notAfter'], timeformat)
if not_before < now and now < not_after:
expired = 'NO'
print('Expired:', expired)
print('Issuer:', cert['issuer'])
print('Subject:', cert['subject'])
print('Not before:', cert['notBefore'])
print('Not after:', cert['notAfter'])
print()
def main():
parser = argparse.ArgumentParser(description='Print certificate chain and check if it is expired.')
parser.add_argument('certs', nargs='+', metavar='certificate', help='cert file to check')
args = parser.parse_args()
for f in args.certs:
chain = get_cert_chain_from(f)
if chain:
print('chain for {}\n'.format(f))
for cert in reversed(chain):
print_openssl_data(get_openssl_data(cert))
if __name__ == '__main__':
main()