JavaScript generic ASN.1 parser (mirror)
at github-64 2.4 kB view raw
1#!/usr/bin/env node 2'use strict'; 3 4const 5 fs = require('fs'), 6 Base64 = require('./base64'), 7 ASN1 = require('./asn1'), 8 Defs = require('./defs'), 9 colYellow = '\x1b[33m', 10 colBlue = '\x1b[34m', 11 colReset = '\x1b[0m'; 12 13function print(value, indent) { 14 if (indent === undefined) indent = ''; 15 const def = value.def; 16 let name = ''; 17 if (def?.type) { 18 if (def.id) name += colBlue + def.id + colReset; 19 if (typeof def.type == 'object' && def.name) name = (name ? name + ' ' : '') + def.name; 20 if (def.mismatch) name = (name ? name + ' ' : '') + '[?]'; 21 if (name) name += ' '; 22 } 23 let s = indent + name + colYellow + value.typeName() + colReset + ' @' + value.stream.pos; 24 if (value.length >= 0) 25 s += '+'; 26 s += value.length; 27 if (value.tag.tagConstructed) 28 s += ' (constructed)'; 29 else if ((value.tag.isUniversal() && ((value.tag.tagNumber == 0x03) || (value.tag.tagNumber == 0x04))) && (value.sub !== null)) 30 s += ' (encapsulates)'; 31 let content = value.content(); 32 if (content) 33 s += ': ' + content.replace(/\n/g, '|'); 34 s += '\n'; 35 if (value.sub !== null) { 36 indent += ' '; 37 for (const subval of value.sub) 38 s += print(subval, indent); 39 } 40 return s; 41} 42 43let content = fs.readFileSync(process.argv[2]); 44try { // try PEM first 45 content = Base64.unarmor(content); 46} catch (e) { // try DER/BER then 47} 48let result = ASN1.decode(content); 49content = null; 50const t0 = performance.now(); 51const types = Defs.commonTypes 52 .map(type => { 53 const stats = Defs.match(result, type); 54 return { type, match: stats.recognized / stats.total }; 55 }) 56 .sort((a, b) => b.match - a.match); 57const t1 = performance.now(); 58console.log('Parsed in ' + (t1 - t0).toFixed(2) + ' ms; possible types:'); 59for (const t of types) 60 console.log((t.match * 100).toFixed(2).padStart(6) + '% ' + t.type.description); 61Defs.match(result, types[0].type); 62// const stats = Defs.match(result, types[0].type); 63// console.log('Stats:', stats); 64console.log('Parsed as:', result.def); 65// const type = searchType(process.argv[2]); 66// const stats = applyDef(result, type); 67console.log(print(result)); 68// console.log('Stats:', (stats.recognized * 100 / stats.total).toFixed(2) + '%'); 69// // print(result, searchType(process.argv[2]), stats); 70// // console.log('Defs:', stats.defs);