~ubuntu-branches/ubuntu/maverick/pyca/maverick

« back to all changes in this revision

Viewing changes to pylib/openssl/cert.py

  • Committer: Bazaar Package Importer
  • Author(s): Lars Bahner
  • Date: 2003-12-02 19:39:35 UTC
  • Revision ID: james.westby@ubuntu.com-20031202193935-fzzt289mntvy6a8q
Tags: upstream-20031118
ImportĀ upstreamĀ versionĀ 20031118

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
########################################################################
 
7
 
 
8
import sys, string, os, time
 
9
 
 
10
import openssl, charset, certhelper
 
11
 
 
12
certformats = ['pem','der','txt','net']
 
13
X509v1_certattrlist = ['CN','Email','OU','O','L','ST','C']
 
14
 
 
15
 
 
16
########################################################################
 
17
# functions used throughout this module
 
18
########################################################################
 
19
 
 
20
 
 
21
def GuessFormatbyExt(certfilename):
 
22
  ext = string.lower(os.path.splitext(certfilename)[1])
 
23
  if ext in certformats:
 
24
    return ext
 
25
  else:
 
26
    return 'pem'
 
27
 
 
28
 
 
29
def GetCertValues(certfilename,inform='',command='x509'):
 
30
 
 
31
  command = string.lower(command)
 
32
  if command == 'x509':
 
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)
 
36
 
 
37
  result={}
 
38
  hash=''
 
39
  pipe = os.popen(opensslcommand)
 
40
  s=pipe.readline()
 
41
  while s:
 
42
    try:
 
43
      name, value = string.split(s,'=',1)
 
44
    except ValueError:
 
45
      hash = string.strip(s)
 
46
    result[name]=string.strip(value)
 
47
    s=pipe.readline()
 
48
  rc = pipe.close()
 
49
  if rc and rc!=256:
 
50
    raise IOError,"Error %s: %s" % (rc,opensslcommand)
 
51
 
 
52
  return hash, result
 
53
 
 
54
 
 
55
########################################################################
 
56
# X509CertificateClass
 
57
########################################################################
 
58
 
 
59
class X509CertificateClass:
 
60
 
 
61
  def __init__(self,certfilename,inform=''):
 
62
 
 
63
    self.filename = certfilename
 
64
    if not inform:
 
65
      self.format = GuessFormatbyExt(self.filename)
 
66
    else:
 
67
      self.format = inform
 
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','')
 
73
    if self.notBefore:
 
74
      self.notBefore_secs = time.mktime(time.strptime(self.notBefore,'%b %d %H:%M:%S %Y GMT'))
 
75
    else:
 
76
      self.notBefore_secs = 0
 
77
    self.notAfter = certattrs.get('notAfter','')
 
78
    if self.notAfter:
 
79
      self.notAfter_secs = time.mktime(time.strptime(self.notAfter,'%b %d %H:%M:%S %Y GMT'))
 
80
    else:
 
81
      self.notAfter_secs = 0
 
82
    # Fingerprint suchen
 
83
    certattrs_keys = certattrs.keys()
 
84
    self.fingerprint = {}
 
85
    for i in certattrs_keys:
 
86
      if i[-11:]=='Fingerprint':
 
87
        self.fingerprint[string.upper(string.split(i)[0])] = string.split(certattrs[i],':')
 
88
 
 
89
  # get serial number of certificate
 
90
  def serial(self):
 
91
    return string.atoi(self.serial)
 
92
 
 
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]
 
99
    elif digest=='MD5':
 
100
      return certhelper.MD5Fingerprint(certhelper.pem2der(open(self.filename,'r').read()),delimiter)
 
101
    elif digest=='SHA1':
 
102
      return certhelper.SHA1Fingerprint(certhelper.pem2der(open(self.filename,'r').read()),delimiter)
 
103
    else:
 
104
      opensslcommand = '%s x509 -in %s -inform %s -outform DER | %s %s' % (
 
105
        openssl.bin_filename,
 
106
        self.filename,
 
107
        self.format,
 
108
        openssl.bin_filename,
 
109
        string.lower(digest)
 
110
      )
 
111
      f = os.popen(opensslcommand)
 
112
      rawdigest = string.strip(f.read())
 
113
      rc = f.close()
 
114
      if rc and rc!=256:
 
115
        raise IOError,"Error %s: %s" % (rc,opensslcommand)
 
116
      result = []
 
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))
 
121
 
 
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))
 
127
    buf = f.read()
 
128
    result = []
 
129
    while buf:
 
130
      result.append(buf)
 
131
      buf = f.read()
 
132
    rc = f.close()
 
133
    if rc and rc!=256:
 
134
      raise IOError,"Error %s: %s" % (rc,opensslcommand)
 
135
    return string.join(result)
 
136
 
 
137
  # Return a string containing the cert attributes
 
138
  def asciiprint(self):
 
139
 
 
140
    # Convert character sets
 
141
    subjectdatalist = []
 
142
    issuerdatalist = []
 
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,'')))))
 
146
 
 
147
    return """This certificate belongs to:
 
148
%s
 
149
 
 
150
This certificate was issued by:
 
151
%s
 
152
 
 
153
Serial Number: %s
 
154
 
 
155
This certificate is valid
 
156
from %s until %s.
 
157
 
 
158
Certificate Fingerprint:
 
159
SHA-1: %s
 
160
MD5  : %s
 
161
""" % ( \
 
162
        string.join(subjectdatalist,'\n'),
 
163
        string.join(issuerdatalist,'\n'),
 
164
        self.serial,
 
165
        self.notBefore,
 
166
        self.notAfter,
 
167
        self.getfingerprint('sha1'),
 
168
        self.getfingerprint('md5'),
 
169
       )
 
170
 
 
171
  # Return a string containing a nice formatted <TABLE> with cert info
 
172
  def htmlprint(self):
 
173
 
 
174
    # Convert character sets
 
175
    subjectdatalist = []
 
176
    issuerdatalist = []
 
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,''))))
 
180
 
 
181
    return """
 
182
  <TABLE BORDER=1 WIDTH="100%%" CELLPADDING="5%%">
 
183
  <TR>
 
184
    <TD WIDTH="50%%">
 
185
      <DL>
 
186
        <DT><STRONG>This certificate belongs to:</STRONG></DT>
 
187
        <DD>%s</DD>
 
188
      </DL>
 
189
    </TD>
 
190
    <TD>
 
191
      <DL>
 
192
        <DT><STRONG>This certificate was issued by:</STRONG></DT>
 
193
        <DD>%s</DD>
 
194
      </DL>
 
195
    </TD>
 
196
  </TR>
 
197
  <TR>
 
198
    <TD COLSPAN=2>
 
199
      <DL>
 
200
        <DT><STRONG>Serial Number:</STRONG><DT>
 
201
        <DD>%s</DD>
 
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>
 
205
      </DL>
 
206
    </TD>
 
207
  </TR>
 
208
  </TABLE>
 
209
  """ % ( \
 
210
          string.join(subjectdatalist,'<BR>'),
 
211
          string.join(issuerdatalist,'<BR>'),
 
212
          self.serial,
 
213
          self.notBefore,
 
214
          self.notAfter,
 
215
          self.getfingerprint('sha1'),
 
216
          self.getfingerprint('md5'),
 
217
         )
 
218
 
 
219
 
 
220
########################################################################
 
221
# CRLClass
 
222
########################################################################
 
223
 
 
224
class CRLClass:
 
225
 
 
226
  def __init__(self,crlfilename,inform=''):
 
227
    self.filename = crlfilename
 
228
    if not inform:
 
229
      self.format = GuessFormatbyExt(self.filename)
 
230
    else:
 
231
      self.format = inform
 
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','')
 
236
    if self.lastUpdate:
 
237
      self.lastUpdate_secs = time.mktime(time.strptime(self.lastUpdate,'%b %d %H:%M:%S %Y GMT'))
 
238
    else:
 
239
      self.lastUpdate_secs = 0
 
240
    self.nextUpdate = certattrs.get('nextUpdate','')
 
241
    if self.nextUpdate:
 
242
      self.nextUpdate_secs = time.mktime(time.strptime(self.nextUpdate,'%b %d %H:%M:%S %Y GMT'))
 
243
    else:
 
244
      self.notAfter_secs = 0
 
245
 
 
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))
 
251
    buf = f.read()
 
252
    result = []
 
253
    while buf:
 
254
      result.append(buf)
 
255
      buf = f.read()
 
256
    rc = f.close()
 
257
    if rc and rc!=256:
 
258
      raise IOError,"Error %s: %s" % (rc,opensslcommand)
 
259
    return string.join(result)
 
260
 
 
261
 
 
262
########################################################################
 
263
# SPKACClass
 
264
########################################################################
 
265
 
 
266
class SPKACClass:
 
267
 
 
268
  def __init__(self,spkacfilename,inform=''):
 
269
    self.filename = spkacfilename
 
270
    self.data = {}
 
271
    spkacfile = open(self.filename,'r')
 
272
    s = spkacfile.readline()
 
273
    while s:
 
274
      try:
 
275
        attr,value=string.split(s,'=',1)
 
276
        self.data[string.strip(attr)]=string.strip(value)
 
277
      except ValueError:
 
278
        pass
 
279
      s = spkacfile.readline()
 
280