5
(c) by Michael Stroeder <michael@stroeder.com>
7
CGI-BIN for viewing certificates
8
with Netscape Navigator and M$ Internet Explorer
13
- Name of CA in openssl.cnf (section [ca] of openssl.cnf)
14
- Type of certificate ('email', 'user', 'ca', 'crl')
15
QUERY_STRING only for ('email', 'user')
16
- Serial number of desired certificate
17
max. 8 digits hexadecimal (32 Bit)
20
view-cert.py/Persona/ca
21
displays CA certificate of CA "Persona"
23
view-cert.py/Persona/email?01
24
displays client certificate of CA "Persona" with serial 0x01
26
view-cert.py/Server/crl
27
displays CRL of CA "Server"
29
view-cert.py/Server/server?01
30
displays server certificate of CA "Server" with serial 0x01
35
import sys,os,string,re,pycacnf,htmlbase,openssl,charset
37
from time import time,localtime,strftime,mktime
39
from pycacnf import opensslcnf, pyca_section
41
from openssl.db import \
43
DB_type,DB_exp_date,DB_rev_date,DB_serial,DB_file,DB_name,DB_number, \
44
DB_TYPE_REV,DB_TYPE_EXP,DB_TYPE_VAL, \
45
dbtime2tuple,GetEntriesbyDN,SplitDN
47
# Wir lesen rein gar nix von Standardeingabe => gleich dicht machen
50
# Path to openssl executable
51
openssl.bin_filename = pyca_section.get('OpenSSLExec','/usr/bin/openssl')
53
# Ein paar Umgebungsvariablen auslesen, welche der Apache liefert
54
request_method = os.environ.get('REQUEST_METHOD','')
55
query_string = os.environ.get('QUERY_STRING','')
56
path_info = os.environ.get('PATH_INFO','')[1:]
58
nsBaseUrl = pyca_section.get('nsBaseUrl','/')
59
nsGetCertUrl = pyca_section.get('nsGetCertUrl','get-cert.py')
60
nsViewCertUrl = pyca_section.get('nsViewCertUrl','view-cert.py')
62
# Hier die ueblichen Paranoid-Pruefungen der Parameter
64
if request_method!='GET':
65
# Skript nicht mit GET aufgerufen
66
htmlbase.PrintErrorMsg('Wrong method.')
69
# Bezeichnung der Sub-CA und MIME-Typ aus PATH_INFO splitten
71
ca_name, cert_typeandformat = string.split(path_info,'/',1)
72
cert_typeandformat=string.lower(cert_typeandformat)
74
htmlbase.PrintErrorMsg('Invalid parameter format.')
78
if not opensslcnf.data['ca'].has_key(ca_name):
79
# CA-Definition nicht in openssl-Konfiguration enthalten
80
htmlbase.PrintErrorMsg('Unknown certificate authority "%s".' % ca_name)
83
if re.compile('^(ca|crl|server|user|email)(.(der|pem|b64|crt|crl))*$').match(cert_typeandformat) is None:
84
htmlbase.PrintErrorMsg('Certificate type has invalid format.')
88
cert_type,cert_format = string.split(cert_typeandformat,'.',1)
90
cert_type,cert_format = cert_typeandformat,'der'
91
if cert_format=='crt' or cert_format=='crl':
94
if len(query_string)>8:
95
# Seriennummer mit mehr 32 Bit
96
htmlbase.PrintErrorMsg('Serial number too long.')
99
if (not cert_type in ['ca','crl']) and (not query_string):
101
htmlbase.PrintErrorMsg('No serial number.')
106
ca = opensslcnf.getcadata(ca_name)
109
# Abruf des CA-Zertifikates
110
certfilename = ca.certificate
111
elif cert_type=='crl':
112
certfilename = ca.crl
113
elif cert_type in ['user','email','server']:
114
if re.compile('^[0-9a-fA-F]+$').match(query_string) is None:
115
# Parameter war keine Hex-Nummer
116
htmlbase.PrintErrorMsg('Serial number not in hexadecimal format.')
118
# Abruf eines Zertifikates mittels Seriennummer
119
serialnumber=string.atoi(query_string,16)
120
entry = openssl.db.GetEntrybySerial(ca.database,serialnumber)
121
# Kein entsprechender Eintrag gefunden
123
htmlbase.PrintErrorMsg('Certificate not found.')
125
certfilename = os.path.join(ca.certs,'%s.pem' % (entry[DB_serial]))
127
# Zertifikattyp war nicht gueltig
128
htmlbase.PrintErrorMsg('Invalid certificate type "%s"' % cert_type)
131
# Does the certificate file exist?
132
if not os.path.isfile(certfilename):
133
htmlbase.PrintErrorMsg('Certificate file not found.')
138
htmlbase.PrintHeader('View CRL')
139
htmlbase.PrintHeading('View CRL')
140
crl = openssl.cert.CRLClass(certfilename)
142
for attr in openssl.cert.X509v1_certattrlist:
143
issuerdatalist.append(string.strip(charset.asn12html4(crl.issuer.get(attr,''))))
146
<DT><STRONG>This CRL was issued by:</STRONG></DT>
148
<DT><STRONG>last updated:</STRONG></DT>
150
<DT><STRONG>next update:</STRONG></DT>
153
<P><A HREF="%s%s/%s/crl.crl">Download CRL</A></P>
154
<HR><FONT SIZE=-1><PRE>
156
string.join(issuerdatalist,'<BR>'),
157
crl.lastUpdate,crl.nextUpdate,
158
nsBaseUrl,nsGetCertUrl,ca_name
161
os.system('%s crl -inform PEM -in "%s" -noout -text' %(openssl.bin_filename,ca.crl))
163
print '</PRE></FONT>'
164
htmlbase.PrintFooter()
166
elif cert_type=='ca':
168
htmlbase.PrintHeader('View CA Certificate')
169
htmlbase.PrintHeading('View CA Certificate')
170
cert = openssl.cert.X509CertificateClass(certfilename)
175
<A HREF="%s%s/%s/ca.crt">Download certificate</A>
177
<HR><FONT SIZE=-1><PRE>
178
""" % (cert.htmlprint(),nsBaseUrl,nsGetCertUrl,ca_name)
181
os.system('%s x509 -inform PEM -in "%s" -noout -text' %(openssl.bin_filename,certfilename))
184
print '</PRE></FONT>'
185
htmlbase.PrintFooter()
187
elif cert_type in ['user','email','server']:
189
htmlbase.PrintHeader('View Certificate')
190
htmlbase.PrintHeading('View Certificate')
191
cert = openssl.cert.X509CertificateClass(certfilename)
192
if entry[DB_type]==openssl.db.DB_TYPE_VAL:
193
statusstr = 'Certificate is valid.'
194
elif entry[DB_type]==openssl.db.DB_TYPE_REV:
195
statusstr = 'Certificate revoked since %s.' % (strftime('%Y-%m-%d %H:%M',localtime(mktime(dbtime2tuple(entry[DB_rev_date])))))
196
elif entry[DB_type]==openssl.db.DB_TYPE_EXP:
197
statusstr = 'Certificate expired.'
201
<DT><STRONG>Current status</STRONG>:</DT>
207
""" % (statusstr,cert.htmlprint())
210
<A HREF="%s%s/%s/%s.crt?%s">Download certificate</A>
211
<A HREF="%s%s/%s/ca.crt">View issuer certificate</A>
213
<HR><FONT SIZE=-1><PRE>
215
nsBaseUrl,nsGetCertUrl,ca_name,cert_type,entry[DB_serial],
216
nsBaseUrl,nsViewCertUrl,ca_name
219
os.system('%s x509 -inform PEM -in "%s" -noout -text' %(openssl.bin_filename,certfilename))
221
print '</PRE></FONT>'
222
htmlbase.PrintFooter()