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);