diff options
author | elie <elie> | 2015-04-25 22:57:21 +0000 |
---|---|---|
committer | elie <elie> | 2015-04-25 22:57:21 +0000 |
commit | ed29b5a505ec315c7446e732aec36394b104424d (patch) | |
tree | 8cc588f7346c3dbc9b8893b80f802b0eaa6c4fed /pyasn1 | |
parent | f2f35576877b143bfd870f4600359ee21c7d81a8 (diff) | |
download | pyasn1-ed29b5a505ec315c7446e732aec36394b104424d.tar.gz |
DER codec hardened not to tolerate indefinite length encoding/decoding
Diffstat (limited to 'pyasn1')
-rw-r--r-- | pyasn1/codec/ber/decoder.py | 5 | ||||
-rw-r--r-- | pyasn1/codec/ber/encoder.py | 5 | ||||
-rw-r--r-- | pyasn1/codec/cer/encoder.py | 10 | ||||
-rw-r--r-- | pyasn1/codec/der/decoder.py | 3 | ||||
-rw-r--r-- | pyasn1/codec/der/encoder.py | 7 |
5 files changed, 19 insertions, 11 deletions
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index 6794f5e..61bfbce 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -598,6 +598,7 @@ class Decoder: defaultErrorState = stErrorCondition # defaultErrorState = stDumpRawValue defaultRawDecoder = AnyDecoder() + supportIndefLength = True def __init__(self, tagMap, typeMap={}): self.__tagMap = tagMap self.__typeMap = typeMap @@ -630,7 +631,7 @@ class Decoder: # Look for end-of-octets sentinel if t == 0: if substrate and oct2int(substrate[0]) == 0: - if allowEoo: + if allowEoo and self.supportIndefLength: debug.logger and debug.logger & debug.flagDecoder and debug.logger('end-of-octets sentinel found') value, substrate = eoo.endOfOctets, substrate[1:] state = stStop @@ -704,6 +705,8 @@ class Decoder: raise error.SubstrateUnderrunError( '%d-octet short' % (length - len(substrate)) ) + if length == -1 and not self.supportIndefLength: + error.PyAsn1Error('Indefinite length encoding not supported by this codec') state = stGetValueDecoder debug.logger and debug.logger & debug.flagDecoder and debug.logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length]))) if state == stGetValueDecoder: diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py index 7f204c8..0fb4ae7 100644 --- a/pyasn1/codec/ber/encoder.py +++ b/pyasn1/codec/ber/encoder.py @@ -400,11 +400,14 @@ typeMap = { } class Encoder: + supportIndefLength = True def __init__(self, tagMap, typeMap={}): self.__tagMap = tagMap self.__typeMap = typeMap - def __call__(self, value, defMode=1, maxChunkSize=0): + def __call__(self, value, defMode=True, maxChunkSize=0): + if not defMode and not self.supportIndefLength: + raise error.PyAsn1Error('Indefinite length encoding not supported by this codec') debug.logger & debug.flagEncoder and debug.logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.prettyPrintType(), value.prettyPrint())) tagSet = value.getTagSet() if len(tagSet) > 1: diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py index d834931..b432b96 100644 --- a/pyasn1/codec/cer/encoder.py +++ b/pyasn1/codec/cer/encoder.py @@ -15,13 +15,13 @@ 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 - ) + ) class RealEncoder(encoder.RealEncoder): def _chooseEncBase(self, value): @@ -75,16 +75,16 @@ tagMap.update({ univ.OctetString.tagSet: OctetStringEncoder(), univ.Real.tagSet: RealEncoder(), 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): + def __call__(self, client, defMode=False, maxChunkSize=0): return encoder.Encoder.__call__(self, client, defMode, maxChunkSize) encode = Encoder(tagMap, typeMap) diff --git a/pyasn1/codec/der/decoder.py b/pyasn1/codec/der/decoder.py index 1ecdf5c..ea58d6d 100644 --- a/pyasn1/codec/der/decoder.py +++ b/pyasn1/codec/der/decoder.py @@ -3,6 +3,7 @@ from pyasn1.codec.cer import decoder tagMap = decoder.tagMap typeMap = decoder.typeMap -Decoder = decoder.Decoder +class Decoder(decoder.Decoder): + supportIndefLength = False decode = Decoder(tagMap, typeMap) diff --git a/pyasn1/codec/der/encoder.py b/pyasn1/codec/der/encoder.py index 4e5faef..0219ae7 100644 --- a/pyasn1/codec/der/encoder.py +++ b/pyasn1/codec/der/encoder.py @@ -17,12 +17,13 @@ tagMap.update({ univ.OctetString.tagSet: encoder.encoder.OctetStringEncoder(), # Set & SetOf have same tags univ.SetOf().tagSet: SetOfEncoder() - }) +}) typeMap = encoder.typeMap class Encoder(encoder.Encoder): - def __call__(self, client, defMode=1, maxChunkSize=0): + supportIndefLength = False + def __call__(self, client, defMode=True, maxChunkSize=0): return encoder.Encoder.__call__(self, client, defMode, maxChunkSize) - + encode = Encoder(tagMap, typeMap) |