An ASN.1 parser in less than 100 lines of Vanilla JavaScript, part of the BlueCrypt suite.
Go to file
Valters Jansons 36e450659d
v1.1.9: bugfix Node.js `atob` invocation
Browsers have a global `atob` function, but Node.js does not.
This is very important for allowing `PEM.parseBlock` to work
out of the box, as it calls `Enc.base64ToBuf` directly.
2020-02-14 02:12:29 +02:00
README.md Update 'README.md' 2018-11-28 16:53:44 +00:00
asn1-parser.js v1.1.9: bugfix Node.js `atob` invocation 2020-02-14 02:12:29 +02:00
index.html fix link 2018-12-01 21:10:30 -07:00
package.json v1.1.9: bugfix Node.js `atob` invocation 2020-02-14 02:12:29 +02:00
screenshot.png v1.0.0: An ASN.1 parser in 100 lines of Vanilla JavaScript, part of the BlueCrypt suite 2018-11-25 21:17:00 -07:00

README.md

Bluecrypt ASN.1 Parser

An ASN.1 decoder in less than 100 lines of Vanilla JavaScript, part of the Bluecrypt suite.
(< 150 with newlines and comments)

Features

| <100 lines of code | 1.1k gzipped | 2.5k minified | 4.7k with comments |

  • Complete ASN.1 parser
    • Parses x.509 certificates
    • PEM (base64-encoded DER)
  • VanillaJS, Zero Dependencies
    • Browsers (even old ones)
    • Online Demo
    • Node.js (built, publishing soon)

Need an ASN.1 Builder too?

Check out https://git.coolaj86.com/coolaj86/asn1-packer.js/

Demo

https://coolaj86.com/demos/asn1-parser/

Usage

<script src="https://git.coolaj86.com/coolaj86/asn1-parser.js/raw/branch/master/asn1-parser.js"></script>
'use strict';

var ASN1 = window.ASN1  // 62 lines
var Enc = window.Enc    // 27 lines
var PEM = window.PEM    //  6 lines

var pem = [ '-----BEGIN EC PRIVATE KEY-----'
          + 'MHcCAQEEIImMnaNu2jRjvQwVFnhhDw/KDYtS2Q6n8T5kJYniwY1UoAoGCCqGSM49'
          + 'AwEHoUQDQgAEIT1SWLxsacPiE5Z16jkopAn8/+85rMjgyCokrnjDft6Y/YnA4A50'
          + 'yZe7CnFsqeDcpnPbubP6cpYiVcnevNIYyg=='
          + '-----END EC PRIVATE KEY-----'
          ].join('\n');

var der = PEM.parseBlock(pem).der;
var json = ASN1.parse(der);

console.log(json);
{ "type": 48 /*0x30*/, "lengthSize": 0, "length": 89
, "children": [
    { "type": 48 /*0x30*/, "lengthSize": 0, "length": 19
		, "children": [
        { "type": 6, "lengthSize": 0, "length": 7, "value": "<0x2a8648ce3d0201>" },
        { "type": 6, "lengthSize": 0, "length": 8, "value": "<0x2a8648ce3d030107>" }
      ]
    },
    { "type": 3, "lengthSize": 0, "length": 66,
      "value": "<0x04213d5258bc6c69c3e2139675ea3928a409fcffef39acc8e0c82a24ae78c37ede98fd89c0e00e74c997bb0a716ca9e0dca673dbb9b3fa72962255c9debcd218ca>"
    }
  ]
}

Note: value will be a Uint8Array, not a hex string.

Optimistic Parsing

This is a dumbed-down, minimal ASN1 parser (though quite clever in its simplicity).

There are some ASN.1 types (at least Bit String and Octet String, possibly others) that can be treated either as primitive values or as container types base on the schema being used.

Rather than incorporating knowledge of each possible x509 schema, this parser will return values for types that are always values, it recurse on types that are always containers and, for ambigiuous types, it will first try to recurse and, on error, will fall back to returning a value.

In theory, it is possible that it will produce false positives, but that would be highly unlikely in real-world scenarios (PEM, x509, PKCS#1, SEC1, PKCS#8, SPKI, PKIX, CSR, etc).

I'd be interested to hear if you encounter such a case.

Zero Dependencies

A little copying is better than a little dependency - Golang Proverbs by Rob Pike

Rather than requiring hundreds (or thousands) of lines of dependencies, this library takes the approach of including from other libraries in its suite to produce a small, focused file that does exactly what it needs to do.

Legal

Bluecrypt VanillaJS ASN.1 Parser | MPL-2.0