107 lines
3.5 KiB
Markdown
107 lines
3.5 KiB
Markdown
# `@peculiar/asn1-schema`
|
|
|
|
[](https://raw.githubusercontent.com/PeculiarVentures/asn1-schema/master/packages/schema/LICENSE.md)
|
|
[](https://badge.fury.io/js/%40peculiar%2Fasn1-schema)
|
|
|
|
[](https://nodei.co/npm/@peculiar/asn1-schema/)
|
|
|
|
This package uses ES2015 [decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) to simplify working with ASN.1 creation and parsing.
|
|
|
|
|
|
## Introduction
|
|
|
|
Abstract Syntax Notation One (ASN.1) is a standard interface description language for defining data structures that can be serialized and deserialized in a cross-platform way. Working with ASN.1 can be complicated as there are many ways to represent the same data and many solutions handcraft, incorrectly, the ASN.1 representation of the data.
|
|
|
|
`asn1-schema` addresses this by using decorators to make both serialization and parsing of ASN.1 possible via a simple class that handles these problems for you.
|
|
|
|
This is important because validating input data before its use is important to do because all input data is evil.
|
|
|
|
|
|
## Installation
|
|
|
|
Installation is handled via `npm`:
|
|
|
|
```
|
|
$ npm install @peculiar/asn1-schema
|
|
```
|
|
|
|
## TypeScript examples
|
|
Node.js:
|
|
|
|
ASN.1 schema
|
|
```
|
|
Extension ::= SEQUENCE {
|
|
extnID OBJECT IDENTIFIER,
|
|
critical BOOLEAN DEFAULT FALSE,
|
|
extnValue OCTET STRING
|
|
-- contains the DER encoding of an ASN.1 value
|
|
-- corresponding to the extension type identified
|
|
-- by extnID
|
|
}
|
|
|
|
id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
|
|
|
|
BasicConstraints ::= SEQUENCE {
|
|
cA BOOLEAN DEFAULT FALSE,
|
|
pathLenConstraint INTEGER (0..MAX) OPTIONAL
|
|
}
|
|
```
|
|
|
|
ASN.1 schema declaration in TypeScript project
|
|
```ts
|
|
import { Asn1Prop, Asn1PropTypes, Asn1Serializer } from "@peculiar/asn1-schema";
|
|
|
|
class Extension {
|
|
|
|
public static CRITICAL = false;
|
|
|
|
@AsnProp({ type: Asn1PropTypes.ObjectIdentifier })
|
|
public extnID: string = "";
|
|
|
|
@AsnProp({
|
|
type: Asn1PropTypes.Boolean,
|
|
defaultValue: Extension.CRITICAL,
|
|
})
|
|
public critical = Extension.CRITICAL;
|
|
|
|
@AsnProp({ type: Asn1PropTypes.OctetString })
|
|
public extnValue: ArrayBuffer = new ArrayBuffer(0);
|
|
|
|
}
|
|
|
|
class BasicConstraints {
|
|
@AsnProp({ type: Asn1PropTypes.Boolean, defaultValue: false })
|
|
public ca = false;
|
|
|
|
@AsnProp({ type: Asn1PropTypes.Integer, optional: true })
|
|
public pathLenConstraint?: number;
|
|
}
|
|
```
|
|
|
|
Encoding ASN.1 data
|
|
```ts
|
|
const basicConstraints = new BasicConstraints();
|
|
basicConstraints.ca = true;
|
|
basicConstraints.pathLenConstraint = 1;
|
|
|
|
const extension = new Extension();
|
|
extension.critical = true;
|
|
extension.extnID = "2.5.29.19";
|
|
extension.extnValue = AsnSerializer.serialize(basicConstraints);
|
|
|
|
console.log(Buffer.from(AsnSerializer.serialize(extension)).toString("hex")); // 30120603551d130101ff040830060101ff020101
|
|
```
|
|
|
|
[ASN.1 encoded data](http://lapo.it/asn1js/#MBIGA1UdEwEB_wQIMAYBAf8CAQE)
|
|
|
|
Decoding ASN.1 data
|
|
```ts
|
|
const extension = AsnParser.parse(Buffer.from("30120603551d130101ff040830060101ff020101", "hex"), Extension);
|
|
console.log("Extension ID:", extension.extnID); // Extension ID: 2.5.29.19
|
|
console.log("Critical:", extension.critical); // Critical: true
|
|
|
|
const basicConstraints = AsnParser.parse(extension.extnValue, BasicConstraints);
|
|
console.log("CA:", basicConstraints.ca); // CA: true
|
|
console.log("Path length:", basicConstraints.pathLenConstraint); // Path length: 1
|
|
```
|