etingof/pyasn1

parsing LDAP search message openldap

michael-dev opened this issue · 1 comments

I've tried to parse an LDAP SearchQuery Message from ldapsearch from openldap.
It fails with specific search queries when given an ASN.1 spec for LDAP messages, but also fails when trying to decode the ldap message without any ASN.1 specification. As this is used in an ldap proxy that should just pass-through LDAP search messages, I am mostly interested in pyasn1 not failing at special messages.

The message it fails at is given in hex here: 30560201026351041064633d6578616d6c652c64633d6f72670a01020a0100020100020100010100a02c870b6f626a656374436c617373a31d040e73616d4163636f756e744e616d65040b6578616d706c65557365723000

The message can be parsed by asn1js here: https://lapo.it/asn1js/#MFYCAQJjUQQQZGM9ZXhhbWxlLGRjPW9yZwoBAgoBAAIBAAIBAAEBAKAshwtvYmplY3RDbGFzc6MdBA5zYW1BY2NvdW50TmFtZQQLZXhhbXBsZVVzZXIwAA

Testcode:
from binascii import unhexlify
from pyasn1.codec.ber.decoder import decode as ber_decoder
from pyasn1 import debug

debug.setLogger(debug.Debug('all'))

data = unhexlify('30560201026351041064633d6578616d6c652c64633d6f72670a01020a0100020100020100010100a02c870b6f626a656374436c617373a31d040e73616d4163636f756e744e616d65040b6578616d706c65557365723000')

obj, rest_of_input = ber_decoder(data)

print(data)
print(obj)
print(rest_of_input)

GIT Master shows:
2022-12-12 16:06:12,821 pyasn1: running pyasn1 0.4.9, debug flags all
2022-12-12 16:06:12,821 pyasn1: debug category 'all' enabled
2022-12-12 16:06:12,821 pyasn1: decoder called at scope with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7fa36eff9ee0>
2022-12-12 16:06:12,821 pyasn1: tag decoded into <TagSet object, tags 0:32:16>, decoding length
2022-12-12 16:06:12,821 pyasn1: value length decoded into 86
2022-12-12 16:06:12,821 pyasn1: codec SequenceOrSequenceOfPayloadDecoder chosen by a built-in type, decoding value
2022-12-12 16:06:12,821 pyasn1: state is stDecodeValue
2022-12-12 16:06:12,821 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7fa36eff9ee0>
2022-12-12 16:06:12,821 pyasn1: tag decoded into <TagSet object, tags 0:0:2>, decoding length
2022-12-12 16:06:12,821 pyasn1: value length decoded into 1
2022-12-12 16:06:12,821 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-12 16:06:12,821 pyasn1: state is stDecodeValue
2022-12-12 16:06:12,821 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
2
...
2022-12-12 16:06:12,821 pyasn1: decoder left scope NoneType, call completed
2022-12-12 16:06:12,821 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7fa36eff9ee0>
2022-12-12 16:06:12,821 pyasn1: tag decoded into <TagSet object, tags 64:32:3>, decoding length
2022-12-12 16:06:12,821 pyasn1: value length decoded into 81
2022-12-12 16:06:12,821 pyasn1: codec chosen by a built-in type, decoding as explicit tag
2022-12-12 16:06:12,821 pyasn1: A: codec RawPayloadDecoder chosen, decoding value
2022-12-12 16:06:12,821 pyasn1: state is stDecodeValue
2022-12-12 16:06:12,821 pyasn1: valueDecoder
2022-12-12 16:06:12,821 pyasn1: valueDecoder B decodeFun=<pyasn1.codec.ber.decoder.SingleItemDecoder object at 0x7fa36efdbd90> len=81
2022-12-12 16:06:12,821 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7fa36eff9ee0>
2022-12-12 16:06:12,821 pyasn1: tag decoded into <TagSet object, tags 0:0:4-64:32:3>, decoding length
2022-12-12 16:06:12,821 pyasn1: value length decoded into 16
2022-12-12 16:06:12,822 pyasn1: codec OctetStringPayloadDecoder chosen by a built-in type, decoding value
2022-12-12 16:06:12,822 pyasn1: state is stDecodeValue
2022-12-12 16:06:12,822 pyasn1: codec OctetStringPayloadDecoder yields type OctetString, value:
dc=examle,dc=org
...
2022-12-12 16:06:12,822 pyasn1: decoder left scope NoneType.?, call completed
Traceback (most recent call last):
File "/home/ron/test-pyasn1/test.py", line 10, in
obj, rest_of_input = ber_decoder(data)
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 2013, in call
for asn1Object in streamingDecoder:
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 1928, in iter
for asn1Object in self._singleItemDecoder(
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 1788, in call
for value in concreteDecoder.valueDecoder(
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 673, in valueDecoder
for asn1Object in self._decodeComponentsSchemaless(
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 609, in _decodeComponentsSchemaless
for component in decodeFun(substrate, **options):
File "/home/ron/test-pyasn1/pyasn1/codec/ber/decoder.py", line 1797, in call
raise PyAsn1Error(
pyasn1.error.PyAsn1Error: Read 18 bytes instead of expected 81.

Making RawPayloadDecoder.valueDecoder loop like RawPayloadDecoder.indefLenValueDecoder changes the error messages as it fails at decoding the query message part.

lextm commented

Please close this issue here and report to https://github.com/pyasn1/pyasn1/issues.

This repo is no longer maintained.