diff options
author | elie <elie> | 2013-11-01 16:01:24 +0000 |
---|---|---|
committer | elie <elie> | 2013-11-01 16:01:24 +0000 |
commit | 9f70e62e36400bd4c48642fdaf499b68e70011ef (patch) | |
tree | 23bb8b2e027d264f6361798cae15bb46a6273ab3 /pyasn1/codec/ber | |
parent | f905a2d2d73a2ac1bf7992c15af3173699152d19 (diff) | |
download | pyasn1-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.py | 50 | ||||
-rw-r--r-- | pyasn1/codec/ber/encoder.py | 38 |
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 |