/
easyrsa_doctor.py
executable file
·115 lines (101 loc) · 5.76 KB
/
easyrsa_doctor.py
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#! /usr/bin/env python3
import datetime
from OpenSSL.crypto import load_crl
from OpenSSL.crypto import FILETYPE_PEM
from docopt import docopt
help = """Easy-rsa Doctor
This tool is intended to diagnose an index.txt file generated by easy-rsa (2 and 3).
This file keeps all the information on certificates up to date.
Without arguments, it displays all valid certificates.
You can use this tool to display expired certificates, revoked certificates, or certificates to expire in the next n days.
You can also analyse this file against a PEM formated CRL to find which certificates it revokes, and find missing revoked certificates in the CRL.
Usage:
easy_rsa_helper.py -i <index> [-w <days>]
easy_rsa_helper.py -i <index> [-r]
easy_rsa_helper.py -i <index> [-e]
easy_rsa_helper.py -i <index> --crl <crl> [-m]
Options:
-h --help Help
-i <index>, --index <index> index.txt file
-w <days>, --watch <days> Watch certificates to renew in the next n days
-e, --expired Print only expired certificates
-r, --revoked Print only revoked certificates
--crl <crl> Print revoked certificates in a PEM file
-m, --missing Find missing revoked certificates in PEM file
"""
def decode_date(date):
try:
date = datetime.datetime.strptime(date, "%y%m%d%H%M%SZ")
return date
except: # Happens when certificate revoked in CRL and not in index.txt
return u"No valid date found"
def print_cn(cert):
# Two formats exist for DN : cn_only and org
# Let's try both
try: # org format
return cert[5].split("=")[5][:-13].strip()
except IndexError: # maybe cn_only format ?
try:
return cert[5].split("=")[1].strip()
except:
print(u"Format error.")
exit(1)
def parse_crl():
rev_list = []
with open(arguments["--crl"]) as f:
pem = f.read()
crl = load_crl(FILETYPE_PEM, pem)
revoked = crl.get_revoked()
for r in revoked:
rev_list.append(r.get_serial().decode("utf-8"))
with open(arguments["--index"], "r") as index:
certifs = index.readlines()
for cert in certifs:
cert = cert.split("\t")
if cert[3] in rev_list and not arguments["--missing"]:
print(u"Revoked certificate found !")
if cert[0] != "R":
print(u"Not revoked in index.txt file")
print(u"CN : {0}".format(print_cn(cert)))
print(u"Revoked {0}\n".format(decode_date(cert[2])))
elif cert[0] == "R" and arguments["--missing"]:
if cert[3] not in rev_list:
print(u"Missing revoked certificate found !")
print(u"CN : {0}".format(print_cn(cert)))
print(u"Revoked {0}\n".format(decode_date(cert[2])))
def parse_index():
with open(arguments["--index"], "r") as index:
certifs = index.readlines()
for cert in certifs:
cert = cert.split("\t")
if cert[0] == "V" and not arguments["--revoked"]: # If certificate not revoked
if decode_date(cert[1]) > datetime.datetime.now() and not arguments["--expired"] and not arguments["--watch"]: # If not expired
delta = decode_date(cert[1]) - datetime.datetime.now()
print(u"CN : {0}".format(print_cn(cert)))
print(u"Expires after {0}".format(decode_date(cert[1])))
print(u"Expires in {0} days\n".format(delta.days))
elif arguments["--watch"]:
try:
days = int(arguments["--watch"])
except:
print(u"You did not entered a correct number of days. Exiting...")
exit(1)
if decode_date(cert[1]) > datetime.datetime.now() and decode_date(cert[1]) < datetime.datetime.now() + datetime.timedelta(days):
delta = decode_date(cert[1]) - datetime.datetime.now()
print(u"CN : {0}".format(print_cn(cert)))
print(u"Expires after {0}".format(decode_date(cert[1])))
print(u"Expires in {0} days\n".format(delta.days))
elif decode_date(cert[1]) < datetime.datetime.now() and arguments["--expired"]: # If expired
print(u"Certificat expired :")
print(u"CN : {0}".format(print_cn(cert)))
print(u"Expired since {0}\n".format(decode_date(cert[1])))
elif cert[0] == "R" and arguments["--revoked"]:
print(u"Certificat revoked :")
print(u"CN : {0}".format(print_cn(cert)))
print(u"Revoked {0}\n".format(decode_date(cert[2])))
if __name__ == "__main__":
arguments = docopt(help)
if arguments["--crl"]:
parse_crl()
else:
parse_index()