简体   繁体   English

ASN.1 序列混淆

[英]ASN.1 Sequence Confusion

I'm studying the syntax for ASN.1 , and I've read a lot of the relevant material online:我正在研究ASN.1的语法,并且在网上阅读了很多相关材料:

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

I'm very confused over the encoding of ASN.1 SEQUENCE types.我对 ASN.1 SEQUENCE类型的编码感到非常困惑。 In general, I realize that a SEQUENCE is basically an aggregate - what we'd call an OBJECT or an INSTANCE in most programming languages.一般而言,我意识到SEQUENCE基本上是一个聚合体——在大多数编程语言中我们称之为 OBJECT 或 INSTANCE。 It's basically a list of name/value pairs, similar to a JSON object.它基本上是一个名称/值对列表,类似于 JSON 对象。 But unlike a JSON object, an ASN.1 SEQUENCE has an implicit SCHEMA, because it is an instance of a "class" .但与 JSON 对象不同,ASN.1 SEQUENCE具有隐式 SCHEMA,因为它是“类”实例

So, the class/schema for a SEQUENCE might be something like:因此, SEQUENCE的类/模式可能类似于:

{
  name  UTF8String
  age   INTEGER
}

And an INSTANCE of that schema could be the SEQUENCE该模式的一个实例可能是SEQUENCE

{
  "John Smith"
  42
}

But I'm totally confused as to how you can tell the difference between a CLASS and an INSTANCE in the actual BER encoding.但是我对如何在实际 BER 编码中区分 CLASS 和 INSTANCE 之间的区别感到非常困惑。 In fact, I'm so confused, I'm not even sure if a ASN.1 SEQUENCE is supposed to be a class definition or an instance of a class.事实上,我很困惑,我什至不确定 ASN.1 SEQUENCE应该是类定义还是类的实例。

The documentation seems to imply it's an instance:文档似乎暗示它是一个实例:

8.9 Encoding of a sequence value 8.9序列值的编码

8.9.1 The encoding of a sequence value shall be constructed. 8.9.1应构造序列值的编码。

8.9.2 The contents octets shall consist of the complete encoding of one data value from each of the types listed in the ASN.1 definition of the sequence type, in the order of their appearance in the definition, unless the type was referenced with the keyword OPTIONAL or the keyword DEFAULT. 8.9.2内容八位字节应由序列类型的 ASN.1 定义中列出的每个类型的一个数据值的完整编码组成,按照它们在定义中出现的顺序,除非类型被引用关键字 OPTIONAL 或关键字 DEFAULT。

8.9.3 The encoding of a data value may, but need not, be present for a type which was referenced with the keyword OPTIONAL or the keyword DEFAULT. 8.9.3对于用关键字 OPTIONAL 或关键字 DEFAULT 引用的类型,数据值的编码可以,但不是必须的。 If present, it shall appear in the encoding at the point corresponding to the appearance of the type in the ASN.1 definition.如果存在,它应出现在编码中对应于 ASN.1 定义中类型出现的点。

So it seems a SEQUENCE is just a list of data values, which must correspond to some schema (class).所以看起来 SEQUENCE 只是一个数据值列表,它必须对应于某个模式(类)。 But ASN.1 doesn't have a CLASS type, so how do you get the actual class, so you know what class any given SEQUENCE is an instance of?但是 ASN.1 没有CLASS类型,那么您如何获得实际的类,以便您知道任何给定的 SEQUENCE 是哪个类的实例?

Suppose you write the following:假设你写了以下内容:

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

The part between BEGIN and END above is called a "type assignment".上面 BEGIN 和 END 之间的部分称为“类型分配”。 "USPostalAddress" is the name of a (user-defined) "type". “USPostalAddress”是(用户定义的)“类型”的名称。 By writing the above, you have specified a user-defined type and you have given a name to it.通过编写上述内容,您已经指定了一个用户定义的类型并为其命名。 Each SEQUENCE construct (the above SEQUENCE construct, for example) is a "type".每个 SEQUENCE 构造(例如上面的 SEQUENCE 构造)都是一个“类型”。 It's a complex type, in that it contains one or more "fields" each having its own type.它是一种复杂类型,因为它包含一个或多个“字段”,每个“字段”都有自己的类型。 A possible "value" of the above type is denoted as follows:上述类型的可能“值”表示如下:

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

We are just talking about types and their values, not about classes and instances.我们只是在谈论类型和它们的值,而不是类和实例。 Just like you can have a type INTEGER (0..15) whose values are integer numbers between 0 and 15, you can have a SEQUENCE type whose values are arrangements of lower-level values.就像您可以拥有一个类型为 INTEGER (0..15) 的值是 0 到 15 之间的整数一样,您可以拥有一个 SEQUENCE 类型,其值是较低级别值的排列。 The above sequence type is a very simple example of the data structures ("types") you can define in ASN.1.上述序列类型是您可以在 ASN.1 中定义的数据结构(“类型”)的一个非常简单的示例。

(In ASN.1 there is also something called a "class" but it's a completely different thing.) (在 ASN.1 中还有一个叫做“类”的东西,但它是完全不同的东西。)

In ASN.1, messages of protocols are usually specified as top-level types (usually they are SEQUENCE or CHOICE types).在 ASN.1 中,协议的消息通常被指定为顶级类型(通常是 SEQUENCE 或 CHOICE 类型)。 A particular "message value" is a value of a top-level type.特定的“消息值”是顶级类型的值。 When you have a value of a top-level type in your hands, you can encode that value into a stream of bits by using one of the standard encoding rules (BER, PER, etc.).当您拥有顶级类型的值时,您可以使用标准编码规则之一(BER、PER 等)将该值编码为位流。 When you receive a stream of bits from the network which you know was a value of a particular ASN.1 type encoded in BER, PER, etc., you can decode those bits and obtain the original value.当您从网络接收到一个比特流时,您知道它是一个特定 ASN.1 类型的值,以 BER、PER 等编码,您可以对这些比特进行解码并获得原始值。

ASN.1 file contains usually type assignments (type definitions) like this SEQUENCE type: ASN.1 文件通常包含这样的序列类型的类型分配(类型定义):

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

Those SEQUENCE types inside ASN.1 file can be considered same as classes in C++/java or struct definitions in C. ASN.1 文件中的那些 SEQUENCE 类型可以被认为与 C++/java 中的类或 C 中的结构定义相同。

Instances of SEQUENCE can be in encoded format (BER, PER, DER etc) or in local format (objects/variables) inside your programs. SEQUENCE 的实例可以是程序中的编码格式(BER、PER、DER 等)或本地格式(对象/变量)。

Example how you could implement those in C code:示例如何在 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) );

And decoding side for that:和解码方面:

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

You usually know what is the top level type of encoded instance, before you decode it.在解码之前,您通常知道什么是编码实例的顶级类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM