aboutsummaryrefslogtreecommitdiff
path: root/pow/POW-0.7/lib
diff options
context:
space:
mode:
Diffstat (limited to 'pow/POW-0.7/lib')
-rw-r--r--pow/POW-0.7/lib/__init__.py16
-rw-r--r--pow/POW-0.7/lib/_der.py2294
-rwxr-xr-xpow/POW-0.7/lib/_simpledb.py55
-rwxr-xr-xpow/POW-0.7/lib/pkix.py2087
4 files changed, 0 insertions, 4452 deletions
diff --git a/pow/POW-0.7/lib/__init__.py b/pow/POW-0.7/lib/__init__.py
deleted file mode 100644
index b150bbf1..00000000
--- a/pow/POW-0.7/lib/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from _POW import *
-from _POW import _docset
-
-## @mainpage
-##
-## Python OpenSSL Wrappers (POW) is an old (but well-written)
-## interface between Python and OpenSSL (ok, you could have guessed
-## that from the name). Sadly, it appears to have fallen by the
-## wayside, and M2Crypto is getting a lot more attention these days.
-##
-## POW ships with a submodule, POW.pkix, which includes a wonderful
-## set of pure-Python routines for dealing with ASN.1 encodings of
-## X.509v3 certificates, extensions, and related data. I haven't
-## found anything as good anywhere else. This code deserves to be
-## salvaged and put to work.
-
diff --git a/pow/POW-0.7/lib/_der.py b/pow/POW-0.7/lib/_der.py
deleted file mode 100644
index c7f58411..00000000
--- a/pow/POW-0.7/lib/_der.py
+++ /dev/null
@@ -1,2294 +0,0 @@
-#*****************************************************************************#
-#* *#
-#* Copyright (c) 2002, Peter Shannon *#
-#* All rights reserved. *#
-#* *#
-#* Redistribution and use in source and binary forms, with or without *#
-#* modification, are permitted provided that the following conditions *#
-#* are met: *#
-#* *#
-#* * Redistributions of source code must retain the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer. *#
-#* *#
-#* * Redistributions in binary form must reproduce the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer in the documentation and/or other materials *#
-#* provided with the distribution. *#
-#* *#
-#* * The name of the contributors may be used to endorse or promote *#
-#* products derived from this software without specific prior *#
-#* written permission. *#
-#* *#
-#* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *#
-#* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *#
-#* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *#
-#* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *#
-#* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *#
-#* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *#
-#* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *#
-#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *#
-#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *#
-#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *#
-#* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *#
-#* *#
-#*****************************************************************************#
-
-import exceptions, types, copy, string, time, base64, traceback, cStringIO
-
-DEBUG = 0
-
-# CLASS
-CLASS_UNIVERSAL = 0x00
-CLASS_APPLICATION = 0x40
-CLASS_CONTEXT = 0x80
-CLASS_PRIVATE = 0xC0
-
-# FORM
-FORM_PRIMITIVE = 0x00
-FORM_CONSTRUCTED = 0x20
-
-# TAG
-TAG_BOOLEAN = 0x01
-TAG_INTEGER = 0x02
-TAG_BITSTRING = 0x03
-TAG_OCTETSTRING = 0x04
-TAG_NULL = 0x05
-TAG_OID = 0x06
-TAG_OBJDESCRIPTOR = 0x07
-TAG_EXTERNAL = 0x08
-TAG_REAL = 0x09
-TAG_ENUMERATED = 0x0A
-TAG_EMBEDDED_PDV = 0x0B
-TAG_UTF8STRING = 0x0C
-TAG_SEQUENCE = 0x10
-TAG_SET = 0x11
-TAG_NUMERICSTRING = 0x12
-TAG_PRINTABLESTRING = 0x13
-TAG_T61STRING = 0x14
-TAG_VIDEOTEXSTRING = 0x15
-TAG_IA5STRING = 0x16
-TAG_UTCTIME = 0x17
-TAG_GENERALIZEDTIME = 0x18
-TAG_GRAPHICSTRING = 0x19
-TAG_VISIBLESTRING = 0x1A
-TAG_GENERALSTRING = 0x1B
-TAG_UNIVERSALSTRING = 0x1C
-TAG_BMPSTRING = 0x1E
-
-_fragments = []
-
-def _docset():
- return _fragments
-
-def _addFragment(frag):
- global _fragments
- _fragments.append(frag)
-
-
-_addFragment('''
-<moduleDescription>
- <header>
- <name>POW.pkix</name>
- <author>Peter Shannon</author>
- </header>
- <body>
- <para>
- This module is a solution to reading and writing X509v3 written
- purely in Python. It does use limited facilities from POW for
- signing and verifying but these could be replaced easily. It is
- an abstract module and to use it successfully RFC3280 should be
- referred to as well as the sourcecode where necessary. The correct
- use of many extensions often not clear from the definitions alone.
- Do refer to the RFC for details.
- </para>
- <para>
- Each constructed objects defined in the RFC is built from primitives
- defined by the ASN1 recommedations. Not all ASN1 primitive are available but all those
- required for X509v3 should be. The implementation is more or less
- complete for DER encoding the only caveat, aside from a few
- missing objects, is the behaviour of <classname>SET</classname> objects
- and <classname>SET OF</classname> objects. The order the objects are
- written in should be determined at runtime by sorting their tags but this
- library does not do this. For X509 it isn't really necessary
- since all the <classname>Set</classname> objects are simple and the
- order they are written in is defined by the object's constructor.
- </para>
- <para>
- Every documented object in this module supports the functions documented for
- <classname>_GeneralObject</classname>. In general the function
- will only be documented in descendant classes if the class changes
- the behaviour significantly from its ancestor. This would
- normally be <classname>_GeneralObject</classname> or
- <classname>Sequence</classname>.
- </para>
- </body>
-</moduleDescription>
-''')
-
-class DerError(Exception):
- def __init__(self, msg):
- if not isinstance(msg, types.StringType):
- raise Exception, 'argunment should be a string'
- self.msg = msg
-
- def __repr__(self):
- return self.msg
-
- __str__ = __repr__
-
-class _Tag(object):
- def __init__(self):
- self.tagclass = 0
- self.tagform = 0
- self.tagnumber = 0
-
- def __repr__(self):
- return '(%s, %s, %s)' % (self.tagclass, self.tagform, self.tagnumber)
-
- def write(self, file):
- if self.tagnumber < 31:
- file.write( chr(self.tagclass | self.tagform | self.tagnumber) )
- else:
- val = copy.deepcopy(self.tagnumber)
- bytes = []
- while val:
- byte = val & 0x7F
- bytes.append(byte | 0x80)
- val = val >> 7
- bytes[0] = bytes[0] ^ 0x80
- bytes.append( self.tagclass | self.tagform | 0x1F )
- bytes.reverse()
- file.write( string.join(map(chr, bytes), '') )
-
- def read(self, file):
- octet1 = ord( file.read(1) )
- self.tagclass = octet1 & 0xC0
- self.tagform = octet1 & 0x20
- value = octet1 & 0x1F
- if value < 31:
- self.tagnumber = value
- else:
- total = 0
- byte = 0x80
- while byte & 0x80:
- byte = ord( file.read(1) )
- if byte & 0x80:
- total = (total << 7) | byte ^ 0x80
- else:
- total = (total << 7) | byte
- self.tagnumber = total
-
-class _Length(object):
- def __init__(self):
- self.length = 0
-
- def __repr__(self):
- return '(%s)' % self.length
-
- def write(self, file):
- if self.length < 128:
- file.write( chr(self.length) )
- else:
- val = copy.deepcopy(self.length)
- bytes = []
- while val:
- byte = val & 0xFF
- bytes.append(byte)
- val = val >> 8
- lengthOfLength = len(bytes)
- if lengthOfLength > 126:
- raise DerError, 'object is too long!'
- bytes.append(lengthOfLength)
- bytes.reverse()
- bytes[0] = bytes[0] ^ 0x80
- file.write( string.join(map(chr, bytes), '') )
-
- def read(self, file):
- octet1 = ord( file.read(1) )
- if octet1 < 128:
- self.length = octet1
- else:
- total = 0
- byte = 0
- for i in range(octet1 ^ 0x80):
- byte = ord( file.read(1) )
- total = (total << 8) | byte
- self.length = total
-
-class _TlvIo(_Tag, _Length):
- def __init__(self, file):
- self.file = file
- self.offset = None
- self.valueOffset = None
-
- def __repr__(self):
- return '<TAG:%s Length:%s>' % (_Tag.__repr__(self), _Length.__repr__(self))
-
- def __nonzero__(self):
- pos = self.file.tell()
- self.file.seek(0,2)
- if self.file.tell():
- self.file.seek(pos)
- return 1
- else:
- return 0
-
- def read(self):
- self.offset = self.file.tell()
- _Tag.read( self, self.file )
- _Length.read( self, self.file )
- self.valueOffset = self.file.tell()
- self.file.seek( self.length, 1 )
-
- def readValue(self):
- self.file.seek( self.valueOffset )
- return self.file.read( self.length )
-
- def write(self, val):
- _Tag.write( self, self.file )
- self.length = len(val)
- _Length.write( self, self.file )
- self.file.write(val)
-
-def _decodeBoolean(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- if ord(val) == 0xFF:
- return 1
- elif ord(val) == 0x00:
- return 0
- else:
- raise DerError, 'boolean should be encode as all 1s or all 0s'
-
-def _encodeBoolean(val):
- 'anything we can test for truth'
- if val:
- return chr(0xFF)
- else:
- return chr(0x00)
-
-def _decodeInteger(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- total = 0L
- if ord(val[0]) & 0x80:
- val = map( lambda x : ord(x) ^ 0xFF, val )
- for byte in val:
- total = (total << 8) | byte
- total = -(total+1)
- else:
- for byte in val:
- total = (total << 8) | ord(byte)
- return total
-
-def _encodeInteger(val):
- 'python integer'
- if not isinstance(val, types.IntType) and not isinstance(val, types.LongType):
- raise DerError, 'argument should be an integer'
- if val == 0:
- return chr(0x00)
- else:
- val2 = copy.deepcopy(val)
- if val2 < 0:
- val2 = -(val2+1)
- bytes = []
- byte = 0
- while val2:
- byte = val2 & 0xFF
- bytes.append(byte)
- val2 = val2 >> 8
- # if we have no used up the last byte to represent the value we need
- # to add one more on to show if this is negative of positive. Also,
- # due to adding 1 and inverting -1 would be 0 or if 0 is the encoding
- # value, so bytes would empty and this would lead to and empty value
- # and this would not be working properly. Adding this null byte
- # fixes this, since it is inverted to -1 and preserved for 0.
- if byte & 0x80 or not bytes:
- bytes.append(0x00)
- if val < 0:
- bytes = map( lambda x : x ^ 0xFF, bytes )
- bytes.reverse()
-
- return string.join(map(chr, bytes), '')
-
-def _decodeBitString(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- bitmasks = [0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01]
- unused = ord( val[0] )
- bits = []
- for byte in val[1:]:
- for j in range(8):
- if ord(byte) & bitmasks[j]:
- bits.append(1)
- else:
- bits.append(0)
- if unused == 0:
- return tuple(bits)
- else:
- return tuple(bits[:-unused])
-
-def _encodeBitString(val):
- 'list of true/false objects ie [0,1,1,0,1,1]'
- if not (isinstance(val, types.ListType) or isinstance(val, types.TupleType)):
- raise DerError, 'argument should be a list or tuple'
- bitmasks = [0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01]
- bytes = []
- fits, leftover = divmod(len(val), 8)
- nobytes = fits
- if leftover > 0:
- nobytes = nobytes + 1
- if leftover:
- unused = 8 - leftover
- else:
- unused = 0
- bytes.append(unused)
- for i in range(nobytes):
- byte = 0
- for j in range(8):
- offset = j + i*8
- if offset < len(val):
- if val[offset]:
- byte = byte | bitmasks[j]
- bytes.append(byte)
-
- return string.join(map(chr, bytes), '')
-
-def _decodeOid(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- arc12 = ord( val[0] )
- arc1, arc2 = divmod(arc12, 40)
- oids = [arc1,arc2]
-
- total = 0
- for byte in val[1:]:
- val = ord(byte)
- if val & 0x80:
- total = (total << 7) | (val ^ 0x80)
- else:
- total = (total << 7) | val
- oids.append(total)
- total = 0
-
- return tuple(oids)
-
-def _encodeOid(val):
- 'list of intgers'
- if not (isinstance(val, types.ListType) or isinstance(val, types.TupleType)):
- raise DerError, 'argument should be a list or tuple'
- oids = []
- oids.append( chr(40 * val[0] + val[1]) )
- for val in val[2:]:
- if val == 0:
- oids.append( chr(0) )
- else:
- bytes = []
- while val:
- val, rem = divmod(val, 128)
- bytes.append(rem | 0x80)
- bytes[0] = bytes[0] ^ 0x80
- bytes.reverse()
- oids.append( string.join(map(chr, bytes), '') )
-
- return string.join(oids, '')
-
-def _decodeSequence(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- buf = cStringIO.StringIO(val)
- buflen = len(val)
- tvls = []
- while buf.tell() < buflen:
- t = _TlvIo(buf)
- t.read()
- tvls.append(t)
- return tuple(tvls)
-
-def _encodeSequence(val):
- 'list of GenerlObjects'
- if not (isinstance(val, types.ListType) or isinstance(val, types.TupleType)):
- raise DerError, 'argument should be a list or tuple'
- buf = cStringIO.StringIO()
- for obj in val:
- if obj or isinstance(obj, _GeneralObject):
- obj.write(buf)
- elif not obj.optional:
- raise DerError, 'object not set which should be: %s' % obj
-
- return buf.getvalue()
-
-_addFragment('''
-<class>
- <header>
- <name>_GeneralObject</name>
- </header>
- <body>
- <para>
- <classname>_GeneralObject</classname> is the basis for all DER objects,
- primitive or constructed. It defines the basic behaviour of an
- object which is serialised using the tag, length and value
- approach of DER. It is unlikely you would ever want to
- instantiate one of these directly but I include a description
- since many primatives don't override much of
- <classname>_GeneralObject</classname>'s functions.
- </para>
- </body>
-</class>
-''')
-
-class _GeneralObject(object):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>_GeneralObject</memberof>
- <parameter>normclass</parameter>
- <parameter>normform</parameter>
- <parameter>normnumber</parameter>
- <parameter>encRoutine</parameter>
- <parameter>decRoutine</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- <parameter>normclass</parameter> is the class of the object,
- ei: universal, application, context or private.
- <parameter>normform</parameter> is the form of the object, ei
- primitive or constructed. <parameter>normnumber</parameter> is
- the tag number of the object.
- <parameter>encRoutine</parameter> is a function which takes a
- value and encodes it according the appropriate DER rules.
- <parameter>decRoutine</parameter> is a function which reads a
- string value and returns a value which is more useful in
- Python. <parameter>optional</parameter> is a boolean
- indicating if this object is optional. The final parameter,
- <parameter>default</parameter> is the base 64 encoded DER
- value, which should be used as the default in leu of a value to
- read or incase it is unset.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, normclass, normform, normnumber, encRoutine, decRoutine, optional=0, default=''):
- if not isinstance(normclass, types.IntType):
- raise DerError, 'nomrclass argument should be an integer : %s' % normclass
- if not isinstance(normform, types.IntType):
- raise DerError, 'normform argument should be an integer : %s' % normform
- if not isinstance(normnumber, types.IntType):
- raise DerError, 'normnumber argument should be an integer : %s' % normnumber
- if not isinstance(encRoutine, types.FunctionType):
- raise DerError, 'encRoutine argument should be an function : %s' % encRoutine
- if not isinstance(decRoutine, types.FunctionType):
- raise DerError, 'decRoutine argument should be an function : %s' % decRoutine
- if not isinstance(optional, types.IntType):
- raise DerError, 'optional argument should be an integer : %s' % optional
- if not isinstance(default, types.StringType):
- raise DerError, 'default argument should be an String : %s' % default
- self.normclass = normclass
- self.normform = normform
- self.normnumber = normnumber
- self.encRoutine = encRoutine
- self.decRoutine = decRoutine
- self.value = None
- self.optional = optional
- self.default = default
- self.reset()
-
- def _ioSafe(self):
- 'is it safe to write this object'
- if self.optional or self._isSet():
- return 1
- else:
- return 0
-
- def _isSet(self):
- 'are the values of this object set or not'
- if self.value is not None:
- return 1
- else:
- return 0
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>reset</name>
- </header>
- <body>
- <para>
- This function re-initialises the object, clearing the value or
- setting it to any default.
- </para>
- </body>
- </method>
- ''')
- def reset(self):
- self.value = None
- if self.default:
- buf = cStringIO.StringIO( base64.decodestring( self.default ) )
- io = _TlvIo(buf)
- io.read()
- self.read(io)
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>set</name>
- <parameter>value</parameter>
- </header>
- <body>
- <para>
- This dosn't do much except store <parameter>value</parameter>,
- presumably prior to writing the object. The correct values to
- use would be determined by the encoder or decoder this class is
- instantiated with. Be careful, there is some flexibility in
- setting objects so you might find that once the object has been
- written and read back in the value isn't identical. A good
- example would be anything which contains a sequence(list or
- tuple), all sequence objects are returned as tuples.
- </para>
- </body>
- </method>
- ''')
- def set(self, value):
- if value is not None:
- self.value = value
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>get</name>
- </header>
- <body>
- <para>
- Gets the value stored presumably after reading the object.
- </para>
- </body>
- </method>
- ''')
- def get(self):
- return self.value
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>implied</name>
- <parameter>impclass</parameter>
- <parameter>impform</parameter>
- <parameter>impnumber</parameter>
- </header>
- <body>
- <para>
- This function is used to change how the tag is written or read
- for a particular object and should be called in the constructor
- for derived objects. If you have an example of the structure you need to
- process, Pete Gutmann's excellent
- <application>dumpasn1</application> can be invaluable for
- debugging objects.
- </para>
- </body>
- </method>
- ''')
- def implied(self, impclass, impform, impnumber):
- if not isinstance(impclass, types.IntType):
- raise DerError, 'impclass argument should be an integer'
- if not isinstance(impform, types.IntType):
- raise DerError, 'impform argument should be an integer'
- if not isinstance(impnumber, types.IntType):
- raise DerError, 'impnumber argument should be an integer'
- self.normclass = impclass
- self.normform = impform
- self.normnumber = impnumber
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>read</name>
- <parameter>io</parameter>
- </header>
- <body>
- <para>
- <parameter>io</parameter> should be a file like object. If the
- object being read matches the expected class, form and tag the
- value is read and decoded using
- <function>decRoutine</function>. Else, if it has a default
- that is read and stored.
- </para>
- <para>
- The return value of this function does not indicate success but
- whether this TLV was processed successfully. This bahaviour is
- vital for processing constructed types since the object may be
- optional or have a default. Failure to decode would be indicated
- by an exception.
- </para>
- </body>
- </method>
- ''')
-
- def read(self, io=None):
-
- processDefOpt = 0
- if io is None:
- processDefOpt = 1
- elif isinstance(io, _TlvIo):
- if not io:
- processDefOpt = 1
- else:
- pos = io.tell()
- io.seek(0,2)
- if io.tell():
- io.seek(pos)
- else:
- processDefOpt = 1
-
- if processDefOpt:
- if self.optional or self.default:
- self.reset()
- return 0
- else:
- raise DerError, 'no TLV is available to read in non-optional/non-default object: %s' % repr(self)
-
- if not isinstance(io, _TlvIo):
- tmp = _TlvIo(io)
- tmp.read()
- io = tmp
-
- if io.tagclass != self.normclass or io.tagform != self.normform or io.tagnumber != self.normnumber:
- if self.default or self.optional:
- self.reset()
- return 0
- else:
- raise DerError, 'error in encoding, missing object:%s' % repr(self)
- else:
- derval = io.readValue()
- self.value = self.decRoutine( derval )
- return 1
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>write</name>
- <parameter>io</parameter>
- </header>
- <body>
- <para>
- If this object has not been set and is not optional and dosn't
- have a default, a <classname>DerError</classname> exception will be raised
- </para>
- <para>
- If no value has been set and this object is optional, nothing
- is written. If this object's value is equal to the default,
- nothing is written as stipulated by DER. Otherwise the value
- is encoded and written.
- </para>
- </body>
- </method>
- ''')
-
- def write(self, file):
- if not self._ioSafe():
- raise DerError, 'object not set which must be: %s' % repr(self)
- elif self.optional and self.value is None:
- pass
- else:
- buf = cStringIO.StringIO()
- io = _TlvIo(buf)
- io.tagclass = self.normclass
- io.tagform = self.normform
- io.tagnumber = self.normnumber
- derval = self.encRoutine( self.value )
- io.length = len(derval)
- io.write(derval)
- if self.default:
- if buf.getvalue() != base64.decodestring(self.default):
- file.write( buf.getvalue() )
- else:
- file.write( buf.getvalue() )
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>toString</name>
- </header>
- <body>
- <para>
- Encodes the value in DER and returns it as a string.
- </para>
- </body>
- </method>
- ''')
-
- def toString(self):
- buf = cStringIO.StringIO()
- self.write(buf)
- return buf.getvalue()
-
- _addFragment('''
- <method>
- <header>
- <memberof>_GeneralObject</memberof>
- <name>fromString</name>
- </header>
- <body>
- <para>
- Decodes the string and sets the value of this object.
- </para>
- </body>
- </method>
- ''')
-
- def fromString(self, value):
- buf = cStringIO.StringIO(value)
- self.read(buf)
-
-class Any(_GeneralObject):
-
- def __init__(self):
- self.value = None
- self.normclass = None
- self.normform = None
- self.normnumber = None
-
- def _ioSafe(self):
- if self.optional or (self._isSet() and self.normclass is not None and self.normform is not None and self.normnumber is not None):
- return 1
- else:
- return 0
-
- def setTag(self, klass, form, number):
- self.normclass = klass
- self.normform = form
- self.normnumber = number
-
- def reset(self):
- self.value = None
-
- def get(self):
- return self.value
-
- def set(self, value):
- self.value = value
-
- def write(self,file):
- if not self._ioSafe():
- raise DerError, 'object not set which must be: %s' % repr(self)
- elif self.optional and self.value is None:
- pass
- else:
- buf = cStringIO.StringIO()
- io = _TlvIo(buf)
- io.tagclass = self.normclass
- io.tagform = self.normform
- io.tagnumber = self.normnumber
- io.length = len(self.value)
- io.write(self.value)
- file.write(buf.getvalue())
-
- def read(self, io=None):
-
- processDefOpt = 0
- if io is None:
- processDefOpt = 1
- elif isinstance(io, _TlvIo):
- if not io:
- processDefOpt = 1
- else:
- pos = io.tell()
- io.seek(0,2)
- if io.tell():
- io.seek(pos)
- else:
- processDefOpt = 1
- if processDefOpt:
- if self.optional or self.default:
- self.reset()
- return 0
- else:
- raise DerError, 'no TLV is available to read in non-optional/non-default object: %s' % repr(self)
-
- if not isinstance(io, _TlvIo):
- tmp = _TlvIo(io)
- tmp.read()
- io = tmp
-
- self.value = io.readValue()
- self.normclass = io.tagclass
- self.normform = io.tagform
- self.normnumber = io.tagnumber
-
-_addFragment('''
-<class>
- <header>
- <name>Boolean</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 BOOLEAN type. It can be set
- with any object which can be tested for truth.
- </para>
- </body>
-</class>
-''')
-
-class Boolean(_GeneralObject): # 0x01
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Boolean</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_BOOLEAN, _encodeBoolean, _decodeBoolean, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Integer</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 INTEGER type. It should be set
- with a Python integer.
- </para>
- </body>
-</class>
-''')
-
-class Integer(_GeneralObject): # 0x02
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Integer</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_INTEGER, _encodeInteger, _decodeInteger, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>BitString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 BIT STRING type. It should be set
- with a sequence of integers. A non-zero number will set the bit,
- zero will leave the bit unset.
- </para>
- </body>
-</class>
-''')
-
-class BitString(_GeneralObject): # 0x03
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>BitString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_BITSTRING, _encodeBitString, _decodeBitString, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>AltBitString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 BIT STRING type. It differs from
- the first <classname>BitString</classname> in that it's coding
- routines treat values as binary data and do not interpret the data
- in any way. Some application treat the
- <classname>BIT STRING</classname> in the same way as
- <classname>OCTET STRING</classname> type, hence this extra object.
- </para>
- </body>
-</class>
-''')
-
-class AltBitString(_GeneralObject): # 0x03
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>AltBitString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_BITSTRING, lambda x : chr(0)+x, lambda x : x[1:], optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>OctetString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 OCTET STRING type. This object
- can be set with any binary data.
- </para>
- </body>
-</class>
-''')
-class OctetString(_GeneralObject): # 0x04
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>OctetString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_OCTETSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Null</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 NULL type. There is no point in
- setting this object, the value will always be ignored when it is
- written out.
- </para>
- </body>
-</class>
-''')
-class Null(_GeneralObject): # 0x05
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Null</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_NULL, lambda x : '', lambda x : '', optional, default)
- self.value = ''
-
- def _ioSafe(self):
- return 1
-
- def reset(self):
- self.value = ''
-
-_addFragment('''
-<class>
- <header>
- <name>Oid</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 OID type. This object should be
- set with a list or tuple of integers defining an objects oid.
- Please note that the first three arcs have a restricted set of
- values, so encoding (5, 3, 7, 1) will produce bad results.
- </para>
- </body>
-</class>
-''')
-class Oid(_GeneralObject): # 0x06
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Oid</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_OID, _encodeOid, _decodeOid, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Enum</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 ENUM type. This should be set
- using a Python integer, the meaning should be described in the
- ASN1 document for the object you are encoding.
- </para>
- </body>
-</class>
-''')
-class Enum(_GeneralObject): # 0x0A
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Enum</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_ENUMERATED, _encodeInteger, _decodeInteger, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Utf8String</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 UTF8String type. This object
- should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class Utf8String(_GeneralObject): # 0x0C
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Utf8String</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_UTF8STRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>NumericString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 NumericString type. This should
- object should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class NumericString(_GeneralObject): # 0x12
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>NumericString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_NUMERICSTRING, lambda x : x, lambda x : x, optional, default)
-_addFragment('''
-<class>
- <header>
- <name>PrintableString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 PrintableString type. This should
- object should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class PrintableString(_GeneralObject): # 0x13
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>PrintableString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_PRINTABLESTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>T61String</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 T61String type. This object
- should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class T61String(_GeneralObject): # 0x14
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>T61String</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_T61STRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>VideotexString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 VideotexString type. This should
- object should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class VideotexString(_GeneralObject): # 0x15
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>VideotexString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_VIDEOTEXSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IA5String</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 IA5String type. This object
- should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class IA5String(_GeneralObject): # 0x16
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>IA5String</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_IA5STRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>UtcTime</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 UTCTime type. This object should
- be set with a string of the general format YYMMDDhhmmssZ. The
- helper functions <function>time2utc</function> and
- <function>utc2time</function> can be used to handle the conversion
- from an integer to a string and back.
- </para>
- </body>
-</class>
-''')
-class UtcTime(_GeneralObject): # 0x17
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>UtcTime</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_UTCTIME, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>GeneralizedTime</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 GeneralizedTime type. This object should
- be set with a string of the general format YYYYMMDDhhmmssZ. The
- helper functions <function>time2utc</function> and
- <function>utc2time</function> can be used to handle the conversion
- from an integer to a string and back.
- </para>
- </body>
-</class>
-''')
-class GeneralizedTime(_GeneralObject): # 0x18
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>GeneralizedTime</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_GENERALIZEDTIME, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>GraphicString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 GraphicString type. This should
- object should be set with a string. It is up to the application to
- ensure it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class GraphicString(_GeneralObject): # 0x19
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>GraphicString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_GRAPHICSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>VisibleString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 VisibleString type. This should
- object should be set with a string. It is up to the application to
- ensure it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class VisibleString(_GeneralObject): # 0xC0
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>VisibleString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_VISIBLESTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>GeneralString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 GeneralString type. This should
- object should be set with a string. It is up to the application to
- ensure it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class GeneralString(_GeneralObject): # 0xC0
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>GeneralString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_GENERALSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>UniversalString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 UniversalString type. This should
- object should be set with a string. It is up to the application to
- ensure it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class UniversalString(_GeneralObject): # 0xC0
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>UniversalString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_UNIVERSALSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>BmpString</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 BMPString type. This object
- should be set with a string. It is up to the application to ensure
- it only contains valid characters for this type.
- </para>
- </body>
-</class>
-''')
-class BmpString(_GeneralObject): # 0xC0
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>BmpString</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
-
- def __init__(self, optional=0, default=''):
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_PRIMITIVE, TAG_BMPSTRING, lambda x : x, lambda x : x, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Sequence</name>
- <super>_GeneralObject</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 SEQUENCE type.
- </para>
- </body>
-</class>
-''')
-class Sequence(_GeneralObject): # 0x10
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Sequence</memberof>
- <super>_GeneralObject</super>
- <parameter>contents</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- The <parameter>contents</parameter> should be a list or tuple containing
- the contents of the sequence.
- Two important members are initialised this this constructor.
- First <constant>self.next</constant> this is used to keep track
- of which TLVs in this sequence has been read succesfully. The second,
- <constant>self.contents</constant> should be set to the list of
- objects stored in this sequence. Note that the order they are
- specified in is the order in which they are written or read.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, contents, optional=0, default=''):
- self.contents = contents
- self.next = 0
- _GeneralObject.__init__(self, CLASS_UNIVERSAL, FORM_CONSTRUCTED, TAG_SEQUENCE, _encodeSequence, _decodeSequence, optional, default)
-
- def _childRead(self, obj):
- if self.next < len(self.value):
- if obj.read( self.value[self.next] ):
- self.next += 1
- else:
- obj.read()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Sequence</memberof>
- <name>readContents</name>
- <parameter>io</parameter>
- <parameter>contents</parameter>
- </header>
- <body>
- <para>
- This function implements basic SEQUENCE like reading behaviour.
- It will attempt to read each of the objects in
- <parameter>contents</parameter> in turn from
- <parameter>io</parameter>. It exists as a function, separate
- from <function>read</function> for the benefit of the SEQUENCE
- OF implementation.
- </para>
- <para>
- The TLV of this SEQUENCE is read and parsed into a list of
- TLVs, which are store in <constant>self.value</constant>, by
- <classname>_GeneralObject</classname>.<function>read</function>.
- Then <function>read</function> is called on each member to
- process each TLV in turn. The next TLV is moved onto only when
- a member returns TRUE from the read call.
- </para>
- </body>
- </method>
- ''')
-
- def readContents(self, io, contents):
- if _GeneralObject.read( self, io ):
- for item in contents:
- Sequence._childRead( self, item )
- return 1
- else:
- return 0
-
- _addFragment('''
- <method>
- <header>
- <memberof>Sequence</memberof>
- <name>read</name>
- <parameter>io</parameter>
- </header>
- <body>
- <para>
- Most of the logic for reading is implemented in <function>readContents</function>
- so it can be reused for <classname>SequenceOf</classname>'s
- <function>read</function> function.
- </para>
- </body>
- </method>
- ''')
-
- def read(self, io=None):
- self.next = 0
- return self.readContents(io, self.contents)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Sequence</memberof>
- <name>write</name>
- <parameter>file</parameter>
- </header>
- <body>
- <para>
- <constant>self.value</constant> is set to the contents of this
- SEQUENCE and then written by calling
- <classname>_GeneralObject</classname>.<function>write</function>
- whos encoder will call <function>write</function> of
- each element in the list of contents in turn.
- </para>
- </body>
- </method>
- ''')
-
- def write(self, file):
- if self._ioSafe():
- if self._isSet():
- _GeneralObject.set( self, self.contents )
- _GeneralObject.write( self, file )
- elif self.optional:
- pass
- else:
- prob = self.findUnset()
- raise DerError, '%s is not in a state which can be written, %s is unset' % (repr(self), repr(prob) )
-
- _addFragment('''
- <method>
- <header>
- <memberof>Sequence</memberof>
- <name>set</name>
- <parameter>values</parameter>
- </header>
- <body>
- <para>
- Accessing and setting values for ASN1 objects is a bit of a
- thorny issue. The problem stems from the arbitrary complexity
- of the data and the possible levels of nesting, which in
- practice are used and are quite massive. Designing a good general
- approach is a bit tricky, perhaps nearly
- impossible. I choose to use a most compact
- form which is excellent for simple objects and is very concise.
- </para>
- <para>
- <parameter>value</parameter> should be a list or tuple of
- values. Each element of the list (or tuple) will be used in
- turn to set a member. Defaults can be specified by using the
- default value itself or <constant>None</constant>. Hence, for
- SEQUENCES of SEQUENCES, SEQUENCES OF, SET and so on
- <parameter>values</parameter> should consist of nested lists or
- tuples. Look at the ASN1 specs for that object to figure out
- exactly what these should look like.
- </para>
- </body>
- </method>
- ''')
-
- def set(self, values):
- if self.contents is None:
- raise DerError, 'the contents attribute should be set before using this object'
- if not( isinstance(values, types.ListType) or isinstance(values, types.TupleType) ):
- raise DerError, 'a sequence should be set with a list or tuple of values'
- if len(values) != len(self.contents):
- raise DerError, 'wrong number of values have been supplied to set %s. Expecting %i, got %i' % \
- (self.__class__.__name__, len(self.contents), len(values) )
-
- i = 0
- for val in values:
- self.contents[i].set(val)
- i = i + 1
-
- _addFragment('''
- <method>
- <header>
- <memberof>Sequence</memberof>
- <name>get</name>
- </header>
- <body>
- <para>
- A tuple of the values of the contents of this sequence will be
- returned. Hence, for SEQUENCES of SEQUENCES, SEQUENCES OF, SET
- and so on nested tuples will be returned.
- <function>get</function> always returns tuples even if a list
- was used to set and object.
- </para>
- </body>
- </method>
- ''')
-
- def get(self):
- if self.contents is None:
- return _GeneralObject.get(self)
- else:
- results = []
- for obj in self.contents:
- results.append( obj.get() )
- return tuple(results)
-
- def reset(self):
- if self.contents is None:
- raise DerError, 'this object has no members to set'
- self.next = 0
- for obj in self.contents:
- obj.reset() # clear all child objects prior to possible setting
- # via default
- _GeneralObject.reset(self)
-
- def _isSet(self):
- if self.contents is None:
- raise DerError, 'this object has no members to set'
- for obj in self.contents:
- if not obj._ioSafe():
- return 0
- return 1
-
- def findUnset(self):
- if self.contents is None:
- raise DerError, 'this object has no members to check'
- for obj in self.contents:
- if not obj._ioSafe():
- return obj
-
- def _ioSafe(self):
- if self.optional or self._isSet():
- return 1
- else:
- for obj in self.contents:
- if not obj._ioSafe():
- return 0
- return 1
-
-_addFragment('''
-<class>
- <header>
- <name>SequenceOf</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 SEQUENCE OF construct.
- </para>
- </body>
-</class>
-''')
-class SequenceOf(Sequence):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>SequenceOf</memberof>
- <super>Sequence</super>
- <parameter>contains</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- The <parameter>contains</parameter> should be the constructor
- for the objects which this SEQUENCE OF contains.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, contains, optional=0, default=''):
- self.contains = contains
- self.sequenceOf = []
- Sequence.__init__(self, [], optional, default)
-
- def _ioSafe(self):
- return 1
-
- def reset(self):
- if self.contents is None:
- raise DerError, 'this object has no members to set'
- self.next = 0
- self.sequenceOf = []
- _GeneralObject.reset(self)
-
- def _isSet(self):
- if self.sequenceOf:
- for obj in self.contents:
- if not obj._ioSafe():
- return 0
- return 1
- else:
- return 0
-
- def set(self, values):
- if isinstance(values, types.NoneType):
- return
- objects = []
- for val in values:
- obj = self.contains()
- obj.set(val)
- objects.append(obj)
- self.sequenceOf = objects
-
- def get(self):
- results = []
- for obj in self.sequenceOf:
- results.append( obj.get() )
- return tuple(results)
-
- def read(self, io=None):
- self.sequenceOf = []
- self.next = 0
- if _GeneralObject.read( self, io ):
- for tagio in _GeneralObject.get(self):
- value = self.contains()
- value.read(tagio)
- self.sequenceOf.append(value)
- return 1
- else:
- return 0
-
- def write(self, file):
- if not self._isSet() and self.optional:
- pass
- else:
- _GeneralObject.set( self, self.sequenceOf )
- _GeneralObject.write( self, file )
-
- def __len__(self):
- return len(self.sequenceOf)
-
- def __getitem__(self, key):
- return self.sequenceOf[key]
-
- def __iter__(self):
- for i in self.sequenceOf:
- yield(i)
-
- def __contains__(self, item):
- return item in self.sequenceOf
-
-_addFragment('''
-<class>
- <header>
- <name>Set</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 Set type.
- </para>
- </body>
-</class>
-''')
-class Set(Sequence): # 0x11
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Set</memberof>
- <super>Sequence</super>
- <parameter>contents</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- The <parameter>contents</parameter> should be a list containing
- the contents of the sequence.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, contents, optional=0, default=''):
- Sequence.__init__(self, contents, optional, default)
- self.normnumber = TAG_SET
-
-_addFragment('''
-<class>
- <header>
- <name>SetOf</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <para>
- This object represents the ASN1 SET OF construct.
- </para>
- </body>
-</class>
-''')
-class SetOf(SequenceOf):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>SetOf</memberof>
- <super>SequenceOf</super>
- <parameter>contains</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- The <parameter>contains</parameter> should be the constructor
- for the objects which this SET OF contains.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, contains, optional=0, default=''):
- SequenceOf.__init__(self, contains, optional, default)
- self.normnumber = TAG_SET
-
-_addFragment('''
-<class>
- <header>
- <name>Explicit</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- Explicit objects support the DER concept of explicit tagging. In
- general they behave just like a SEQUENCE which must have only one
- element. See below for other differences.
- </para>
- </body>
-</class>
-''')
-class Explicit(Sequence):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Explicit</memberof>
- <super>Sequence</super>
- <parameter>expclass</parameter>
- <parameter>expform</parameter>
- <parameter>expnumber</parameter>
- <parameter>contents</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- <parameter>expclass</parameter>,
- <parameter>expform</parameter>,
- <parameter>expnumber</parameter> should be as
- specified in the ASN1 documentation for this object.
- <parameter>contents</parameter> should be an object instance
- such as <classname>Integer</classname>,
- <classname>Oid</classname> or a derived object which supports
- the <classname>_GeneralObjec</classname> interface.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, expclass, expform, expnumber, contents, optional=0, default=''):
- self.contents = [contents]
- self.next = 0
- _GeneralObject.__init__(self, expclass, expform, expnumber, _encodeSequence, _decodeSequence, optional, default)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Explicit</memberof>
- <name>set</name>
- <parameter>value</parameter>
- </header>
- <body>
- <para>
- <parameter>value</parameter> is passed direct to
- <function>set</function> of the explicit object, so it should
- not be placed in a list or tuple(unless you are setting a constructed
- object).
- </para>
- </body>
- </method>
- ''')
- def set(self, value):
- return Sequence.set(self, [value])
-
- _addFragment('''
- <method>
- <header>
- <memberof>Explicit</memberof>
- <name>get</name>
- </header>
- <body>
- <para>
- The value of explicit object is returned and not
- put in a tuple.
- </para>
- </body>
- </method>
- ''')
- def get(self):
- return Sequence.get(self)[0]
-
-_addFragment('''
-<class>
- <header>
- <name>Choice</name>
- </header>
- <body>
- <para>
- This object represents the ASN1 Choice type.
- </para>
- </body>
-</class>
-''')
-class Choice(object):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Choice</memberof>
- <parameter>choices</parameter>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- <body>
- <para>
- <parameter>choices</parameter> should be a dictionary of
- objects which support the <classname>_GeneralObject</classname>
- interface. The key being the name of the choice specified in the
- ASN1 documentation. <parameter>optional</parameter> is a boolean
- indicating if this object is optional. The final parameter,
- <parameter>default</parameter> is the base 64 encoded DER
- value, which should be used as the default in leu of a value to
- read or incase it is unset. If neither
- <parameter>optional</parameter> or
- <parameter>default</parameter> is not set then the first choice
- which is optional or has a default will be honored.
- </para>
- </body>
- </constructor>
- ''')
-
- def __init__(self, choices, optional=0, default=''):
- self.value = None
- self.choices = choices
- self.optional = optional
- self.default = default
- self.choice = None
- self.reset()
-
- def _ioSafe(self):
- if self.optional or self._isSet():
- return 1
- elif self.choice and self.choices[ self.choice ]._ioSafe():
- return 1
- else:
- return 0
-
- def _isSet(self):
- if self.choice and self.choices[self.choice]._isSet():
- return 1
- else:
- return 0
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>reset</name>
- </header>
- <body>
- <para>
- This function re-initialises the object, clearing the value or
- setting it to any default.
- </para>
- </body>
- </method>
- ''')
- def reset(self):
- self.value = None
- self.choice = None
- if self.default:
- buf = cStringIO.StringIO( base64.decodestring( self.default ) )
- io = _TlvIo(buf)
- io.read()
- self.read(io)
- else:
- for key in self.choices.keys():
- self.choices[key].reset()
- if self.choices[key]._ioSafe():
- self.choice = key
- break;
-
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>set</name>
- <parameter>value</parameter>
- </header>
- <body>
- <para>
- <parameter>value</parameter> should be a list or tuple with two
- elements. The first value should be the name of the choice to
- be set and the second the value to set it with.
- </para>
- </body>
- </method>
- ''')
- def set(self, val):
- if val is None:
- return
- if not (isinstance(val, types.ListType) or isinstance(val, types.TupleType)):
- raise DerError, 'argument should be a list or tuple'
- if not self.choices.has_key( val[0] ):
- raise DerError, 'unknown choice: %s' % val[0]
- self.choices[ val[0] ].set(val[1])
- self.choice = val[0]
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>get</name>
- </header>
- <body>
- <para>
- This function will return tuple with two elements. The first
- value will be the name of the choice which was set and the second
- the value it was set to.
- </para>
- </body>
- </method>
- ''')
-
- def get(self):
- if self._isSet():
- return (self.choice, self.choices[ self.choice ].get())
- else:
- return None
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>toString</name>
- </header>
- <body>
- <para>
- Encodes the value in DER and returns it as a string.
- </para>
- </body>
- </method>
- ''')
-
- def toString(self):
- buf = cStringIO.StringIO()
- self.write(buf)
- return buf.getvalue()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>fromString</name>
- </header>
- <body>
- <para>
- Decodes the string and sets the value of this object.
- </para>
- </body>
- </method>
- ''')
-
- def fromString(self, value):
- buf = cStringIO.StringIO(value)
- self.read(buf)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>read</name>
- <parameter>io</parameter>
- </header>
- <body>
- <para>
- <parameter>io</parameter> should be a file like object. If the
- object being read matches the expected class, form and tag the
- value is read and decoded using
- <function>decRoutine</function>. Else, if it has a default
- that is read and stored.
- </para>
- <para>
- The return value of this function does not indicate success but
- whether this TLV was processed successfully. This bahaviour is
- vital for processing constructed types since the object may be
- optional or have a default. Failure to decode would be indicated
- by an exception.
- </para>
- </body>
- </method>
- ''')
-
- def _readChoices(self, io):
- for key in self.choices.keys():
- try:
- readindicator = self.choices[key].read(io)
- self.choice = key
- break;
- except DerError:
- if DEBUG:
- traceback.print_exc()
- return readindicator
-
- def read(self, io=None):
-
- self.choice = None
- processDefOpt = 0
- readindicator = 0
-
- if io is None:
- processDefOpt = 1
- elif isinstance(io, _TlvIo):
- if not io:
- processDefOpt = 1
- else:
- pos = io.tell()
- io.seek(0,2)
- if io.tell():
- io.seek(pos)
- else:
- processDefOpt = 1
-
- if processDefOpt:
- if self.optional or self.default:
- self.reset()
- return 0
- else:
- readindicator = self._readChoices(io)
- for key in self.choices.keys():
- try:
- readindicator = self.choices[key].read(io)
- self.choice = key
- break;
- except DerError:
- if DEBUG:
- traceback.print_exc()
- if not self._isSet():
- raise DerError, 'no TLV is available to read in non-optional/non-default object: %s' % repr(self)
- else:
- return readindicator
-
- if not isinstance(io, _TlvIo):
- tmp = _TlvIo(io)
- tmp.read()
- io = tmp
-
- for key in self.choices.keys():
- try:
- if self.choices[key].read(io):
- self.choice = key
- readindicator = 1
- break;
- except DerError:
- if DEBUG:
- traceback.print_exc()
-
- if not self._isSet():
- self.reset()
- else:
- return readindicator
-
- _addFragment('''
- <method>
- <header>
- <memberof>Choice</memberof>
- <name>write</name>
- <parameter>file</parameter>
- </header>
- <body>
- <para>
- If this object has not been set and is not optional and dosn't
- have a default, a <classname>DerError</classname> exception will be raised
- </para>
- <para>
- If no value has been set and this object is optional, nothing
- is written. If this object's value is equal to the default,
- nothing is written as stipulated by DER. Otherwise the value
- is encoded and written.
- </para>
- </body>
- </method>
- ''')
- def write(self,file):
- if self.optional and not self.choice:
- pass
- elif not self.choice:
- raise DerError, 'choice not set'
- elif self.choice:
- if self.default:
- defval = base64.decodestring( self.default )
- if defval != self.choices[ self.choice ].toString():
- self.choices[ self.choice ].write(file)
- else:
- self.choices[ self.choice ].write(file)
- else:
- raise DerError, 'an internal error has occured: %s' % repr(self)
-
-
diff --git a/pow/POW-0.7/lib/_simpledb.py b/pow/POW-0.7/lib/_simpledb.py
deleted file mode 100755
index 190e96be..00000000
--- a/pow/POW-0.7/lib/_simpledb.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#*****************************************************************************#
-#* *#
-#* Copyright (c) 2002, Peter Shannon *#
-#* All rights reserved. *#
-#* *#
-#* Redistribution and use in source and binary forms, with or without *#
-#* modification, are permitted provided that the following conditions *#
-#* are met: *#
-#* *#
-#* * Redistributions of source code must retain the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer. *#
-#* *#
-#* * Redistributions in binary form must reproduce the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer in the documentation and/or other materials *#
-#* provided with the distribution. *#
-#* *#
-#* * The name of the contributors may be used to endorse or promote *#
-#* products derived from this software without specific prior *#
-#* written permission. *#
-#* *#
-#* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *#
-#* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *#
-#* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *#
-#* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *#
-#* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *#
-#* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *#
-#* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *#
-#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *#
-#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *#
-#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *#
-#* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *#
-#* *#
-#*****************************************************************************#
-
-import _oids, _objects, types
-
-class OidData(object):
- def __init__(self):
- self.oids = _oids.data
- self.objs = _objects.data
-
- def obj2oid(self, obj):
- if not self.objs.has_key(obj):
- raise Exception, 'unknown object: %s' % obj
- return tuple(self.objs[obj]['oid'])
-
- def oid2obj(self, oid):
- if isinstance( oid, types.ListType ):
- oid = tuple(oid)
- if not self.oids.has_key(oid):
- raise Exception, 'unknown oid %s' % `oid`
- return self.oids[oid]['name']
-
diff --git a/pow/POW-0.7/lib/pkix.py b/pow/POW-0.7/lib/pkix.py
deleted file mode 100755
index e7d9dde1..00000000
--- a/pow/POW-0.7/lib/pkix.py
+++ /dev/null
@@ -1,2087 +0,0 @@
-#*****************************************************************************#
-#* *#
-#* Copyright (c) 2002, Peter Shannon *#
-#* All rights reserved. *#
-#* *#
-#* Redistribution and use in source and binary forms, with or without *#
-#* modification, are permitted provided that the following conditions *#
-#* are met: *#
-#* *#
-#* * Redistributions of source code must retain the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer. *#
-#* *#
-#* * Redistributions in binary form must reproduce the above *#
-#* copyright notice, this list of conditions and the following *#
-#* disclaimer in the documentation and/or other materials *#
-#* provided with the distribution. *#
-#* *#
-#* * The name of the contributors may be used to endorse or promote *#
-#* products derived from this software without specific prior *#
-#* written permission. *#
-#* *#
-#* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *#
-#* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *#
-#* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *#
-#* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *#
-#* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *#
-#* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *#
-#* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *#
-#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *#
-#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *#
-#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *#
-#* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *#
-#* *#
-#*****************************************************************************#
-
-import types, time, pprint, cStringIO, _der
-from _simpledb import OidData as _OidData
-from _der import *
-
-DEBUG = 0
-
-_oidData = _OidData()
-obj2oid = _oidData.obj2oid
-oid2obj = _oidData.oid2obj
-
-_fragments = []
-
-def _docset():
- return _der._docset() + _fragments
-
-#---------- crypto driver ----------#
-
-class CryptoDriver(object):
- """Dispatcher for crypto calls.
-
- This module has very minimal dependencies on crypto code, as it's
- almost entirely about ASN.1 encoding and decoding. Rather than
- wiring in the handful of crypto calls, we dispatch them through
- this driver. The default driver uses POW, but you can replace it
- with any crypto package you like.
-
- This is a virtual class. You will have to subtype it.
- """
-
- def getOID(self, digestType):
- """Convert a digest identifier into an OID.
-
- If the identifier we get is a tuple, we assume it's already an
- OID and just return it. If the identifier is in the driver
- identifier mapping table, we use that to return an OID.
- Otherwise, we try mapping it via the name-to-OID database.
- """
- if isinstance(digestType, tuple):
- return digestType
- if digestType in self.driver2OID:
- return self.driver2OID[digestType]
- return obj2oid(digestType)
-
- def sign(self, key, oid, plaintext):
- """Sign something with an RSA key and a given digest algorithm."""
- raise NotImplementedError
-
- def verify(self, key, oid, plaintext, signature):
- """Verify a signature."""
- raise NotImplementedError
-
- def toPublicDER(self, key):
- """Get the DER representation of an RSA key."""
- raise NotImplementedError
-
- def fromPublicDER(self, der):
- """Set the driver representation of an RSA key from DER."""
- raise NotImplementedError
-
-class POWCryptoDriver(CryptoDriver):
- """Dispatcher for crypto calls using POW package."""
-
- def __init__(self):
- global POW
- try:
- import rpki.POW
- POW = rpki.POW
- except ImportError:
- import POW
- self.driver2OID = {}
- for k, v in (("MD2_DIGEST", (1, 2, 840, 113549, 1, 1, 2)), # md2WithRSAEncryption
- ("MD5_DIGEST", (1, 2, 840, 113549, 1, 1, 4)), # md5WithRSAEncryption
- ("SHA_DIGEST", (1, 3, 14, 3, 2, 15)), # shaWithRSAEncryption
- ("SHA1_DIGEST", (1, 2, 840, 113549, 1, 1, 5)), # sha1withRSAEncryption
- ("RIPEMD160_DIGEST", (1, 2, 840, 113549, 1, 1, 6)), # ripemd160WithRSAEncryption
- ("SHA256_DIGEST", (1, 2, 840, 113549, 1, 1, 11)), # sha256WithRSAEncryption
- ("SHA384_DIGEST", (1, 2, 840, 113549, 1, 1, 12)), # sha384WithRSAEncryption
- ("SHA512_DIGEST", (1, 2, 840, 113549, 1, 1, 13)), # sha512WithRSAEncryption
- ):
- try:
- self.driver2OID[getattr(POW, k)] = v
- except AttributeError:
- pass
- self.OID2driver = dict((v,k) for k,v in self.driver2OID.items())
-
- def _digest(self, oid, plaintext):
- digest = POW.Digest(self.OID2driver[oid])
- digest.update(plaintext)
- return digest.digest()
-
- def sign(self, key, oid, plaintext):
- return key.sign(self._digest(oid, plaintext), self.OID2driver[oid])
-
- def verify(self, key, oid, plaintext, signature):
- return key.verify(signature, self._digest(oid, plaintext), self.OID2driver[oid])
-
- def toPublicDER(self, key):
- return key.derWrite(POW.RSA_PUBLIC_KEY)
-
- def fromPublicDER(self, der):
- return POW.derRead(POW.RSA_PUBLIC_KEY, der)
-
-_cryptoDriver = None # Don't touch this directly
-
-def setCryptoDriver(driver):
- """Set crypto driver.
-
- The driver should be an instance of CryptoDriver.
- """
- assert isinstance(driver, CryptoDriver)
- global _cryptoDriver
- _cryptoDriver = driver
-
-def getCryptoDriver():
- """Return the currently selected CryptoDriver instance.
-
- If no driver has been selected, instantiate the default POW driver.
- """
- global _cryptoDriver
- if _cryptoDriver is None:
- setCryptoDriver(POWCryptoDriver())
- return _cryptoDriver
-
-#---------- crypto driver ----------#
-
-def _addFragment(frag):
- global _fragments
- _fragments.append(frag)
-
-_addFragment('''
-<modulefunction>
- <header>
- <name>utc2time</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This is a helper function for turning a UTCTime string into an
- integer. It isn't built into the encoder since the various
- functions which are used to manipulate the tm structure are
- notoriously unreliable.
- </para>
- </body>
-</modulefunction>
-''')
-def utc2time(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- t = time.strptime(val, '%y%m%d%H%M%SZ')
- return int(time.mktime(t))
-
-_addFragment('''
-<modulefunction>
- <header>
- <name>time2utc</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This is a helper function for turning an integer into a
- UTCTime string. It isn't built into the encoder since the
- various functions which are used to manipulate the tm structure
- are notoriously unreliable.
- </para>
- </body>
-</modulefunction>
-''')
-def time2utc(val):
- 'numerical time value like time_t'
- val = int(val)
- t = time.gmtime(val)
- return time.strftime('%y%m%d%H%M%SZ', t)
-
-_addFragment('''
-<modulefunction>
- <header>
- <name>gen2time</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This is a helper function for turning a GeneralizedTime string into an
- integer. It isn't built into the encoder since the various
- functions which are used to manipulate the tm structure are
- notoriously unreliable.
- </para>
- </body>
-</modulefunction>
-''')
-def gen2Time(val):
- 'der encoded value not including tag or length'
- if not isinstance(val, types.StringType):
- raise DerError, 'argument should be a string'
- t = time.strptime(val, '%Y%m%d%H%M%SZ')
- return int(time.mktime(t))
-
-_addFragment('''
-<modulefunction>
- <header>
- <name>time2gen</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This is a helper function for turning an integer into a
- GeneralizedTime string. It isn't built into the encoder since the
- various functions which are used to manipulate the tm structure
- are notoriously unreliable.
- </para>
- </body>
-</modulefunction>
-''')
-def time2gen(val):
- 'numerical time value like time_t'
- val = int(val)
- t = time.gmtime(val)
- return time.strftime('%Y%m%d%H%M%SZ', t)
-
-_addFragment('''
-<method>
- <header>
- <name>ip42oct</name>
- <parameter>ip</parameter>
- </header>
- <body>
- <para>
- <parameter>ip</parameter> should be a list or tuple of integers,
- from 0 to 256.
- </para>
- <example>
- <title>Setting <classname>IpAddress</classname></title>
- <programlisting>
- ip = IpAddress()
- ip.set( ip42oct(192, 168, 0, 231) )
- </programlisting>
- </example>
- </body>
-</method>
-''')
-def ip42oct(val0, val1, val2, val3):
- return chr(val0) + chr(val1) + chr(val2) + chr(val3)
-
-_addFragment('''
-<method>
- <header>
- <name>oct2ip4</name>
- <parameter>val</parameter>
- </header>
- <body>
- <para>
- Returns a tuple of 4 integers, from 0 to 256.
- </para>
- </body>
-</method>
-''')
-def oct2ip4(val):
- if not isinstance(val, types.StringType) or len(val) != 4:
- raise DerError, 'parameter should be string of 4 characters'
- return ( ord(val[0]), ord(val[1]), ord(val[2]), ord(val[3]) )
-
-#---------- certificate support ----------#
-class TbsCertificate(Sequence):
- def __init__(self, optional=0, default=''):
-
- self.version = Integer()
- self.explicitVersion = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.version, 0, 'oAMCAQA=\n' )
-
- self.serial = Integer()
- self.signature = AlgorithmIdentifier()
- self.issuer = Name()
- self.subject = Name()
- self.subjectPublicKeyInfo = SubjectPublicKeyInfo()
-
- self.validity = Validity()
-
- self.issuerUniqueID = BitString(1)
- self.issuerUniqueID.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 1 )
- self.subjectUniqueID = BitString(1)
- self.subjectUniqueID.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 2 )
-
- self.extensions = Extensions()
- self.explicitExtensions = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 3, self.extensions, 1 )
-
- contents = [
- self.explicitVersion,
- self.serial,
- self.signature,
- self.issuer,
- self.validity,
- self.subject,
- self.subjectPublicKeyInfo,
- self.issuerUniqueID,
- self.subjectUniqueID,
- self.explicitExtensions
- ]
-
- Sequence.__init__(self, contents, optional, default)
-
-class Validity(Sequence):
- def __init__(self, optional=0, default=''):
- Time = lambda : Choice({ 'generalTime' : GeneralizedTime(), 'utcTime' : UtcTime() })
- self.notBefore = Time()
- self.notAfter = Time()
- contents = [self.notBefore, self.notAfter]
- Sequence.__init__(self, contents, optional, default)
-
-# IA5String should not be allowed in DirectoryString, but old
-# implementations (deprecated but not quite outlawed by RFC 3280)
-# sometimes use it for EmailAddress attributes in subject names, which
-# triggers decode failures here unless we violate RFC 3280 by allowing
-# IA5String. Do not use, do not use, do not use.
-
-class DirectoryString(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'teletexString' : T61String(),
- 'printableString' : PrintableString(),
- 'universalString' : UniversalString(),
- 'bmpString' : BmpString(),
- 'utf8String' : Utf8String(),
- 'ia5String' : IA5String() }
-
- Choice.__init__(self, choices, optional, default)
-
-class AttributeTypeAndValue(Sequence):
- def __init__(self, optional=0, default=''):
- self.type = Oid()
- self.dirstr = DirectoryString()
- contents = [ self.type, self.dirstr ]
- Sequence.__init__(self, contents, optional, default)
-
-class RelativeDistinguishedName(SetOf):
- def __init__(self, optional=0, default=''):
- SetOf.__init__(self, AttributeTypeAndValue, optional, default)
-
-class Name(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, RelativeDistinguishedName, optional, default)
-
-class AlgorithmIdentifier(Sequence):
- def __init__(self, optional=0, default=''):
- self.algorithm = Oid()
- self.parameters = Null()
- contents = [self.algorithm, self.parameters]
- Sequence.__init__(self, contents, optional, default)
-
-class SubjectPublicKeyInfo(Sequence):
- def __init__(self, optional=0, default=''):
- self.algorithmId = AlgorithmIdentifier()
- self.subjectPublicKey = AltBitString()
- contents = [ self.algorithmId, self.subjectPublicKey ]
- Sequence.__init__(self, contents, optional, default)
-
-class Extensions(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, Extension, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>Certificate</name>
- <super>Sequence</super>
- </header>
- <body>
- <example>
- <title>Setting <classname>Certificate</classname></title>
- <programlisting>
- rsa = POW.Asymmetric()
- cert = POW.pkix.Certificate()
- cert.setVersion(1)
- cert.setSerial(5)
-
- name = ( (( o2i('countryName'), ('printableString', 'GB') ),),
- (( o2i('stateOrProvinceName'), ('printableString', 'Hertfordshire') ),),
- (( o2i('organizationName'), ('printableString', 'The House') ),),
- (( o2i('commonName'), ('printableString', 'Client') ),) )
-
- cert.setIssuer(name)
- cert.setSubject(name)
-
- now = POW.pkix.time2gen( time.time() )
- then = POW.pkix.time2gen(time.time() + 60*60*24*365*12)
- cert.setNotBefore( ('generalTime', now) )
- cert.setNotAfter( ( 'generalTime', then) )
- cert.setIssuerUniqueID((1,0,1,0))
- cert.setSubjectUniqueID((1,0,0,1))
- cert.sign(rsa, POW.MD5_DIGEST)
- </programlisting>
- </example>
- </body>
-</class>
-''')
-
-class Certificate(Sequence):
-
- _addFragment('''
- <constructor>
- <header>
- <memberof>Certificate</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- self.tbs = TbsCertificate()
- self.signatureAlgorithm = AlgorithmIdentifier()
- self.signatureValue = AltBitString()
- contents = [ self.tbs, self.signatureAlgorithm, self.signatureValue ]
- Sequence.__init__(self, contents, optional, default)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setVersion</name>
- <parameter>version</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Integer</classname> object. 0
- indicates a version 1 certificate, 1 a version 2 certificate and 2 a
- version 3 certificate.
- </para>
- </body>
- </method>
- ''')
- def setVersion(self, version):
- self.tbs.version.set(version)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getVersion</name>
- </header>
- <body>
- <para>
- This function returns whatever the version object is set to,
- this should be 0, 1 or 2.
- </para>
- </body>
- </method>
- ''')
- def getVersion(self):
- return self.tbs.version.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setSerial</name>
- <parameter>serial</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Integer</classname> object.
- No two certificates issued should ever have the same serial
- number.
- </para>
- </body>
- </method>
- ''')
- def setSerial(self, serial):
- self.tbs.serial.set(serial)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getVersion</name>
- </header>
- <body>
- <para>
- This function returns whatever the serial object is set to.
- </para>
- </body>
- </method>
- ''')
- def getSerial(self):
- return self.tbs.serial.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setIssuer</name>
- <parameter>names</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Name</classname> object.
- See <classname>Certificate</classname> class for an example.
- </para>
- </body>
- </method>
- ''')
- def setIssuer(self, issuer):
- self.tbs.issuer.set(issuer)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getIssuer</name>
- </header>
- <body>
- <para>
- This function returns a complex tuple containing other tuples.
- </para>
- </body>
- </method>
- ''')
- def getIssuer(self):
- return self.tbs.issuer.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setSubject</name>
- <parameter>names</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Name</classname> object.
- See <classname>Certificate</classname> class for an example.
- </para>
- </body>
- </method>
- ''')
- def setSubject(self, subject):
- self.tbs.subject.set(subject)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getSubject</name>
- </header>
- <body>
- <para>
- This function returns a complex tuple containing other tuples.
- </para>
- </body>
- </method>
- ''')
- def getSubject(self):
- return self.tbs.subject.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setNotBefore</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This function sets a <classname>Choice</classname> object.
- It can be either a <classname>GeneralTime</classname> or
- <classname>UTCTime</classname> object. The functions
- <function>gen2time</function>, <function>utc2time</function>,
- <function>time2gen</function> and <function>time2utc</function>
- can be used to convert to and from integer times and their
- string representation.
- </para>
- <example>
- <title><function>setNotBefore</function> method usage</title>
- <programlisting>
- cert = POW.pkix.Certificate()
- now = POW.pkix.time2gen( time.time() )
- cert.setNotBefore( ('generalTime', now) )
- </programlisting>
- </example>
- </body>
- </method>
- ''')
- def setNotBefore(self, nb):
- self.tbs.validity.notBefore.set(nb)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getNotBefore</name>
- </header>
- <body>
- <para>
- This function returns a tuple indicating which type of time was
- stored and its value. See <function>setNotBefore</function> for details.
- </para>
- </body>
- </method>
- ''')
- def getNotBefore(self):
- return self.tbs.validity.notBefore.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setNotAfter</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This function sets a <classname>Choice</classname> object.
- See <function>setNotBefore</function> for details.
- </para>
- </body>
- </method>
- ''')
- def setNotAfter(self, na):
- self.tbs.validity.notAfter.set(na)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getNotAfter</name>
- </header>
- <body>
- <para>
- This function returns a tuple indicating which type of time was
- stored and its value. See <function>setNotBefore</function> for details.
- </para>
- </body>
- </method>
- ''')
- def getNotAfter(self):
- return self.tbs.validity.notAfter.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setIssuerUniqueID</name>
- <parameter>id</parameter>
- </header>
- <body>
- <para>
- This function sets a <classname>BitString</classname> object.
- This is part of the X509v2 standard and is quite poorly
- regarded in general, its use is not recommended. It is set
- using the normal <classname>BitString</classname> method, that
- is with a sequence of true/false objects.
- </para>
- </body>
- </method>
- ''')
- def setIssuerUniqueID(self, id):
- self.tbs.issuerUniqueID.set(id)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getIssuerUniqueID</name>
- </header>
- <body>
- <para>
- This function returns a tuple of integers, 1 or 0.
- </para>
- </body>
- </method>
- ''')
- def getIssuerUniqueID(self):
- return self.tbs.issuerUniqueID.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setSubjectUniqueID</name>
- <parameter>id</parameter>
- </header>
- <body>
- <para>
- This function sets a <classname>BitString</classname> object.
- This is part of the X509v2 standard and is quite poorly
- regarded in general, its use is not recommended. It is set
- using the normal <classname>BitString</classname> method, that
- is with a sequence of true/false objects.
- </para>
- </body>
- </method>
- ''')
- def setSubjectUniqueID(self, id):
- self.tbs.subjectUniqueID.set(id)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getSubjectUniqueID</name>
- </header>
- <body>
- <para>
- This function returns a tuple of integers, 1 or 0.
- </para>
- </body>
- </method>
- ''')
- def getSubjectUniqueID(self):
- return self.tbs.subjectUniqueID.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>setExtensions</name>
- <parameter>extns</parameter>
- </header>
- <body>
- <para>
- This method sets an <classname>Extensions</classname> object,
- defined as SEQUENCE OF Extension. The parameter
- <parameter>extns</parameter> should consist of a list or tuple
- of values suitable to set an extension. See the extension
- class for details.
- </para>
- </body>
- </method>
- ''')
- def setExtensions(self, extns):
- self.tbs.extensions.set(extns)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>getExtensions</name>
- </header>
- <body>
- <para>
- This function returns a tuple of
- <classname>Extension</classname> values. See
- <classname>Extension</classname> for details.
- </para>
- </body>
- </method>
- ''')
- def getExtensions(self):
- return self.tbs.extensions.get()
-
- def getExtension(self, oid):
- for x in self.getExtensions():
- if x[0] == oid:
- return x
- return None
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>sign</name>
- <parameter>rsa</parameter>
- <parameter>digestType</parameter>
- </header>
- <body>
- <para>
- This function updates structured of the
- <classname>Certificate</classname> and
- <constant>tbs</constant> as appropriate and performs the
- specified digest on the <constant>tbs</constant> and set
- <constant>signedText</constant> to signed the digest.
- </para>
- </body>
- </method>
- ''')
- def sign(self, rsa, digestType):
- driver = getCryptoDriver()
- oid = driver.getOID(digestType)
- self.tbs.signature.set([oid, None])
- signedText = driver.sign(rsa, oid, self.tbs.toString())
- self.signatureAlgorithm.set([oid, None])
- self.signatureValue.set(signedText)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>verify</name>
- <parameter>rsa</parameter>
- </header>
- <body>
- <para>
- This function works out what kind of digest was used to
- during signing, calculates the digest of
- <constant>tbs</constant> and verifies the envelope using the
- key.
- </para>
- </body>
- </method>
- ''')
- def verify(self, rsa):
- driver = getCryptoDriver()
- oid = self.signatureAlgorithm.get()[0]
- return driver.verify(rsa, oid, self.tbs.toString(), self.signatureValue.get())
-
-#---------- certificate support ----------#
-#---------- CRL ----------#
-
-class RevokedCertificate(Sequence):
- def __init__(self, optional=0, default=''):
- self.userCertificate = Integer()
- self.revocationDate = Choice( { 'generalTime' : GeneralizedTime(), 'utcTime' : UtcTime() } )
- self.crlEntryExtensions = Extensions(1)
- contents = [ self.userCertificate, self.revocationDate, self.crlEntryExtensions ]
- Sequence.__init__(self, contents, optional, default)
-
-class RevokedCertificates(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, RevokedCertificate, optional, default)
-
-class TbsCertList(Sequence):
- def __init__(self, optional=0, default=''):
- self.version = Integer(1)
- self.signature = AlgorithmIdentifier()
- self.issuer = Name()
- self.thisUpdate = Choice( { 'generalTime' : GeneralizedTime(), 'utcTime' : UtcTime() } )
- self.nextUpdate = Choice( { 'generalTime' : GeneralizedTime(), 'utcTime' : UtcTime() }, 1 )
- self.revokedCertificates = RevokedCertificates(1)
- self.crlExtensions = Extensions()
- self.explicitCrlExtensions = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.crlExtensions, 1 )
- contents = [ self.version,
- self.signature,
- self.issuer,
- self.thisUpdate,
- self.nextUpdate,
- self.revokedCertificates,
- self.explicitCrlExtensions ]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>CertificateList</name>
- <super>Sequence</super>
- </header>
- <body>
- <example>
- <title>Setting <classname>CertificateList</classname></title>
- <programlisting>
- now = POW.pkix.time2gen( time.time() )
- then = POW.pkix.time2gen(time.time() + 60*60*24*365*12)
- rsa = POW.Asymmetric()
-
- crl = POW.pkix.CertificateList()
- crl.setThisUpdate( ('generalTime', now ) )
-
- name = ( (( o2i('countryName'), ('printableString', 'GB') ),),
- (( o2i('stateOrProvinceName'), ('printableString', 'Hertfordshire') ),),
- (( o2i('organizationName'), ('printableString', 'The House') ),),
- (( o2i('commonName'), ('printableString', 'Client') ),) )
-
- myRevocations = (
- (1, ('generalTime', now), ()),
- (2, ('generalTime', now), ()),
- (3, ('generalTime', now), (( o2i('cRLReason'), 0, 1),))
- )
-
- crl.setIssuer(name)
- crl.setRevokedCertificates( myRevocations )
-
- crl.sign(rsa, POW.MD5_DIGEST)
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class CertificateList(Sequence):
- _addFragment('''
- <constructor>
- <header>
- <memberof>CertificateList</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- self.tbs = TbsCertList()
- self.signatureAlgorithm = AlgorithmIdentifier()
- self.signature = AltBitString()
- contents = [self.tbs, self.signatureAlgorithm, self.signature]
- Sequence.__init__(self, contents, optional, default)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>setVersion</name>
- <parameter>version</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Integer</classname> object. 0
- indicates a version 1 CRL, and 1 a version 2 CRL.
- </para>
- </body>
- </method>
- ''')
- def setVersion(self, version):
- self.tbs.version.set(version)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getVersion</name>
- </header>
- <body>
- <para>
- This function returns whatever the version object is set to,
- this should be 0, 1 or 2.
- </para>
- </body>
- </method>
- ''')
- def getVersion(self):
- return self.tbs.version.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>setIssuer</name>
- <parameter>names</parameter>
- </header>
- <body>
- <para>
- This function sets an <classname>Name</classname> object.
- </para>
- </body>
- </method>
- ''')
- def setIssuer(self, issuer):
- self.tbs.issuer.set(issuer)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getIssuer</name>
- </header>
- <body>
- <para>
- This function returns a complex tuple containing other tuples.
- </para>
- </body>
- </method>
- ''')
- def getIssuer(self):
- return self.tbs.issuer.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>setThisUpdate</memberof>
- <name>setNotBefore</name>
- <parameter>time</parameter>
- </header>
- <body>
- <para>
- This function sets a <classname>Choice</classname> object.
- It can be either a <classname>GeneralTime</classname> or
- <classname>UTCTime</classname> object. The functions
- <function>gen2time</function>, <function>utc2time</function>,
- <function>time2gen</function> and <function>time2utc</function>
- can be used to convert to and from integer times and their
- string representation.
- </para>
- <example>
- <title><function>setNotBefore</function> method usage</title>
- <programlisting>
- crl = POW.pkix.CertificateList()
- now = POW.pkix.time2gen( time.time() )
- crl.setNotBefore( ('generalTime', now) )
- </programlisting>
- </example>
- </body>
- </method>
- ''')
- def setThisUpdate(self, nu):
- self.tbs.thisUpdate.set(nu)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getThisUpdate</name>
- </header>
- <body>
- <para>
- This function returns a tuple containing two strings. The first
- is either 'utcTime' or 'generalTime' and the second is the time
- value as a string.
- </para>
- </body>
- </method>
- ''')
- def getThisUpdate(self):
- return self.tbs.thisUpdate.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>setNextUpdate</name>
- </header>
- <body>
- <para>
- See set <function>setThisUpdate</function>.
- </para>
- </body>
- </method>
- ''')
- def setNextUpdate(self, nu):
- self.tbs.nextUpdate.set(nu)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getNextUpdate</name>
- </header>
- <body>
- <para>
- See set <function>getThisUpdate</function>.
- </para>
- </body>
- </method>
- ''')
- def getNextUpdate(self):
- return self.tbs.nextUpdate.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>setExtensions</name>
- <parameter>extns</parameter>
- </header>
- <body>
- <para>
- This method sets an <classname>Extensions</classname> object,
- defined as SEQUENCE OF Extension. The parameter
- <parameter>extns</parameter> should consist of a list or tuple
- of values suitable to set an extension. See the extension
- class for details.
- </para>
- </body>
- </method>
- ''')
- def setExtensions(self, extns):
- self.tbs.crlExtensions.set(extns)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getExtensions</name>
- </header>
- <body>
- <para>
- This function returns a tuple of
- <classname>Extension</classname> values. See
- <classname>Extension</classname> for details.
- </para>
- </body>
- </method>
- ''')
- def getExtensions(self):
- return self.tbs.crlExtensions.get()
-
- def getExtension(self, oid):
- for x in self.getExtensions():
- if x[0] == oid:
- return x
- return None
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>setRevokedCertificates</name>
- </header>
- <body>
- <para>
- This function sets a sequence of
- <classname>revokedCertificate</classname> objects.
- This object is optional. See
- <classname>CertificateList</classname> for an example of its
- use.
- </para>
- </body>
- </method>
- ''')
- def setRevokedCertificates(self, rc):
- self.tbs.revokedCertificates.set(rc)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>getRevokedCertificates</name>
- </header>
- <body>
- <para>
- This function return a sequence of
- <classname>revokedCertificate</classname> objects or None.
- </para>
- </body>
- </method>
- ''')
- def getRevokedCertificates(self):
- return self.tbs.revokedCertificates.get()
-
- _addFragment('''
- <method>
- <header>
- <memberof>Certificate</memberof>
- <name>sign</name>
- </header>
- <body>
- <para>
- This function updates structured of the
- <classname>certificateList</classname> and
- <classname>tBSCertList</classname> as appropriate, performs the
- specified digest on the <classname>tBSCertList</classname> and sets
- <constant>signedValue</constant> to signed the digest.
- </para>
- </body>
- </method>
- ''')
- def sign(self, rsa, digestType):
- driver = getCryptoDriver()
- oid = driver.getOID(digestType)
- self.tbs.signature.set([oid, None])
- signedText = driver.sign(rsa, oid, self.tbs.toString())
- self.signatureAlgorithm.set([oid, None])
- self.signature.set(signedText)
-
- _addFragment('''
- <method>
- <header>
- <memberof>CertificateList</memberof>
- <name>verify</name>
- </header>
- <body>
- <para>
- This function works out what kind of digest was used to during
- signing, calculates the digest of
- <classname>tBSCertList</classname> and verifies the
- <constant>signedText</constant> using the key.
- </para>
- </body>
- </method>
- ''')
- def verify(self, rsa):
- driver = getCryptoDriver()
- oid = self.signatureAlgorithm.get()[0]
- return driver.verify(rsa, oid, self.tbs.toString(), self.signature.get())
-
-#---------- CRL ----------#
-#---------- PKCS10 ----------#
-
-# My ASN.1-foo (and perhaps this ASN.1 implementation) isn't quite up
-# to X.501 or PKCS #10, so this is partly based on a dump of what
-# OpenSSL generates, and doesn't handle attributes other than X.509v3
-# extensions.
-
-class PKCS10AttributeSet(SetOf):
- def __init__(self, optional=0, default=''):
- SetOf.__init__(self, Extensions, optional, default)
-
-class PKCS10AttributeChoice(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'single' : Extensions(),
- 'set' : PKCS10AttributeSet() }
- Choice.__init__(self, choices, optional, default)
-
-class PKCS10Attributes(Sequence):
- def __init__(self, optional=1, default=''):
- self.oid = Oid()
- self.val = PKCS10AttributeChoice()
- contents = [ self.oid, self.val ]
- Sequence.__init__(self, contents, optional, default)
-
-class CertificationRequestInfo(Sequence):
- def __init__(self, optional=0, default=''):
- self.version = Integer()
- self.subject = Name()
- self.subjectPublicKeyInfo = SubjectPublicKeyInfo()
- self.attributes = PKCS10Attributes()
- self.explicitAttributes = Explicit(CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.attributes)
- contents = [ self.version, self.subject, self.subjectPublicKeyInfo, self.explicitAttributes ]
- Sequence.__init__(self, contents, optional, default)
-
-class CertificationRequest(Sequence):
- def __init__(self, optional=0, default=''):
- self.certificationRequestInfo = CertificationRequestInfo()
- self.signatureAlgorithm = AlgorithmIdentifier()
- self.signatureValue = AltBitString()
- contents = [ self.certificationRequestInfo, self.signatureAlgorithm, self.signatureValue ]
- Sequence.__init__(self, contents, optional, default)
-
- def sign(self, rsa, digestType):
- driver = getCryptoDriver()
- oid = driver.getOID(digestType)
- self.certificationRequestInfo.subjectPublicKeyInfo.fromString(driver.toPublicDER(rsa))
- signedText = driver.sign(rsa, oid, self.certificationRequestInfo.toString())
- self.signatureAlgorithm.set([oid, None])
- self.signatureValue.set(signedText)
-
- def verify(self):
- driver = getCryptoDriver()
- oid = self.signatureAlgorithm.get()[0]
- rsa = driver.fromPublicDER(self.certificationRequestInfo.subjectPublicKeyInfo.toString())
- return driver.verify(rsa, oid, self.certificationRequestInfo.toString(), self.signatureValue.get())
-
- def getExtensions(self):
- oid = self.certificationRequestInfo.attributes.oid.get()
- if oid is None:
- return ()
- if oid != (1, 2, 840, 113549, 1, 9, 14) or \
- self.certificationRequestInfo.attributes.val.choice != "set" or \
- len(self.certificationRequestInfo.attributes.val.choices["set"]) > 1:
- raise DerError, "failed to understand X.501 Attribute encoding, sorry: %s" % self.get()
- return self.certificationRequestInfo.attributes.val.choices["set"][0].get()
-
- def getExtension(self, oid):
- for x in self.getExtensions():
- if x[0] == oid:
- return x
- return None
-
- def setExtensions(self, exts):
- self.certificationRequestInfo.attributes.oid.set((1, 2, 840, 113549, 1, 9, 14))
- self.certificationRequestInfo.attributes.val.set(("set", [exts]))
-
-#---------- PKCS10 ----------#
-#---------- GeneralNames object support ----------#
-class OtherName(Sequence):
- def __init__(self, optional=0, default=''):
- self.typeId = Oid()
- self.any = Any()
- contents = [self.typeId, self.any]
- Sequence.__init__(self, contents, optional, default)
-
-class EdiPartyName(Sequence):
- def __init__(self, optional=0, default=''):
- self.nameAssigner = DirectoryString()
- self.partyName = DirectoryString()
- self.explicitNameAssigner = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.nameAssigner, 1 )
- self.explicitPartyName = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 1, self.partyName )
- contents = [ self.explicitNameAssigner, self.explicitPartyName ]
- Sequence.__init__(self, contents, optional, default)
-
-class IpAddress(OctetString):
- pass
-
-class GeneralName(Choice):
- def __init__(self, optional=0, default=''):
-
- otherName = OtherName()
- otherName.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 0 )
- rfc822Name = IA5String()
- rfc822Name.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 1 )
- dnsName = IA5String()
- dnsName.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 2 )
- directoryName = Name()
- explicitDirectoryName = Explicit( CLASS_CONTEXT, FORM_CONSTRUCTED, 4, directoryName)
- ediPartyName = EdiPartyName()
- ediPartyName.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 5 )
- uri = IA5String()
- uri.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 6 )
- ipAddress = IpAddress()
- ipAddress.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 7 )
- registeredId = Oid()
- registeredId.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 8 )
-
- choices = { 'otherName' : otherName ,
- 'rfc822Name' : rfc822Name ,
- 'dNSName' : dnsName ,
- 'directoryName' : explicitDirectoryName ,
- 'ediPartyName' : ediPartyName ,
- 'uri' : uri ,
- 'iPAddress' : ipAddress ,
- 'registeredId' : registeredId }
-
- Choice.__init__(self, choices, optional, default)
-
-class GeneralNames(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, GeneralName, optional, default)
-
-#---------- GeneralNames object support ----------#
-#---------- X509v3 extensions ----------#
-
-_addFragment('''
-<class>
- <header>
- <name>BasicConstraints</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- This little extension has recently caused plenty of problems for
- several large organisations. It consist of a
- <classname>Boolean</classname> and an
- <classname>Integer</classname>. The first indicates if the owner
- is a CA, the second indicates how long a chain of CAs you should
- trust which the subject of this certificate trusts.
- </para>
- <example>
- <title>Setting <classname>BasicConstraints</classname></title>
- <programlisting>
- bc = BasicConstraints()
- bc.set( (1, 1) )
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class BasicConstraints(Sequence):
- _addFragment('''
- <constructor>
- <header>
- <memberof>BasicConstraints</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- self.ca = Boolean(0, 'AQEA\n')
- self.pathLenConstraint = Integer(1)
- contents = [self.ca, self.pathLenConstraint]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>KeyUsage</name>
- <super>BitString</super>
- </header>
-</class>
-''')
-class KeyUsage(BitString):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>SubjectAltName</name>
- <super>GeneralNames</super>
- </header>
-</class>
-''')
-class SubjectAltName(GeneralNames):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>IssuerAltName</name>
- <super>GeneralNames</super>
- </header>
-</class>
-''')
-class IssuerAltName(GeneralNames):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>SubjectKeyIdentifier</name>
- <super>OctetString</super>
- </header>
-</class>
-''')
-class SubjectKeyIdentifier(OctetString):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>AuthorityKeyIdentifier</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- </para>
- <example>
- <title>Setting <classname>AuthorityKeyIdentifier</classname></title>
- <programlisting>
- id = AuthorityKeyIdentifier()
- authdigest = POW.Digest( POW.SHA1_DIGEST )
- authdigest.update(rsa.derWrite(POW.RSA_PUBLIC_KEY))
- keyHash = authdigest.digest()
- id.set( (keyHash, None, None) )
- </programlisting>
- </example>
- </body>
-
-</class>
-''')
-class AuthorityKeyIdentifier(Sequence):
- _addFragment('''
- <constructor>
- <header>
- <memberof>AuthorityKeyIdentifier</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- self.keyIdentifier = OctetString(1)
- self.keyIdentifier.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 0 )
- self.authorityCertIssuer = GeneralNames(1)
- self.authorityCertIssuer.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 1 )
- self.authorityCertSerialNumber = Integer(1)
- self.authorityCertSerialNumber.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 2 )
- contents = [self.keyIdentifier, self.authorityCertIssuer, self.authorityCertSerialNumber]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>PrivateKeyUsagePeriod</name>
- <super>Sequence</super>
- </header>
- <body>
- <example>
- <title>Setting <classname>PrivateKeyUsagePeriod</classname></title>
- <programlisting>
- period = PrivateKeyUsagePeriod()
- period.set( ( time2gen( time.time() ), None) )
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class PrivateKeyUsagePeriod(Sequence):
- _addFragment('''
- <constructor>
- <header>
- <memberof>PrivateKeyUsagePeriod</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- self.notBefore = GeneralizedTime()
- self.notBefore.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 0 )
- self.notAfter = GeneralizedTime()
- self.notAfter.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 1 )
- contents = [self.notBefore, self.notAfter]
- Sequence.__init__(self, contents, optional, default)
-
-class DisplayText(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'visibleString' : VisibleString(),
- 'bmpString' : BmpString(),
- 'utf8String' : Utf8String() }
-
- Choice.__init__(self, choices, optional, default)
-
-class NoticeNumbers(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, Integer, optional, default)
-
-class NoticeReference(Sequence):
- def __init__(self, optional=0, default=''):
- self.organization = DisplayText()
- self.noticeNumbers = NoticeNumbers()
- contents = [self.organization, self.noticeNumbers]
- Sequence.__init__(self, contents, optional, default)
-
-class UserNotice(Sequence):
- def __init__(self, optional=0, default=''):
- self.noticeRef = NoticeReference(1)
- self.explicitText = DisplayText(1)
- contents = [self.noticeRef, self.explicitText]
- Sequence.__init__(self, contents, optional, default)
-
-class Qualifier(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'cPSuri' : IA5String(),
- 'userNotice' : UserNotice() }
-
- Choice.__init__(self, choices, optional, default)
-
-class PolicyQualifierInfo(Sequence):
- def __init__(self, optional=0, default=''):
- self.policyQualifierId = Oid()
- self.qualifier = Qualifier()
- contents = [self.policyQualifierId, self.qualifier]
- Sequence.__init__(self, contents, optional, default)
-
-class PolicyQualifiers(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, PolicyQualifierInfo, optional, default)
-
-class PolicyInformation(Sequence):
- def __init__(self, optional=0, default=''):
- self.policyIdentifier = Oid()
- self.policyQualifiers = PolicyQualifiers(1)
- contents = [self.policyIdentifier, self.policyQualifiers]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>CertificatePolicies</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <example>
- <title>Setting <classname>CertificatePolicies</classname></title>
- <programlisting>
- data = (
- ( o2i('id-cti-ets-proofOfReceipt'), (
- (o2i('cps'), ('cPSuri', 'http://www.p-s.org.uk/policies/policy1')),
- (o2i('unotice'), ( 'userNotice',
- ((('visibleString', 'The House'),(1,2,3)),
- ('visibleString', 'We guarentee nothing')))),
- )),
- ( o2i('id-cti-ets-proofOfOrigin'), (
- (o2i('cps'), ('cPSuri', 'http://www.p-s.org.uk/policies/policy2')),
- ))
- )
- policies = CertificatePolicies()
- policies.set( data )
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class CertificatePolicies(SequenceOf):
- _addFragment('''
- <constructor>
- <header>
- <memberof>CertificatePolicies</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, PolicyInformation, optional, default)
-
-class DistributionPointName(Choice):
- def __init__(self, optional=0, default=''):
- fullName = GeneralNames()
- fullName.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 0 )
- nameRelativeToCRLIssuer = RelativeDistinguishedName()
- nameRelativeToCRLIssuer.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 1 )
-
- choices = { 'fullName' : fullName,
- 'nameRelativeToCRLIssuer ' : nameRelativeToCRLIssuer }
-
- Choice.__init__(self, choices, optional, default)
-
-class DistributionPoint(Sequence):
- def __init__(self, optional=0, default=''):
- self.distributionPoint = DistributionPointName(1)
- self.explicitDistributionPoint = Explicit(CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.distributionPoint)
- self.reasons = BitString(1)
- self.reasons.implied( CLASS_CONTEXT, FORM_PRIMITIVE, 1 )
- self.cRLIssuer = GeneralNames(1)
- self.cRLIssuer.implied( CLASS_CONTEXT, FORM_CONSTRUCTED, 2 )
- contents = [self.explicitDistributionPoint, self.reasons, self.cRLIssuer]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>CRLDistrobutionPoints</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <example>
- <title>Setting <classname>CRLDistrobutionPoints</classname></title>
- <programlisting>
- n1 = ('directoryName',
- ( (( o2i('countryName'), ('printableString', 'UK') ),),
- (( o2i('stateOrProvinceName'), ('printableString', 'Herts') ),),
- (( o2i('organizationName'), ('printableString', 'The House') ),),
- (( o2i('commonName'), ('printableString', 'Shannon Works') ),) ) )
-
- n2 = ('iPAddress', POW.pkix.ip42oct(192,168,100,51))
-
- data = ( ( ('fullName',(n1, n2)), (1,1,1,1,1), (n1,) ), )
- points = CRLDistrobutionPoints()
- points.set( data )
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class CRLDistributionPoints(SequenceOf):
- _addFragment('''
- <constructor>
- <header>
- <memberof>CRLDistrobutionPoints</memberof>
- <parameter>optional=0</parameter>
- <parameter>default=''</parameter>
- </header>
- </constructor>
- ''')
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, DistributionPoint, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>CrlNumber</name>
- <super>Integer</super>
- </header>
-</class>
-''')
-class CrlNumber(Integer):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>DeltaCrlIndicator</name>
- <super>Integer</super>
- </header>
-</class>
-''')
-class DeltaCrlIndicator(Integer):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>InvalidityDate</name>
- <super>GeneralizedTime</super>
- </header>
-</class>
-''')
-class InvalidityDate(GeneralizedTime):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>CrlReason</name>
- <super>Enum</super>
- </header>
-</class>
-''')
-class CrlReason(Enum):
- pass
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddressRange</name>
- <super>Sequence</super>
- </header>
-</class>
-''')
-class IPAddressRange(Sequence):
- def __init__(self, optional=0, default=''):
- self.min = BitString()
- self.max = BitString()
- contents = [ self.min, self.max ]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddressOrRange</name>
- <super>Choice</super>
- </header>
-</class>
-''')
-class IPAddressOrRange(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'addressPrefix' : BitString(),
- 'addressRange' : IPAddressRange() }
- Choice.__init__(self, choices, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddressesOrRanges</name>
- <super>SequenceOf</super>
- </header>
-</class>
-''')
-class IPAddressesOrRanges(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, IPAddressOrRange, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddressChoice</name>
- <super>Choice</super>
- </header>
-</class>
-''')
-class IPAddressChoice(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'inherit' : Null(),
- 'addressesOrRanges' : IPAddressesOrRanges() }
- Choice.__init__(self, choices, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddressFamily</name>
- <super>Sequence</super>
- </header>
-</class>
-''')
-class IPAddressFamily(Sequence):
- def __init__(self, optional=0, default=''):
- self.addressFamily = OctetString()
- self.ipAddressChoice = IPAddressChoice()
- contents = [ self.addressFamily, self.ipAddressChoice ]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>IPAddrBlocks</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <para>
- Implementation of RFC 3779 section 2.2.3.
- </para>
- </body>
-</class>
-''')
-class IPAddrBlocks(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, IPAddressFamily, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>ASRange</name>
- <super>Sequence</super>
- </header>
-</class>
-''')
-class ASRange(Sequence):
- def __init__(self, optional=0, default=''):
- self.min = Integer()
- self.max = Integer()
- contents = [ self.min, self.max ]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>ASIdOrRange</name>
- <super>Choice</super>
- </header>
-</class>
-''')
-class ASIdOrRange(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'id' : Integer(),
- 'range' : ASRange() }
- Choice.__init__(self, choices, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>ASIdsOrRanges</name>
- <super>SequenceOf</super>
- </header>
-</class>
-''')
-class ASIdsOrRanges(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, ASIdOrRange, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>ASIdentifierChoice</name>
- <super>Choice</super>
- </header>
-</class>
-''')
-class ASIdentifierChoice(Choice):
- def __init__(self, optional=0, default=''):
- choices = { 'inherit' : Null(),
- 'asIdsOrRanges' : ASIdsOrRanges() }
- Choice.__init__(self, choices, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>ASIdentifiers</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- Implementation of RFC 3779 section 3.2.3.
- </para>
- </body>
-</class>
-''')
-class ASIdentifiers(Sequence):
- def __init__(self, optional=0, default=''):
- #
- # This is what we -should- be doing
- #self.asnum = ASIdentifierChoice()
- #self.rdi = ASIdentifierChoice()
- #self.explicitAsnum = Explicit(CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.asnum, 1)
- #self.explictRdi = Explicit(CLASS_CONTEXT, FORM_CONSTRUCTED, 1, self.rdi, 1)
- #contents = [ self.explicitAsnum, self.explictRdi ]
- #
- # ...but it generates a spurious empty RDI clause, so try this instead
- # since we know that we never use RDI anyway.
- self.asnum = ASIdentifierChoice()
- self.explicitAsnum = Explicit(CLASS_CONTEXT, FORM_CONSTRUCTED, 0, self.asnum, 1)
- contents = [ self.explicitAsnum ]
- #
- Sequence.__init__(self, contents, optional, default)
-
- def set(self, values):
- assert len(values) == 1 or (len(values) == 2 and values[1] is None)
- Sequence.set(self, (values[0],))
-
-_addFragment('''
-<class>
- <header>
- <name>AccessDescription</name>
- <super>Sequence</super>
- </header>
-</class>
-''')
-class AccessDescription(Sequence):
- def __init__(self, optional=0, default=''):
- self.accessMethod = Oid()
- self.accessLocation = GeneralName()
- contents = [ self.accessMethod, self.accessLocation ]
- Sequence.__init__(self, contents, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>AuthorityInfoAccess</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <para>
- Implementation of RFC 3280 section 4.2.2.1.
- </para>
- </body>
-</class>
-''')
-class AuthorityInfoAccess(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, AccessDescription, optional, default)
-
-_addFragment('''
-<class>
- <header>
- <name>SubjectInfoAccess</name>
- <super>SequenceOf</super>
- </header>
- <body>
- <para>
- Implementation of RFC 3280 section 4.2.2.2.
- </para>
- </body>
-</class>
-''')
-class SubjectInfoAccess(SequenceOf):
- def __init__(self, optional=0, default=''):
- SequenceOf.__init__(self, AccessDescription, optional, default)
-
-#---------- X509v3 extensions ----------#
-
-_addFragment('''
-<class>
- <header>
- <name>Extension</name>
- <super>Sequence</super>
- </header>
- <body>
- <para>
- This class is a useful little object. It is set by passing three
- values: an oid, an integer(a boolean really) and a value. The
- boolean indicates if this extension is critical. The value is
- used to set the extension once it has been created. The oid
- is used to create the correct object which, to be fully supported it must
- be one of these:
- <simplelist>
- <member><classname>basicConstraints</classname></member>
- <member><classname>subjectAltName</classname></member>
- <member><classname>issuerAltName</classname></member>
- <member><classname>authorityKeyIdentifier</classname></member>
- <member><classname>privateKeyUsagePeriod</classname></member>
- <member><classname>certificatePolicies</classname></member>
- <member><classname>cRLDistributionPoints</classname></member>
- <member><classname>subjectKeyIdentifier</classname></member>
- <member><classname>keyUsage</classname></member>
- <member><classname>crlNumber</classname></member>
- <member><classname>deltaCrlIndicator</classname></member>
- <member><classname>invalidityDate</classname></member>
- <member><classname>crlReason</classname></member>
- </simplelist>
- </para>
- <example>
- <title>Setting <classname>Extension</classname></title>
- <programlisting>
- extn = Extension()
- email = ('rfc822Name', 'peter_shannon@yahoo.com')
- extn.set( (obj2oid('subjectAltName'),1, (email,)) )
- </programlisting>
- </example>
- </body>
-</class>
-''')
-class Extension(Sequence):
-
- classMap = {
- (2, 5, 29, 19) : BasicConstraints,
- (2, 5, 29, 17) : SubjectAltName,
- (2, 5, 29, 18) : IssuerAltName,
- (2, 5, 29, 35) : AuthorityKeyIdentifier,
- (2, 5, 29, 16) : PrivateKeyUsagePeriod,
- (2, 5, 29, 32) : CertificatePolicies,
- (2, 5, 29, 31) : CRLDistributionPoints,
- (2, 5, 29, 14) : SubjectKeyIdentifier,
- (2, 5, 29, 15) : KeyUsage,
- (2, 5, 29, 20) : CrlNumber,
- (2, 5, 29, 27) : DeltaCrlIndicator,
- (2, 5, 29, 24) : InvalidityDate,
- (2, 5, 29, 21) : CrlReason,
- (1, 3, 6, 1, 5, 5, 7, 1, 1) : AuthorityInfoAccess,
- (1, 3, 6, 1, 5, 5, 7, 1, 7) : IPAddrBlocks,
- (1, 3, 6, 1, 5, 5, 7, 1, 8) : ASIdentifiers,
- (1, 3, 6, 1, 5, 5, 7, 1, 11) : SubjectInfoAccess,
- }
-# Missing -- fix later
-# extendedKeyUsage
-# privateKeyUsagePeriod
-# policyMappings
-# nameConstraints
-# policyConstraints
-# subjectDirectoryAttributes
-# instructionCode
-# issuingDistrobutionPoint
-
- def __init__(self, optional=0, default=''):
- self.extnID = Oid()
- self.critical = Boolean(0, 'AQEA')
- self.extnValue = OctetString()
- contents = [self.extnID, self.critical, self.extnValue]
- Sequence.__init__(self, contents, optional, default)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Extension</memberof>
- <name>set</name>
- <parameter>values</parameter>
- </header>
- <body>
- <para>
- <parameter>values</parameter> should be a sequence of three
- values, the oid, critical marker and a value to set the
- extension. If an unknown oid is passed to this function it
- will raise an exception. <parameter>critical</parameter> is a
- boolean. <parameter>value</parameter> will be used to set the
- extension after it has been created.
- </para>
- </body>
- </method>
- ''')
- def set(self, (oid, critical, val) ):
- self.extnID.set( oid )
- self.critical.set( critical )
-
- extnObj = None
- if self.classMap.has_key(oid):
- extnObj = self.classMap[oid]()
- else:
- if not (isinstance(oid, types.TupleType) or isinstance(oid, types.ListType)):
- raise DerError, 'the oid should be specified as a sequence of integers'
- else:
- raise DerError, 'unknown object extension %s' % oid
-
- try:
- extnObj.set( val )
- self.extnValue.set( extnObj.toString() )
- except DerError, e:
- raise DerError, 'failed to set %s, with:\n\t%s\nresulting in:\n\t%s' % (oid, val, `e`)
-
- _addFragment('''
- <method>
- <header>
- <memberof>Extension</memberof>
- <name>get</name>
- </header>
- <body>
- <para>
- There are several ways this function might fail to decode an
- extension. Firstly if the extension was marked critical but if
- the oid cannot be mapped to a class or If a failure occurs decoding the
- <constant>extnValue</constant>, an exception will be raised.
- If a failure occurred and the extension was not marked critical it
- will return a tuple like this: <constant>(oid, critical,
- ())</constant>. If no failures occur a tuple will be returned,
- containg the oid, critical and extension values.
- </para>
- </body>
- </method>
- ''')
- def get(self):
- oid = self.extnID.get()
- critical = self.critical.get()
-
- if self.classMap.has_key(oid):
- extnObj = self.classMap[oid]()
- else:
- if critical:
- raise DerError, 'failed to read critical extension %s' % str(oid)
- else:
- return (oid, critical, ())
-
- try:
- extnObj = self.classMap[oid]()
- extnObj.fromString(self.extnValue.get())
- value = extnObj.get()
- except:
- if critical:
- raise DerError, 'failed to read critical extension %s' % str(oid)
- else:
- return (oid, critical, ())
-
- return (oid, critical, value)