Question

I am trying to parse an LDAP bind request using the Apache Harmony ASN.1/BER classes (could use another library, I just chose that as it has an Apache License).

My question is on the encoding specifically of a "CHOICE" in ASN.1. The RFC that defines the LDAP ASN.1 schema (http://www.rfc-editor.org/rfc/rfc2251.txt) gives the following as part a bind request:

   BindRequest ::= [APPLICATION 0] SEQUENCE {
            version                 INTEGER (1 .. 127),
            name                    LDAPDN,
            authentication          AuthenticationChoice }

    AuthenticationChoice ::= CHOICE {
            simple                  [0] OCTET STRING,
                                     -- 1 and 2 reserved
            sasl                    [3] SaslCredentials }

    SaslCredentials ::= SEQUENCE {
            mechanism               LDAPString,
            credentials             OCTET STRING OPTIONAL }

How is that CHOICE there actually encoded?

I generated a sample bind request using JXplorer and captured the raw data that was sent. It looks like this:

00000000  30 31 02 01 01 60 2c 02  01 03 04 1b 75 69 64 3d  |01...`,.....uid=|
00000010  74 65 73 74 75 73 65 72  2c 64 63 3d 74 65 73 74  |testuser,dc=test|
00000020  2c 64 63 3d 63 6f 6d 80  0a 74 65 73 74 69 6e 67  |,dc=com..testing|
00000030  31 32 33                                          |123|

The 80 there (at offset 0x27) seems to represent that choice. Fair enough - and I get that (per http://en.wikipedia.org/wiki/Basic_Encoding_Rules#BER_encoding) the last bit is set in order to indicate that it's "context specific" (i.e. defined by this application/protocol) But how would I know if this is a "simple" or "sasl" auth? What indicates which option of the choice is being used? In this case it looks like the next byte (0x0a) is the length of the string - so this could be an OctetString or something of the sort - but I don't see anything here that indicates what the actual is other than 0x80...

I'm also not sure what the [0] and [3] mean in the CHOICE section above. Is that saying there are four options but only options numbered 0 and 3 are in use?

Was it helpful?

Solution

Below you can see output of openssl asn1parse command. The CHOICE members are encoded using so called context specific tags - which means normal tag value is replaced with the one specified in ASN.1 definition for respective item in the CHOICE. The tag has value 0 which implicates the first item in CHOICE is selected. The first choice item is of type OCTET STRING. The value 0 of context specific tag gives you the information about the value type. If there was no context tag, normal OCTET STRING tag would be used.

 0:d=0  hl=2 l=  49 cons: SEQUENCE          
 2:d=1  hl=2 l=   1 prim:  INTEGER           :01
 5:d=1  hl=2 l=  44 cons:  appl [ 0 ]        
 7:d=2  hl=2 l=   1 prim:   INTEGER           :03
10:d=2  hl=2 l=  27 prim:   OCTET STRING      :uid=testuser,dc=test,dc=com
39:d=2  hl=2 l=  10 prim:   cont [ 0 ]        

OTHER TIPS

The '80'H in the encoded message above is called the "identifier octets" (in general it may be more than one octet). This value of the identifier octet(s) indicates that the selected alternative of the CHOICE is "simple", because the five low-order bits of '80'H are '00000'B, which matches the tag number of the tag of "simple" ([0]).

If the sender had selected the "sasl" alternative, the identifier octet would be 'A3'H instead of '80'H. The '3'H in 'A3'H (the five low-order bits) is the tag number of the tag of "sasl" ([3]). The two highest-order bits of the identifier octet are set to '10'B for both alternatives because both [0] and [3] are "context-specific" tags (this just means that these tags don't contain the APPLICATION keyword or the PRIVATE keyword). The next bit of the identifier octet (the "constructed" bit) is set to '0' for "simple" but is set to '1' for "sasl", because the encoding of "sasl" contains nested tags whereas the encoding of "simple" does not contain any nested tags.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top