hat.asn1 - Python Abstract Syntax Notation One library¶
This library provides implementation of ASN.1 schema parser and BER encoder/decoder. Additionally, HTML documentation of parsed ASN.1 schemas can be generated.
Python data mappings¶
Mapping between ASN.1 data types and built in types:
ASN.1 type
Python type
Boolean
bool
Integer
int
BitString
List[bool]
OctetString
Bytes
Null
NoneType
ObjectIdentifier
Tuple[int, …]
String
str
External
External
Real
float
Enumerated
int
EmbeddedPDV
EmbeddedPDV
Choice
Tuple[str, Value]
Set
Dict[str, Value]
SetOf
Iterable[Value]
Sequence
Dict[str, Value]
SequenceOf
List[Value]
ABSTRACT-SYNTAX.&Type
Entity
For Choice, Set and Sequence, str represents field name.
According to previous mapping, this library defines following types:
Bytes = typing.Union[bytes, bytearray, memoryview]
Value = typing.Union['Boolean',
'Integer',
'BitString',
'OctetString',
'Null',
'ObjectIdentifier',
'String',
'External',
'Real',
'Enumerated',
'EmbeddedPDV',
'Choice',
'Set',
'SetOf',
'Sequence',
'SequenceOf',
'Entity']
Boolean = bool
Integer = int
BitString = typing.List[bool]
OctetString = Bytes
Null = None
ObjectIdentifier = typing.Tuple[int, ...]
String = str
Real = float
Enumerated = int
Choice = typing.Tuple[str, Value]
Set = typing.Dict[str, Value]
SetOf = typing.Iterable[Value]
Sequence = typing.Dict[str, Value]
SequenceOf = typing.List[Value]
class External(typing.NamedTuple):
data: typing.Union['Entity', Data, typing.List[bool]]
direct_ref: typing.Optional[ObjectIdentifier]
indirect_ref: typing.Optional[int]
class EmbeddedPDV(typing.NamedTuple):
abstract: typing.Optional[typing.Union[int, ObjectIdentifier]]
transfer: typing.Optional[ObjectIdentifier]
data: Data
class Entity(abc.ABC):
"""Encoding independent ASN.1 Entity"""
Repository¶
hat.asn1.Repository is used as parser of ASN.1 schemas. ASN.1 data definition is parsed during Repository instance initialization. These definitions are required for encoding/decoding ASN.1 data. Instance of Repository can be represented as JSON data enabling efficient storage and reconstruction of ASN.1 repositories without repetitive parsing of ASN.1 schemas.
class Repository:
def __init__(self, *args: typing.Union[pathlib.PurePath,
str,
'Repository']): ...
@staticmethod
def from_json(data: typing.Union[pathlib.PurePath, json.Data]
) -> 'Repository': ...
def to_json(self) -> json.Data: ...
def generate_html_doc(self) -> str: ...
Once instance of Repository is created, HTML documentation describing data structures can be generated with generate_html_doc method (example of generated documentation).
Encoder¶
hat.asn1.Encoder provides interface for encoding/decoding ASN.1 data based on ASN.1 data definitions parsed by hat.asn1.Repository:
Encoding = enum.Enum('Encoding', ['BER'])
class Encoder:
def __init__(self,
encoding: Encoding,
repository: Repository): ...
@property
def syntax_name(self) -> ObjectIdentifier: ...
def encode(self,
module: str,
name: str,
value: Value
) -> Bytes: ...
def decode(self,
module: str,
name: str,
data: Bytes
) -> typing.Tuple[Value, Bytes]: ...
def encode_value(self,
module: str,
name: str,
value: Value
) -> Entity: ...
def decode_value(self,
module: str,
name: str,
entity: Entity
) -> Value: ...
def encode_entity(self,
entity: Entity
) -> Bytes: ...
def decode_entity(self,
data: Bytes
) -> typing.Tuple[Entity, Bytes]: ...
Example¶
repo = asn1.Repository(r"""
Example DEFINITIONS ::= BEGIN
T ::= SEQUENCE OF CHOICE {
a BOOLEAN,
b INTEGER,
c UTF8String
}
END
""")
encoder = asn1.Encoder(asn1.Encoding.BER, repo)
value = [('c', '123'), ('a', True), ('a', False), ('b', 123)]
encoded = encoder.encode('Example', 'T', value)
decoded, rest = encoder.decode('Example', 'T', encoded)
assert value == decoded
assert len(rest) == 0
API¶
API reference is available as part of generated documentation: