diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /python/pyasn1/doc/tagging.html | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'python/pyasn1/doc/tagging.html')
-rw-r--r-- | python/pyasn1/doc/tagging.html | 233 |
1 files changed, 233 insertions, 0 deletions
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 @@ +<html> +<title> +Tagging in PyASN1 +</title> +<head> +</head> +<body> +<center> +<table width=60%> +<tr> +<td> +<a name="1.2"></a> +<h4> +1.2 Tagging in PyASN1 +</h4> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +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 <i>tag</i> 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. +</p> + +<p> +For that reason almost every ASN.1 type has a tag (which is actually a +BER type) associated with it by default. +</p> + +<p> +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). +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +MyIntegerType ::= [12] INTEGER +MyOctetString ::= [APPLICATION 0] OCTET STRING +</pre> +</td></tr></table> + +<p> +In pyasn1, tags are implemented as immutable, tuple-like objects: +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +>>> 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 +>>> +</pre> +</td></tr></table> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +When tagging in IMPLICIT mode, the outermost existing tag is dropped and +replaced with a new one. +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +MyIntegerType ::= [12] IMPLICIT INTEGER +MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING +</pre> +</td></tr></table> + +<p> +To model both modes of tagging, a specialized container TagSet object (holding +zero, one or more Tag objects) is used in pyasn1. +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +>>> 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)) +>>> +</pre> +</td></tr></table> + +<p> +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. +</p> + +<p> +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. +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +>>> 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 +>>> +</pre> +</td></tr></table> + +<p> +We will complete this discussion on tagging with a real-world example. The +following ASN.1 tagged type: +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +MyIntegerType ::= [12] EXPLICIT INTEGER +</pre> +</td></tr></table> + +<p> +could be expressed in pyasn1 like this: +</p> + +<table bgcolor="lightgray" border=0 width=100%><TR><TD> +<pre> +>>> 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)) +>>> +</pre> +</td></tr></table> + +<p> +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. +</p> + +<p> +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. +</p> + +<hr> + +</td> +</tr> +</table> +</center> +</body> +</html> |