From e495fbc88c4f651939667a24baccd032dd247128 Mon Sep 17 00:00:00 2001 From: Lapo Luchini Date: Fri, 24 Mar 2023 18:01:05 +0000 Subject: [PATCH] Improve support for type recognition. Add `[?]` marker for mismatched types. --- defs.js | 22 +++++++++++++++------- dom.js | 4 ++++ dumpASN1.js | 4 +++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/defs.js b/defs.js index 3c3b1cf..2a85ef1 100644 --- a/defs.js +++ b/defs.js @@ -22,7 +22,6 @@ const rfc = require('./rfcdef'); function translate(def, tn) { - const id = def?.id; if (def?.type == 'tag' && !def.explicit) // def.type = def.content[0].type; def = def.content[0].type; @@ -41,6 +40,7 @@ function translate(def, tn) { } } } + const id = def?.id; if (id) def = Object.assign({}, def, { id }); return def ?? { type: {} }; @@ -68,12 +68,16 @@ class Defs { static match(value, def, stats = { total: 0, recognized: 0, defs: {} }) { value.def = {}; - let tn = value.typeName(); + let tn = value.typeName().replaceAll('_', ' '); def = translate(def, tn); ++stats.total; if (def?.type) { + // if (def.id || def.name) ++stats.recognized; + if (tn == def.type.name || tn == def.name || def.name == 'ANY') + ++stats.recognized; + else if (def.name) + def = Object.assign({ mismatch: 1 }, def); value.def = def; - if (def.id || def.name) ++stats.recognized; } if (value.sub !== null) { if (def?.type?.type) @@ -85,16 +89,19 @@ class Defs { if (def.typeOf) type = def.content[0]; else { - let tn = subval.typeName(); //.replaceAll('_', ' '); + let tn = subval.typeName().replaceAll('_', ' '); do { type = def.content[j++]; // type = translate(type, tn); if (type?.type?.type) type = type.type; } while (type && ('optional' in type || 'default' in type) && type.name != 'ANY' && type.name != tn); - if (type?.type == 'defined') - stats.defs[type.id] = subval.content().split(/\n/); - else if (type?.definedBy && stats.defs?.[type.definedBy]?.[1]) // hope current OIDs contain the type name (will need to parse from RFC itself) + if (type?.type == 'builtin' || type?.type == 'defined') { + let v = subval.content(); + if (typeof v == 'string') + v = v.split(/\n/); + stats.defs[type.id] = v; + } else if (type?.definedBy && stats.defs?.[type.definedBy]?.[1]) // hope current OIDs contain the type name (will need to parse from RFC itself) type = Defs.searchType(firstUpper(stats.defs[type.definedBy][1])); } } @@ -112,6 +119,7 @@ Defs.commonTypes = [ [ 'X.509 certificate', '1.3.6.1.5.5.7.0.18', 'Certificate' ], [ 'CMS / PKCS#7 envelope', '1.2.840.113549.1.9.16.0.14', 'ContentInfo' ], [ 'PKCS#8 encrypted private key', '1.2.840.113549.1.8.1.1', 'EncryptedPrivateKeyInfo' ], + [ 'PKCS#8 private key', '1.2.840.113549.1.8.1.1', 'PrivateKeyInfo' ], ].map(arr => ({ description: arr[0], ...Defs.moduleAndType(rfc[arr[1]], arr[2]) })); return Defs; diff --git a/dom.js b/dom.js index aef4c74..f065571 100644 --- a/dom.js +++ b/dom.js @@ -74,6 +74,10 @@ class ASN1DOM extends ASN1 { head.appendChild(DOM.tag('span', 'name type', this.def.name)); head.appendChild(DOM.space()); } + if (this.def.mismatch) { + head.appendChild(DOM.tag('span', 'name type', '[?]')); + head.appendChild(DOM.space()); + } } head.appendChild(DOM.text(typeName)); let content = this.content(contentLength); diff --git a/dumpASN1.js b/dumpASN1.js index c67531d..d43872f 100755 --- a/dumpASN1.js +++ b/dumpASN1.js @@ -17,6 +17,7 @@ function print(value, indent) { if (def?.type) { if (def.id) name += colBlue + def.id + colReset; if (typeof def.type == 'object' && def.name) name = (name ? name + ' ' : '') + def.name; + if (def.mismatch) name = (name ? name + ' ' : '') + '[?]'; if (name) name += ' '; } let s = indent + name + colYellow + value.typeName() + colReset + ' @' + value.stream.pos; @@ -57,7 +58,8 @@ const t1 = performance.now(); console.log('Parsed in ' + (t1 - t0).toFixed(2) + ' ms; possible types:'); for (const t of types) console.log((t.match * 100).toFixed(2).padStart(6) + '% ' + t.type.description); -Defs.match(result, types[0].match >= 0.1 ? types[0].type : null); +const stats = Defs.match(result, types[0].match >= 0.1 ? types[0].type : null); +// console.log('Stats:', stats); console.log('Parsed as:', result.def); // const type = searchType(process.argv[2]); // const stats = applyDef(result, type); -- 2.51.2