Package asn1plus ("ASN.1+") implements an extensible Go-based ASN.1 API supporting subsets of ITU-T X-Series Recommendations 680 and 690.
The asn1plus package is released under the terms of the MIT license. See the LICENSE file in the repository root for details.
This package is under heavy development and is HIGHLY EXPERIMENTAL. As such, it should NOT be used in a mission-critical capacity at this time.
Go version 1.21 or later is required
If you or your organization use my software regularly and find it useful, I only ask that you donate to animal shelters, non-profit environmental entities or similar. If you cannot afford a monetary contribution to these causes, please volunteer at animal shelters and/or visit kill shelters for the purpose of liberating animals unfairly awaiting execution.
As indicated by the above badge, I am actively looking for experienced open source volunteers who have a keen grasp of ASN.1, encoding rules and other relevant components.
Interested? Email me.
This package has no dependence upon the encoding/asn1 package, as this package is meant to serve as an alternative.
- Fast ASN.1 BER, CER and DER encoding/decoding
- Flexible build system
- Full ASN.1 primitive type support -- twenty six (26) types are implemented, such as
OctetString,Time,Realand many others (including legacy/deprecated types) SETandSEQUENCEsupport- Constraints -- Flexible ASN.1 constraint logic has been implemented for maximum control
- Choice support, with custom interface registration bindings to concrete types
- Intuitive, easy to use
- Well documented, containing many useful examples
This package supports flexible build instructions. By default, this package enables all features except debugging.
But in certain cases it may be advantageous to disable certain elements, such as CER or DER encoding, or even to disable deprecated ASN.1 types.
Regardless of the permutation, this package offers build tags to make the task easy. Whether you're building an executable -- even a simple main.go -- or, if you're running the included test suite directly, it is painless to enable/disable select features.
| Build Tag | Description |
|---|---|
asn1_no_adapter_pf |
Do not implement prefabricated type bindings |
asn1_no_cer |
Do not implement CER encoding |
asn1_no_constr_pf |
Do not implement prefabricated constraint functions |
asn1_debug |
Enable debug tracer; use with extreme caution |
asn1_no_der |
Do not implement DER encoding |
asn1_no_dprc |
Do not implement deprecated/obsolete ASN.1 types |
To utilize these tags, simply invoke the -tags command-line option when executing the go binary, e.g.:
## Test without type adapters prefabs and without deprecated types
$ go test -tags asn1_no_adapter_pf,asn1_no_dprc ./...
## Build main.go without CER support
$ go build -tags asn1_no_cer main.go
## Run main.go without constraint prefabs
$ go run -tags asn1_no_constr_pf main.go
Depending on the tags invoked, the elapsed time of subsequent runs of the test suite will vary.
Note that certain features -- namely BER encoding -- cannot be disabled.
This package relies upon the following packages from the standard library:
bytesencoding/binaryencoding/hexerrorsfmt†iomathmath/bigmath/bitsmath/rand‡os‡reflectruntime‡slicesstrconvstringssyncsync/atomictestingtimeunicodeunicode/utf8unicode/utf16unsafe
This package relies upon the following packages from the golang/x/exp library:
constraints⹋
‡ - used ONLY when debugging is enabled
⹋ - used ONLY when prefabricated constraints are loaded
The ASN.1 specification allows constraints to be applied to values. This might include restricting the allowed character set of a string beyond its base definition (for instance, forbid lower-case letters).
This package honors this capability, and allows Constraints to be custom-written and applied in two different ways:
- Manually via a type constructor (e.g.:
NewOctetString(myValue, constraintFunc1, constraintFunc2)), or ... - Automatically via an
Optionsinstance -- whether hand-crafted or specified via struct tag (e.g.:asn1:"constraint:constraintFunc1,...")
A Constraint may be used ad hoc, or as part of a ConstraintGroup, which iterates any number of Constraint functions in the order in which they are specified.
When using any number of Constraints via Options, the Constraint function MUST be pre-registered using the package-level RegisterTaggedConstraint or RegisterTaggedConstraintGroup functions.
There are many examples compiled into the package on this topic.
Prefabricated Constraint instances can be excluded from builds using the asn1_no_constr_pf build tag.
In addition to the ASN.1 primitive types defined in this package, users may opt for standard Go types such as []byte, string, int and a few others to be supported via internal "type adapters".
This means that the following two SEQUENCE instances are functionally identical:
// Use readily identifiable ASN.1 primitive types
type MySequence struct {
Name PrintableString
Email IA5String
}
// Use Go types with tagged instructions
type MySequence struct {
Name string `asn1:"printable"`
Email string `asn1:"ia5"`
}
Subsequent encoded values will be identical.
The caveat to using tagged instructions in this manner -- as opposed to actual ASN.1 types as used in the first MySequence example -- is that the Unmarshal function will need to receive the same instructions which Marshal received. Thus, if we attempt to Unmarshal into a SEQUENCE with untagged string fields and without instructions, defaults may be erroneously applied (e.g.: a UTF-8 STRING is mistaken for an OCTET STRING, or some other such permutation). This is not an issue when using actual ASN.1 types, as the compiler will recognize them and decode them properly automatically.
Prefabricated adapter bindings can be excluded from builds using the asn1_no_adapter_pf build tag.
