summaryrefslogtreecommitdiff
path: root/pyasn1/codec/ber
diff options
context:
space:
mode:
authorelie <elie>2013-11-01 16:01:24 +0000
committerelie <elie>2013-11-01 16:01:24 +0000
commit9f70e62e36400bd4c48642fdaf499b68e70011ef (patch)
tree23bb8b2e027d264f6361798cae15bb46a6273ab3 /pyasn1/codec/ber
parentf905a2d2d73a2ac1bf7992c15af3173699152d19 (diff)
downloadpyasn1-9f70e62e36400bd4c48642fdaf499b68e70011ef.tar.gz
* some more fixes to OID codecs
* explicit limit on ObjectIdentifier arc value size removed * some more tests in OID encoding problem areas added
Diffstat (limited to 'pyasn1/codec/ber')
-rw-r--r--pyasn1/codec/ber/decoder.py50
-rw-r--r--pyasn1/codec/ber/encoder.py38
2 files changed, 43 insertions, 45 deletions
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 1530a54..d0c9814 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -216,30 +216,14 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder):
if not head:
raise error.PyAsn1Error('Empty substrate')
- # Decode the first octet
- index = 1
- subId = oct2int(head[0])
- if 0 <= subId <= 39:
- oid = 0, subId
- elif 40 <= subId <= 79:
- oid = 1, subId - 40
- elif subId >= 80:
- oid = 2,
- index = 0
- else:
- raise error.PyAsn1Error('Malformed first OID octet: %s' % subId)
-
+ oid = ()
+ index = 0
substrateLen = len(head)
while index < substrateLen:
subId = oct2int(head[index])
- if index == 0:
- subId -= 80
- index = index + 1
- if subId == 128:
- # ASN.1 spec forbids leading zeros (0x80) in sub-ID OID
- # encoding, tolerating it opens a vulnerability.
- # See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf page 7
- raise error.PyAsn1Error('Invalid leading 0x80 in sub-OID')
+ index += 1
+ if subId < 128:
+ oid = oid + (subId,)
elif subId > 128:
# Construct subid from a number of octets
nextSubId = subId
@@ -249,11 +233,27 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder):
if index >= substrateLen:
raise error.SubstrateUnderrunError(
'Short substrate for sub-OID past %s' % (oid,)
- )
+ )
nextSubId = oct2int(head[index])
- index = index + 1
- subId = (subId << 7) + nextSubId
- oid = oid + (subId,)
+ index += 1
+ oid = oid + ((subId << 7) + nextSubId,)
+ elif subId == 128:
+ # ASN.1 spec forbids leading zeros (0x80) in OID
+ # encoding, tolerating it opens a vulnerability. See
+ # http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
+ # page 7
+ raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
+
+ # Decode two leading arcs
+ if 0 <= oid[0] <= 39:
+ oid = (0,) + oid
+ elif 40 <= oid[0] <= 79:
+ oid = (1, oid[0]-40) + oid[1:]
+ elif oid[0] >= 80:
+ oid = (2, oid[0]-80) + oid[1:]
+ else:
+ raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
+
return self._createComponent(asn1Spec, tagSet, oid), tail
class RealDecoder(AbstractSimpleDecoder):
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index a52f9da..b19f240 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -156,48 +156,46 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
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:
+ oid = oid[5:]
octets = self.precomputedValues[oid[:5]]
- index = 5
else:
if len(oid) < 2:
raise error.PyAsn1Error('Short OID %s' % (value,))
- index = 2
+ octets = ()
# Build the first twos
if oid[0] == 0 and 0 <= oid[1] <= 39:
- octets = (oid[1],)
+ oid = (oid[1],) + oid[2:]
elif oid[0] == 1 and 0 <= oid[1] <= 39:
- octets = (oid[1] + 40,)
+ oid = (oid[1] + 40,) + oid[2:]
elif oid[0] == 2:
- octets = ()
oid = (oid[1] + 80,) + oid[2:]
- index = 0
else:
raise error.PyAsn1Error(
- 'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)
+ 'Impossible initial arcs %s at %s' % (oid[:2], value)
)
- # Cycle through subids
- for subid in oid[index:]:
- if subid > -1 and subid < 128:
+ # Cycle through subIds
+ for subId in oid:
+ if subId > -1 and subId < 128:
# Optimize for the common case
- octets = octets + (subid & 0x7f,)
- elif subid < 0:
+ octets = octets + (subId & 0x7f,)
+ elif subId < 0:
raise error.PyAsn1Error(
- 'SubId overflow %s in %s' % (subid, value)
- )
+ 'Negative OID arc %s at %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
+ 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