v1.1.0: add case for known primitive-only values

This commit is contained in:
AJ ONeal 2018-11-25 22:53:43 -07:00
parent 01384daa80
commit bf359477a9
4 changed files with 30 additions and 23 deletions

View File

@ -71,14 +71,22 @@ Note: `value` will be a `Uint8Array`, not a hex string.
### Optimistic Parsing
This is a dumbed-down, minimal ASN1 parser.
This is a dumbed-down, minimal ASN1 parser
(though quite clever in its simplicity).
Rather than incorporating knowledge of each possible x509 schema
to know whether to traverse deeper into a value container,
it always tries to dive in (and backs out when parsing fails).
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.
It is possible that it will produce false positives, but not likely
in real-world scenarios (PEM, x509, CSR, etc).
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.

View File

@ -15,10 +15,12 @@ var PEM = exports.PEM;
ASN1.ELOOP = "uASN1.js Error: iterated over 15+ elements (probably a malformed file)";
ASN1.EDEEP = "uASN1.js Error: element nested 20+ layers deep (probably a malformed file)";
// Container Types are Sequence 0x30, Octect String 0x04, Array? (0xA0, 0xA1)
// Value Types are Integer 0x02, Bit String 0x03, Null 0x05, Object ID 0x06,
// Container Types are Sequence 0x30, Container Array? (0xA0, 0xA1)
// Value Types are Integer 0x02, Null 0x05, Object ID 0x06, Value Array? (0x82)
// Bit String (0x03) and Octet String (0x04) may be values or containers
// Sometimes Bit String is used as a container (RSA Pub Spki)
ASN1.CTYPES = [ 0x30, 0x31, 0xa0, 0xa1 ];
ASN1.VTYPES = [ 0x02, 0x05, 0x06, 0x82 ];
ASN1.parse = function parseAsn1(buf, depth, ws) {
if (!ws) { ws = ''; }
if (!depth) { depth = 0; }
@ -81,23 +83,21 @@ ASN1.parse = function parseAsn1(buf, depth, ws) {
return asn1;
}
// We want to fail if we know for sure that it's bad
if (-1 !== ASN1.CTYPES.indexOf(asn1.type)) {
return parseChildren();
}
// Recurse into types that are _always_ containers
if (-1 !== ASN1.CTYPES.indexOf(asn1.type)) { return parseChildren(); }
// Return types that are _always_ values
asn1.value = buf.slice(index, index + adjustedLen);
try {
return parseChildren(true);
} catch(e) {
// leaving iterable array as a matter of convenience
asn1.children = [];
return asn1;
}
if (-1 !== ASN1.VTYPES.indexOf(asn1.type)) { return asn1; }
// For ambigious / unknown types, recurse and return on failure
// (and return child array size to zero)
try { return parseChildren(true); }
catch(e) { asn1.children.length = 0; return asn1; }
};
ASN1._replacer = function (k, v) {
if ('type' === k) { return '0x' + Enc.numToHex(v); }
if ('value' === k) { return '0x' + Enc.bufToHex(v.data || v); }
if (v && 'value' === k) { return '0x' + Enc.bufToHex(v.data || v); }
return v;
};

View File

@ -26,10 +26,9 @@ rMjgyCokrnjDft6Y/YnA4A50yZe7CnFsqeDcpnPbubP6cpYiVcnevNIYyg==
var $input = document.querySelector('.js-input');
function convert() {
console.log('change');
console.log('keyup');
var pem = PEM.parseBlock(document.querySelector('.js-input').value);
var hex = Enc.bufToHex(pem.der);
console.log(hex);
document.querySelector('.js-hex').innerText = hex
.match(/.{2}/g).join(' ').match(/.{1,24}/g).join(' ').match(/.{1,50}/g).join('\n');
var json = ASN1.parse(pem.der);

View File

@ -1,6 +1,6 @@
{
"name": "asn1-parser",
"version": "1.0.2",
"version": "1.1.0",
"description": "An ASN.1 parser in less than 100 lines of Vanilla JavaScript, part of the Bluecrypt suite.",
"homepage": "https://git.coolaj86.com/coolaj86/asn1-parser.js",
"main": "asn1-parser.js",