Skip to content

Encode only values for class "Universal" #57

@TelManuel

Description

@TelManuel

I am pretty new to ASN.1, but as far as I understand the class concept, only "Universal" content can be encoded without further knowledge of the context, right?

I am having a look at LDAP ExtendedResponse for instance. I implemented it like this:

    encoder = asn1.Encoder()

    encoder.start()
    encoder.enter(asn1.Numbers.Sequence)
    encoder.write(msgId)
    encoder.enter(nr=24, cls=asn1.Classes.Application)
    encoder.write(resultCode, cls=asn1.Numbers.Enumerated)
    encoder.write(matchDn, nr=asn1.Numbers.OctetString)
    encoder.write(errorMsg, nr=asn1.Numbers.OctetString)
    encoder.write(responseName, cls=asn1.Classes.Context, nr=10)
    encoder.leave()
    encoder.leave()

    return encoder.output()

ExtendedResponse is defined in RFC4511:

ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
             COMPONENTS OF LDAPResult,
             responseName     [10] LDAPOID OPTIONAL,
             responseValue    [11] OCTET STRING OPTIONAL }
LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
                                 -- [RFC4512]

It defines a responseName which is "context-specific" and its tag-value is "10". This contains a LDAPOID which is encoded as OCTET STRING.

I try to write it with

    encoder.write(responseName, cls=asn1.Classes.Context, nr=10)

When I do this, the tag-value (nr) is used to derive the encoding to be used, which matches Numbers.Integer although it is OCTECT STRING. Therefore, I get the following error:

lib/ldapMessageFactory.py:192: in ldapExtendedResponse
    encoder.write(responseName, cls=asn1.Classes.Context, nr=10)
/usr/local/lib/python3.6/site-packages/asn1.py:176: in write
    value = self._encode_value(nr, value)
/usr/local/lib/python3.6/site-packages/asn1.py:265: in _encode_value
    value = self._encode_integer(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

value = b'1.3.6.1.4.1.1466.20036'

    @staticmethod
    def _encode_integer(value):  # type: (int) -> bytes
        """Encode an integer."""
>       if value < 0:
E       TypeError: '<' not supported between instances of 'bytes' and 'int'

/usr/local/lib/python3.6/site-packages/asn1.py:286: TypeError

So from my point of view, write has to be changed, so that it only encodes values if cls is equal to Classes.Universal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions