aboutsummaryrefslogtreecommitdiff
path: root/docs/source/pyasn1/type/opentype/contents.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/pyasn1/type/opentype/contents.rst')
-rw-r--r--docs/source/pyasn1/type/opentype/contents.rst94
1 files changed, 84 insertions, 10 deletions
diff --git a/docs/source/pyasn1/type/opentype/contents.rst b/docs/source/pyasn1/type/opentype/contents.rst
index 9ae10d0..034870b 100644
--- a/docs/source/pyasn1/type/opentype/contents.rst
+++ b/docs/source/pyasn1/type/opentype/contents.rst
@@ -1,16 +1,67 @@
.. _type.opentype:
-Untyped fields of constructed types
------------------------------------
+Dynamic or open type
+--------------------
-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.
+ASN.1 allows data structure designer to leave "holes" in field type
+specification of :ref:`Sequence <univ.Sequence>` or
+: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.
+The idea behind that feature is that there can be times, when the
+exact field type is not known at the design time, or it is anticipated
+that new field types may come up in the future.
+
+This "hole" type is manifested in the data structure by :ref:`Any <univ.Any>`
+type. Technically, the actual type is serialized into an octet stream
+and then put into :ref:`Any <univ.Any>` "container", which is in fact an
+(untagged, by default) specialization of ASN.1
+:ref:`OctetString <univ.OctetString>` type.
+
+.. code-block:: bash
+
+ Algorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL
+ }
+
+On the receiving end, to know how to interpret the open type
+serialization, the receiver can rely on the supplied value in
+the other field of the data structure. That other field is
+semantically linked with the open type field. This link
+is expressed in ASN.1 by the *DEFINE BY* clause.
+
+From ASN.1 perspective, it is not an error if the decoder does
+not know a type selector value it receives. In that case pyasn1 decoder
+just leaves serialized blob in the open type field.
+
+.. note::
+
+ By default, ASN.1 ANY type has no tag. That makes it an
+ "invisible" in serialization. However, like any other ASN.1 type,
+ ANY type can be subtyped by :ref:`tagging <type.tag>`.
+
+Besides scalar open type fields, ASN.1 allows using *SET OF*
+or *SEQUENCE OF* containers holding zero or more of *ANY*
+scalars.
+
+.. code-block:: bash
+
+ AttributeTypeAndValues ::= SEQUENCE {
+ type OBJECT IDENTIFIER,
+ values SET OF ANY DEFINED BY type
+ }
+
+.. note::
+
+ A single type selector field is used to guide the decoder
+ of potentially many elements of a *SET OF* or *SEQUENCE OF* container
+ all at once. That implies that all *ANY* elements must be of the same
+ type in any given instance of a data structure.
+
+When expressing ASN.1 type "holes" in pyasn1, the
+:ref:`OpenType <opentype.OpenType>` object should be used to establish
+a semantic link between type selector field and open type field.
.. code-block:: python
@@ -24,15 +75,38 @@ be captured by the :ref:`OpenType <opentype.OpenType>` object.
"""
Algorithm ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
- parameters ANY DEFINED BY algorithm OPTIONAL
+ parameters ANY DEFINED BY algorithm
}
"""
componentType = NamedTypes(
NamedType('algorithm', ObjectIdentifier()),
- OptionalNamedType('parameters', Any(),
+ NamedType('parameters', Any(),
openType=OpenType('algorithm', algo_map))
)
+Similarly for `SET OF ANY DEFINED BY` or `SEQUENCE OF ANY DEFINED BY`
+constructs:
+
+.. 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 SET OF ANY DEFINED BY algorithm
+ }
+ """
+ componentType = NamedTypes(
+ NamedType('algorithm', ObjectIdentifier()),
+ NamedType('parameters', SetOf(componentType=Any()),
+ openType=OpenType('algorithm', algo_map))
+ )
.. toctree::
:maxdepth: 2