From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- python/pyasn1/doc/tagging.html | 233 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 python/pyasn1/doc/tagging.html (limited to 'python/pyasn1/doc/tagging.html') diff --git a/python/pyasn1/doc/tagging.html b/python/pyasn1/doc/tagging.html new file mode 100644 index 000000000..187f1180d --- /dev/null +++ b/python/pyasn1/doc/tagging.html @@ -0,0 +1,233 @@ + + +Tagging in PyASN1 + + + + +
+ + + + +
+ +

+1.2 Tagging in PyASN1 +

+ +

+In order to continue with the Constructed ASN.1 types, we will first have +to introduce the concept of tagging (and its pyasn1 implementation), as +some of the Constructed types rely upon the tagging feature. +

+ +

+When a value is coming into an ASN.1-based system (received from a network +or read from some storage), the receiving entity has to determine the +type of the value to interpret and verify it accordingly. +

+ +

+Historically, the first data serialization protocol introduced in +ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized +value is packed into a triplet of (Type, Length, Value) where Type is a +code that identifies the value (which is called tag in ASN.1), +length is the number of bytes occupied by the value in its serialized form +and value is ASN.1 value in a form suitable for serial transmission or storage. +

+ +

+For that reason almost every ASN.1 type has a tag (which is actually a +BER type) associated with it by default. +

+ +

+An ASN.1 tag could be viewed as a tuple of three numbers: +(Class, Format, Number). While Number identifies a tag, Class component +is used to create scopes for Numbers. Four scopes are currently defined: +UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component +is actually a one-bit flag - zero for tags associated with scalar types, +and one for constructed types (will be discussed later on). +

+ +
+
+MyIntegerType ::= [12] INTEGER
+MyOctetString ::= [APPLICATION 0] OCTET STRING
+
+
+ +

+In pyasn1, tags are implemented as immutable, tuple-like objects: +

+ +
+
+>>> from pyasn1.type import tag
+>>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+>>> myTag
+Tag(tagClass=128, tagFormat=0, tagId=10)
+>>> tuple(myTag)
+(128, 0, 10)
+>>> myTag[2]
+10
+>>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
+False
+>>>
+
+
+ +

+Default tag, associated with any ASN.1 type, could be extended or replaced +to make new type distinguishable from its ancestor. The standard provides +two modes of tag mangling - IMPLICIT and EXPLICIT. +

+ +

+EXPLICIT mode works by appending new tag to the existing ones thus creating +an ordered set of tags. This set will be considered as a whole for type +identification and encoding purposes. Important property of EXPLICIT tagging +mode is that it preserves base type information in encoding what makes it +possible to completely recover type information from encoding. +

+ +

+When tagging in IMPLICIT mode, the outermost existing tag is dropped and +replaced with a new one. +

+ +
+
+MyIntegerType ::= [12] IMPLICIT INTEGER
+MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
+
+
+ +

+To model both modes of tagging, a specialized container TagSet object (holding +zero, one or more Tag objects) is used in pyasn1. +

+ +
+
+>>> from pyasn1.type import tag
+>>> tagSet = tag.TagSet(
+...   # base tag
+...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10),
+...   # effective tag
+...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+... )
+>>> tagSet
+TagSet(Tag(tagClass=128, tagFormat=0, tagId=10))
+>>> tagSet.getBaseTag()
+Tag(tagClass=128, tagFormat=0, tagId=10)
+>>> tagSet = tagSet.tagExplicitly(
+...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
+... )
+>>> tagSet
+TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
+       Tag(tagClass=128, tagFormat=32, tagId=20))
+>>> tagSet = tagSet.tagExplicitly(
+...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30)
+... )
+>>> tagSet
+TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
+       Tag(tagClass=128, tagFormat=32, tagId=20), 
+       Tag(tagClass=128, tagFormat=32, tagId=30))
+>>> tagSet = tagSet.tagImplicitly(
+...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
+... )
+>>> tagSet
+TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
+       Tag(tagClass=128, tagFormat=32, tagId=20),
+       Tag(tagClass=128, tagFormat=32, tagId=40))
+>>> 
+
+
+ +

+As a side note: the "base tag" concept (accessible through the getBaseTag() +method) is specific to pyasn1 -- the base tag is used to identify the original +ASN.1 type of an object in question. Base tag is never occurs in encoding +and is mostly used internally by pyasn1 for choosing type-specific data +processing algorithms. The "effective tag" is the one that always appears in +encoding and is used on tagSets comparation. +

+ +

+Any two TagSet objects could be compared to see if one is a derivative +of the other. Figuring this out is also useful in cases when a type-specific +data processing algorithms are to be chosen. +

+ +
+
+>>> from pyasn1.type import tag
+>>> tagSet1 = tag.TagSet(
+...   # base tag
+...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+...   # effective tag
+...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+... )
+>>> tagSet2 = tagSet1.tagExplicitly(
+...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
+... )
+>>> tagSet1.isSuperTagSetOf(tagSet2)
+True
+>>> tagSet2.isSuperTagSetOf(tagSet1)
+False
+>>> 
+
+
+ +

+We will complete this discussion on tagging with a real-world example. The +following ASN.1 tagged type: +

+ +
+
+MyIntegerType ::= [12] EXPLICIT INTEGER
+
+
+ +

+could be expressed in pyasn1 like this: +

+ +
+
+>>> from pyasn1.type import univ, tag
+>>> class MyIntegerType(univ.Integer):
+...   tagSet = univ.Integer.tagSet.tagExplicitly(
+...        tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12)
+...        )
+>>> myInteger = MyIntegerType(12345)
+>>> myInteger.getTagSet()
+TagSet(Tag(tagClass=0, tagFormat=0, tagId=2), 
+       Tag(tagClass=128, tagFormat=32, tagId=12))
+>>>
+
+
+ +

+Referring to the above code, the tagSet class attribute is a property of any +pyasn1 type object that assigns default tagSet to a pyasn1 value object. This +default tagSet specification can be ignored and effectively replaced by some +other tagSet value passed on object instantiation. +

+ +

+It's important to understand that the tag set property of pyasn1 type/value +object can never be modifed in place. In other words, a pyasn1 type/value +object can never change its tags. The only way is to create a new pyasn1 +type/value object and associate different tag set with it. +

+ +
+ +
+
+ + -- cgit v1.2.3