1

I use asn1c to parse the LDAP messages.

For this purpose, after compiling the ASN.1 Definition defined in rfc4511, I use the ber_decode and xer_fprint functions for decoding and printing content in my program.

For example, the two outputs indicated below are related to two different LDAP messages:

<LDAPMessage>
    <messageID>1</messageID>
    <protocolOp>
        <bindRequest>
            <version>3</version>
            <name>75 69 64 3D 61 2C 64 63 3D 63 6F 6D</name>
            <authentication>
                <simple>70 61 73 73 77 6F 72 64</simple>
            </authentication>
        </bindRequest>
    </protocolOp>
</LDAPMessage>

<LDAPMessage>
    <messageID>5</messageID>
    <protocolOp>
        <searchRequest>
            <baseObject></baseObject>
            <scope><baseObject/></scope>
            <derefAliases><neverDerefAliases/></derefAliases>
            <sizeLimit>0</sizeLimit>
            <timeLimit>0</timeLimit>
            <typesOnly><true/></typesOnly>
            <filter>
                <present>4F 62 6A 65 63 74 43 6C 61 73 73</present>
            </filter>
            <attributes>
                <selector>31 2E 31</selector>
            </attributes>
        </searchRequest>
    </protocolOp>
</LDAPMessage>

As you can see, the values ​​for the name, simple, present and selector fields are displayed as hexadecimal. While I want them displayed as human readable values ​​(similar to what wireshark does).

second message on the wireshark (present field have ObjectClass Value)

I know that the same question was asked in this link (decoding asn.1 compiler output as strings). Lev Walkin said that OCTET STRING should be replaced with IA5String or UTF8String. But in LDAP ASN.1 Definition, OCTET STRING has been used in many places.

Which one should I change? Is my perception of replacing OCTET STRING with IA5String or UTF8String correct? Should this be done in LDAP ASN.1 Definition or elsewhere? Is there any problem with changing the LDAP standard definition? for example I only changed LDAPDN :: = LDAPString to LDAPDN :: = UTF8String, but I encountered an error in the ber_decode function.

What is the general solution for displaying all values ​​in human readable?

Thanks ...

m_zanjani
  • 65
  • 1
  • 6

2 Answers2

1

There is one rather hackish solution, you could change the xer_encoder function of the types you need to be printed as human readable values.

In the asn.1 file next to the LDAPString definition add a new type that references the UTF8String type

    LDAPString ::= OCTET STRING -- UTF-8 encoded,
                                 -- [ISO10646] characters

    LDAPStringUTF8 ::= UTF8String
                      -- [RFC4514]

Without this the asn1c won't copy the UTF8String.[hc] files that we will need.

Than in your main function, or just before calling asn_encode with ATS_BASIC_XER/ATS_CANONICAL_XER add the following

asn_DEF_LDAPDN.op->xer_encoder = OCTET_STRING_encode_xer_utf8;

and include the LDAPDN.h header.

Here is the full patch in case you are using the converter-example.c and rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1 from the asn1c's examples

diff --git a/converter-example.c b/converter-example.c
index b540452..bb883b4 100644
--- a/converter-example.c
+++ b/converter-example.c
@@ -189,6 +189,8 @@ ats_by_name(const char *name, const asn_TYPE_descriptor_t *td,
     return NULL;
 }

+#include "LDAPDN.h"
+
 int
 main(int ac, char *av[]) {
     FILE *binary_out;
@@ -216,6 +218,8 @@ main(int ac, char *av[]) {
 #endif
     }

+    asn_DEF_LDAPDN.op->xer_encoder = OCTET_STRING_encode_xer_utf8;
+
     /* Figure out if a specialty decoder needs to be default */
 #ifndef ASN_DISABLE_OER_SUPPORT
     isyntax = ATS_BASIC_OER;
diff --git a/pdu_collection.c b/pdu_collection.c
index 4fde16b..55e2c2f 100644
--- a/pdu_collection.c
+++ b/pdu_collection.c
@@ -7,6 +7,7 @@ struct asn_TYPE_descriptor_s;   /* Forward declaration */
 extern struct asn_TYPE_descriptor_s asn_DEF_LDAPMessage;
 extern struct asn_TYPE_descriptor_s asn_DEF_MessageID;
 extern struct asn_TYPE_descriptor_s asn_DEF_LDAPString;
+extern struct asn_TYPE_descriptor_s asn_DEF_LDAPStringUTF8;
 extern struct asn_TYPE_descriptor_s asn_DEF_LDAPOID;
 extern struct asn_TYPE_descriptor_s asn_DEF_LDAPDN;
 extern struct asn_TYPE_descriptor_s asn_DEF_RelativeLDAPDN;
@@ -58,6 +59,7 @@ struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {
    &asn_DEF_LDAPMessage,   
    &asn_DEF_MessageID, 
    &asn_DEF_LDAPString,    
+   &asn_DEF_LDAPStringUTF8,    
    &asn_DEF_LDAPOID,   
    &asn_DEF_LDAPDN,    
    &asn_DEF_RelativeLDAPDN,    
diff --git a/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1 b/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
index 53de3cf..b29ec11 100644
--- a/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
+++ b/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
@@ -47,6 +47,7 @@
         LDAPString ::= OCTET STRING -- UTF-8 encoded,
                                     -- [ISO10646] characters

+        LDAPStringUTF8 ::= UTF8String

And here is the output

./converter-example -iber ldap1.der
<LDAPMessage>
    <messageID>1</messageID>
    <protocolOp>
        <bindRequest>
            <version>3</version>
            <name>uid=a,dc=com</name>
            <authentication>
                <simple>password</simple>
            </authentication>
        </bindRequest>
    </protocolOp>
</LDAPMessage>
Vasil Velichkov
  • 1,236
  • 11
  • 17
  • 1
    Thanks for your great answers. Just to complete the answer and for those who want to use this solution in the future: To print the output with the `asn_fprint` function, it is necessary to add the following code `asn_DEF_LDAPDN.op-> print_struct = OCTET_STRING_print_utf8;` – m_zanjani Dec 18 '18 at 09:06
0

You cannot change LDAP asn1 specification to solve your problem.

For example: when you decode a BindRequest, to decode name (of type LDAPDN) ber_decode expects the tag of OCTET STRING. If you change the spec as you suggest, you will expect the tag of UTF8String and receive the tag of OCTET STRING (hence the error)

Unfortunately, with generic tools, there is no way to display a human readable text while the specification is using OCTET STRING

YaFred
  • 9,698
  • 3
  • 28
  • 40
  • Thank you for your answer. I was trying to change the `OCTET_STRING_encode_xer` and `OCTET_STRING_print` functions to print out the output as I wanted. But the solution provided by **vasko** was very simple and nice and solved my problem. – m_zanjani Dec 18 '18 at 09:05