Addons
In addition to core functionality, awesn1 provides three out-of-the-box addons:
- Integration with kotlinx-io
- DER+kotlinx.serialization integration on top of kotlinx-io
- A plethora of standardised, known object identifiers
The awesn1 core module works on byte arrays. IO-oriented support is provided through kotlinx-io integration using the
io module.
Maven Coordinates
Features
kotlinx.io.Sourceintegration for ASN.1 parsing:Asn1Element.parse(source),parseAll(source),parseFirst(source),source.readAsn1Element().kotlinx.io.Sinkintegration for DER encoding:asn1Value.encodeToDer(sink).- Primitive ASN.1 content helpers directly on
Source/Sink:readAsn1…Content(...)andwriteAsn1…Content(...)for booleans, numbers, strings, reals, and time values. - VarInt and two's-complement helpers:
writeAsn1VarInt(...),decodeAsn1VarUInt()/decodeAsn1VarULong(),readTwosComplement...(...),writeTwosComplement...(...).
Source/Sink Integration Sketches
Decode one ASN.1 element from a Source:
Encode an Asn1Encodable value to a Sink:
Primitive Content Helpers (Sink/Source)
Boolean content:
Integer content:
val n = Buffer()
val nBytes = n.writeAsn1IntContent(42)
val value = n.readAsn1IntContent(nBytes) // 42
String content:
val s = Buffer()
val sBytes = s.writeAsn1StringContent("hello")
val value = s.readAsn1StringContent(sBytes) // "hello"
Reading Content Bytes
Note that readAsn1…Content(nBytes) helpers consume ASN.1 content octets (not a full TLV),
so pass the expected content length.
kxs-io contains kotlinx-io extensions for awesn1's DER kotlinx.serialization format.
Maven Coordinates
Integration with kotlinx.serialization
val oid = ObjectIdentifier("1.2.840.113549.1.1.11")
// Encode directly to a kotlinx.io.Sink using DER + kxs-io extension
val sink = Buffer()
DER.encodeToSink(oid, sink)
// Decode directly from a kotlinx.io.Source using DER + kxs-io extension
val source = Buffer().apply { write(sink.readByteArray()) }
val decoded: ObjectIdentifier = DER.decodeFromSource(source)
The oids module is literally Peter Gutmann's dumpasn1.cfg
transformed into a Kotlin extensions on the awesn1 core module's KnownOIDs object.
In fact, the ability to do just that is the reason this object is part of the core module at all.
Maven Coordinates
Features
- Generated known OID constants as extension properties on
KnownOIDs. This gives discoverable names such asKnownOIDs.date,KnownOIDs.countryName, etc., each returning anObjectIdentifier. - Human-readable descriptions are stored in
KnownOIDs(a mutable map fromObjectIdentifiertoString). KnownOIDs.describeAll()bulk-loads all descriptions shipped by theoidsmodule. The first call initialises the map; subsequent calls are effectively no-ops.- You can add or override your own labels at runtime:
KnownOIDs[myOid] = "My Domain OID". - Pretty-print integration:
when an ASN.1 primitive with tag
OIDis pretty-printed, awesn1 checksKnownOIDs[oid]. If a description exists, output isDescription (1.2.3...); otherwise it falls back to the plain numeric OID.
Working with Known OIDs
Use named OID constants (extension properties):
Load bundled descriptions and query them:
KnownOIDs.describeAll()
val description = KnownOIDs[KnownOIDs.date] // returns human-readable descriptions
Add your own description:
val expressionistOID = ObjectIdentifier(Uuid.random())
KnownOIDs[expressionistOID].shouldBeNull()
KnownOIDs[expressionistOID] = "Edvard Munch"
KnownOIDs[expressionistOID] shouldBe "Edvard Munch"
All described known OIDs are used when prettyPrinting Asn1Elements. This can prove helpful for debugging, but
describeAll should not be used in memory-constrained environments (such as iOS app extensions), because it will increase
resident memory consumption by a couple of megabytes.