summaryrefslogtreecommitdiff
path: root/docs/source/pyasn1
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2017-10-21 16:07:17 +0200
committerGitHub <noreply@github.com>2017-10-21 16:07:17 +0200
commit262793a79cad797601fa855eec1e1020e1a534cb (patch)
treec8ef7e3d079887a4aaf9b87e662787f47785a191 /docs/source/pyasn1
parent69c29f0522fe118262c813005590fbb256dfd679 (diff)
downloadpyasn1-git-262793a79cad797601fa855eec1e1020e1a534cb.tar.gz
Add more content to docs (#96)
* minor fixes to RsT docstrings * more explanations in the docs, better linkage * cosmetic fixes to NamedValues() docstring
Diffstat (limited to 'docs/source/pyasn1')
-rw-r--r--docs/source/pyasn1/contents.rst147
-rw-r--r--docs/source/pyasn1/type/char/bmpstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/contents.rst10
-rw-r--r--docs/source/pyasn1/type/char/generalstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/graphicstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/ia5string.rst2
-rw-r--r--docs/source/pyasn1/type/char/iso646string.rst2
-rw-r--r--docs/source/pyasn1/type/char/numericstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/printablestring.rst2
-rw-r--r--docs/source/pyasn1/type/char/t61string.rst2
-rw-r--r--docs/source/pyasn1/type/char/teletexstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/universalstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/utf8string.rst2
-rw-r--r--docs/source/pyasn1/type/char/videotexstring.rst2
-rw-r--r--docs/source/pyasn1/type/char/visiblestring.rst2
-rw-r--r--docs/source/pyasn1/type/namedtype/contents.rst29
-rw-r--r--docs/source/pyasn1/type/namedtype/defaultednamedtype.rst2
-rw-r--r--docs/source/pyasn1/type/namedtype/namedtype.rst2
-rw-r--r--docs/source/pyasn1/type/namedtype/namedtypes.rst2
-rw-r--r--docs/source/pyasn1/type/namedtype/optionalnamedtype.rst2
-rw-r--r--docs/source/pyasn1/type/namedval/contents.rst38
-rw-r--r--docs/source/pyasn1/type/namedval/namedval.rst2
-rw-r--r--docs/source/pyasn1/type/opentype/contents.rst32
-rw-r--r--docs/source/pyasn1/type/opentype/opentype.rst4
-rw-r--r--docs/source/pyasn1/type/tag/contents.rst48
-rw-r--r--docs/source/pyasn1/type/tag/tag.rst2
-rw-r--r--docs/source/pyasn1/type/tag/tagmap.rst2
-rw-r--r--docs/source/pyasn1/type/tag/tagset.rst6
-rw-r--r--docs/source/pyasn1/type/univ/any.rst2
-rw-r--r--docs/source/pyasn1/type/univ/bitstring.rst2
-rw-r--r--docs/source/pyasn1/type/univ/boolean.rst2
-rw-r--r--docs/source/pyasn1/type/univ/choice.rst2
-rw-r--r--docs/source/pyasn1/type/univ/contents.rst17
-rw-r--r--docs/source/pyasn1/type/univ/enumerated.rst2
-rw-r--r--docs/source/pyasn1/type/univ/integer.rst2
-rw-r--r--docs/source/pyasn1/type/univ/null.rst2
-rw-r--r--docs/source/pyasn1/type/univ/objectidentifier.rst2
-rw-r--r--docs/source/pyasn1/type/univ/octetstring.rst2
-rw-r--r--docs/source/pyasn1/type/univ/real.rst2
-rw-r--r--docs/source/pyasn1/type/univ/sequence.rst2
-rw-r--r--docs/source/pyasn1/type/univ/sequenceof.rst2
-rw-r--r--docs/source/pyasn1/type/univ/set.rst2
-rw-r--r--docs/source/pyasn1/type/univ/setof.rst2
-rw-r--r--docs/source/pyasn1/type/useful/contents.rst5
-rw-r--r--docs/source/pyasn1/type/useful/generalizedtime.rst2
-rw-r--r--docs/source/pyasn1/type/useful/objectdescriptor.rst2
-rw-r--r--docs/source/pyasn1/type/useful/utctime.rst2
47 files changed, 400 insertions, 10 deletions
diff --git a/docs/source/pyasn1/contents.rst b/docs/source/pyasn1/contents.rst
index 5d58a4f..0795830 100644
--- a/docs/source/pyasn1/contents.rst
+++ b/docs/source/pyasn1/contents.rst
@@ -1,8 +1,115 @@
+.. _pyasn1:
ASN.1 types
-----------
+The ASN.1 data description
+`language <https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items>`_
+defines a handful of built-in data types. ASN.1 types exhibit different semantics
+(e.g. number vs string) and can be distinguished from each other by
+:ref:`tags <type.tag>`.
+
+Subtypes can be created on top of base ASN.1 types by adding/overriding the
+tags and/or imposing additional *constraints* on accepted values.
+
+ASN.1 types in pyasn1 are Python objects. One or more ASN.1 types
+comprise a *schema* describing data structures of unbounded complexity.
+
+.. code-block:: python
+
+ class RSAPublicKey(Sequence):
+ """
+ ASN.1 specification:
+
+ RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER -- e
+ }
+ """
+ componentType = NamedTypes(
+ NamedType('modulus', Integer()),
+ NamedType('publicExponent', Integer())
+ )
+
+ASN.1 schema can be "instantiated" by essentially putting some concrete value
+into the type container. Such instantiated schema object can still be
+used as a schema, but additionally it can play a role of a value in the
+context of any applicable operator (e.g. arithmetic etc.).
+
+.. code-block:: python
+
+ rsaPublicKey = RSAPublicKey()
+
+ # ASN.1 SEQUENCE type quacks like Python dict
+ rsaPublicKey['modulus'] = 280789907761334970323210643584308373
+ rsaPublicKey['publicExponent'] = 65537
+
+Main use of ASN.1 schemas is to guide data transformation. Instantiated
+ASN.1 schemas carry concrete data to/from data transformation services.
+
+.. _isValue:
+
+To tell instantiated schema object from just a schema, the *.isValue*
+property can come in handy:
+
+.. code-block:: python
+
+ schema = RSAPublicKey()
+
+ # non-instantiated schema
+ assert schema.isValue == False
+
+ rsaPublicKey['modulus'] = 280789907761334970323210643584308373
+
+ # partially instantiated schema
+ assert schema['modulus'].isValue == True
+ assert schema.isValue == False
+
+ rsaPublicKey['publicExponent'] = 65537
+
+ # fully instantiated schema
+ assert schema.isValue == True
+
+Copies of existing ASN.1 types can be created with *.clone()* method.
+All the existing properties of the prototype ASN.1 object get copied
+over the new type unless the replacements are given. Main use-case
+for *.clone()* is to instantiate a schema.
+
+.. _clone:
+
+.. code-block:: python
+
+ instantiated_schema_A = Integer(1)
+
+ # ASN.1 INTEGER type quacks like Python int
+ assert instantiated_schema_A == 1
+
+ instantiated_schema_B = instantiated_schema_A.clone(2)
+
+ assert instantiated_schema_B == 2
+
+.. _subtype:
+
+New ASN.1 types can be created on top of existing ASN.1 types with
+the *subtype()* method. Desired properties of the new type get
+merged with the corresponding properties of the old type. Main use-case
+for *.subtype()* is to assemble new ASN.1 types by :ref:`tagging <type.tag>`
+or applying additional constraints to accepted type's values.
+
+.. code-block:: python
+
+ parent_type_schema = Integer()
+
+ child_type_schema = parent_type_schema.subtype(
+ explicitTag=Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x06)
+ )
+
+ # test ASN.1 type relationships
+ assert child_type_schema.isSubtypeOf(parent_type_schema) == True
+ assert child_type_schema.isSameTypeWith(parent_type_schema) == False
+
+
.. toctree::
:maxdepth: 2
@@ -17,6 +124,46 @@ ASN.1 types
Serialisation codecs
--------------------
+Common use-case for pyasn1 is to instantiate ASN.1 schema with
+user-supplied values and pass instantiated schema to the encoder.
+The encoder will then turn the data structure into serialized form
+(stream of bytes) suitable for storing into a file or sending over
+the network.
+
+.. code-block:: python
+
+ value = 1
+ instantiated_schema = Integer(value)
+
+ serialized = encode(instantiated_schema)
+
+Alternatively, value and schema can be passed separately:
+
+.. code-block:: python
+
+ value = 1
+ schema = Integer()
+
+ serialized = encode(value, asn1Spec=schema)
+
+At the receiving end, a decoder would be invoked and given the
+serialized data as received from the network along with the ASN.1
+schema describing the layout of the data structures. The outcome
+would be an instance of ASN.1 schema filled with values as supplied
+by the sender.
+
+.. code-block:: python
+
+ serialized = b'\x01\x01\x01'
+ schema = Integer()
+
+ value, _ = decode(serialized, asn1Spec=schema)
+
+ assert value == 1
+
+Many distinct serialization protocols exist for ASN.1, some are
+implemented in pyasn1.
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/char/bmpstring.rst b/docs/source/pyasn1/type/char/bmpstring.rst
index 3809e9b..24040c7 100644
--- a/docs/source/pyasn1/type/char/bmpstring.rst
+++ b/docs/source/pyasn1/type/char/bmpstring.rst
@@ -1,4 +1,6 @@
+.. _char.BMPString:
+
.. |ASN.1| replace:: BMPString
.. |encoding| replace:: utf-16-be
diff --git a/docs/source/pyasn1/type/char/contents.rst b/docs/source/pyasn1/type/char/contents.rst
index ddfbe1c..87e3f22 100644
--- a/docs/source/pyasn1/type/char/contents.rst
+++ b/docs/source/pyasn1/type/char/contents.rst
@@ -1,7 +1,17 @@
+.. _type.char:
+
Character types
---------------
+Besides :ref:`universal types <type.univ>` also defines a collection
+of text types. Most of these types come from the past trying to capture
+the fragments of long-forgotten technologies.
+
+These *character* types are all scalars. They are similar to
+:ref:`univ.OctetString` except that they all operate on text,
+not bytes.
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/char/generalstring.rst b/docs/source/pyasn1/type/char/generalstring.rst
index 8ce730f..722c062 100644
--- a/docs/source/pyasn1/type/char/generalstring.rst
+++ b/docs/source/pyasn1/type/char/generalstring.rst
@@ -1,4 +1,6 @@
+.. _char.GeneralString:
+
.. |ASN.1| replace:: GeneralString
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/char/graphicstring.rst b/docs/source/pyasn1/type/char/graphicstring.rst
index 1f57209..9a35a2a 100644
--- a/docs/source/pyasn1/type/char/graphicstring.rst
+++ b/docs/source/pyasn1/type/char/graphicstring.rst
@@ -1,4 +1,6 @@
+.. _char.GraphicString:
+
.. |ASN.1| replace:: GraphicString
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/char/ia5string.rst b/docs/source/pyasn1/type/char/ia5string.rst
index 1ae80af..6d057d8 100644
--- a/docs/source/pyasn1/type/char/ia5string.rst
+++ b/docs/source/pyasn1/type/char/ia5string.rst
@@ -1,4 +1,6 @@
+.. _char.IA5String:
+
.. |ASN.1| replace:: IA5String
.. |encoding| replace:: us-ascii
diff --git a/docs/source/pyasn1/type/char/iso646string.rst b/docs/source/pyasn1/type/char/iso646string.rst
index f21836a..3607616 100644
--- a/docs/source/pyasn1/type/char/iso646string.rst
+++ b/docs/source/pyasn1/type/char/iso646string.rst
@@ -1,4 +1,6 @@
+.. _char.ISO646String:
+
.. |ASN.1| replace:: ISO646String
.. |encoding| replace:: us-ascii
diff --git a/docs/source/pyasn1/type/char/numericstring.rst b/docs/source/pyasn1/type/char/numericstring.rst
index dc805e4..2f3cfb4 100644
--- a/docs/source/pyasn1/type/char/numericstring.rst
+++ b/docs/source/pyasn1/type/char/numericstring.rst
@@ -1,4 +1,6 @@
+.. _char.NumericString:
+
.. |ASN.1| replace:: NumericString
.. |encoding| replace:: us-ascii
diff --git a/docs/source/pyasn1/type/char/printablestring.rst b/docs/source/pyasn1/type/char/printablestring.rst
index 22ebe28..645c0a1 100644
--- a/docs/source/pyasn1/type/char/printablestring.rst
+++ b/docs/source/pyasn1/type/char/printablestring.rst
@@ -1,4 +1,6 @@
+.. _char.PrintableString:
+
.. |ASN.1| replace:: PrintableString
.. |encoding| replace:: us-ascii
diff --git a/docs/source/pyasn1/type/char/t61string.rst b/docs/source/pyasn1/type/char/t61string.rst
index ed9d61e..11bf384 100644
--- a/docs/source/pyasn1/type/char/t61string.rst
+++ b/docs/source/pyasn1/type/char/t61string.rst
@@ -1,4 +1,6 @@
+.. _char.T61String:
+
.. |ASN.1| replace:: T61String
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/char/teletexstring.rst b/docs/source/pyasn1/type/char/teletexstring.rst
index 86aa248..f025d76 100644
--- a/docs/source/pyasn1/type/char/teletexstring.rst
+++ b/docs/source/pyasn1/type/char/teletexstring.rst
@@ -1,4 +1,6 @@
+.. _char.TeletexString:
+
.. |ASN.1| replace:: TeletexString
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/char/universalstring.rst b/docs/source/pyasn1/type/char/universalstring.rst
index e3159dc..5e4c8b4 100644
--- a/docs/source/pyasn1/type/char/universalstring.rst
+++ b/docs/source/pyasn1/type/char/universalstring.rst
@@ -1,4 +1,6 @@
+.. _char.UniversalString:
+
.. |ASN.1| replace:: UniversalString
.. |encoding| replace:: utf-32-be
diff --git a/docs/source/pyasn1/type/char/utf8string.rst b/docs/source/pyasn1/type/char/utf8string.rst
index ddeeebf..380feb7 100644
--- a/docs/source/pyasn1/type/char/utf8string.rst
+++ b/docs/source/pyasn1/type/char/utf8string.rst
@@ -1,4 +1,6 @@
+.. _char.UTF8String:
+
.. |ASN.1| replace:: UTF8String
.. |encoding| replace:: utf-8
diff --git a/docs/source/pyasn1/type/char/videotexstring.rst b/docs/source/pyasn1/type/char/videotexstring.rst
index 0570471..27ddf80 100644
--- a/docs/source/pyasn1/type/char/videotexstring.rst
+++ b/docs/source/pyasn1/type/char/videotexstring.rst
@@ -1,4 +1,6 @@
+.. _char.VideotexString:
+
.. |ASN.1| replace:: VideotexString
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/char/visiblestring.rst b/docs/source/pyasn1/type/char/visiblestring.rst
index b895eb5..778720a 100644
--- a/docs/source/pyasn1/type/char/visiblestring.rst
+++ b/docs/source/pyasn1/type/char/visiblestring.rst
@@ -1,4 +1,6 @@
+.. _char.VisibleString:
+
.. |ASN.1| replace:: VisibleString
.. |encoding| replace:: us-ascii
diff --git a/docs/source/pyasn1/type/namedtype/contents.rst b/docs/source/pyasn1/type/namedtype/contents.rst
index a5618e5..2e553e6 100644
--- a/docs/source/pyasn1/type/namedtype/contents.rst
+++ b/docs/source/pyasn1/type/namedtype/contents.rst
@@ -1,7 +1,36 @@
+.. _type.namedtype:
+
Fields of constructed types
---------------------------
+The :ref:`Sequence <univ.Sequence>`, :ref:`Set <univ.Set>` and
+:ref:`Choice <univ.Choice>` ASN.1 types embed other ASN.1 types
+as named fields.
+
+Each field can be expressed via the :ref:`NamedType <namedtype.NamedType>`
+object while the individual fields are brought together by the
+:ref:`NamedTypes <namedtype.NamedTypes>` object.
+
+Ultimately, the fields get attached to the ASN.1 type's *.componentType*
+attributes.
+
+.. code-block:: python
+
+ class RSAPublicKey(Sequence):
+ """
+ ASN.1 specification:
+
+ RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER -- e
+ }
+ """
+ componentType = NamedTypes(
+ NamedType('modulus', Integer()),
+ NamedType('publicExponent', Integer())
+ )
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/namedtype/defaultednamedtype.rst b/docs/source/pyasn1/type/namedtype/defaultednamedtype.rst
index 9a331dc..e617288 100644
--- a/docs/source/pyasn1/type/namedtype/defaultednamedtype.rst
+++ b/docs/source/pyasn1/type/namedtype/defaultednamedtype.rst
@@ -1,4 +1,6 @@
+.. _namedtype.DefaultedNamedType:
+
.. |NamedType| replace:: DefaultedNamedType
|NamedType|
diff --git a/docs/source/pyasn1/type/namedtype/namedtype.rst b/docs/source/pyasn1/type/namedtype/namedtype.rst
index ea978ef..2e6c270 100644
--- a/docs/source/pyasn1/type/namedtype/namedtype.rst
+++ b/docs/source/pyasn1/type/namedtype/namedtype.rst
@@ -1,4 +1,6 @@
+.. _namedtype.NamedType:
+
.. |NamedType| replace:: NamedType
|NamedType|
diff --git a/docs/source/pyasn1/type/namedtype/namedtypes.rst b/docs/source/pyasn1/type/namedtype/namedtypes.rst
index fa8234d..d6ca43a 100644
--- a/docs/source/pyasn1/type/namedtype/namedtypes.rst
+++ b/docs/source/pyasn1/type/namedtype/namedtypes.rst
@@ -1,4 +1,6 @@
+.. _namedtype.NamedTypes:
+
NamedTypes
----------
diff --git a/docs/source/pyasn1/type/namedtype/optionalnamedtype.rst b/docs/source/pyasn1/type/namedtype/optionalnamedtype.rst
index 8655a1e..f78bec5 100644
--- a/docs/source/pyasn1/type/namedtype/optionalnamedtype.rst
+++ b/docs/source/pyasn1/type/namedtype/optionalnamedtype.rst
@@ -1,4 +1,6 @@
+.. _namedtype.OptionalNamedType:
+
.. |NamedType| replace:: OptionalNamedType
|NamedType|
diff --git a/docs/source/pyasn1/type/namedval/contents.rst b/docs/source/pyasn1/type/namedval/contents.rst
index 169da15..73f86c7 100644
--- a/docs/source/pyasn1/type/namedval/contents.rst
+++ b/docs/source/pyasn1/type/namedval/contents.rst
@@ -1,11 +1,41 @@
+.. _type.namedval:
+
Enumerating numbers
-------------------
-Some ASN.1 types such as :py:class:`~pyasn1.type.univ.Integer`,
-:py:class:`~pyasn1.type.univ.Enumerated` and
-:py:class:`~pyasn1.type.univ.BitString` may enumerate their values
-with human-friendly labels.
+Some ASN.1 types such as :ref:`Integer <univ.Integer>`,
+:ref:`Enumerated <univ.Enumerated>` and :ref:`BitString <univ.BitString>`
+may enumerate their otherwise numeric values associating them with
+human-friendly labels.
+
+.. code-block:: python
+
+ class ErrorStatus(Integer):
+ """
+ ASN.1 specification:
+
+ error-status
+ INTEGER {
+ noError(0),
+ tooBig(1),
+ noSuchName(2),
+ ...
+ }
+ """
+ namedValues = NamedValues(
+ ('noError', 0), ('tooBig', 1), ('noSuchName', 2)
+ )
+
+The enumerated types behave exactly like the non-enumerated ones but,
+additionally, values can be referred by labels.
+
+.. code-block:: python
+
+ errorStatus = ErrorStatus('tooBig')
+
+ assert errorStatus == 1
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/namedval/namedval.rst b/docs/source/pyasn1/type/namedval/namedval.rst
index 24847a9..0bcfd69 100644
--- a/docs/source/pyasn1/type/namedval/namedval.rst
+++ b/docs/source/pyasn1/type/namedval/namedval.rst
@@ -1,4 +1,6 @@
+.. _namedval.NamedValues:
+
.. |NamedValues| replace:: NamedValues
|NamedValues|
diff --git a/docs/source/pyasn1/type/opentype/contents.rst b/docs/source/pyasn1/type/opentype/contents.rst
index 93b0a58..9ae10d0 100644
--- a/docs/source/pyasn1/type/opentype/contents.rst
+++ b/docs/source/pyasn1/type/opentype/contents.rst
@@ -1,7 +1,39 @@
+.. _type.opentype:
+
Untyped fields of constructed types
-----------------------------------
+To aid data structures flexibility, ASN.1 allows the designer to
+leave incomplete field type specification in the
+:ref:`Sequence <univ.Sequence>` and :ref:`Set <univ.Set>` types.
+
+To figure out field's type at the run time, a type selector field
+must accompany the open type field. The open type situation can
+be captured by the :ref:`OpenType <opentype.OpenType>` object.
+
+.. code-block:: python
+
+ algo_map = {
+ ObjectIdentifier('1.2.840.113549.1.1.1'): rsaEncryption(),
+ ObjectIdentifier('1.2.840.113549.1.1.2'): md2WithRSAEncryption()
+ }
+
+
+ class Algorithm(Sequence):
+ """
+ Algorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL
+ }
+ """
+ componentType = NamedTypes(
+ NamedType('algorithm', ObjectIdentifier()),
+ OptionalNamedType('parameters', Any(),
+ openType=OpenType('algorithm', algo_map))
+ )
+
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/opentype/opentype.rst b/docs/source/pyasn1/type/opentype/opentype.rst
index f01ab5d..dc2fa47 100644
--- a/docs/source/pyasn1/type/opentype/opentype.rst
+++ b/docs/source/pyasn1/type/opentype/opentype.rst
@@ -1,4 +1,6 @@
+.. _opentype.OpenType:
+
.. |OpenType| replace:: OpenType
|OpenType|
@@ -11,5 +13,5 @@
The |OpenType| class models an untyped field of a constructed ASN.1
type. In ASN.1 syntax it is usually represented by the
- `ANY DEFINED BY` clause. Typically used with `Any </pyasn1/type/univ/any>`_
+ `ANY DEFINED BY` clause. Typically used with :ref:`Any <univ.Any>`
type.
diff --git a/docs/source/pyasn1/type/tag/contents.rst b/docs/source/pyasn1/type/tag/contents.rst
index 1d868b6..4e5510c 100644
--- a/docs/source/pyasn1/type/tag/contents.rst
+++ b/docs/source/pyasn1/type/tag/contents.rst
@@ -1,6 +1,50 @@
-Tagging types
--------------
+.. _type.tag:
+
+Tags
+----
+
+ASN.1 types formally differ from each other by carrying distinct
+tags. A tag is essentially an integer exhibiting certain inner
+structure.
+
+Individual tags are usually combined into a collection known as
+*TagSet*. Tags and tag sets in pyasn1 are immutable objects assigned
+to ASN.1 types as the *tagSet* attribute.
+
+Tags can be appended to one another (in EXPLICIT tagging mode)
+or overridden (IMPLICIT tagging mode) ultimately creating a new
+ASN.1 subtype.
+
+.. code-block:: python
+
+ class Counter64(Integer):
+ """
+ ASN.1 specification:
+
+ Counter64 ::=
+ [APPLICATION 6]
+ IMPLICIT INTEGER
+ """
+ tagSet = Integer.tagSet.tagImplicitly(
+ Tag(tagClassApplication, tagFormatSimple, 6)
+ )
+
+ # alternatively
+ counter64 = Integer().subtype(
+ implicitTag=Tag(tagClassApplication, tagFormatSimple, 6)
+ )
+
+ASN.1 types can be related to each other via the *.isSameTypeWith()*,
+*.isSuperTypeOf()* and *.isSubTypeOf()* methods. Internally, the *.tagSet*
+of the types are compared along with the value constraints
+(e.g. *.subtypeSpec*).
+
+.. code-block:: python
+
+ assert Counter64().isSubTypeOf(Integer()) == True
+ assert Counter64().isSameTypeWith(Integer()) == False
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/tag/tag.rst b/docs/source/pyasn1/type/tag/tag.rst
index 65be836..0536b61 100644
--- a/docs/source/pyasn1/type/tag/tag.rst
+++ b/docs/source/pyasn1/type/tag/tag.rst
@@ -1,4 +1,6 @@
+.. _tag.tag:
+
Solitary tag
------------
diff --git a/docs/source/pyasn1/type/tag/tagmap.rst b/docs/source/pyasn1/type/tag/tagmap.rst
index 5891abc..a3222e3 100644
--- a/docs/source/pyasn1/type/tag/tagmap.rst
+++ b/docs/source/pyasn1/type/tag/tagmap.rst
@@ -1,4 +1,6 @@
+.. _tag.tagmap:
+
Tag->type map
-------------
diff --git a/docs/source/pyasn1/type/tag/tagset.rst b/docs/source/pyasn1/type/tag/tagset.rst
index 5ffb2fc..566238a 100644
--- a/docs/source/pyasn1/type/tag/tagset.rst
+++ b/docs/source/pyasn1/type/tag/tagset.rst
@@ -1,6 +1,8 @@
-Composition of tags
--------------------
+.. _tag.tagset:
+
+Tag set
+-------
.. autoclass:: pyasn1.type.tag.TagSet
:members:
diff --git a/docs/source/pyasn1/type/univ/any.rst b/docs/source/pyasn1/type/univ/any.rst
index 089a792..6727519 100644
--- a/docs/source/pyasn1/type/univ/any.rst
+++ b/docs/source/pyasn1/type/univ/any.rst
@@ -1,4 +1,6 @@
+.. _univ.Any:
+
.. |ASN.1| replace:: Any
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/univ/bitstring.rst b/docs/source/pyasn1/type/univ/bitstring.rst
index 17f6116..7d57774 100644
--- a/docs/source/pyasn1/type/univ/bitstring.rst
+++ b/docs/source/pyasn1/type/univ/bitstring.rst
@@ -1,4 +1,6 @@
+.. _univ.BitString:
+
.. |ASN.1| replace:: BitString
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/boolean.rst b/docs/source/pyasn1/type/univ/boolean.rst
index c486bd0..ab4021a 100644
--- a/docs/source/pyasn1/type/univ/boolean.rst
+++ b/docs/source/pyasn1/type/univ/boolean.rst
@@ -1,4 +1,6 @@
+.. _univ.Boolean:
+
.. |ASN.1| replace:: Boolean
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/choice.rst b/docs/source/pyasn1/type/univ/choice.rst
index 1507e9d..9731971 100644
--- a/docs/source/pyasn1/type/univ/choice.rst
+++ b/docs/source/pyasn1/type/univ/choice.rst
@@ -1,4 +1,6 @@
+.. _univ.Choice:
+
.. |ASN.1| replace:: Choice
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/contents.rst b/docs/source/pyasn1/type/univ/contents.rst
index af4a8f3..2a5ba25 100644
--- a/docs/source/pyasn1/type/univ/contents.rst
+++ b/docs/source/pyasn1/type/univ/contents.rst
@@ -1,8 +1,19 @@
+.. _type.univ:
+
Universal types
---------------
-.. autoclass:: pyasn1.type.univ.NoValue()
+The ASN.1 language defines a collection of core data types
+also known as *universal* types.
+
+Some of these types behave like a scalar (e.g. *simple* types) while
+the rest are structured types (the standard calls them *constructed*).
+
+Example of simple types include :ref:`Integer <univ.Integer>` or
+:ref:`OctetString <univ.OctetString>`. Constructed types like
+:ref:`Sequence <univ.Sequence>` embed other types, both simple
+and constructed.
.. toctree::
:maxdepth: 2
@@ -21,3 +32,7 @@ Universal types
/pyasn1/type/univ/set
/pyasn1/type/univ/sequence
/pyasn1/type/univ/choice
+
+.. _univ.noValue:
+
+.. autoclass:: pyasn1.type.univ.NoValue()
diff --git a/docs/source/pyasn1/type/univ/enumerated.rst b/docs/source/pyasn1/type/univ/enumerated.rst
index 2e88e99..ab225ae 100644
--- a/docs/source/pyasn1/type/univ/enumerated.rst
+++ b/docs/source/pyasn1/type/univ/enumerated.rst
@@ -1,4 +1,6 @@
+.. _univ.Enumerated:
+
.. |ASN.1| replace:: Enumerated
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/integer.rst b/docs/source/pyasn1/type/univ/integer.rst
index fd9fbec..4dcfabb 100644
--- a/docs/source/pyasn1/type/univ/integer.rst
+++ b/docs/source/pyasn1/type/univ/integer.rst
@@ -1,4 +1,6 @@
+.. _univ.Integer:
+
.. |ASN.1| replace:: Integer
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/null.rst b/docs/source/pyasn1/type/univ/null.rst
index a959146..5553fcc 100644
--- a/docs/source/pyasn1/type/univ/null.rst
+++ b/docs/source/pyasn1/type/univ/null.rst
@@ -1,4 +1,6 @@
+.. _univ.Null:
+
.. |ASN.1| replace:: Null
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/objectidentifier.rst b/docs/source/pyasn1/type/univ/objectidentifier.rst
index c63140f..cc4ae0b 100644
--- a/docs/source/pyasn1/type/univ/objectidentifier.rst
+++ b/docs/source/pyasn1/type/univ/objectidentifier.rst
@@ -1,4 +1,6 @@
+.. _univ.ObjectIdentifier:
+
.. |ASN.1| replace:: ObjectIdentifier
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/octetstring.rst b/docs/source/pyasn1/type/univ/octetstring.rst
index a58476d..a984a34 100644
--- a/docs/source/pyasn1/type/univ/octetstring.rst
+++ b/docs/source/pyasn1/type/univ/octetstring.rst
@@ -1,4 +1,6 @@
+.. _univ.OctetString:
+
.. |ASN.1| replace:: OctetString
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/univ/real.rst b/docs/source/pyasn1/type/univ/real.rst
index f80c725..31ea07b 100644
--- a/docs/source/pyasn1/type/univ/real.rst
+++ b/docs/source/pyasn1/type/univ/real.rst
@@ -1,4 +1,6 @@
+.. _univ.Real:
+
.. |ASN.1| replace:: Real
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/sequence.rst b/docs/source/pyasn1/type/univ/sequence.rst
index d9123d8..7b0549e 100644
--- a/docs/source/pyasn1/type/univ/sequence.rst
+++ b/docs/source/pyasn1/type/univ/sequence.rst
@@ -1,4 +1,6 @@
+.. _univ.Sequence:
+
.. |ASN.1| replace:: Sequence
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/sequenceof.rst b/docs/source/pyasn1/type/univ/sequenceof.rst
index 8f5c6f3..52c9d50 100644
--- a/docs/source/pyasn1/type/univ/sequenceof.rst
+++ b/docs/source/pyasn1/type/univ/sequenceof.rst
@@ -1,4 +1,6 @@
+.. _univ.SequenceOf:
+
.. |ASN.1| replace:: SequenceOf
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/set.rst b/docs/source/pyasn1/type/univ/set.rst
index 6216210..f44d09e 100644
--- a/docs/source/pyasn1/type/univ/set.rst
+++ b/docs/source/pyasn1/type/univ/set.rst
@@ -1,4 +1,6 @@
+.. _univ.Set:
+
.. |ASN.1| replace:: Set
|ASN.1| type
diff --git a/docs/source/pyasn1/type/univ/setof.rst b/docs/source/pyasn1/type/univ/setof.rst
index 74fdd42..a943a88 100644
--- a/docs/source/pyasn1/type/univ/setof.rst
+++ b/docs/source/pyasn1/type/univ/setof.rst
@@ -1,4 +1,6 @@
+.. _univ.SetOf:
+
.. |ASN.1| replace:: SetOf
|ASN.1| type
diff --git a/docs/source/pyasn1/type/useful/contents.rst b/docs/source/pyasn1/type/useful/contents.rst
index 2107349..2e4ae7b 100644
--- a/docs/source/pyasn1/type/useful/contents.rst
+++ b/docs/source/pyasn1/type/useful/contents.rst
@@ -1,7 +1,12 @@
+.. _type.useful:
+
Useful types
------------
+Some assorted utility ASN.1 types belong to the *useful* group.
+These types are all scalar.
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/pyasn1/type/useful/generalizedtime.rst b/docs/source/pyasn1/type/useful/generalizedtime.rst
index abf4351..d1f5b85 100644
--- a/docs/source/pyasn1/type/useful/generalizedtime.rst
+++ b/docs/source/pyasn1/type/useful/generalizedtime.rst
@@ -1,4 +1,6 @@
+.. _useful.GeneralizedTime:
+
.. |ASN.1| replace:: GeneralizedTime
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/useful/objectdescriptor.rst b/docs/source/pyasn1/type/useful/objectdescriptor.rst
index 3b62a5d..f7bf4f6 100644
--- a/docs/source/pyasn1/type/useful/objectdescriptor.rst
+++ b/docs/source/pyasn1/type/useful/objectdescriptor.rst
@@ -1,4 +1,6 @@
+.. _useful.ObjectDescriptor:
+
.. |ASN.1| replace:: ObjectDescriptor
.. |encoding| replace:: iso-8859-1
diff --git a/docs/source/pyasn1/type/useful/utctime.rst b/docs/source/pyasn1/type/useful/utctime.rst
index 2ad86a9..7bdfa8a 100644
--- a/docs/source/pyasn1/type/useful/utctime.rst
+++ b/docs/source/pyasn1/type/useful/utctime.rst
@@ -1,4 +1,6 @@
+.. _useful.UTCTime:
+
.. |ASN.1| replace:: UTCTime
.. |encoding| replace:: iso-8859-1