[os-devel] SF.net SVN: ospace:[321] branches/ospace_0.5
Brought to you by:
qark
|
From: <qa...@us...> - 2011-11-22 21:22:18
|
Revision: 321
http://ospace.svn.sourceforge.net/ospace/?rev=321&view=rev
Author: qark
Date: 2011-11-22 21:22:09 +0000 (Tue, 22 Nov 2011)
Log Message:
-----------
- Added support for RSA authentication. [Qark]
Modified Paths:
--------------
branches/ospace_0.5/ChangeLog.txt
branches/ospace_0.5/server/lib/ige/Authentication.py
Added Paths:
-----------
branches/ospace_0.5/server/lib/pyasn1/
branches/ospace_0.5/server/lib/pyasn1/__init__.py
branches/ospace_0.5/server/lib/pyasn1/codec/
branches/ospace_0.5/server/lib/pyasn1/codec/__init__.py
branches/ospace_0.5/server/lib/pyasn1/codec/ber/
branches/ospace_0.5/server/lib/pyasn1/codec/ber/__init__.py
branches/ospace_0.5/server/lib/pyasn1/codec/ber/decoder.py
branches/ospace_0.5/server/lib/pyasn1/codec/ber/encoder.py
branches/ospace_0.5/server/lib/pyasn1/codec/ber/eoo.py
branches/ospace_0.5/server/lib/pyasn1/codec/cer/
branches/ospace_0.5/server/lib/pyasn1/codec/cer/__init__.py
branches/ospace_0.5/server/lib/pyasn1/codec/cer/decoder.py
branches/ospace_0.5/server/lib/pyasn1/codec/cer/encoder.py
branches/ospace_0.5/server/lib/pyasn1/codec/der/
branches/ospace_0.5/server/lib/pyasn1/codec/der/__init__.py
branches/ospace_0.5/server/lib/pyasn1/codec/der/decoder.py
branches/ospace_0.5/server/lib/pyasn1/codec/der/encoder.py
branches/ospace_0.5/server/lib/pyasn1/compat/
branches/ospace_0.5/server/lib/pyasn1/compat/__init__.py
branches/ospace_0.5/server/lib/pyasn1/compat/octets.py
branches/ospace_0.5/server/lib/pyasn1/error.py
branches/ospace_0.5/server/lib/pyasn1/type/
branches/ospace_0.5/server/lib/pyasn1/type/__init__.py
branches/ospace_0.5/server/lib/pyasn1/type/base.py
branches/ospace_0.5/server/lib/pyasn1/type/char.py
branches/ospace_0.5/server/lib/pyasn1/type/constraint.py
branches/ospace_0.5/server/lib/pyasn1/type/error.py
branches/ospace_0.5/server/lib/pyasn1/type/namedtype.py
branches/ospace_0.5/server/lib/pyasn1/type/namedval.py
branches/ospace_0.5/server/lib/pyasn1/type/tag.py
branches/ospace_0.5/server/lib/pyasn1/type/tagmap.py
branches/ospace_0.5/server/lib/pyasn1/type/univ.py
branches/ospace_0.5/server/lib/pyasn1/type/useful.py
branches/ospace_0.5/server/lib/rsa/
branches/ospace_0.5/server/lib/rsa/__init__.py
branches/ospace_0.5/server/lib/rsa/_version133.py
branches/ospace_0.5/server/lib/rsa/_version200.py
branches/ospace_0.5/server/lib/rsa/bigfile.py
branches/ospace_0.5/server/lib/rsa/cli.py
branches/ospace_0.5/server/lib/rsa/common.py
branches/ospace_0.5/server/lib/rsa/core.py
branches/ospace_0.5/server/lib/rsa/key.py
branches/ospace_0.5/server/lib/rsa/pem.py
branches/ospace_0.5/server/lib/rsa/pkcs1.py
branches/ospace_0.5/server/lib/rsa/prime.py
branches/ospace_0.5/server/lib/rsa/randnum.py
branches/ospace_0.5/server/lib/rsa/transform.py
branches/ospace_0.5/server/lib/rsa/util.py
branches/ospace_0.5/server/lib/rsa/varblock.py
Property Changed:
----------------
branches/ospace_0.5/client-pygame/
Modified: branches/ospace_0.5/ChangeLog.txt
===================================================================
--- branches/ospace_0.5/ChangeLog.txt 2011-11-15 07:50:47 UTC (rev 320)
+++ branches/ospace_0.5/ChangeLog.txt 2011-11-22 21:22:09 UTC (rev 321)
@@ -6,6 +6,9 @@
- $Author$
- $Revision$
+[2011-11-22]
+- Added support for RSA authentication. [Qark]
+
[2011-11-15]
- MD5 authentication is now backward compatible. [Qark]
Property changes on: branches/ospace_0.5/client-pygame
___________________________________________________________________
Modified: svn:ignore
- var
MANIFEST
build
res.ext
+ var
MANIFEST
build
res.ext
var*
Modified: branches/ospace_0.5/server/lib/ige/Authentication.py
===================================================================
--- branches/ospace_0.5/server/lib/ige/Authentication.py 2011-11-15 07:50:47 UTC (rev 320)
+++ branches/ospace_0.5/server/lib/ige/Authentication.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -1,11 +1,50 @@
-from ige import SecurityException
+import binascii
+from ige import SecurityException, log
import hashlib
+import os
+import rsa
import time
# default method is set to MD5 for backward compatibility
# with version 0.5.68 (revision 308)
defaultMethod = "md5"
+# support for RSA keys
+publicKey = None
+privateKey = None
+
+def createRSAKeys():
+ """Load or generate and save RSA keys"""
+ global publicKey, privateKey
+ if os.path.exists("var/private.pem"):
+ log.message("Loading PRIVATE RSA key")
+ privateKey = rsa.PrivateKey.load_pkcs1(open("var/private.pem", "rb").read())
+ if os.path.exists("var/public.pem"):
+ log.message("Loading PUBLIC RSA key")
+ publicKey = rsa.PublicKey.load_pkcs1(open("var/public.pem", "rb").read())
+ if privateKey and publicKey:
+ return
+ # no keys, let's generate them
+ log.message("Generating RSA keys, please wait...")
+ publicKey, privateKey = rsa.newkeys(2048)
+ open("var/public.pem", "w").write(publicKey.save_pkcs1())
+ open("var/private.pem", "w").write(privateKey.save_pkcs1())
+
+def getPublicKey():
+ """Get current RSA public key"""
+ global publicKey
+ if not publicKey:
+ createRSAKeys()
+ return publicKey
+
+def getPrivateKey():
+ """Get current RSA private key"""
+ global privateKey
+ if not privateKey:
+ createRSAKeys()
+ return privateKey
+
+#
def getMethod(challenge):
return challenge.split(":")[0]
@@ -17,10 +56,13 @@
return "md5:" + hashlib.md5(str(time.time())).hexdigest()
elif method == "sha256":
return "sha256:" + hashlib.sha256(str(time.time())).hexdigest()
+ elif method == "rsa":
+ publicKey = getPublicKey()
+ return "rsa:%s:%s" % (publicKey.n, publicKey.e)
raise SecurityException("Unsupported authentication method %s" % str(method))
def encode(password, challenge):
- """Encodes password using auth method specified in the challenge"""
+ """Encode password using auth method specified in the challenge"""
method = getMethod(challenge)
if method == "plain":
return password
@@ -28,10 +70,14 @@
return hashlib.md5(password + challenge).hexdigest()
elif method == "sha256":
return hashlib.sha256(password + challenge).hexdigest()
+ elif method == "rsa":
+ dummy, n, e = challenge.split(":")
+ key = rsa.PublicKey(int(n), int(e))
+ return binascii.hexlify(rsa.encrypt(password, key))
raise SecurityException("Unsupported authentication method %s" % str(method))
def verify(encodedPassword, password, challenge):
- """Verifies password based on client encoded password and auth method"""
+ """Verify password based on client encoded password and auth method"""
method = getMethod(challenge)
if method == "plain":
return encodedPassword == password
@@ -39,4 +85,6 @@
return hashlib.md5(password + challenge).hexdigest() == encodedPassword
elif method == "sha256":
return hashlib.sha256(password + challenge).hexdigest() == encodedPassword
+ elif method == "rsa":
+ return rsa.decrypt(binascii.unhexlify(encodedPassword), getPrivateKey()) == password
raise SecurityException("Unsupported authentication method %s" % str(method))
Added: branches/ospace_0.5/server/lib/pyasn1/__init__.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/__init__.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/__init__.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1 @@
+majorVersionId = '1'
Property changes on: branches/ospace_0.5/server/lib/pyasn1/__init__.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/__init__.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/ber/__init__.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/ber/decoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/ber/decoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/ber/decoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,746 @@
+# BER decoder
+from pyasn1.type import tag, base, univ, char, useful, tagmap
+from pyasn1.codec.ber import eoo
+from pyasn1.compat.octets import oct2int, octs2ints
+from pyasn1 import error
+
+class AbstractDecoder:
+ protoComponent = None
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ raise error.PyAsn1Error('Decoder not implemented for %s' % tagSet)
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % tagSet)
+
+class AbstractSimpleDecoder(AbstractDecoder):
+ def _createComponent(self, asn1Spec, tagSet, value=None):
+ if asn1Spec is None:
+ return self.protoComponent.clone(value, tagSet)
+ elif value is None:
+ return asn1Spec
+ else:
+ return asn1Spec.clone(value)
+
+class AbstractConstructedDecoder(AbstractDecoder):
+ def _createComponent(self, asn1Spec, tagSet, value=None):
+ if asn1Spec is None:
+ return self.protoComponent.clone(tagSet)
+ else:
+ return asn1Spec.clone()
+
+class EndOfOctetsDecoder(AbstractSimpleDecoder):
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ return eoo.endOfOctets, substrate[:length]
+
+class ExplicitTagDecoder(AbstractSimpleDecoder):
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ return decodeFun(substrate[:length], asn1Spec, tagSet, length)
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ value, substrate = decodeFun(substrate, asn1Spec, tagSet, length)
+ terminator, substrate = decodeFun(substrate)
+ if terminator == eoo.endOfOctets:
+ return value, substrate
+ else:
+ raise error.PyAsn1Error('Missing end-of-octets terminator')
+
+explicitTagDecoder = ExplicitTagDecoder()
+
+class IntegerDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.Integer(0)
+ precomputedValues = {
+ '\x00': 0,
+ '\x01': 1,
+ '\x02': 2,
+ '\x03': 3,
+ '\x04': 4,
+ '\x05': 5,
+ '\x06': 6,
+ '\x07': 7,
+ '\x08': 8,
+ '\x09': 9,
+ '\xff': -1,
+ '\xfe': -2,
+ '\xfd': -3,
+ '\xfc': -4,
+ '\xfb': -5
+ }
+
+ def _valueFilter(self, value):
+ try:
+ return int(value)
+ except OverflowError:
+ return value
+
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
+ state, decodeFun):
+ substrate = substrate[:length]
+ if not substrate:
+ raise error.PyAsn1Error('Empty substrate')
+ if substrate in self.precomputedValues:
+ value = self.precomputedValues[substrate]
+ else:
+ firstOctet = oct2int(substrate[0])
+ if firstOctet & 0x80:
+ value = -1
+ else:
+ value = 0
+ for octet in substrate:
+ value = value << 8 | oct2int(octet)
+ value = self._valueFilter(value)
+ return self._createComponent(asn1Spec, tagSet, value), substrate
+
+class BooleanDecoder(IntegerDecoder):
+ protoComponent = univ.Boolean(0)
+ def _valueFilter(self, value):
+ if value:
+ return 1
+ else:
+ return 0
+
+class BitStringDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.BitString(())
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
+ state, decodeFun):
+ substrate = substrate[:length]
+ if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
+ if not substrate:
+ raise error.PyAsn1Error('Missing initial octet')
+ trailingBits = oct2int(substrate[0])
+ if trailingBits > 7:
+ raise error.PyAsn1Error(
+ 'Trailing bits overflow %s' % trailingBits
+ )
+ substrate = substrate[1:]
+ lsb = p = 0; l = len(substrate)-1; b = ()
+ while p <= l:
+ if p == l:
+ lsb = trailingBits
+ j = 7
+ o = oct2int(substrate[p])
+ while j >= lsb:
+ b = b + ((o>>j)&0x01,)
+ j = j - 1
+ p = p + 1
+ return self._createComponent(asn1Spec, tagSet, b), ''
+ r = self._createComponent(asn1Spec, tagSet, ())
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate)
+ r = r + component
+ return r, substrate
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ r = self._createComponent(asn1Spec, tagSet, '')
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate)
+ if component == eoo.endOfOctets:
+ break
+ r = r + component
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ return r, substrate
+
+class OctetStringDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.OctetString('')
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
+ state, decodeFun):
+ substrate = substrate[:length]
+ if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
+ return self._createComponent(asn1Spec, tagSet, substrate), ''
+ r = self._createComponent(asn1Spec, tagSet, '')
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate)
+ r = r + component
+ return r, substrate
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ r = self._createComponent(asn1Spec, tagSet, '')
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate)
+ if component == eoo.endOfOctets:
+ break
+ r = r + component
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ return r, substrate
+
+class NullDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.Null('')
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ substrate = substrate[:length]
+ r = self._createComponent(asn1Spec, tagSet)
+ if substrate:
+ raise error.PyAsn1Error('Unexpected substrate for Null')
+ return r, substrate
+
+class ObjectIdentifierDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.ObjectIdentifier(())
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
+ state, decodeFun):
+ substrate = substrate[:length]
+ if not substrate:
+ raise error.PyAsn1Error('Empty substrate')
+ oid = (); index = 0
+ # Get the first subid
+ subId = oct2int(substrate[index])
+ oid = oid + divmod(subId, 40)
+
+ index = index + 1
+ substrateLen = len(substrate)
+
+ while index < substrateLen:
+ subId = oct2int(substrate[index])
+ if subId < 128:
+ oid = oid + (subId,)
+ index = index + 1
+ else:
+ # Construct subid from a number of octets
+ nextSubId = subId
+ subId = 0
+ while nextSubId >= 128 and index < substrateLen:
+ subId = (subId << 7) + (nextSubId & 0x7F)
+ index = index + 1
+ nextSubId = oct2int(substrate[index])
+ if index == substrateLen:
+ raise error.SubstrateUnderrunError(
+ 'Short substrate for OID %s' % oid
+ )
+ subId = (subId << 7) + nextSubId
+ oid = oid + (subId,)
+ index = index + 1
+ return self._createComponent(asn1Spec, tagSet, oid), substrate[index:]
+
+class RealDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.Real()
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ substrate = substrate[:length]
+ if not length:
+ raise error.SubstrateUnderrunError('Short substrate for Real')
+ fo = oct2int(substrate[0]); substrate = substrate[1:]
+ if fo & 0x40: # infinite value
+ value = fo & 0x01 and '-inf' or 'inf'
+ elif fo & 0x80: # binary enoding
+ if fo & 0x11 == 0:
+ n = 1
+ elif fo & 0x01:
+ n = 2
+ elif fo & 0x02:
+ n = 3
+ else:
+ n = oct2int(substrate[0])
+ eo, substrate = substrate[:n], substrate[n:]
+ if not eo or not substrate:
+ raise error.PyAsn1Error('Real exponent screwed')
+ e = 0
+ while eo: # exponent
+ e <<= 8
+ e |= oct2int(eo[0])
+ eo = eo[1:]
+ p = 0
+ while substrate: # value
+ p <<= 8
+ p |= oct2int(substrate[0])
+ substrate = substrate[1:]
+ if fo & 0x40: # sign bit
+ p = -p
+ value = (p, 2, e)
+ elif fo & 0xc0 == 0: # character encoding
+ try:
+ if fo & 0x3 == 0x1: # NR1
+ value = (int(substrate), 10, 0)
+ elif fo & 0x3 == 0x2: # NR2
+ value = float(substrate)
+ elif fo & 0x3 == 0x3: # NR3
+ value = float(substrate)
+ else:
+ raise error.SubstrateUnderrunError(
+ 'Unknown NR (tag %s)' % fo
+ )
+ except ValueError:
+ raise error.SubstrateUnderrunError(
+ 'Bad character Real syntax'
+ )
+ elif fo & 0xc0 == 0x40: # special real value
+ pass
+ else:
+ raise error.SubstrateUnderrunError(
+ 'Unknown encoding (tag %s)' % fo
+ )
+ return self._createComponent(asn1Spec, tagSet, value), substrate
+
+class SequenceDecoder(AbstractConstructedDecoder):
+ protoComponent = univ.Sequence()
+ def _getComponentTagMap(self, r, idx):
+ try:
+ return r.getComponentTagMapNearPosition(idx)
+ except error.PyAsn1Error:
+ return
+
+ def _getComponentPositionByType(self, r, t, idx):
+ return r.getComponentPositionNearType(t, idx)
+
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ substrate = substrate[:length]
+ r = self._createComponent(asn1Spec, tagSet)
+ idx = 0
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ asn1Spec = self._getComponentTagMap(r, idx)
+ component, substrate = decodeFun(
+ substrate, asn1Spec
+ )
+ idx = self._getComponentPositionByType(
+ r, component.getEffectiveTagSet(), idx
+ )
+ r.setComponentByPosition(idx, component, asn1Spec is None)
+ idx = idx + 1
+ r.setDefaultComponents()
+ r.verifySizeSpec()
+ return r, substrate
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ r = self._createComponent(asn1Spec, tagSet)
+ idx = 0
+ while substrate:
+ asn1Spec = self._getComponentTagMap(r, idx)
+ if not decodeFun:
+ return r, substrate
+ component, substrate = decodeFun(substrate, asn1Spec)
+ if component == eoo.endOfOctets:
+ break
+ idx = self._getComponentPositionByType(
+ r, component.getEffectiveTagSet(), idx
+ )
+ r.setComponentByPosition(idx, component, asn1Spec is None)
+ idx = idx + 1
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ r.setDefaultComponents()
+ r.verifySizeSpec()
+ return r, substrate
+
+class SequenceOfDecoder(AbstractConstructedDecoder):
+ protoComponent = univ.SequenceOf()
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ substrate = substrate[:length]
+ r = self._createComponent(asn1Spec, tagSet)
+ asn1Spec = r.getComponentType()
+ idx = 0
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(
+ substrate, asn1Spec
+ )
+ r.setComponentByPosition(idx, component, asn1Spec is None)
+ idx = idx + 1
+ r.verifySizeSpec()
+ return r, substrate
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ r = self._createComponent(asn1Spec, tagSet)
+ asn1Spec = r.getComponentType()
+ idx = 0
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate, asn1Spec)
+ if component == eoo.endOfOctets:
+ break
+ r.setComponentByPosition(idx, component, asn1Spec is None)
+ idx = idx + 1
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ r.verifySizeSpec()
+ return r, substrate
+
+class SetDecoder(SequenceDecoder):
+ protoComponent = univ.Set()
+ def _getComponentTagMap(self, r, idx):
+ return r.getComponentTagMap()
+
+ def _getComponentPositionByType(self, r, t, idx):
+ nextIdx = r.getComponentPositionByType(t)
+ if nextIdx is None:
+ return idx
+ else:
+ return nextIdx
+
+class SetOfDecoder(SequenceOfDecoder):
+ protoComponent = univ.SetOf()
+
+class ChoiceDecoder(AbstractConstructedDecoder):
+ protoComponent = univ.Choice()
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ substrate = substrate[:length]
+ r = self._createComponent(asn1Spec, tagSet)
+ if not decodeFun:
+ return r, substrate
+ if r.getTagSet() == tagSet: # explicitly tagged Choice
+ component, substrate = decodeFun(
+ substrate, r.getComponentTagMap()
+ )
+ else:
+ component, substrate = decodeFun(
+ substrate, r.getComponentTagMap(), tagSet, length, state
+ )
+ if isinstance(component, univ.Choice):
+ effectiveTagSet = component.getEffectiveTagSet()
+ else:
+ effectiveTagSet = component.getTagSet()
+ r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None)
+ return r, substrate
+
+ indefLenValueDecoder = valueDecoder
+
+class AnyDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.Any()
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ if asn1Spec is None or \
+ asn1Spec is not None and tagSet != asn1Spec.getTagSet():
+ # untagged Any container, recover inner header substrate
+ length = length + len(fullSubstrate) - len(substrate)
+ substrate = fullSubstrate
+ substrate = substrate[:length]
+ return self._createComponent(asn1Spec, tagSet, value=substrate), ''
+
+ def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
+ length, state, decodeFun):
+ if asn1Spec is not None and tagSet == asn1Spec.getTagSet():
+ # tagged Any type -- consume header substrate
+ header = ''
+ else:
+ # untagged Any, recover header substrate
+ header = fullSubstrate[:-len(substrate)]
+
+ r = self._createComponent(asn1Spec, tagSet, header)
+
+ # Any components do not inherit initial tag
+ asn1Spec = self.protoComponent
+
+ if not decodeFun:
+ return r, substrate
+ while substrate:
+ component, substrate = decodeFun(substrate, asn1Spec)
+ if component == eoo.endOfOctets:
+ break
+ r = r + component
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ return r, substrate
+
+# character string types
+class UTF8StringDecoder(OctetStringDecoder):
+ protoComponent = char.UTF8String()
+class NumericStringDecoder(OctetStringDecoder):
+ protoComponent = char.NumericString()
+class PrintableStringDecoder(OctetStringDecoder):
+ protoComponent = char.PrintableString()
+class TeletexStringDecoder(OctetStringDecoder):
+ protoComponent = char.TeletexString()
+class VideotexStringDecoder(OctetStringDecoder):
+ protoComponent = char.VideotexString()
+class IA5StringDecoder(OctetStringDecoder):
+ protoComponent = char.IA5String()
+class GraphicStringDecoder(OctetStringDecoder):
+ protoComponent = char.GraphicString()
+class VisibleStringDecoder(OctetStringDecoder):
+ protoComponent = char.VisibleString()
+class GeneralStringDecoder(OctetStringDecoder):
+ protoComponent = char.GeneralString()
+class UniversalStringDecoder(OctetStringDecoder):
+ protoComponent = char.UniversalString()
+class BMPStringDecoder(OctetStringDecoder):
+ protoComponent = char.BMPString()
+
+# "useful" types
+class GeneralizedTimeDecoder(OctetStringDecoder):
+ protoComponent = useful.GeneralizedTime()
+class UTCTimeDecoder(OctetStringDecoder):
+ protoComponent = useful.UTCTime()
+
+tagMap = {
+ eoo.endOfOctets.tagSet: EndOfOctetsDecoder(),
+ univ.Integer.tagSet: IntegerDecoder(),
+ univ.Boolean.tagSet: BooleanDecoder(),
+ univ.BitString.tagSet: BitStringDecoder(),
+ univ.OctetString.tagSet: OctetStringDecoder(),
+ univ.Null.tagSet: NullDecoder(),
+ univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
+ univ.Enumerated.tagSet: IntegerDecoder(),
+ univ.Real.tagSet: RealDecoder(),
+ univ.Sequence.tagSet: SequenceDecoder(), # conflicts with SequenceOf
+ univ.Set.tagSet: SetDecoder(), # conflicts with SetOf
+ univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
+ # character string types
+ char.UTF8String.tagSet: UTF8StringDecoder(),
+ char.NumericString.tagSet: NumericStringDecoder(),
+ char.PrintableString.tagSet: PrintableStringDecoder(),
+ char.TeletexString.tagSet: TeletexStringDecoder(),
+ char.VideotexString.tagSet: VideotexStringDecoder(),
+ char.IA5String.tagSet: IA5StringDecoder(),
+ char.GraphicString.tagSet: GraphicStringDecoder(),
+ char.VisibleString.tagSet: VisibleStringDecoder(),
+ char.GeneralString.tagSet: GeneralStringDecoder(),
+ char.UniversalString.tagSet: UniversalStringDecoder(),
+ char.BMPString.tagSet: BMPStringDecoder(),
+ # useful types
+ useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
+ useful.UTCTime.tagSet: UTCTimeDecoder()
+ }
+
+# Type-to-codec map for ambiguous ASN.1 types
+typeMap = {
+ univ.Set.typeId: SetDecoder(),
+ univ.SetOf.typeId: SetOfDecoder(),
+ univ.Sequence.typeId: SequenceDecoder(),
+ univ.SequenceOf.typeId: SequenceOfDecoder(),
+ univ.Choice.typeId: ChoiceDecoder(),
+ univ.Any.typeId: AnyDecoder()
+ }
+
+( stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
+ stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
+ stDumpRawValue, stErrorCondition, stStop ) = [x for x in range(10)]
+
+class Decoder:
+ defaultErrorState = stErrorCondition
+# defaultErrorState = stDumpRawValue
+ defaultRawDecoder = AnyDecoder()
+ def __init__(self, tagMap, typeMap={}):
+ self.__tagMap = tagMap
+ self.__typeMap = typeMap
+ self.__endOfOctetsTagSet = eoo.endOfOctets.getTagSet()
+ # Tag & TagSet objects caches
+ self.__tagCache = {}
+ self.__tagSetCache = {}
+
+ def __call__(self, substrate, asn1Spec=None, tagSet=None,
+ length=None, state=stDecodeTag, recursiveFlag=1):
+ fullSubstrate = substrate
+ while state != stStop:
+ if state == stDecodeTag:
+ # Decode tag
+ if not substrate:
+ raise error.SubstrateUnderrunError(
+ 'Short octet stream on tag decoding'
+ )
+
+ firstOctet = substrate[0]
+ substrate = substrate[1:]
+ if firstOctet in self.__tagCache:
+ lastTag = self.__tagCache[firstOctet]
+ else:
+ t = oct2int(firstOctet)
+ tagClass = t&0xC0
+ tagFormat = t&0x20
+ tagId = t&0x1F
+ if tagId == 0x1F:
+ tagId = 0
+ while 1:
+ if not substrate:
+ raise error.SubstrateUnderrunError(
+ 'Short octet stream on long tag decoding'
+ )
+ t = oct2int(substrate[0])
+ tagId = tagId << 7 | (t&0x7F)
+ substrate = substrate[1:]
+ if not t&0x80:
+ break
+ lastTag = tag.Tag(
+ tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
+ )
+ if tagId < 31:
+ # cache short tags
+ self.__tagCache[firstOctet] = lastTag
+ if tagSet is None:
+ if firstOctet in self.__tagSetCache:
+ tagSet = self.__tagSetCache[firstOctet]
+ else:
+ # base tag not recovered
+ tagSet = tag.TagSet((), lastTag)
+ if firstOctet in self.__tagCache:
+ self.__tagSetCache[firstOctet] = tagSet
+ else:
+ tagSet = lastTag + tagSet
+ state = stDecodeLength
+ if state == stDecodeLength:
+ # Decode length
+ if not substrate:
+ raise error.SubstrateUnderrunError(
+ 'Short octet stream on length decoding'
+ )
+ firstOctet = oct2int(substrate[0])
+ if firstOctet == 128:
+ size = 1
+ length = -1
+ elif firstOctet < 128:
+ length, size = firstOctet, 1
+ else:
+ size = firstOctet & 0x7F
+ # encoded in size bytes
+ length = 0
+ lengthString = substrate[1:size+1]
+ # missing check on maximum size, which shouldn't be a
+ # problem, we can handle more than is possible
+ if len(lengthString) != size:
+ raise error.SubstrateUnderrunError(
+ '%s<%s at %s' %
+ (size, len(lengthString), tagSet)
+ )
+ for char in lengthString:
+ length = (length << 8) | oct2int(char)
+ size = size + 1
+ state = stGetValueDecoder
+ substrate = substrate[size:]
+ if length != -1 and len(substrate) < length:
+ raise error.SubstrateUnderrunError(
+ '%d-octet short' % (length - len(substrate))
+ )
+ if state == stGetValueDecoder:
+ if asn1Spec is None:
+ state = stGetValueDecoderByTag
+ else:
+ state = stGetValueDecoderByAsn1Spec
+ #
+ # There're two ways of creating subtypes in ASN.1 what influences
+ # decoder operation. These methods are:
+ # 1) Either base types used in or no IMPLICIT tagging has been
+ # applied on subtyping.
+ # 2) Subtype syntax drops base type information (by means of
+ # IMPLICIT tagging.
+ # The first case allows for complete tag recovery from substrate
+ # while the second one requires original ASN.1 type spec for
+ # decoding.
+ #
+ # In either case a set of tags (tagSet) is coming from substrate
+ # in an incremental, tag-by-tag fashion (this is the case of
+ # EXPLICIT tag which is most basic). Outermost tag comes first
+ # from the wire.
+ #
+ if state == stGetValueDecoderByTag:
+ if tagSet in self.__tagMap:
+ concreteDecoder = self.__tagMap[tagSet]
+ else:
+ concreteDecoder = None
+ if concreteDecoder:
+ state = stDecodeValue
+ else:
+ _k = tagSet[:1]
+ if _k in self.__tagMap:
+ concreteDecoder = self.__tagMap[_k]
+ else:
+ concreteDecoder = None
+ if concreteDecoder:
+ state = stDecodeValue
+ else:
+ state = stTryAsExplicitTag
+ if state == stGetValueDecoderByAsn1Spec:
+ if isinstance(asn1Spec, (dict, tagmap.TagMap)):
+ if tagSet in asn1Spec:
+ __chosenSpec = asn1Spec[tagSet]
+ else:
+ __chosenSpec = None
+ else:
+ __chosenSpec = asn1Spec
+ if __chosenSpec is not None and (
+ tagSet == __chosenSpec.getTagSet() or \
+ tagSet in __chosenSpec.getTagMap()
+ ):
+ # use base type for codec lookup to recover untagged types
+ baseTagSet = __chosenSpec.baseTagSet
+ if __chosenSpec.typeId is not None and \
+ __chosenSpec.typeId in self.__typeMap:
+ # ambiguous type
+ concreteDecoder = self.__typeMap[__chosenSpec.typeId]
+ elif baseTagSet in self.__tagMap:
+ # base type or tagged subtype
+ concreteDecoder = self.__tagMap[baseTagSet]
+ else:
+ concreteDecoder = None
+ if concreteDecoder:
+ asn1Spec = __chosenSpec
+ state = stDecodeValue
+ else:
+ state = stTryAsExplicitTag
+ elif tagSet == self.__endOfOctetsTagSet:
+ concreteDecoder = self.__tagMap[tagSet]
+ state = stDecodeValue
+ else:
+ state = stTryAsExplicitTag
+ if state == stTryAsExplicitTag:
+ if tagSet and \
+ tagSet[0][1] == tag.tagFormatConstructed and \
+ tagSet[0][0] != tag.tagClassUniversal:
+ # Assume explicit tagging
+ concreteDecoder = explicitTagDecoder
+ state = stDecodeValue
+ else:
+ state = self.defaultErrorState
+ if state == stDumpRawValue:
+ concreteDecoder = self.defaultRawDecoder
+ state = stDecodeValue
+ if state == stDecodeValue:
+ if recursiveFlag:
+ decodeFun = self
+ else:
+ decodeFun = None
+ if length == -1: # indef length
+ value, substrate = concreteDecoder.indefLenValueDecoder(
+ fullSubstrate, substrate, asn1Spec, tagSet, length,
+ stGetValueDecoder, decodeFun
+ )
+ else:
+ value, _substrate = concreteDecoder.valueDecoder(
+ fullSubstrate, substrate, asn1Spec, tagSet, length,
+ stGetValueDecoder, decodeFun
+ )
+ if recursiveFlag:
+ substrate = substrate[length:]
+ else:
+ substrate = _substrate
+ state = stStop
+ if state == stErrorCondition:
+ raise error.PyAsn1Error(
+ '%s not in asn1Spec: %s' % (tagSet, repr(asn1Spec))
+ )
+ return value, substrate
+
+decode = Decoder(tagMap, typeMap)
+
+# XXX
+# non-recursive decoding; return position rather than substrate
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/ber/decoder.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/ber/encoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/ber/encoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/ber/encoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,334 @@
+# BER encoder
+from pyasn1.type import base, tag, univ, char, useful
+from pyasn1.codec.ber import eoo
+from pyasn1.compat.octets import int2oct, ints2octs, null, str2octs
+from pyasn1 import error
+
+class Error(Exception): pass
+
+class AbstractItemEncoder:
+ supportIndefLenMode = 1
+ def encodeTag(self, t, isConstructed):
+ tagClass, tagFormat, tagId = t.asTuple() # this is a hotspot
+ v = tagClass | tagFormat
+ if isConstructed:
+ v = v|tag.tagFormatConstructed
+ if tagId < 31:
+ return int2oct(v|tagId)
+ else:
+ s = int2oct(tagId&0x7f)
+ tagId = tagId >> 7
+ while tagId:
+ s = int2oct(0x80|(tagId&0x7f)) + s
+ tagId = tagId >> 7
+ return int2oct(v|0x1F) + s
+
+ def encodeLength(self, length, defMode):
+ if not defMode and self.supportIndefLenMode:
+ return int2oct(0x80)
+ if length < 0x80:
+ return int2oct(length)
+ else:
+ substrate = null
+ while length:
+ substrate = int2oct(length&0xff) + substrate
+ length = length >> 8
+ substrateLen = len(substrate)
+ if substrateLen > 126:
+ raise Error('Length octets overflow (%d)' % substrateLen)
+ return int2oct(0x80 | substrateLen) + substrate
+
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ raise Error('Not implemented')
+
+ def _encodeEndOfOctets(self, encodeFun, defMode):
+ if defMode or not self.supportIndefLenMode:
+ return null
+ else:
+ return encodeFun(eoo.endOfOctets, defMode)
+
+ def encode(self, encodeFun, value, defMode, maxChunkSize):
+ substrate, isConstructed = self.encodeValue(
+ encodeFun, value, defMode, maxChunkSize
+ )
+ tagSet = value.getTagSet()
+ if tagSet:
+ if not isConstructed: # primitive form implies definite mode
+ defMode = 1
+ return self.encodeTag(
+ tagSet[-1], isConstructed
+ ) + self.encodeLength(
+ len(substrate), defMode
+ ) + substrate + self._encodeEndOfOctets(encodeFun, defMode)
+ else:
+ return substrate # untagged value
+
+class EndOfOctetsEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ return null, 0
+
+class ExplicitlyTaggedItemEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ if isinstance(value, base.AbstractConstructedAsn1Item):
+ value = value.clone(tagSet=value.getTagSet()[:-1],
+ cloneValueFlag=1)
+ else:
+ value = value.clone(tagSet=value.getTagSet()[:-1])
+ return encodeFun(value, defMode, maxChunkSize), 1
+
+explicitlyTaggedItemEncoder = ExplicitlyTaggedItemEncoder()
+
+class IntegerEncoder(AbstractItemEncoder):
+ supportIndefLenMode = 0
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ octets = []
+ value = int(value) # to save on ops on asn1 type
+ while 1:
+ octets.insert(0, value & 0xff)
+ if value == 0 or value == -1:
+ break
+ value = value >> 8
+ if value == 0 and octets[0] & 0x80:
+ octets.insert(0, 0)
+ while len(octets) > 1 and \
+ (octets[0] == 0 and octets[1] & 0x80 == 0 or \
+ octets[0] == 0xff and octets[1] & 0x80 != 0):
+ del octets[0]
+ return ints2octs(octets), 0
+
+class BitStringEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ if not maxChunkSize or len(value) <= maxChunkSize*8:
+ r = {}; l = len(value); p = 0; j = 7
+ while p < l:
+ i, j = divmod(p, 8)
+ r[i] = r.get(i,0) | value[p]<<(7-j)
+ p = p + 1
+ keys = list(r); keys.sort()
+ return int2oct(7-j) + ints2octs([r[k] for k in keys]), 0
+ else:
+ pos = 0; substrate = null
+ while 1:
+ # count in octets
+ v = value.clone(value[pos*8:pos*8+maxChunkSize*8])
+ if not v:
+ break
+ substrate = substrate + encodeFun(v, defMode, maxChunkSize)
+ pos = pos + maxChunkSize
+ return substrate, 1
+
+class OctetStringEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ if not maxChunkSize or len(value) <= maxChunkSize:
+ return value.asOctets(), 0
+ else:
+ pos = 0; substrate = null
+ while 1:
+ v = value.clone(value[pos:pos+maxChunkSize])
+ if not v:
+ break
+ substrate = substrate + encodeFun(v, defMode, maxChunkSize)
+ pos = pos + maxChunkSize
+ return substrate, 1
+
+class NullEncoder(AbstractItemEncoder):
+ supportIndefLenMode = 0
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ return null, 0
+
+class ObjectIdentifierEncoder(AbstractItemEncoder):
+ supportIndefLenMode = 0
+ precomputedValues = {
+ (1, 3, 6, 1, 2): (43, 6, 1, 2),
+ (1, 3, 6, 1, 4): (43, 6, 1, 4)
+ }
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ oid = value.asTuple()
+ if oid[:5] in self.precomputedValues:
+ octets = self.precomputedValues[oid[:5]]
+ index = 5
+ else:
+ if len(oid) < 2:
+ raise error.PyAsn1Error('Short OID %s' % value)
+
+ # Build the first twos
+ index = 0
+ subid = oid[index] * 40
+ subid = subid + oid[index+1]
+ if subid < 0 or subid > 0xff:
+ raise error.PyAsn1Error(
+ 'Initial sub-ID overflow %s in OID %s' % (oid[index:], value)
+ )
+ octets = (subid,)
+ index = index + 2
+
+ # Cycle through subids
+ for subid in oid[index:]:
+ if subid > -1 and subid < 128:
+ # Optimize for the common case
+ octets = octets + (subid & 0x7f,)
+ elif subid < 0 or subid > 0xFFFFFFFF:
+ raise error.PyAsn1Error(
+ 'SubId overflow %s in %s' % (subid, value)
+ )
+ else:
+ # Pack large Sub-Object IDs
+ res = (subid & 0x7f,)
+ subid = subid >> 7
+ while subid > 0:
+ res = (0x80 | (subid & 0x7f),) + res
+ subid = subid >> 7
+ # Add packed Sub-Object ID to resulted Object ID
+ octets += res
+
+ return ints2octs(octets), 0
+
+class RealEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ if value.isPlusInfinity():
+ return int2oct(0x40), 0
+ if value.isMinusInfinity():
+ return int2oct(0x41), 0
+ m, b, e = value
+ if not m:
+ return null, 0
+ if b == 10:
+ return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), 0
+ elif b == 2:
+ fo = 0x80 # binary enoding
+ if m < 0:
+ fo = fo | 0x40 # sign bit
+ m = -m
+ while int(m) != m: # drop floating point
+ m *= 2
+ e -= 1
+ while m & 0x1 == 0: # mantissa normalization
+ m >>= 1
+ e += 1
+ eo = null
+ while e:
+ eo = int2oct(e&0xff) + eo
+ e >>= 8
+ n = len(eo)
+ if n > 0xff:
+ raise error.PyAsn1Error('Real exponent overflow')
+ if n == 1:
+ pass
+ elif n == 2:
+ fo |= 1
+ elif n == 3:
+ fo |= 2
+ else:
+ fo |= 3
+ eo = int2oct(n//0xff+1) + eo
+ po = null
+ while m:
+ po = int2oct(m&0xff) + po
+ m >>= 8
+ substrate = int2oct(fo) + eo + po
+ return substrate, 0
+ else:
+ raise error.PyAsn1Error('Prohibited Real base %s' % b)
+
+class SequenceEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ value.setDefaultComponents()
+ value.verifySizeSpec()
+ substrate = null; idx = len(value)
+ while idx > 0:
+ idx = idx - 1
+ if value[idx] is None: # Optional component
+ continue
+ component = value.getDefaultComponentByPosition(idx)
+ if component is not None and component == value[idx]:
+ continue
+ substrate = encodeFun(
+ value[idx], defMode, maxChunkSize
+ ) + substrate
+ return substrate, 1
+
+class SequenceOfEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ value.verifySizeSpec()
+ substrate = null; idx = len(value)
+ while idx > 0:
+ idx = idx - 1
+ substrate = encodeFun(
+ value[idx], defMode, maxChunkSize
+ ) + substrate
+ return substrate, 1
+
+class ChoiceEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ return encodeFun(value.getComponent(), defMode, maxChunkSize), 1
+
+class AnyEncoder(OctetStringEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ return value.asOctets(), defMode == 0
+
+tagMap = {
+ eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),
+ univ.Boolean.tagSet: IntegerEncoder(),
+ univ.Integer.tagSet: IntegerEncoder(),
+ univ.BitString.tagSet: BitStringEncoder(),
+ univ.OctetString.tagSet: OctetStringEncoder(),
+ univ.Null.tagSet: NullEncoder(),
+ univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),
+ univ.Enumerated.tagSet: IntegerEncoder(),
+ univ.Real.tagSet: RealEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
+ univ.SequenceOf.tagSet: SequenceOfEncoder(),
+ univ.SetOf.tagSet: SequenceOfEncoder(),
+ univ.Choice.tagSet: ChoiceEncoder(),
+ # character string types
+ char.UTF8String.tagSet: OctetStringEncoder(),
+ char.NumericString.tagSet: OctetStringEncoder(),
+ char.PrintableString.tagSet: OctetStringEncoder(),
+ char.TeletexString.tagSet: OctetStringEncoder(),
+ char.VideotexString.tagSet: OctetStringEncoder(),
+ char.IA5String.tagSet: OctetStringEncoder(),
+ char.GraphicString.tagSet: OctetStringEncoder(),
+ char.VisibleString.tagSet: OctetStringEncoder(),
+ char.GeneralString.tagSet: OctetStringEncoder(),
+ char.UniversalString.tagSet: OctetStringEncoder(),
+ char.BMPString.tagSet: OctetStringEncoder(),
+ # useful types
+ useful.GeneralizedTime.tagSet: OctetStringEncoder(),
+ useful.UTCTime.tagSet: OctetStringEncoder()
+ }
+
+# Type-to-codec map for ambiguous ASN.1 types
+typeMap = {
+ univ.Set.typeId: SequenceEncoder(),
+ univ.SetOf.typeId: SequenceOfEncoder(),
+ univ.Sequence.typeId: SequenceEncoder(),
+ univ.SequenceOf.typeId: SequenceOfEncoder(),
+ univ.Choice.typeId: ChoiceEncoder(),
+ univ.Any.typeId: AnyEncoder()
+ }
+
+class Encoder:
+ def __init__(self, tagMap, typeMap={}):
+ self.__tagMap = tagMap
+ self.__typeMap = typeMap
+
+ def __call__(self, value, defMode=1, maxChunkSize=0):
+ tagSet = value.getTagSet()
+ if len(tagSet) > 1:
+ concreteEncoder = explicitlyTaggedItemEncoder
+ else:
+ if value.typeId is not None and value.typeId in self.__typeMap:
+ concreteEncoder = self.__typeMap[value.typeId]
+ elif tagSet in self.__tagMap:
+ concreteEncoder = self.__tagMap[tagSet]
+ else:
+ baseTagSet = value.baseTagSet
+ if baseTagSet in self.__tagMap:
+ concreteEncoder = self.__tagMap[baseTagSet]
+ else:
+ raise Error('No encoder for %s' % value)
+ return concreteEncoder.encode(
+ self, value, defMode, maxChunkSize
+ )
+
+encode = Encoder(tagMap, typeMap)
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/ber/encoder.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/ber/eoo.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/ber/eoo.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/ber/eoo.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,8 @@
+from pyasn1.type import base, tag
+
+class EndOfOctets(base.AbstractSimpleAsn1Item):
+ defaultValue = 0
+ tagSet = tag.initTagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)
+ )
+endOfOctets = EndOfOctets()
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/ber/eoo.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/cer/__init__.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/cer/decoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/cer/decoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/cer/decoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,32 @@
+# CER decoder
+from pyasn1.type import univ
+from pyasn1.codec.ber import decoder
+from pyasn1.compat.octets import oct2int
+from pyasn1 import error
+
+class BooleanDecoder(decoder.AbstractSimpleDecoder):
+ protoComponent = univ.Boolean(0)
+ def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
+ state, decodeFun):
+ substrate = substrate[:length]
+ if not substrate:
+ raise error.PyAsn1Error('Empty substrate')
+ byte = oct2int(substrate[0])
+ if byte == 0xff:
+ value = 1
+ elif byte == 0x00:
+ value = 0
+ else:
+ raise error.PyAsn1Error('Boolean CER violation: %s' % byte)
+ return self._createComponent(asn1Spec, tagSet, value), substrate[1:]
+
+tagMap = decoder.tagMap.copy()
+tagMap.update({
+ univ.Boolean.tagSet: BooleanDecoder(),
+ })
+
+typeMap = decoder.typeMap
+
+class Decoder(decoder.Decoder): pass
+
+decode = Decoder(tagMap, decoder.typeMap)
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/cer/decoder.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/cer/encoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/cer/encoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/cer/encoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,87 @@
+# CER encoder
+from pyasn1.type import univ
+from pyasn1.codec.ber import encoder
+from pyasn1.compat.octets import int2oct, null
+
+class BooleanEncoder(encoder.IntegerEncoder):
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ if client == 0:
+ substrate = int2oct(0)
+ else:
+ substrate = int2oct(255)
+ return substrate, 0
+
+class BitStringEncoder(encoder.BitStringEncoder):
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ return encoder.BitStringEncoder.encodeValue(
+ self, encodeFun, client, defMode, 1000
+ )
+
+class OctetStringEncoder(encoder.OctetStringEncoder):
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ return encoder.OctetStringEncoder.encodeValue(
+ self, encodeFun, client, defMode, 1000
+ )
+
+# specialized RealEncoder here
+# specialized GeneralStringEncoder here
+# specialized GeneralizedTimeEncoder here
+# specialized UTCTimeEncoder here
+
+class SetOfEncoder(encoder.SequenceOfEncoder):
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ if isinstance(client, univ.SequenceAndSetBase):
+ client.setDefaultComponents()
+ client.verifySizeSpec()
+ substrate = null; idx = len(client)
+ # This is certainly a hack but how else do I distinguish SetOf
+ # from Set if they have the same tags&constraints?
+ if isinstance(client, univ.SequenceAndSetBase):
+ # Set
+ comps = []
+ while idx > 0:
+ idx = idx - 1
+ if client[idx] is None: # Optional component
+ continue
+ if client.getDefaultComponentByPosition(idx) == client[idx]:
+ continue
+ comps.append(client[idx])
+ comps.sort(key=lambda x: isinstance(x, univ.Choice) and \
+ x.getMinTagSet() or x.getTagSet())
+ for c in comps:
+ substrate += encodeFun(c, defMode, maxChunkSize)
+ else:
+ # SetOf
+ compSubs = []
+ while idx > 0:
+ idx = idx - 1
+ compSubs.append(
+ encodeFun(client[idx], defMode, maxChunkSize)
+ )
+ compSubs.sort() # perhaps padding's not needed
+ substrate = null
+ for compSub in compSubs:
+ substrate += compSub
+ return substrate, 1
+
+tagMap = encoder.tagMap.copy()
+tagMap.update({
+ univ.Boolean.tagSet: BooleanEncoder(),
+ univ.BitString.tagSet: BitStringEncoder(),
+ univ.OctetString.tagSet: OctetStringEncoder(),
+ univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set
+ })
+
+typeMap = encoder.typeMap.copy()
+typeMap.update({
+ univ.Set.typeId: SetOfEncoder(),
+ univ.SetOf.typeId: SetOfEncoder()
+ })
+
+class Encoder(encoder.Encoder):
+ def __call__(self, client, defMode=0, maxChunkSize=0):
+ return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
+
+encode = Encoder(tagMap, typeMap)
+
+# EncoderFactory queries class instance and builds a map of tags -> encoders
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/cer/encoder.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/der/__init__.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/der/decoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/der/decoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/der/decoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,5 @@
+# DER decoder
+from pyasn1.type import univ
+from pyasn1.codec.cer import decoder
+
+decode = decoder.Decoder(decoder.tagMap, decoder.typeMap)
Property changes on: branches/ospace_0.5/server/lib/pyasn1/codec/der/decoder.py
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/ospace_0.5/server/lib/pyasn1/codec/der/encoder.py
===================================================================
--- branches/ospace_0.5/server/lib/pyasn1/codec/der/encoder.py (rev 0)
+++ branches/ospace_0.5/server/lib/pyasn1/codec/der/encoder.py 2011-11-22 21:22:09 UTC (rev 321)
@@ -0,0 +1,28 @@
+# DER encoder
+from pyasn1.type import univ
+from pyasn1.codec.cer import encoder
+
+class SetOfEncoder(encoder.SetOfEncoder):
+ def _cmpSetComponents(self, c1, c2):
+ tagSet1 = isinstance(c1, univ.Choice) and \
+ c1.getEffectiveTagSet() or c1.getTagSet()
+ tagSet2 = isinstance(c2, univ.Choice) and \
+ c2.getEffectiveTagSet() or c2.getTagSet()
+ return cmp(tagSet1, tagSet2)
+
+tagMap = encoder....
[truncated message content] |