我正在尝试使用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 }
那里的选择实际上是如何编码的?
我使用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“auth?什么表明正在使用哪个选项?在这种情况下,它看起来像下一个字节(0x0a)是字符串的长度 - 所以这可能是一个OctetString或类似的东西 - 但我在这里看不到任何指示实际不是0x80的东西..
我也不确定上面的“选择”部分中[0]和[3]的意思。这是说有四个选项,但只有使用编号为0和3的选项?
答案 0 :(得分:3)
下面你可以看到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 ]
答案 1 :(得分:2)
上面编码消息中的'80'H称为“标识符八位字节”(通常它可能超过一个八位字节)。标识符八位位组的这个值表示所选择的CHOICE选项是“简单”,因为'80'H的五个低位是'00000'B,它匹配标签的标签号“简单的“([0])。
如果发件人选择了“sasl”替代,则标识符八位字节将是'A3'H而不是'80'H。 'A3'H中的'3'H(五个低位)是“sasl”([3])标签的标签号。标识符八位字节的两个最高位对于两个备选项都设置为“10”B,因为[0]和[3]都是“特定于上下文”的标记(这只是意味着这些标记不包含APPLICATION关键字)或者PRIVATE关键字)。标识符八位字节的下一位(“构造”位)对于“简单”设置为“0”,但对于“sasl”设置为“1”,因为“sasl”的编码包含嵌套标记而编码为“simple”不包含任何嵌套标记。