【问题标题】:BER Encoding of a "Choice"“选择”的BER编码
【发布时间】:2013-08-09 21:00:13
【问题描述】:

我正在尝试使用 Apache Harmony ASN.1/BER 类解析 LDAP 绑定请求(可以使用另一个库,我只是选择了它,因为它具有 Apache 许可证)。

我的问题是关于 ASN.1 中“CHOICE”的具体编码。定义 LDAP ASN.1 架构 (http://www.rfc-editor.org/rfc/rfc2251.txt) 的 RFC 将以下内容作为绑定请求的一部分提供:

   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 }

那里的 CHOICE 实际上是如何编码的?

我使用 JXplorer 生成了一个示例绑定请求,并捕获了发送的原始数据。它看起来像这样:

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|

那里的 80(偏移量 0x27)似乎代表了这种选择。很公平 - 我知道(根据http://en.wikipedia.org/wiki/Basic_Encoding_Rules#BER_encoding)设置最后一位是为了表明它是“特定于上下文的”(即由这个应用程序/协议定义)但是我怎么知道这是一个“简单”还是“sasl”身份验证?什么表明正在使用哪个选项?在这种情况下,它看起来下一个字节(0x0a)是字符串的长度 - 所以这可能是一个 OctetString 或类似的东西 - 但我在这里看不到任何表明实际是什么而不是 0x80.. .

我也不确定上面 CHOICE 部分中的 [0] 和 [3] 是什么意思。那是说有四个选项,但只有编号为 0 和 3 的选项在使用?

【问题讨论】:

    标签: ldap asn.1


    【解决方案1】:

    您可以在下面看到 openssl asn1parse 命令的输出。 CHOICE 成员使用所谓的上下文特定标签进行编码 - 这意味着普通标签值将替换为 CHOICE 中相应项目的 ASN.1 定义中指定的值。该标签的值为 0,表示选择了 CHOICE 中的第一项。第一个选择项的类型为OCTET STRING。上下文特定标记的值 0 为您提供有关值类型的信息。如果没有上下文标签,将使用普通的OCTET STRING 标签。

     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 ]        
    

    【讨论】:

      【解决方案2】:

      上面编码消息中的'80'H 称为“标识符八位字节”(通常它可能不止一个八位字节)。标识符octet(s)的这个值表明CHOICE的选择是“简单的”,因为'80'H的五个低位是'00000'B,与“的标签的标签号匹配”简单”([0])。

      如果发件人选择了“sasl”替代方案,标识符八位字节将是“A3”H 而不是“80”H。 'A3'H中的'3'H(低5位)是“sasl”标签的标签号([3])。对于这两种选择,标识符八位字节的两个最高位都设置为 '10'B,因为 [0] 和 [3] 都是“特定于上下文”的标签(这只是意味着这些标签不包含 APPLICATION 关键字或 PRIVATE 关键字)。标识符八位字节的下一位(“构造”位)对于“simple”设置为“0”,但对于“sasl”设置为“1”,因为“sasl”的编码包含嵌套标签,而“简单”不包含任何嵌套标签。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多