【问题标题】:ASN.1 Sequence ConfusionASN.1 序列混淆
【发布时间】:2013-07-16 14:55:40
【问题描述】:

我正在研究ASN.1的语法,网上看了很多相关资料:

http://www.itu.int/rec/T-REC-X.690-200811-I/en
http://luca.ntop.org/Teaching/Appunti/asn1.html
http://www.obj-sys.com/asn1tutorial/node11.html

我对 ASN.1 SEQUENCE 类型的编码感到非常困惑。一般来说,我意识到SEQUENCE 基本上是一个聚合——在大多数编程语言中我们称之为对象或实例。它基本上是一个名称/值对列表,类似于 JSON 对象。但与 JSON 对象不同的是,ASN.1 SEQUENCE 具有隐式 SCHEMA,因为它是“类”的实例

因此,SEQUENCE 的类/模式可能类似于:

{
  name  UTF8String
  age   INTEGER
}

并且该架构的 INSTANCE 可能是 SEQUENCE

{
  "John Smith"
  42
}

但是对于如何在实际的 BER 编码中区分 CLASS 和 INSTANCE ,我感到非常困惑。事实上,我很困惑,我什至不确定 ASN.1 SEQUENCE 应该是类定义还是类的实例。

文档似乎暗示它是一个实例:

8.9序列值的编码

8.9.1应构造序列值的编码。

8.9.2 内容八位字节应由 ASN.1 定义中列出的每种类型的一个数据值的完整编码组成 序列类型的,按照它们在 定义,除非该类型是用关键字 OPTIONAL 引用的 或关键字 DEFAULT。

8.9.3 对于使用关键字 OPTIONAL 或关键字引用的类型,数据值的编码可能但不一定存在 默认。如果存在,它应出现在该点的编码中 对应于 ASN.1 定义中类型的外观。

所以看起来 SEQUENCE 只是一个数据值列表,它必须对应于某个模式(类)。但是 ASN.1 没有 CLASS 类型,那么如何获得实际的类,所以您知道任何给定的 SEQUENCE 是哪个类的实例?

【问题讨论】:

    标签: asn.1


    【解决方案1】:

    假设你写了以下内容:

    R DEFINITIONS AUTOMATIC TAGS ::=
    
     BEGIN
    
     USPostalAddress ::= SEQUENCE {
    
          street     IA5String,
    
          city       IA5String,
    
          state      IA5String (SIZE (2)) (FROM("A".."Z")),
    
          zipcode    IA5String (SIZE (5)) (FROM("0".."9"))
    
     }
    
     END
    

    上面BEGIN和END之间的部分称为“类型赋值”。 “USPostalAddress”是(用户定义的)“类型”的名称。通过编写上述内容,您已经指定了一个用户定义的类型并为其命名。每个 SEQUENCE 构造(例如,上面的 SEQUENCE 构造)都是一个“类型”。它是一种复杂类型,因为它包含一个或多个“字段”,每个“字段”都有自己的类型。上述类型的一个可能的“值”表示如下:

    { street "1234 Main St.", city "New York", state "NY", zipcode "12345" }
    

    我们只是在讨论类型和它们的值,而不是类和实例。就像你可以有一个类型 INTEGER (0..15) 的值是 0 到 15 之间的整数一样,你也可以有一个 SEQUENCE 类型,它的值是低级值的排列。上述序列类型是您可以在 ASN.1 中定义的数据结构(“类型”)的一个非常简单的示例。

    (在 ASN.1 中也有一个叫做“类”的东西,但它是完全不同的东西。)

    在 ASN.1 中,协议的消息通常被指定为顶级类型(通常是 SEQUENCE 或 CHOICE 类型)。特定的“消息值”是顶级类型的值。当您手中有一个顶级类型的值时,您可以使用标准编码规则之一(BER、PER 等)将该值编码为比特流。当您从网络接收到比特流时,您知道该比特流是以 BER、PER 等编码的特定 ASN.1 类型的值,您可以对这些比特进行解码并获得原始值。

    【讨论】:

      【解决方案2】:

      ASN.1 文件通常包含像这样的 SEQUENCE 类型的类型分配(类型定义):

      myMessage ::= SEQUENCE
      {
          a INTEGER(0..100),
          b INTEGER
      }
      

      ASN.1 文件中的那些 SEQUENCE 类型可以被认为与 C++/java 中的类或 C 中的结构定义相同。

      SEQUENCE 的实例可以是编码格式(BER、PER、DER 等)或程序内部的本地格式(对象/变量)。

      如何在 C 代码中实现这些示例:

      struct myMessage_t          
      {
        int a;
        int b;
      };
      
      char buffer[1000];   // BER encoded instance will be stored to this buffer
      myMessage_t msg;     // this is the local instance
      
      msg.a = 1;
      msg.b = 2;
      
      size_t berLen = berEncode_myMessage( &msg, buffer, sizeof(buffer) );
      

      还有解码方面:

      myMessage_t msg2;            
      berDecode_myMessage( buffer, berLen, &msg2 );
      assert( msg2.a == 1 );
      

      在解码之前,您通常知道编码实例的顶级类型是什么。

      【讨论】:

        猜你喜欢
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 1970-01-01
        • 1970-01-01
        • 2011-12-02
        相关资源
        最近更新 更多