x690.types

The type classes of X.690 and the decode() function.

Every class wraps a Python value and encodes it with bytes. X690Type is the base class: subclassing it registers a new type with decode(). The documentation pages “Supported types” and “Custom types” describe the classes and how to add new ones.

class x690.types.BitString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 3

The x690 identifier for the type

class x690.types.BmpString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 30

The x690 identifier for the type

class x690.types.Boolean(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[bool]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 1

The x690 identifier for the type

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → bool

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

encode_raw() → bytes

Overrides X690Type.encode_raw()

classmethod validate(data: bytes) → None

Overrides X690Type.validate()

class x690.types.CharacterString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

TAG : int = 29

The x690 identifier for the type

class x690.types.EOC(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[bytes]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 0

The x690 identifier for the type

class x690.types.EmbeddedPdv(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[bytes]

TAG : int = 11

The x690 identifier for the type

class x690.types.Enumerated(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[list[Any]]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 10

The x690 identifier for the type

class x690.types.External(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[bytes]

TAG : int = 8

The x690 identifier for the type

class x690.types.GeneralString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 27

The x690 identifier for the type

class x690.types.GeneralizedTime(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[datetime]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 24

The x690 identifier for the type

class x690.types.GraphicString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 25

The x690 identifier for the type

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → str

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

class x690.types.IA5String(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 22

The x690 identifier for the type

class x690.types.Integer(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[int]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 2

The x690 identifier for the type

classmethod decode_raw(data: bytes, slc: slice = slice(None, None, None)) → int

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

encode_raw() → bytes

Overrides X690Type.encode_raw()

class x690.types.Null(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[None]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 5

The x690 identifier for the type

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → None

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

encode_raw() → bytes

Overrides X690Type.encode_raw()

>>> Null().encode_raw()
b'\x00'
classmethod validate(data: bytes) → None

Overrides X690Type.validate()

class x690.types.NumericString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 18

The x690 identifier for the type

class x690.types.ObjectDescriptor(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 7

The x690 identifier for the type

class x690.types.ObjectIdentifier(value: str | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

Represents an OID.

Instances of this class support containment checks to determine if one OID is a sub-item of another:

>>> ObjectIdentifier("1.2.3.4.5") in ObjectIdentifier("1.2.3")
True

>>> ObjectIdentifier("1.2.4.5.6") in ObjectIdentifier("1.2.3")
False
NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 6

The x690 identifier for the type

childof(other: ObjectIdentifier) → bool

Convenience method to check whether this OID is a child of another OID

collapse_identifiers() → tuple[int, ...]

Meld the first two octets into one octet as defined by x.690

In x.690 ObjectIdentifiers are a sequence of numbers. In the byte-representation the first two of those numbers are stored in the first byte.

This function takes a “human-readable” OID tuple and returns a new tuple with the first two elements merged (collapsed) together.

>>> ObjectIdentifier("1.3.6.1.4.1").collapse_identifiers()
(43, 6, 1, 4, 1)
>>> ObjectIdentifier().collapse_identifiers()
()
static decode_large_value(current_char: int, stream: Iterator[int]) → int

If we encounter a value larger than 127, we have to consume from the stram until we encounter a value below 127 and recombine them.

See: https://msdn.microsoft.com/en-us/library/bb540809(v=vs.85).aspx

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → str

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

static encode_large_value(value: int) → list[int]

Inverse function of decode_large_value()

encode_raw() → bytes

Overrides X690Type.encode_raw()

property nodes : tuple[int, ...]

Returns the numerical nodes for this instance as tuple

>>> ObjectIdentifier("1.2.3").nodes
(1, 2, 3)
>>> ObjectIdentifier().nodes
()
parentof(other: ObjectIdentifier) → bool

Convenience method to check whether this OID is a parent of another OID

class x690.types.OctetString(value: str | bytes | _SENTINEL_UNINITIALISED = b'')

Bases: X690Type[bytes]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 4

The x690 identifier for the type

pretty(depth: int = 0) → str

Returns a prettified string with depth levels of indentation

See pretty()

class x690.types.PrintableString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 19

The x690 identifier for the type

class x690.types.Real(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[float]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 9

The x690 identifier for the type

class x690.types.RelativeOid(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE]

The x690 “private/constructed” information

TAG : int = 13

The x690 identifier for the type

class x690.types.Sequence(value: list[X690Type[Any]] | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[list[X690Type[Any]]]

Represents an X.690 sequence type. Instances of this class are iterable and indexable.

TAG : int = 16

The x690 identifier for the type

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → list[X690Type[Any]]

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

encode_raw() → bytes

Overrides X690Type.encode_raw()

static item_offsets(data: bytes, slc: slice = slice(None, None, None)) → array[int]

Return the start index of every item in the value at slc.

Only the type and length headers are read; no item is decoded.

pretty(depth: int = 0) → str

Returns a prettified string with depth levels of indentation

See pretty()

pythonize() → list[X690Type[Any]]

Overrides pythonize()

property value : list[X690Type[Any]]

The items of this sequence.

Overrides value

class x690.types.Set(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[bytes]

TAG : int = 17

The x690 identifier for the type

class x690.types.T61String(value: str | bytes = '')

Bases: X690Type[str]

The T61String (TeletexString) type, tag 0x14.

Decoding and encoding are strict ITU-T T.61 (1988), via t61codec 3. Accented letters decode to precomposed characters (b"Caf\xc2e" becomes "Café") and 0xE0 is Ω (U+03A9, GREEK CAPITAL LETTER OMEGA). Invalid T.61 raises UnicodeDecodeError, and characters without a T.61 representation raise UnicodeEncodeError.

Data written by OpenSSL is often Latin-1 rather than T.61. For such values, decode the raw bytes with bytes.decode("latin-1").

The T.61 codec is never registered globally.

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 20

The x690 identifier for the type

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → str

Converts the raw byte-value (without type & length header) into a pure Python type

Overrides decode_raw()

Raises:

UnicodeDecodeError – if the data is not valid T.61.

encode_raw() → bytes

Overrides X690Type.encode_raw()

Raises:

UnicodeEncodeError – if the value cannot be represented in T.61.

x690.types.UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>

sentinel value for uninitialised objects (used for lazy decoding)

class x690.types.UniversalString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 28

The x690 identifier for the type

class x690.types.UnknownType(value: bytes = b'', tag: int = -1)

Bases: X690Type[bytes]

A fallback type for anything not in X.690.

Instances of this class contain the raw information as parsed from the bytes as the following attributes:

  • value: The value without leading metadata (as bytes value)

  • tag: The unparsed “tag”. This is the type ID as defined in the reference document. See TypeInfo for details.

  • typeinfo: unused (derived from tag and only here for consistency with __repr__ of this class).

TAG : int = 153

The x690 identifier for the type

pretty(depth: int = 0) → str

Returns a prettified string with depth levels of indentation

See pretty()

class x690.types.UtcTime(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[datetime]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 23

The x690 identifier for the type

class x690.types.Utf8String(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 12

The x690 identifier for the type

class x690.types.VideotexString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 21

The x690 identifier for the type

class x690.types.VisibleString(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: X690Type[str]

NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = 26

The x690 identifier for the type

class x690.types.X690Type(value: TWrappedPyType | _SENTINEL_UNINITIALISED = <x690.types._SENTINEL_UNINITIALISED object>)

Bases: Generic[TWrappedPyType]

The superclass for all supported types.

NATURE = [TypeNature.CONSTRUCTED]

The x690 “private/constructed” information

TAG : int = -1

The x690 identifier for the type

TYPECLASS : TypeClass = 'universal'

The x690 type-class (universal, application or context)

static all() → list[type[X690Type[Any]]]

Returns all registered classes

bounds : slice

The location of the value within “raw_bytes”

classmethod decode(data: bytes) → TConcreteType

This method takes a bytes object which contains the raw content octets of the object. That means, the octets without the type information and length.

This function must be overridden by the concrete subclasses.

static decode_raw(data: bytes, slc: slice = slice(None, None, None)) → TWrappedPyType

Converts the raw byte-value (without type & length header) into a pure Python type

>>> Integer.decode_raw(b"\x05")
5
Parameters:
data: bytes

A data-block containing the byte-information

slc: slice = slice(None, None, None)

A slice of the data-block that contains the exact raw-bytes.

Returns:

The value that should be wrapped by the current x690 type.

encode_raw() → bytes

Convert this instance into raw x690 bytes (excluding the type and length header)

>>> import x690.types as t
>>> Integer(5).encode_raw()
b'\x05'
>>> Boolean(True).encode_raw()
b'\x01'
>>> X690Type(t.UNINITIALISED).encode_raw()
b''
classmethod from_bytes(data: bytes, slc: slice = slice(None, None, None)) → TConcreteType

Creates a new x690.types.X690Type instance from raw-bytes (without type nor length bytes)

>>> Integer.from_bytes(b"\x01")
Integer(1)
>>> OctetString.from_bytes(b"hello-world")
OctetString(b'hello-world')
>>> Boolean.from_bytes(b"\x00")
Boolean(False)
static get(typeclass: str, typeid: int, nature: TypeNature = TypeNature.CONSTRUCTED) → type[X690Type[Any]]

Retrieve a Python class by x690 type information

Classes can be registered by subclassing x690.types.X690Type

property length : int

Return the x690 byte-length of this instance

pretty(depth: int = 0) → str

Returns a readable representation (possibly multiline) of the value.

The value is indented by depth levels of indentation

By default this simply returns the string representation. But more complex values may override this.

pythonize() → TWrappedPyType

Convert this instance to an appropriate pure Python object.

pyvalue : TWrappedPyType | _SENTINEL_UNINITIALISED

The decoded (or to-be encoded) Python value

classmethod validate(data: bytes) → None

Given a bytes object, checks if the given class cls supports decoding this object. If not, raises a ValueError.

property value : TWrappedPyType

Returns the value as a pure Python type

x690.types.decode(data: bytes, start_index: int = 0, enforce_type: type[TPopType] | None = None, strict: bool = False) → tuple[TPopType, int]

Convert a X.690 bytes object into a Python instance, and the location of the next object.

Given a bytes object and any start-index, inspects and parses the octets starting at the given index (as many as required) to determine variable type (and corresponding Python class), and length. That class is then used to parse the object located in data at the given index. The location of the start of the next (subsequent) object is also determined.

The return value is a tuple with the decoded object and the start-index of the next object.

Example:

>>> data = b'\x02\x01\x05\x11'
>>> decode(data)
(Integer(5), 3)
>>> data = b'some-skippable-bytes\x02\x01\x05\x11'
>>> decode(data, 20)
(Integer(5), 23)