ASN.1 encoder/decoder in Java.
Most ASN.1 tooling is either a black box of decades-old generated code or requires heavyweight external dependencies. This project builds a clean, readable Java implementation from first principles: a minimal grammar, a hand-written reference codec, and a code generator that produces production-ready UPER codecs from ASN.1 specs.
| Module | Purpose |
|---|---|
core |
ANTLR4-based ASN.1 parser → typed AST, semantic validation, and JavaPoet-based code generator |
runtime |
UperOutputStream, UperInputStream, UperCodecSupport — shared by generated codecs and the handwritten reference |
handwritten-codec |
Reference UPER codec for simple.asn, written by hand to establish and verify golden tests |
plugin |
Maven plugin (asn1java-maven-plugin) — runs at generate-sources, parses .asn files, generates model records and UPER codec classes |
sample |
End-to-end consumer of the plugin; approval tests verify generated codec output matches the golden-test hex files byte-for-byte |
Add the plugin to your pom.xml. The generated code depends on asn1java-runtime, so declare that dependency too:
<dependencies>
<dependency>
<groupId>io.github.ahmedabadawi</groupId>
<artifactId>asn1java-runtime</artifactId>
<version>VERSION</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.github.ahmedabadawi</groupId>
<artifactId>asn1java-maven-plugin</artifactId>
<version>VERSION</version>
<executions>
<execution>
<goals><goal>generate</goal></goals>
</execution>
</executions>
<configuration>
<specFiles>
<specFile>${project.basedir}/src/main/asn1/my.asn</specFile>
</specFiles>
<basePackage>com.example.gen</basePackage>
</configuration>
</plugin>
</plugins>
</build>For a spec named MyModule with basePackage=com.example.gen, the plugin generates:
com.example.gen.mymodule.MyType— Java record for eachSEQUENCEcom.example.gen.mymodule.MyTypeCodec— UPER encoder/decoder for each type
UPERencoding/decoding
- UPER encoding rules — encoding rules applied in this project with examples, referencing ITU-T X.691
- Select one or more ASN.1 features/constructs
- Create ASN.1 spec file that covers the feature/constructs
- Create 2 or more examples in
JSON(JER) and 1 or more invalid examples as inputs - Use
asn1toolsto generateUPERencoder/decoder for the same spec - Run the examples by the
asn1toolscodec to generate encodergolden-tests - Handwritten
UPERencoder/decoder in Java - Approval tests that validates the outputs against the
golden-tests - Create/Update
ANTLRgrammar to include the new ASN.1 spec constructs - Adapt ASN.1 spec parser to the new grammar
- Adapt Code Generation to include the new constructs
- Add the examples to the example application
- Add approval tests to the example application to validate against the
golden-tests
-
INTEGER (0..MAX)— semi-constrained whole number -
INTEGER (lb..ub)— constrained whole number -
BOOLEAN— single-bit encoding -
UTF8String— unconstrained UTF-8 string (§26 length determinant + bytes) - Single
SEQUENCEwith INTEGER, BOOLEAN, and UTF8String fields
oracle-test-asn1c uses converter-example -oper to request PER output, but the
binary (built from the current asn1c master branch) ignores the flag and falls back
to BER. For valid-1.json (major=1, minor=0) asn1c emits 3006800101810100
(SEQUENCE tag + context tags — BER) while asn1tools emits 01010100 (correct UPER).
The asn1tools oracle is used as the source of truth for golden tests in the meantime.
Root cause is likely a flag rename or regression in asn1c master; needs investigation
of what PER output flag the generated converter-example binary actually accepts.