@ai-dossier/core 1.4.1 → 1.4.2

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/README.md CHANGED
@@ -105,6 +105,9 @@ import {
105
105
  verifyWithEd25519,
106
106
  verifyWithKms,
107
107
  loadTrustedKeys,
108
+ findTrustedIdentifier,
109
+ normalizePublicKey,
110
+ isSupportedPublicKey,
108
111
  } from '@ai-dossier/core';
109
112
  ```
110
113
 
@@ -119,7 +122,7 @@ console.log(result.valid); // true | false
119
122
 
120
123
  #### `verifyWithEd25519(content: string, signature: string, publicKey: string): VerifyResult`
121
124
 
122
- Verify an Ed25519 signature directly.
125
+ Verify an Ed25519 signature directly. `publicKey` may be SPKI PEM, raw 32-byte base64, or base64 SPKI DER.
123
126
 
124
127
  #### `verifyWithKms(content: string, signature: string, keyId: string, region?: string): Promise<VerifyResult>`
125
128
 
@@ -127,7 +130,17 @@ Verify an ECDSA-SHA-256 signature using AWS KMS.
127
130
 
128
131
  #### `loadTrustedKeys(filePath?: string): Map<string, string>`
129
132
 
130
- Load trusted public keys from a file (default: `~/.dossier/trusted-keys.txt`). Returns a map of public key to key ID.
133
+ Load trusted public keys from a file (default: `~/.dossier/trusted-keys.txt`), format `<public-key> <identifier>` one per line. Returns a map of public key to identifier, indexed under both the written and the normalized form. Unreadable lines are reported to stderr, not dropped silently.
134
+
135
+ #### `findTrustedIdentifier(trustedKeys, signature): string | undefined`
136
+
137
+ Resolve the identifier a signature is trusted under. Use this rather than probing the map by hand — it consults `key_id` only when there is no `public_key`, which is what stops a dossier from claiming a trusted signer's identity while verifying under a different key.
138
+
139
+ #### `normalizePublicKey(key) / isSupportedPublicKey(key)`
140
+
141
+ Reduce an Ed25519 key to its canonical raw 32-byte base64 form, and test whether a key is one this project can verify against. Validate with `isSupportedPublicKey` before *storing* a key: `normalizePublicKey` deliberately passes uninterpretable input through.
142
+
143
+ See [core API reference](../../docs/reference/core-api.md#key-format-and-trust-file-helpers) for the full trust-file helper set.
131
144
 
132
145
  ### Linting
133
146
 
package/dist/index.d.ts CHANGED
@@ -20,10 +20,11 @@ export type { ChecksumStatus, ContentRiskResult, SignatureStatus, VerificationRi
20
20
  export { assessContentRisk, assessVerificationRisk } from './risk-assessment';
21
21
  export type { SecurityCategory, SecurityFinding, SecurityReport, SecurityRule, SecurityRuleContext, SecurityRuleSeverityOverride, SecurityScanConfig, SecuritySeverity, } from './security-scanner';
22
22
  export { buildReport, defaultSecurityRules, SecurityRuleRegistry, scanDossier, scanDossierFile, scanMarkdown, } from './security-scanner';
23
- export { loadTrustedKeys, verifySignature, verifyWithEd25519, verifyWithKms } from './signature';
23
+ export type { TrustedKeyEntry, TrustedKeyProblem } from './signature';
24
+ export { findTrustedIdentifier, isKmsKeyIdentifier, loadTrustedKeys, parseTrustedKeys, reportTrustedKeyProblems, trustedKeysFromContent, verifySignature, verifyWithEd25519, verifyWithKms, } from './signature';
24
25
  export { Ed25519Signer, Ed25519Verifier, getVerifierRegistry, KmsSigner, KmsVerifier, SignatureResult, Signer, Verifier, VerifierRegistry, VerifyResult, } from './signers';
25
26
  export type { SignatureCoverage } from './signing-payload';
26
- export { buildSignedPayload, canonicalizeFrontmatter, normalizePublicKey, publicKeysMatch, signatureCoverage, toSpkiPem, } from './signing-payload';
27
+ export { buildSignedPayload, canonicalizeFrontmatter, isSupportedPublicKey, normalizePublicKey, publicKeysMatch, signatureCoverage, toSpkiPem, } from './signing-payload';
27
28
  export type { ConfigLayer as TraceConfigLayer, ResolvedTraceConfig, TraceConfigOptions, TraceConfigSource, } from './trace-config';
28
29
  export { resolveTraceConfig } from './trace-config';
29
30
  export type { DossierTraceInfo, StepInput as TraceStepInput, TraceInput, TraceRecorder, TraceRecorderOptions, TraceStatus, TraceUpdate, } from './trace-recorder';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -24,8 +24,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
24
24
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
25
25
  };
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.readFileIfExists = exports.getErrorStack = exports.getErrorMessage = exports.sha256Hex = exports.sha256Hash = exports.VALID_TRACE_STATUSES = exports.createTraceRecorder = exports.resolveTraceConfig = exports.toSpkiPem = exports.signatureCoverage = exports.publicKeysMatch = exports.normalizePublicKey = exports.canonicalizeFrontmatter = exports.buildSignedPayload = exports.VerifierRegistry = exports.KmsVerifier = exports.KmsSigner = exports.getVerifierRegistry = exports.Ed25519Verifier = exports.Ed25519Signer = exports.verifyWithKms = exports.verifyWithEd25519 = exports.verifySignature = exports.loadTrustedKeys = exports.scanMarkdown = exports.scanDossierFile = exports.scanDossier = exports.SecurityRuleRegistry = exports.defaultSecurityRules = exports.buildReport = exports.assessVerificationRisk = exports.assessContentRisk = exports.validateFrontmatter = exports.VALID_STATUSES = exports.VALID_RISK_LEVELS = exports.REQUIRED_FIELDS = exports.RECOMMENDED_FIELDS = exports.parseDossierFile = exports.parseDossierContent = exports.loadLintConfig = exports.lintDossierFile = exports.lintDossier = exports.LintRuleRegistry = exports.defaultRules = exports.formatDossierFile = exports.formatDossierContent = exports.validateStepCoherence = exports.validateCoherence = exports.verifyIntegrity = exports.calculateChecksum = void 0;
28
- exports.createDefaultVerificationResult = exports.scanBodyForUrls = exports.isUrlCoveredByDeclared = exports.isPlaceholderUrl = exports.findUndeclaredUrls = exports.findStaleReferences = exports.collectDeclaredUrls = void 0;
27
+ exports.createTraceRecorder = exports.resolveTraceConfig = exports.toSpkiPem = exports.signatureCoverage = exports.publicKeysMatch = exports.normalizePublicKey = exports.isSupportedPublicKey = exports.canonicalizeFrontmatter = exports.buildSignedPayload = exports.VerifierRegistry = exports.KmsVerifier = exports.KmsSigner = exports.getVerifierRegistry = exports.Ed25519Verifier = exports.Ed25519Signer = exports.verifyWithKms = exports.verifyWithEd25519 = exports.verifySignature = exports.trustedKeysFromContent = exports.reportTrustedKeyProblems = exports.parseTrustedKeys = exports.loadTrustedKeys = exports.isKmsKeyIdentifier = exports.findTrustedIdentifier = exports.scanMarkdown = exports.scanDossierFile = exports.scanDossier = exports.SecurityRuleRegistry = exports.defaultSecurityRules = exports.buildReport = exports.assessVerificationRisk = exports.assessContentRisk = exports.validateFrontmatter = exports.VALID_STATUSES = exports.VALID_RISK_LEVELS = exports.REQUIRED_FIELDS = exports.RECOMMENDED_FIELDS = exports.parseDossierFile = exports.parseDossierContent = exports.loadLintConfig = exports.lintDossierFile = exports.lintDossier = exports.LintRuleRegistry = exports.defaultRules = exports.formatDossierFile = exports.formatDossierContent = exports.validateStepCoherence = exports.validateCoherence = exports.verifyIntegrity = exports.calculateChecksum = void 0;
28
+ exports.createDefaultVerificationResult = exports.scanBodyForUrls = exports.isUrlCoveredByDeclared = exports.isPlaceholderUrl = exports.findUndeclaredUrls = exports.findStaleReferences = exports.collectDeclaredUrls = exports.readFileIfExists = exports.getErrorStack = exports.getErrorMessage = exports.sha256Hex = exports.sha256Hash = exports.VALID_TRACE_STATUSES = void 0;
29
29
  // Checksum exports
30
30
  var checksum_1 = require("./checksum");
31
31
  Object.defineProperty(exports, "calculateChecksum", { enumerable: true, get: function () { return checksum_1.calculateChecksum; } });
@@ -64,9 +64,13 @@ Object.defineProperty(exports, "SecurityRuleRegistry", { enumerable: true, get:
64
64
  Object.defineProperty(exports, "scanDossier", { enumerable: true, get: function () { return security_scanner_1.scanDossier; } });
65
65
  Object.defineProperty(exports, "scanDossierFile", { enumerable: true, get: function () { return security_scanner_1.scanDossierFile; } });
66
66
  Object.defineProperty(exports, "scanMarkdown", { enumerable: true, get: function () { return security_scanner_1.scanMarkdown; } });
67
- // Signature exports
68
67
  var signature_1 = require("./signature");
68
+ Object.defineProperty(exports, "findTrustedIdentifier", { enumerable: true, get: function () { return signature_1.findTrustedIdentifier; } });
69
+ Object.defineProperty(exports, "isKmsKeyIdentifier", { enumerable: true, get: function () { return signature_1.isKmsKeyIdentifier; } });
69
70
  Object.defineProperty(exports, "loadTrustedKeys", { enumerable: true, get: function () { return signature_1.loadTrustedKeys; } });
71
+ Object.defineProperty(exports, "parseTrustedKeys", { enumerable: true, get: function () { return signature_1.parseTrustedKeys; } });
72
+ Object.defineProperty(exports, "reportTrustedKeyProblems", { enumerable: true, get: function () { return signature_1.reportTrustedKeyProblems; } });
73
+ Object.defineProperty(exports, "trustedKeysFromContent", { enumerable: true, get: function () { return signature_1.trustedKeysFromContent; } });
70
74
  Object.defineProperty(exports, "verifySignature", { enumerable: true, get: function () { return signature_1.verifySignature; } });
71
75
  Object.defineProperty(exports, "verifyWithEd25519", { enumerable: true, get: function () { return signature_1.verifyWithEd25519; } });
72
76
  Object.defineProperty(exports, "verifyWithKms", { enumerable: true, get: function () { return signature_1.verifyWithKms; } });
@@ -81,6 +85,7 @@ Object.defineProperty(exports, "VerifierRegistry", { enumerable: true, get: func
81
85
  var signing_payload_1 = require("./signing-payload");
82
86
  Object.defineProperty(exports, "buildSignedPayload", { enumerable: true, get: function () { return signing_payload_1.buildSignedPayload; } });
83
87
  Object.defineProperty(exports, "canonicalizeFrontmatter", { enumerable: true, get: function () { return signing_payload_1.canonicalizeFrontmatter; } });
88
+ Object.defineProperty(exports, "isSupportedPublicKey", { enumerable: true, get: function () { return signing_payload_1.isSupportedPublicKey; } });
84
89
  Object.defineProperty(exports, "normalizePublicKey", { enumerable: true, get: function () { return signing_payload_1.normalizePublicKey; } });
85
90
  Object.defineProperty(exports, "publicKeysMatch", { enumerable: true, get: function () { return signing_payload_1.publicKeysMatch; } });
86
91
  Object.defineProperty(exports, "signatureCoverage", { enumerable: true, get: function () { return signing_payload_1.signatureCoverage; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;AAEH,mBAAmB;AACnB,uCAAgE;AAAvD,6GAAA,iBAAiB,OAAA;AAAE,2GAAA,eAAe,OAAA;AAU3C,yCAAuE;AAA9D,8GAAA,iBAAiB,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAEjD,oBAAoB;AACpB,yCAAsE;AAA7D,iHAAA,oBAAoB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAUhD,iBAAiB;AACjB,mCAMkB;AALhB,sGAAA,YAAY,OAAA;AACZ,0GAAA,gBAAgB,OAAA;AAChB,qGAAA,WAAW,OAAA;AACX,yGAAA,eAAe,OAAA;AACf,wGAAA,cAAc,OAAA;AAEhB,iBAAiB;AACjB,mCAQkB;AAPhB,6GAAA,mBAAmB,OAAA;AACnB,0GAAA,gBAAgB,OAAA;AAChB,4GAAA,kBAAkB,OAAA;AAClB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,6GAAA,mBAAmB,OAAA;AASrB,0BAA0B;AAC1B,qDAA8E;AAArE,oHAAA,iBAAiB,OAAA;AAAE,yHAAA,sBAAsB,OAAA;AAYlD,uDAO4B;AAN1B,+GAAA,WAAW,OAAA;AACX,wHAAA,oBAAoB,OAAA;AACpB,wHAAA,oBAAoB,OAAA;AACpB,+GAAA,WAAW,OAAA;AACX,mHAAA,eAAe,OAAA;AACf,gHAAA,YAAY,OAAA;AAEd,oBAAoB;AACpB,yCAAiG;AAAxF,4GAAA,eAAe,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,0GAAA,aAAa,OAAA;AAC3E,iDAAiD;AACjD,qCAWmB;AAVjB,wGAAA,aAAa,OAAA;AACb,0GAAA,eAAe,OAAA;AACf,8GAAA,mBAAmB,OAAA;AACnB,oGAAA,SAAS,OAAA;AACT,sGAAA,WAAW,OAAA;AAIX,2GAAA,gBAAgB,OAAA;AAKlB,qDAO2B;AANzB,qHAAA,kBAAkB,OAAA;AAClB,0HAAA,uBAAuB,OAAA;AACvB,qHAAA,kBAAkB,OAAA;AAClB,kHAAA,eAAe,OAAA;AACf,oHAAA,iBAAiB,OAAA;AACjB,4GAAA,SAAS,OAAA;AASX,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAW3B,mDAA6E;AAApE,qHAAA,mBAAmB,OAAA;AAAE,sHAAA,oBAAoB,OAAA;AAClD,eAAe;AACf,0CAAwB;AACxB,mBAAmB;AACnB,yCAAuD;AAA9C,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC9B,kBAAkB;AAClB,yCAAgE;AAAvD,yGAAA,eAAe,OAAA;AAAE,uGAAA,aAAa,OAAA;AACvC,wBAAwB;AACxB,iCAA8C;AAArC,sGAAA,gBAAgB,OAAA;AACzB,yBAAyB;AACzB,mDAO6B;AAN3B,kHAAA,mBAAmB,OAAA;AACnB,kHAAA,mBAAmB,OAAA;AACnB,iHAAA,kBAAkB,OAAA;AAClB,+GAAA,gBAAgB,OAAA;AAChB,qHAAA,sBAAsB,OAAA;AACtB,8GAAA,eAAe,OAAA;AAEjB,yBAAyB;AACzB,qDAAuE;AAA9D,+HAAA,+BAA+B,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;AAEH,mBAAmB;AACnB,uCAAgE;AAAvD,6GAAA,iBAAiB,OAAA;AAAE,2GAAA,eAAe,OAAA;AAU3C,yCAAuE;AAA9D,8GAAA,iBAAiB,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAEjD,oBAAoB;AACpB,yCAAsE;AAA7D,iHAAA,oBAAoB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAUhD,iBAAiB;AACjB,mCAMkB;AALhB,sGAAA,YAAY,OAAA;AACZ,0GAAA,gBAAgB,OAAA;AAChB,qGAAA,WAAW,OAAA;AACX,yGAAA,eAAe,OAAA;AACf,wGAAA,cAAc,OAAA;AAEhB,iBAAiB;AACjB,mCAQkB;AAPhB,6GAAA,mBAAmB,OAAA;AACnB,0GAAA,gBAAgB,OAAA;AAChB,4GAAA,kBAAkB,OAAA;AAClB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,6GAAA,mBAAmB,OAAA;AASrB,0BAA0B;AAC1B,qDAA8E;AAArE,oHAAA,iBAAiB,OAAA;AAAE,yHAAA,sBAAsB,OAAA;AAYlD,uDAO4B;AAN1B,+GAAA,WAAW,OAAA;AACX,wHAAA,oBAAoB,OAAA;AACpB,wHAAA,oBAAoB,OAAA;AACpB,+GAAA,WAAW,OAAA;AACX,mHAAA,eAAe,OAAA;AACf,gHAAA,YAAY,OAAA;AAId,yCAUqB;AATnB,kHAAA,qBAAqB,OAAA;AACrB,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,6GAAA,gBAAgB,OAAA;AAChB,qHAAA,wBAAwB,OAAA;AACxB,mHAAA,sBAAsB,OAAA;AACtB,4GAAA,eAAe,OAAA;AACf,8GAAA,iBAAiB,OAAA;AACjB,0GAAA,aAAa,OAAA;AAEf,iDAAiD;AACjD,qCAWmB;AAVjB,wGAAA,aAAa,OAAA;AACb,0GAAA,eAAe,OAAA;AACf,8GAAA,mBAAmB,OAAA;AACnB,oGAAA,SAAS,OAAA;AACT,sGAAA,WAAW,OAAA;AAIX,2GAAA,gBAAgB,OAAA;AAKlB,qDAQ2B;AAPzB,qHAAA,kBAAkB,OAAA;AAClB,0HAAA,uBAAuB,OAAA;AACvB,uHAAA,oBAAoB,OAAA;AACpB,qHAAA,kBAAkB,OAAA;AAClB,kHAAA,eAAe,OAAA;AACf,oHAAA,iBAAiB,OAAA;AACjB,4GAAA,SAAS,OAAA;AASX,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAW3B,mDAA6E;AAApE,qHAAA,mBAAmB,OAAA;AAAE,sHAAA,oBAAoB,OAAA;AAClD,eAAe;AACf,0CAAwB;AACxB,mBAAmB;AACnB,yCAAuD;AAA9C,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC9B,kBAAkB;AAClB,yCAAgE;AAAvD,yGAAA,eAAe,OAAA;AAAE,uGAAA,aAAa,OAAA;AACvC,wBAAwB;AACxB,iCAA8C;AAArC,sGAAA,gBAAgB,OAAA;AACzB,yBAAyB;AACzB,mDAO6B;AAN3B,kHAAA,mBAAmB,OAAA;AACnB,kHAAA,mBAAmB,OAAA;AACnB,iHAAA,kBAAkB,OAAA;AAClB,+GAAA,gBAAgB,OAAA;AAChB,qHAAA,sBAAsB,OAAA;AACtB,8GAAA,eAAe,OAAA;AAEjB,yBAAyB;AACzB,qDAAuE;AAA9D,+HAAA,+BAA+B,OAAA"}
@@ -5,12 +5,99 @@
5
5
  * supporting multiple signature schemes (Ed25519 and AWS KMS).
6
6
  */
7
7
  import type { SignatureResult, VerifyResult } from './signers';
8
+ /** One `<public-key> <key-id>` entry from a trusted-keys file, as written. */
9
+ export interface TrustedKeyEntry {
10
+ publicKey: string;
11
+ keyId: string;
12
+ }
13
+ /**
14
+ * A line of a trusted-keys file that could not be read as an entry.
15
+ *
16
+ * Reported rather than silently dropped: a skipped entry means a key the user
17
+ * believes is trusted is not, and the only downstream symptom is `dossier verify`
18
+ * saying "not trusted" with nothing pointing back at the file.
19
+ */
20
+ export interface TrustedKeyProblem {
21
+ /** 1-based line number in the trusted-keys file. */
22
+ line: number;
23
+ message: string;
24
+ }
25
+ /**
26
+ * Split a trusted-keys file into `<public-key> <key-id>` pairs.
27
+ *
28
+ * One entry per line, except for PEM blocks: `dossier keys add` used to write its
29
+ * argument verbatim, so passing a PEM appended four lines that a line-oriented
30
+ * parse then shredded into entries matching nothing. Those blocks are rejoined so
31
+ * an already written file works without hand-editing — this only reassembles what
32
+ * the user wrote, it cannot widen a match.
33
+ *
34
+ * This is the single definition of what the trusted-key file format is: anything
35
+ * that lists, counts, or matches trusted keys must go through it, so `keys list`
36
+ * can never disagree with what verification actually trusts.
37
+ *
38
+ * Skipped lines come back alongside the entries rather than being dropped: every
39
+ * skip is a key the user thinks is trusted and isn't, so callers that can show
40
+ * the user something — `keys list`, and verification via `loadTrustedKeys` —
41
+ * report them instead of failing mute.
42
+ */
43
+ export declare function parseTrustedKeys(content: string): {
44
+ entries: TrustedKeyEntry[];
45
+ problems: TrustedKeyProblem[];
46
+ };
47
+ /**
48
+ * Print unusable trusted-key entries to stderr, bounded.
49
+ *
50
+ * `loadTrustedKeys` runs on every `dossier verify`, so this stays silent unless
51
+ * the file is genuinely malformed — and a malformed trust file is precisely when
52
+ * the user needs to hear about it.
53
+ */
54
+ export declare function reportTrustedKeyProblems(problems: TrustedKeyProblem[], source?: string): void;
55
+ /**
56
+ * Build the trusted-key map from the contents of a trusted-keys file.
57
+ *
58
+ * Keys are indexed under both the form they were written in and their normalized
59
+ * form, so a key registered in one encoding still matches a signature that
60
+ * carries another.
61
+ *
62
+ * @param source - Path named in warnings about unusable entries. Omit to stay silent.
63
+ */
64
+ export declare function trustedKeysFromContent(content: string, source?: string): Map<string, string>;
8
65
  /**
9
66
  * Load trusted keys from file
10
67
  * Default location: ~/.dossier/trusted-keys.txt
11
68
  * Format: <public-key> <key-id>
12
69
  */
13
70
  export declare function loadTrustedKeys(filePath?: string): Map<string, string>;
71
+ /**
72
+ * Whether a string identifies an AWS KMS key, and so is a usable trust-list entry
73
+ * for a KMS-signed dossier.
74
+ */
75
+ export declare function isKmsKeyIdentifier(value: string): boolean;
76
+ /**
77
+ * Resolve the identifier a signature is trusted under, or `undefined` if none of
78
+ * its key forms appear in the trust list.
79
+ *
80
+ * The signature and the trust list need not agree on encoding, so every form the
81
+ * *verifying* key carries is tried: the public key as written and normalized to
82
+ * raw base64. Every trust decision goes through here so "is it trusted" and "who
83
+ * is it" can never drift apart.
84
+ *
85
+ * Only the key material the verifier actually used is eligible, which is decided
86
+ * by the algorithm, not by which fields happen to be populated. `KmsVerifier`
87
+ * verifies against `key_id` and ignores `public_key` — which KMS signatures carry
88
+ * anyway — so for KMS only `key_id` can confer trust. Everything else verifies
89
+ * against `public_key`, so only that may.
90
+ *
91
+ * Letting a field the verifier ignored confer trust would hand it out for free:
92
+ * the trust list is keyed by public key and public keys are public, so an Ed25519
93
+ * dossier carrying `key_id: "<any trusted public key>"` would be trusted as that
94
+ * signer while verifying under an attacker's `public_key`.
95
+ */
96
+ export declare function findTrustedIdentifier(trustedKeys: Map<string, string>, signature: {
97
+ algorithm?: string;
98
+ key_id?: string;
99
+ public_key?: string;
100
+ }): string | undefined;
14
101
  /**
15
102
  * Verify signature using Ed25519
16
103
  * @param content - The content to verify
@@ -1 +1 @@
1
- {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAM/D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsCtE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,YAAY,CAkBd;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,SAAc,GACnB,OAAO,CAAC,YAAY,CAAC,CAsBvB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAIvB"}
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAM/D,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IACjD,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B,CAsEA;AAKD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAgB7F;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB5F;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKtE;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,SAAS,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE,MAAM,GAAG,SAAS,CAkBpB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,YAAY,CAkBd;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,SAAc,GACnB,OAAO,CAAC,YAAY,CAAC,CAsBvB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAIvB"}
package/dist/signature.js CHANGED
@@ -6,7 +6,12 @@
6
6
  * supporting multiple signature schemes (Ed25519 and AWS KMS).
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.parseTrustedKeys = parseTrustedKeys;
10
+ exports.reportTrustedKeyProblems = reportTrustedKeyProblems;
11
+ exports.trustedKeysFromContent = trustedKeysFromContent;
9
12
  exports.loadTrustedKeys = loadTrustedKeys;
13
+ exports.isKmsKeyIdentifier = isKmsKeyIdentifier;
14
+ exports.findTrustedIdentifier = findTrustedIdentifier;
10
15
  exports.verifyWithEd25519 = verifyWithEd25519;
11
16
  exports.verifyWithKms = verifyWithKms;
12
17
  exports.verifySignature = verifySignature;
@@ -18,6 +23,141 @@ const signers_1 = require("./signers");
18
23
  const signing_payload_1 = require("./signing-payload");
19
24
  const crypto_1 = require("./utils/crypto");
20
25
  const fs_1 = require("./utils/fs");
26
+ /** Whether a line reads as an entry in its own right. */
27
+ function looksLikeKeyEntry(line) {
28
+ const parts = line.trim().split(/\s+/);
29
+ return parts.length >= 2 && (0, signing_payload_1.isSupportedPublicKey)(parts[0]);
30
+ }
31
+ /**
32
+ * Split a trusted-keys file into `<public-key> <key-id>` pairs.
33
+ *
34
+ * One entry per line, except for PEM blocks: `dossier keys add` used to write its
35
+ * argument verbatim, so passing a PEM appended four lines that a line-oriented
36
+ * parse then shredded into entries matching nothing. Those blocks are rejoined so
37
+ * an already written file works without hand-editing — this only reassembles what
38
+ * the user wrote, it cannot widen a match.
39
+ *
40
+ * This is the single definition of what the trusted-key file format is: anything
41
+ * that lists, counts, or matches trusted keys must go through it, so `keys list`
42
+ * can never disagree with what verification actually trusts.
43
+ *
44
+ * Skipped lines come back alongside the entries rather than being dropped: every
45
+ * skip is a key the user thinks is trusted and isn't, so callers that can show
46
+ * the user something — `keys list`, and verification via `loadTrustedKeys` —
47
+ * report them instead of failing mute.
48
+ */
49
+ function parseTrustedKeys(content) {
50
+ const entries = [];
51
+ const problems = [];
52
+ const lines = content.split('\n');
53
+ for (let i = 0; i < lines.length; i++) {
54
+ const line = lines[i].trim();
55
+ if (!line || line.startsWith('#')) {
56
+ continue;
57
+ }
58
+ if (!line.startsWith('-----BEGIN')) {
59
+ const parts = line.split(/\s+/);
60
+ if (parts.length >= 2) {
61
+ entries.push({ publicKey: parts[0], keyId: parts.slice(1).join(' ') });
62
+ }
63
+ else {
64
+ problems.push({
65
+ line: i + 1,
66
+ message: 'public key has no identifier — expected "<public-key> <identifier>"',
67
+ });
68
+ }
69
+ continue;
70
+ }
71
+ const blockStart = i;
72
+ const block = [line];
73
+ while (i + 1 < lines.length && !block[block.length - 1].includes('-----END')) {
74
+ i++;
75
+ block.push(lines[i].trim());
76
+ }
77
+ // The identifier trails the END marker, or sits on the next line when the
78
+ // PEM carried its own trailing newline.
79
+ const endLine = block[block.length - 1];
80
+ const endMarker = /-----END [^-]*-----/.exec(endLine);
81
+ if (!endMarker) {
82
+ // The scan above ran to end-of-file looking for the END marker, so every
83
+ // later entry was swallowed with it. Say so explicitly: otherwise one
84
+ // truncated paste revokes trust for the whole file with no visible cause.
85
+ problems.push({
86
+ line: blockStart + 1,
87
+ message: 'public key block has no "-----END" marker — this block and every entry after it were ignored',
88
+ });
89
+ continue;
90
+ }
91
+ let keyId = endLine.slice(endMarker.index + endMarker[0].length).trim();
92
+ // Drop the identifier back off the END line, so the reassembled block is a
93
+ // bare PEM. Key parsing requires one block and nothing around it — trailing
94
+ // text would make this key unreadable and therefore untrusted.
95
+ block[block.length - 1] = endLine.slice(0, endMarker.index + endMarker[0].length);
96
+ // Only adopt the next line as the identifier when it is not plainly an entry
97
+ // of its own, or a bare PEM block would swallow the key that follows it.
98
+ if (!keyId && i + 1 < lines.length && !looksLikeKeyEntry(lines[i + 1])) {
99
+ i++;
100
+ keyId = lines[i].trim();
101
+ }
102
+ if (keyId) {
103
+ entries.push({ publicKey: block.join('\n'), keyId });
104
+ }
105
+ else {
106
+ problems.push({
107
+ line: blockStart + 1,
108
+ message: 'public key block has no identifier after the "-----END" marker — entry ignored',
109
+ });
110
+ }
111
+ }
112
+ return { entries, problems };
113
+ }
114
+ /** Cap on printed problems, so a mangled file cannot flood every verify run. */
115
+ const MAX_REPORTED_TRUSTED_KEY_PROBLEMS = 3;
116
+ /**
117
+ * Print unusable trusted-key entries to stderr, bounded.
118
+ *
119
+ * `loadTrustedKeys` runs on every `dossier verify`, so this stays silent unless
120
+ * the file is genuinely malformed — and a malformed trust file is precisely when
121
+ * the user needs to hear about it.
122
+ */
123
+ function reportTrustedKeyProblems(problems, source) {
124
+ if (problems.length === 0) {
125
+ return;
126
+ }
127
+ const where = source ? ` in ${source}` : '';
128
+ console.warn(`Warning: ${problems.length} unusable trusted-key entry(s)${where}:`);
129
+ for (const problem of problems.slice(0, MAX_REPORTED_TRUSTED_KEY_PROBLEMS)) {
130
+ console.warn(` line ${problem.line}: ${problem.message}`);
131
+ }
132
+ if (problems.length > MAX_REPORTED_TRUSTED_KEY_PROBLEMS) {
133
+ console.warn(` ...and ${problems.length - MAX_REPORTED_TRUSTED_KEY_PROBLEMS} more`);
134
+ }
135
+ console.warn(' Those keys are NOT trusted. Re-add each with: ai-dossier keys add <public-key> <identifier>');
136
+ }
137
+ /**
138
+ * Build the trusted-key map from the contents of a trusted-keys file.
139
+ *
140
+ * Keys are indexed under both the form they were written in and their normalized
141
+ * form, so a key registered in one encoding still matches a signature that
142
+ * carries another.
143
+ *
144
+ * @param source - Path named in warnings about unusable entries. Omit to stay silent.
145
+ */
146
+ function trustedKeysFromContent(content, source) {
147
+ const keys = new Map();
148
+ const { entries, problems } = parseTrustedKeys(content);
149
+ for (const { publicKey, keyId } of entries) {
150
+ keys.set(publicKey, keyId);
151
+ const normalized = (0, signing_payload_1.normalizePublicKey)(publicKey);
152
+ if (normalized !== publicKey) {
153
+ keys.set(normalized, keyId);
154
+ }
155
+ }
156
+ if (source) {
157
+ reportTrustedKeyProblems(problems, source);
158
+ }
159
+ return keys;
160
+ }
21
161
  /**
22
162
  * Load trusted keys from file
23
163
  * Default location: ~/.dossier/trusted-keys.txt
@@ -25,37 +165,58 @@ const fs_1 = require("./utils/fs");
25
165
  */
26
166
  function loadTrustedKeys(filePath) {
27
167
  const keysPath = filePath || (0, node_path_1.join)((0, node_os_1.homedir)(), '.dossier', 'trusted-keys.txt');
28
- const keys = new Map();
29
168
  const content = (0, fs_1.readFileIfExists)(keysPath);
30
- if (!content) {
31
- return keys;
32
- }
33
- try {
34
- for (const line of content.split('\n')) {
35
- const trimmed = line.trim();
36
- // Skip empty lines and comments
37
- if (!trimmed || trimmed.startsWith('#')) {
38
- continue;
39
- }
40
- // Parse: <public-key> <key-id>
41
- const parts = trimmed.split(/\s+/);
42
- if (parts.length >= 2) {
43
- const publicKey = parts[0];
44
- const keyId = parts.slice(1).join(' ');
45
- keys.set(publicKey, keyId);
46
- // Index the normalized form too, so a key registered in one encoding
47
- // still matches a signature that carries another.
48
- const normalized = (0, signing_payload_1.normalizePublicKey)(publicKey);
49
- if (normalized !== publicKey) {
50
- keys.set(normalized, keyId);
51
- }
52
- }
169
+ // Pass the path so unusable entries name the file the user has to fix.
170
+ return content ? trustedKeysFromContent(content, keysPath) : new Map();
171
+ }
172
+ /** The algorithm `KmsVerifier` claims, whose key material is the KMS key ARN. */
173
+ const KMS_ALGORITHM = 'ECDSA-SHA-256';
174
+ function isKmsAlgorithm(algorithm) {
175
+ return algorithm === KMS_ALGORITHM;
176
+ }
177
+ /**
178
+ * Whether a string identifies an AWS KMS key, and so is a usable trust-list entry
179
+ * for a KMS-signed dossier.
180
+ */
181
+ function isKmsKeyIdentifier(value) {
182
+ return /^arn:aws[a-z-]*:kms:/.test(value.trim());
183
+ }
184
+ /**
185
+ * Resolve the identifier a signature is trusted under, or `undefined` if none of
186
+ * its key forms appear in the trust list.
187
+ *
188
+ * The signature and the trust list need not agree on encoding, so every form the
189
+ * *verifying* key carries is tried: the public key as written and normalized to
190
+ * raw base64. Every trust decision goes through here so "is it trusted" and "who
191
+ * is it" can never drift apart.
192
+ *
193
+ * Only the key material the verifier actually used is eligible, which is decided
194
+ * by the algorithm, not by which fields happen to be populated. `KmsVerifier`
195
+ * verifies against `key_id` and ignores `public_key` — which KMS signatures carry
196
+ * anyway — so for KMS only `key_id` can confer trust. Everything else verifies
197
+ * against `public_key`, so only that may.
198
+ *
199
+ * Letting a field the verifier ignored confer trust would hand it out for free:
200
+ * the trust list is keyed by public key and public keys are public, so an Ed25519
201
+ * dossier carrying `key_id: "<any trusted public key>"` would be trusted as that
202
+ * signer while verifying under an attacker's `public_key`.
203
+ */
204
+ function findTrustedIdentifier(trustedKeys, signature) {
205
+ const candidates = isKmsAlgorithm(signature.algorithm)
206
+ ? [signature.key_id]
207
+ : signature.public_key
208
+ ? [signature.public_key, (0, signing_payload_1.normalizePublicKey)(signature.public_key)]
209
+ : [];
210
+ for (const candidate of candidates) {
211
+ if (!candidate) {
212
+ continue;
213
+ }
214
+ const identifier = trustedKeys.get(candidate);
215
+ if (identifier !== undefined) {
216
+ return identifier;
53
217
  }
54
218
  }
55
- catch (err) {
56
- console.error(`Warning: failed to parse trusted keys: ${err.message}`);
57
- }
58
- return keys;
219
+ return undefined;
59
220
  }
60
221
  /**
61
222
  * Verify signature using Ed25519
@@ -1 +1 @@
1
- {"version":3,"file":"signature.js","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"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"}
@@ -35,9 +35,27 @@ export declare function signatureCoverage(signature: {
35
35
  * comparison against whatever the source actually contained.
36
36
  */
37
37
  export declare function normalizePublicKey(publicKey: string): string;
38
+ /**
39
+ * Whether a public key is one this project can actually verify against.
40
+ *
41
+ * True for anything that normalizes to a raw 32-byte Ed25519 key (raw base64,
42
+ * SPKI PEM, base64 SPKI DER) and for minisign keys, which are passed through.
43
+ *
44
+ * `normalizePublicKey` deliberately returns uninterpretable input unchanged so
45
+ * exact-match comparison still works on the read path. On the *write* path —
46
+ * `dossier keys add` — that same leniency would silently store a typo, a
47
+ * truncated key, or a file path as if it were a trusted key, and the only
48
+ * symptom would be `dossier verify` reporting "not trusted" forever after. Use
49
+ * this to reject before writing.
50
+ */
51
+ export declare function isSupportedPublicKey(publicKey: string): boolean;
38
52
  /**
39
53
  * Build an SPKI PEM from any accepted public-key form, for use with node:crypto.
40
- * Returns the input unchanged when it is already PEM.
54
+ *
55
+ * Always rebuilt from the parsed key rather than passed through, so the bytes a
56
+ * signature is verified against are the bytes the trust check matched. Returns
57
+ * the input unchanged only when it denotes no Ed25519 key at all, leaving
58
+ * `crypto` to report the error.
41
59
  */
42
60
  export declare function toSpkiPem(publicKey: string): string;
43
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"signing-payload.d.ts","sourceRoot":"","sources":["../src/signing-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,iBAAiB,CAE/F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsC5D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAkBnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrF;AAuBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAGpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,iBAAsC,GAC/C,MAAM,CAKR"}
1
+ {"version":3,"file":"signing-payload.d.ts","sourceRoot":"","sources":["../src/signing-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,iBAAiB,CAE/F;AAmFD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAG/D;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAYnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrF;AAuBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAGpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,iBAAsC,GAC/C,MAAM,CAKR"}
@@ -23,6 +23,7 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.signatureCoverage = signatureCoverage;
25
25
  exports.normalizePublicKey = normalizePublicKey;
26
+ exports.isSupportedPublicKey = isSupportedPublicKey;
26
27
  exports.toSpkiPem = toSpkiPem;
27
28
  exports.publicKeysMatch = publicKeysMatch;
28
29
  exports.canonicalizeFrontmatter = canonicalizeFrontmatter;
@@ -38,57 +39,116 @@ function signatureCoverage(signature) {
38
39
  return signature?.covers === 'frontmatter+body' ? 'frontmatter+body' : 'body';
39
40
  }
40
41
  /**
41
- * Normalize an Ed25519 public key to raw 32-byte base64.
42
+ * One PEM block and nothing else: no content before BEGIN or after END, matching
43
+ * labels, and only base64 in between.
42
44
  *
43
- * Accepts SPKI PEM, raw base64, and base64 SPKI DER. Returns the input trimmed
44
- * when it cannot be interpreted, so callers can still do an exact-match
45
- * comparison against whatever the source actually contained.
45
+ * Anchoring both ends is load-bearing. OpenSSL so `crypto.createPublicKey`
46
+ * skips whatever precedes the BEGIN line and ignores whatever follows END, so a
47
+ * blob with padding around a real block still parses, as the key inside the
48
+ * block. If normalization read that same blob more loosely it could conclude the
49
+ * string denotes a *different* key than the one `createPublicKey` will hand to
50
+ * `verify`, and a trust check is exactly the place where those two answers must
51
+ * never differ.
46
52
  */
47
- function normalizePublicKey(publicKey) {
53
+ const SINGLE_PEM_BLOCK = /^-----BEGIN ([A-Za-z0-9 ]+)-----([A-Za-z0-9+/=\s]*)-----END \1-----$/;
54
+ /**
55
+ * Decode base64 only when the input is exactly what re-encoding those bytes gives.
56
+ *
57
+ * Node's base64 decoder is lenient by design: it silently discards characters it
58
+ * does not recognize and stops at the first `=` padding. That leniency is a
59
+ * key-substitution primitive here, because every raw Ed25519 key is 44 base64
60
+ * characters ending in `=` — meaning `<any key><arbitrary trailing text>` decodes
61
+ * to that key. Requiring a byte-exact round trip collapses each string onto at
62
+ * most one key.
63
+ */
64
+ function decodeExactBase64(value) {
65
+ const decoded = Buffer.from(value, 'base64');
66
+ return decoded.toString('base64') === value ? decoded : undefined;
67
+ }
68
+ /**
69
+ * The raw 32 key bytes a public-key string denotes, or `undefined` when it does
70
+ * not unambiguously denote an Ed25519 key.
71
+ *
72
+ * The single source of truth behind `normalizePublicKey`, `toSpkiPem` and
73
+ * `isSupportedPublicKey`, so the key a trust check matches on and the key a
74
+ * signature is verified against are derived from one parse and cannot drift.
75
+ */
76
+ function ed25519RawKey(publicKey) {
48
77
  const trimmed = publicKey.trim();
49
78
  if (!trimmed) {
50
- return trimmed;
79
+ return undefined;
51
80
  }
52
81
  // minisign keys are a different encoding entirely (and carry a key id); nothing
53
82
  // has produced them since 2025-11-18. Leave them untouched.
54
83
  if (trimmed.startsWith('RWT')) {
55
- return trimmed;
84
+ return undefined;
56
85
  }
57
- const base64Body = trimmed.includes('BEGIN')
58
- ? trimmed
59
- .replace(/-----BEGIN [^-]+-----/g, '')
60
- .replace(/-----END [^-]+-----/g, '')
61
- .replace(/\s+/g, '')
62
- : trimmed.replace(/\s+/g, '');
63
- let decoded;
64
- try {
65
- decoded = Buffer.from(base64Body, 'base64');
86
+ // `-` is not in the base64 alphabet, so this cannot misread a raw key as PEM —
87
+ // whereas testing for the word "BEGIN" would, since B, E, G, I and N all are.
88
+ let base64Body;
89
+ if (trimmed.includes('-----')) {
90
+ const block = SINGLE_PEM_BLOCK.exec(trimmed);
91
+ if (!block) {
92
+ return undefined;
93
+ }
94
+ base64Body = block[2].replace(/\s+/g, '');
66
95
  }
67
- catch {
68
- return trimmed;
96
+ else {
97
+ base64Body = trimmed.replace(/\s+/g, '');
98
+ }
99
+ const decoded = decodeExactBase64(base64Body);
100
+ if (!decoded) {
101
+ return undefined;
69
102
  }
70
103
  if (decoded.length === ED25519_RAW_KEY_BYTES) {
71
- return decoded.toString('base64');
104
+ return decoded;
72
105
  }
73
106
  if (decoded.length === ED25519_SPKI_PREFIX.length + ED25519_RAW_KEY_BYTES &&
74
107
  decoded.subarray(0, ED25519_SPKI_PREFIX.length).equals(ED25519_SPKI_PREFIX)) {
75
- return decoded.subarray(ED25519_SPKI_PREFIX.length).toString('base64');
108
+ return decoded.subarray(ED25519_SPKI_PREFIX.length);
76
109
  }
77
- return trimmed;
110
+ return undefined;
111
+ }
112
+ /**
113
+ * Normalize an Ed25519 public key to raw 32-byte base64.
114
+ *
115
+ * Accepts SPKI PEM, raw base64, and base64 SPKI DER. Returns the input trimmed
116
+ * when it cannot be interpreted, so callers can still do an exact-match
117
+ * comparison against whatever the source actually contained.
118
+ */
119
+ function normalizePublicKey(publicKey) {
120
+ const raw = ed25519RawKey(publicKey);
121
+ return raw ? raw.toString('base64') : publicKey.trim();
122
+ }
123
+ /**
124
+ * Whether a public key is one this project can actually verify against.
125
+ *
126
+ * True for anything that normalizes to a raw 32-byte Ed25519 key (raw base64,
127
+ * SPKI PEM, base64 SPKI DER) and for minisign keys, which are passed through.
128
+ *
129
+ * `normalizePublicKey` deliberately returns uninterpretable input unchanged so
130
+ * exact-match comparison still works on the read path. On the *write* path —
131
+ * `dossier keys add` — that same leniency would silently store a typo, a
132
+ * truncated key, or a file path as if it were a trusted key, and the only
133
+ * symptom would be `dossier verify` reporting "not trusted" forever after. Use
134
+ * this to reject before writing.
135
+ */
136
+ function isSupportedPublicKey(publicKey) {
137
+ const trimmed = publicKey.trim();
138
+ return trimmed.startsWith('RWT') || ed25519RawKey(trimmed) !== undefined;
78
139
  }
79
140
  /**
80
141
  * Build an SPKI PEM from any accepted public-key form, for use with node:crypto.
81
- * Returns the input unchanged when it is already PEM.
142
+ *
143
+ * Always rebuilt from the parsed key rather than passed through, so the bytes a
144
+ * signature is verified against are the bytes the trust check matched. Returns
145
+ * the input unchanged only when it denotes no Ed25519 key at all, leaving
146
+ * `crypto` to report the error.
82
147
  */
83
148
  function toSpkiPem(publicKey) {
84
- const trimmed = publicKey.trim();
85
- if (trimmed.includes('BEGIN')) {
86
- return trimmed;
87
- }
88
- const raw = Buffer.from(normalizePublicKey(trimmed), 'base64');
89
- if (raw.length !== ED25519_RAW_KEY_BYTES) {
90
- // Not something we can rebuild; hand it back and let crypto report the error.
91
- return trimmed;
149
+ const raw = ed25519RawKey(publicKey);
150
+ if (!raw) {
151
+ return publicKey.trim();
92
152
  }
93
153
  const der = Buffer.concat([ED25519_SPKI_PREFIX, raw]);
94
154
  const body = der
@@ -1 +1 @@
1
- {"version":3,"file":"signing-payload.js","sourceRoot":"","sources":["../src/signing-payload.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;AAaH,8CAEC;AASD,gDAsCC;AAMD,8BAkBC;AAKD,0CAKC;AA2BD,0DAGC;AAQD,gDASC;AA7ID,qFAAqF;AACrF,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;AAE3E,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAIjC;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,SAA0C;IAC1E,OAAO,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC;AAChF,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,SAAiB;IAClD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,gFAAgF;IAChF,4DAA4D;IAC5D,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,OAAO;aACJ,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC;aACrC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;aACnC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACxB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEhC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;QAC7C,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IACE,OAAO,CAAC,MAAM,KAAK,mBAAmB,CAAC,MAAM,GAAG,qBAAqB;QACrE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAC3E,CAAC;QACD,OAAO,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,SAAiB;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,GAAG,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;QACzC,8EAA8E;QAC9E,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,GAAG;SACb,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC;SAC3B,OAAO,EAAE,CAAC;IACb,OAAO,+BAA+B,IAAI,8BAA8B,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,CAAqB,EAAE,CAAqB;IAC1E,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,kBAAkB,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACrD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;SAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEjE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAC,WAAoC;IAC1E,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,WAAW,CAAC;IACtD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAChC,WAAoC,EACpC,IAAY,EACZ,WAA8B,kBAAkB;IAEhD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,yBAAyB,uBAAuB,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"signing-payload.js","sourceRoot":"","sources":["../src/signing-payload.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-dossier/core",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Parsing, verification, and signing for dossiers — portable, signed, versioned skills for any LLM tool.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",