@pkistudio/asn1defsifter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pkistudio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # ASN.1 Definition Sifter
2
+
3
+ ASN.1 Definition Sifter is an explainable candidate resolver for ASN.1 data. It compares DER/TLV fragments with a corpus of ASN.1 definitions and returns ranked ASN.1 type candidates with scores, evidence, diagnostics, and ambiguity notes.
4
+
5
+ It does not try to magically identify one globally unique ASN.1 definition from DER bytes alone. DER does not preserve field names, type names, module names, comments, or many other schema-level semantics. This package instead provides deterministic local matches that higher-level tools and AI agents can use when building ASN.1 type hypotheses.
6
+
7
+ Current version: 0.1.0
8
+
9
+ Hosted viewer: https://pkistudio.github.io/asn1defsifter/
10
+
11
+ ## Features
12
+
13
+ - Neutral TLV node model for resolver core inputs.
14
+ - Structural feature extraction for tag class, tag number, constructed state, child tag sequence, OID values, and primitive value kind.
15
+ - ASN.1 Schema Model matching through `@pkistudio/asn1instancebuilder` definitions.
16
+ - Candidate ranking with numeric scores, confidence labels, evidence, diagnostics, ambiguity notes, and matched node/schema paths.
17
+ - PkiStudioJS adapter for parsing supported ASN.1 inputs into resolver-ready TLV nodes.
18
+ - Built-in PKI component corpus for common fragments such as `AlgorithmIdentifier`, `SubjectPublicKeyInfo`, `RSAPublicKey`, `DSA-Sig-Value`, `ECDSA-Sig-Value`, `SignatureValue`, EC named-curve parameters, `Certificate`, `CertificationRequest`, `PrivateKeyInfo`, and `ContentInfo`.
19
+ - PKI-aware semantic filtering for ambiguous structures, including RFC 8017 `RSAPublicKey` shape checks and signature/public-key context filters for integer-pair signatures.
20
+ - Document hypothesis helper with annotated tree output.
21
+
22
+ ## Install
23
+
24
+ ```sh
25
+ npm install @pkistudio/asn1defsifter
26
+ ```
27
+
28
+ Package exports:
29
+
30
+ - `@pkistudio/asn1defsifter`: Core API.
31
+ - `@pkistudio/asn1defsifter/core`: Core API alias.
32
+ - `@pkistudio/asn1defsifter/app`: Standalone viewer app initializer.
33
+ - `@pkistudio/asn1defsifter/styles.css`: Standalone viewer styles.
34
+
35
+ ## Core API
36
+
37
+ ```ts
38
+ import { createPkiComponentCorpus, findAsn1Candidates, parseInputToTlvNodes } from '@pkistudio/asn1defsifter';
39
+
40
+ const corpus = createPkiComponentCorpus();
41
+
42
+ const [node] = await parseInputToTlvNodes('300d06092a864886f70d01010b0500', { format: 'hex' });
43
+ const candidates = findAsn1Candidates(node, { schemaCorpus: corpus, maxResults: 5 });
44
+
45
+ console.log(candidates[0]);
46
+ ```
47
+
48
+ Candidate results include:
49
+
50
+ - `typeName` and optional `moduleName`.
51
+ - `score` from `0` to `1`.
52
+ - `confidence` as `low`, `medium`, or `high`.
53
+ - Human-readable `evidence`.
54
+ - `diagnostics` explaining mismatches or weaker matches.
55
+ - `ambiguities` for structurally plausible alternatives.
56
+ - `matchedPaths` connecting TLV node paths to schema paths.
57
+
58
+ Use `parseAsn1DefinitionCorpus(source)` when you want to match against your own ASN.1 module definitions instead of the built-in PKI component corpus.
59
+
60
+ Pass `minScore` when callers should suppress weak candidates and their diagnostics from candidate lists and reports.
61
+
62
+ Use `includeTypes` and `excludeTypes` to limit candidate matching by type name. Values can be local names such as `SubjectPublicKeyInfo` or qualified names such as `PkiComponents.SubjectPublicKeyInfo`.
63
+
64
+ For the built-in PKI corpus, `getPkiProfileTypeNames()` provides convenient presets for `x509`, `pkcs10`, `pkcs8`, `cms`, and shared `components` matching:
65
+
66
+ ```ts
67
+ import { getPkiProfileTypeNames } from '@pkistudio/asn1defsifter';
68
+
69
+ const candidates = findAsn1Candidates(node, {
70
+ schemaCorpus: corpus,
71
+ includeTypes: getPkiProfileTypeNames(['x509', 'pkcs8'])
72
+ });
73
+ ```
74
+
75
+ For PKI-only report generation, `createPkiCandidateReport()` and `createPkiCandidateReportFromNodes()` apply the built-in PKI corpus automatically:
76
+
77
+ ```ts
78
+ import { createPkiCandidateReport } from '@pkistudio/asn1defsifter';
79
+
80
+ const report = await createPkiCandidateReport(input, {
81
+ profiles: ['x509', 'pkcs8'],
82
+ minScore: 0.8
83
+ });
84
+ ```
85
+
86
+ For agent or workbench integrations, `createCandidateReport()` wraps parsing, feature extraction, candidate ranking, and document hypotheses into one JSON-friendly result:
87
+
88
+ ```ts
89
+ import { createCandidateReport } from '@pkistudio/asn1defsifter';
90
+
91
+ const report = await createCandidateReport('300d06092a864886f70d01010b0500', {
92
+ parseOptions: { format: 'hex' },
93
+ maxResults: 5
94
+ });
95
+
96
+ console.log(report.roots[0].candidates[0]);
97
+ ```
98
+
99
+ Use `createCandidateReportFromNodes(nodes)` when a host already has neutral TLV nodes and should not parse the input again.
100
+
101
+ Each report root includes `summary`, `features`, `candidates`, `hypotheses`, aggregated `diagnostics`, and aggregated `ambiguities`. Hypothesis `annotatedTree` entries include TLV tag names, schema paths, inferred field names, and referenced ASN.1 type names when that information is available from the match.
102
+
103
+ Pass `includeSubtrees: true` to add bounded candidate reports for child TLV nodes. Use `maxSubtreeDepth` and `maxSubtreeReports` to keep report size predictable. Subtree reports omit nodes with no candidates by default; pass `includeEmptySubtrees: true` when exhaustive child-node reporting is needed.
104
+
105
+ ## PKI Matching Notes
106
+
107
+ The built-in PKI corpus includes RFC 8017 `RSAPublicKey`, `DSA-Sig-Value`, and `ECDSA-Sig-Value` definitions. Because DER shape alone cannot always distinguish structurally compatible `SEQUENCE { INTEGER, INTEGER }` values, the PKI report layer applies extra context rules:
108
+
109
+ - `RSAPublicKey` is only kept when the candidate node has the RFC 8017 shape: exactly two positive DER INTEGER values, with a plausible modulus and exponent.
110
+ - `DSA-Sig-Value` and `ECDSA-Sig-Value` are available for integer-pair signature values.
111
+ - `RSAPublicKey` candidates are suppressed below signature BIT STRING contexts, and DSA/ECDSA signature candidates are suppressed below `subjectPublicKey` contexts.
112
+
113
+ These filters keep the resolver deterministic while reducing common PKI false positives.
114
+
115
+ ## Standalone Viewer
116
+
117
+ The package includes a small browser viewer for exercising the resolver without embedding it into another PkiStudio surface. It provides a left pane that is an embedded editable PkiStudioJS viewer, a candidate tree pane, a selected candidate details pane with selected bytes, and a bottom API log pane. Use the PkiStudioJS viewer's own `Load` menu to load data; the resolver watches the loaded and edited viewer document and refreshes candidates from it. Terminal BIT STRING or OCTET STRING values with no ASN.1 candidates are shown as HEX-only tree items so raw key material, such as EC public points, remains inspectable without being mislabeled as another ASN.1 type.
118
+
119
+ The viewer shell uses translucent surfaces and supports light and dark themes. The embedded viewer and candidate panes keep their outer frames visually quiet, while the embedded viewer menu remains framed like the PkiStudio family chrome. Node context menus use an opaque surface so edit, insert, add, delete, send, and copy actions remain readable over the translucent shell. Splitters between the viewer and candidates panes, above selected candidate details, and above the API log let users resize the working areas.
120
+
121
+ Selected candidate details lay out evidence, diagnostics, ambiguities, matched paths, and selected bytes as content-width sections. Non-byte sections keep their lines unwrapped and expand the application minimum width when needed, while `Selected bytes` can wrap and fills the remaining row width or moves to the next row when the remaining space is too narrow.
122
+
123
+ The selected candidate header includes a `Copy` action that writes the currently selected item's analysis result as formatted JSON, including candidate scores, evidence, diagnostics, matched paths, and selected bytes. The copied JSON keeps the original source name when the app knows one, and only falls back to `PkiStudioJS viewer` for viewer-loaded data without a supplied name.
124
+
125
+ The API log records the high-level parse and report operations and then adds one line per root candidate. Candidate log rows include the candidate type, score, confidence, evidence, diagnostic, ambiguity, and matched-path counts, plus representative evidence and diagnostic messages so the ranking work is visible without opening the selected-candidate pane. Embedded viewer edit actions such as edit, insert, add, and delete are also recorded before the changed document is re-read and ranked again.
126
+
127
+ The embedded viewer uses normal PkiStudioJS editing actions. When the viewer document changes, ASN.1 Definition Sifter re-reads the current DER bytes, refreshes candidates, and records the new report in the API log. Its `Send to` menu can still open selected DER in a separate editable PkiStudioJS viewer tab through `viewer.html`. Closing the embedded viewer clears the candidate and selected-candidate panes.
128
+
129
+ ```ts
130
+ import { initAsn1DefinitionSifter } from '@pkistudio/asn1defsifter/app';
131
+ import '@pkistudio/asn1defsifter/styles.css';
132
+
133
+ initAsn1DefinitionSifter({ mount: '#app' });
134
+ ```
135
+
136
+ Run the local viewer with:
137
+
138
+ ```sh
139
+ npm run dev
140
+ ```
141
+
142
+ The hosted viewer is deployed to GitHub Pages by the `Deploy GitHub Pages` workflow. It builds `index.html` and `viewer.html` with `npm run build:pages` and publishes the `pages-dist` artifact.
143
+
144
+ ## Relationship To PkiStudio Projects
145
+
146
+ PkiStudioJS remains the low-level DER/BER/PEM/base64/HEX parser, serializer, viewer, and DER re-encoder. ASN.1 Instance Builder remains the schema-aware definition parser, validator, and DER builder.
147
+
148
+ ASN.1 Definition Sifter sits between them:
149
+
150
+ ```text
151
+ PkiStudioJS
152
+ DER/TLV parsing and encoding
153
+
154
+ ASN.1 Instance Builder
155
+ ASN.1 definition parsing and schema model
156
+
157
+ ASN.1 Definition Sifter
158
+ DER/TLV fragment -> ranked ASN.1 definition candidates
159
+ ```
160
+
161
+ ## Development
162
+
163
+ Run local checks with:
164
+
165
+ ```sh
166
+ npm run check
167
+ npm test
168
+ npm run build
169
+ npm run smoke
170
+ ```
171
+
172
+ The smoke command builds the package and runs a real DER hex fragment through the public API. It should report `PkiComponents.AlgorithmIdentifier` as the best candidate.
173
+
174
+ The CI workflow runs the same verification set on pushes and pull requests targeting `main`.
175
+
176
+ For package or release-related changes, also run:
177
+
178
+ ```sh
179
+ npm run pack:dry-run
180
+ ```
181
+
182
+ Build the GitHub Pages viewer locally with:
183
+
184
+ ```sh
185
+ npm run build:pages
186
+ ```
187
+
188
+ Publishing to npm is handled by the `Publish npm package` GitHub Actions workflow. Configure npm trusted publishing for this repository and workflow, create and push a `v<package version>` tag, then let the tag-triggered workflow publish the package, or run the workflow manually with the same tag. The workflow verifies that the tag matches `package.json`, runs the local verification commands, inspects the package contents, and publishes `@pkistudio/asn1defsifter` with npm provenance.
189
+
190
+ ## License
191
+
192
+ ASN.1 Definition Sifter is licensed under the MIT License. See [LICENSE](LICENSE).
193
+