1
#######################################################################
2
# openssl.cert.py Version 0.6.6
3
# (c) by Michael Stroeder, michael.stroeder@propack-data.de
4
########################################################################
5
# Module for accessing certificate files
6
########################################################################
8
import sys, string, os, time
10
import openssl, charset, certhelper
12
certformats = ['pem','der','txt','net']
13
X509v1_certattrlist = ['CN','Email','OU','O','L','ST','C']
16
########################################################################
17
# functions used throughout this module
18
########################################################################
21
def GuessFormatbyExt(certfilename):
22
ext = string.lower(os.path.splitext(certfilename)[1])
23
if ext in certformats:
29
def GetCertValues(certfilename,inform='',command='x509'):
31
command = string.lower(command)
33
opensslcommand = '%s x509 -in %s -fingerprint -inform %s -noout -subject -issuer -dates -serial -hash' % (openssl.bin_filename,certfilename,inform)
34
elif command == 'crl':
35
opensslcommand = '%s crl -in %s -inform %s -noout -issuer -lastupdate -nextupdate -hash' % (openssl.bin_filename,certfilename,inform)
39
pipe = os.popen(opensslcommand)
43
name, value = string.split(s,'=',1)
45
hash = string.strip(s)
46
result[name]=string.strip(value)
50
raise IOError,"Error %s: %s" % (rc,opensslcommand)
55
########################################################################
56
# X509CertificateClass
57
########################################################################
59
class X509CertificateClass:
61
def __init__(self,certfilename,inform=''):
63
self.filename = certfilename
65
self.format = GuessFormatbyExt(self.filename)
68
self.hash,certattrs = GetCertValues(self.filename,self.format,'x509')
69
self.issuer = openssl.db.SplitDN(certattrs.get('issuer',{}))
70
self.subject = openssl.db.SplitDN(certattrs.get('subject',{}))
71
self.serial = string.atoi(certattrs.get('serial','-1'),16)
72
self.notBefore = certattrs.get('notBefore','')
74
self.notBefore_secs = time.mktime(time.strptime(self.notBefore,'%b %d %H:%M:%S %Y GMT'))
76
self.notBefore_secs = 0
77
self.notAfter = certattrs.get('notAfter','')
79
self.notAfter_secs = time.mktime(time.strptime(self.notAfter,'%b %d %H:%M:%S %Y GMT'))
81
self.notAfter_secs = 0
83
certattrs_keys = certattrs.keys()
85
for i in certattrs_keys:
86
if i[-11:]=='Fingerprint':
87
self.fingerprint[string.upper(string.split(i)[0])] = string.split(certattrs[i],':')
89
# get serial number of certificate
91
return string.atoi(self.serial)
93
def getfingerprint(self,digest='md5',delimiter=':'):
94
digest = string.upper(digest)
95
if not digest in ['MD2','MD5','MDC2','RMD160','SHA','SHA1']:
96
raise ValueError, 'Illegal parameter for digest: %s' % digest
97
elif self.fingerprint.has_key(digest):
98
result = self.fingerprint[digest]
100
return certhelper.MD5Fingerprint(certhelper.pem2der(open(self.filename,'r').read()),delimiter)
102
return certhelper.SHA1Fingerprint(certhelper.pem2der(open(self.filename,'r').read()),delimiter)
104
opensslcommand = '%s x509 -in %s -inform %s -outform DER | %s %s' % (
105
openssl.bin_filename,
108
openssl.bin_filename,
111
f = os.popen(opensslcommand)
112
rawdigest = string.strip(f.read())
115
raise IOError,"Error %s: %s" % (rc,opensslcommand)
117
for i in range(len(rawdigest)/2):
118
result.append(rawdigest[2*i:2*(i+1)])
119
self.fingerprint[digest] = result
120
return string.upper(string.join(result,delimiter))
122
# return certificate in a string, desired format given in outform
123
def readcertfile(self,outform='PEM'):
124
if not (string.lower(outform) in certformats):
125
raise ValueError,'invalid certificate output format'
126
f = os.popen('%s x509 -in %s -inform %s -outform %s' % (openssl.bin_filename,self.filename,self.format,outform))
134
raise IOError,"Error %s: %s" % (rc,opensslcommand)
135
return string.join(result)
137
# Return a string containing the cert attributes
138
def asciiprint(self):
140
# Convert character sets
143
for attr in X509v1_certattrlist:
144
subjectdatalist.append('%-5s: %s' % (attr,string.strip(charset.asn12iso(self.subject.get(attr,'')))))
145
issuerdatalist.append('%-5s: %s' % (attr,string.strip(charset.asn12iso(self.issuer.get(attr,'')))))
147
return """This certificate belongs to:
150
This certificate was issued by:
155
This certificate is valid
158
Certificate Fingerprint:
162
string.join(subjectdatalist,'\n'),
163
string.join(issuerdatalist,'\n'),
167
self.getfingerprint('sha1'),
168
self.getfingerprint('md5'),
171
# Return a string containing a nice formatted <TABLE> with cert info
174
# Convert character sets
177
for attr in X509v1_certattrlist:
178
subjectdatalist.append(string.strip(charset.asn12html4(self.subject.get(attr,''))))
179
issuerdatalist.append(string.strip(charset.asn12html4(self.issuer.get(attr,''))))
182
<TABLE BORDER=1 WIDTH="100%%" CELLPADDING="5%%">
186
<DT><STRONG>This certificate belongs to:</STRONG></DT>
192
<DT><STRONG>This certificate was issued by:</STRONG></DT>
200
<DT><STRONG>Serial Number:</STRONG><DT>
202
<DT><STRONG>This certificate is valid from %s until %s.</STRONG></DT>
203
<DT><STRONG>Certificate Fingerprint:</STRONG></DT>
204
<DD><PRE>SHA-1: %s<BR>MD5: %s</PRE></DD>
210
string.join(subjectdatalist,'<BR>'),
211
string.join(issuerdatalist,'<BR>'),
215
self.getfingerprint('sha1'),
216
self.getfingerprint('md5'),
220
########################################################################
222
########################################################################
226
def __init__(self,crlfilename,inform=''):
227
self.filename = crlfilename
229
self.format = GuessFormatbyExt(self.filename)
232
self.hash,certattrs = GetCertValues(self.filename,self.format,'crl')
233
self.issuer = openssl.db.SplitDN(certattrs.get('issuer',openssl.db.empty_DN_dict))
234
self.hash = certattrs.get('hash','')
235
self.lastUpdate = certattrs.get('lastUpdate','')
237
self.lastUpdate_secs = time.mktime(time.strptime(self.lastUpdate,'%b %d %H:%M:%S %Y GMT'))
239
self.lastUpdate_secs = 0
240
self.nextUpdate = certattrs.get('nextUpdate','')
242
self.nextUpdate_secs = time.mktime(time.strptime(self.nextUpdate,'%b %d %H:%M:%S %Y GMT'))
244
self.notAfter_secs = 0
246
# return certificate in a string, desired format given in outform
247
def readcertfile(self,outform='PEM'):
248
if not (string.lower(outform) in certformats):
249
raise ValueError,'invalid certificate output format'
250
f = os.popen('%s crl -in %s -inform %s -outform %s' % (openssl.bin_filename,self.filename,self.format,outform))
258
raise IOError,"Error %s: %s" % (rc,opensslcommand)
259
return string.join(result)
262
########################################################################
264
########################################################################
268
def __init__(self,spkacfilename,inform=''):
269
self.filename = spkacfilename
271
spkacfile = open(self.filename,'r')
272
s = spkacfile.readline()
275
attr,value=string.split(s,'=',1)
276
self.data[string.strip(attr)]=string.strip(value)
279
s = spkacfile.readline()