Python with ASN.1 in three steps


ASN.1 is an international standard used by many companies in telecom, avionics, intelligent transportation systems, etc, basically anywhere where robustness and security are important. OSS Nokalva offers a set of ASN.1 tools to help with development of data serialization, communication, and storage.

We’ll use just two of the asn1.io online tools to jumpstart a Python project for a communication protocol using ASN.1 schema and data encodings:

  • Json2asn to define a schema based on the JSON representation of our data model.
  • ASN1-Python-Compiler to generate a Python encoder/decoder library.

Step 1: Defining the schema

Let's say we’re developing an app that sends and receives messages to control a sensor. For simplicity we have just two kinds of messages: sending a configuration (to sensor) and receiving a reading (from sensor). Let’s define the data in JSON:

{ "Message":"Configuration", "PublishPeriod":1 } { "Message":"Reading", "Value":2.3 }

Now we can use json2asn to get an ASN.1 schema for each individual message (click one and two), and combine them into a single schema (with minor improvements, highlighted):

GeneratedSchema DEFINITIONS AUTOMATIC TAGS ::= BEGIN SensorConfiguration ::= SEQUENCE { message UTF8String, publishPeriod INTEGER (1..10) -- valid range } SensorReading ::= SEQUENCE { message UTF8String, value REAL } END

Step 2: Generate Python code

Next, we’ll use asn1.io/asn1-python-compiler to generate Python code according to the schema (click here). The generated code includes a sample that looks like:

value = json.loads('{"message": "Configuration","publishPeriod": 1}') encoded = Sensor.GeneratedSchema.SensorConfiguration.encode('DER', value) #here send/receive the encoded/decoded data to/from a sensor decoded = Sensor.GeneratedSchema.SensorReading.decode('DER', encoded) violations = Sensor.GeneratedSchema.SensorReading.validate(decoded)

Every time when the message is encoded or decoded, it can be validated to ensure the required fields (and their values, if constrained) match the schema.


Step 3: Run

Running the code above will encode from a dictionary object value into a byte array (DER) and back to a dictionary object.

encoded (0x30, 0x12, 0x80, 0x0D, 0x43, 0x6F, 0x6E, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x81, 0x01, 0x01) decoded {"message": "Configuration", "publishPeriod": 1}