@e-sig/core 0.5.1 → 0.7.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.
Files changed (102) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +92 -0
  3. package/dist/index.d.ts +7 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +7 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/pem-signer.d.ts +26 -5
  8. package/dist/pem-signer.d.ts.map +1 -1
  9. package/dist/pem-signer.js +84 -13
  10. package/dist/pem-signer.js.map +1 -1
  11. package/dist/pq-cert.d.ts +76 -0
  12. package/dist/pq-cert.d.ts.map +1 -0
  13. package/dist/pq-cert.js +295 -0
  14. package/dist/pq-cert.js.map +1 -0
  15. package/dist/pq-embed.d.ts +22 -0
  16. package/dist/pq-embed.d.ts.map +1 -0
  17. package/dist/pq-embed.js +119 -0
  18. package/dist/pq-embed.js.map +1 -0
  19. package/dist/pq-lifecycle.d.ts +59 -0
  20. package/dist/pq-lifecycle.d.ts.map +1 -0
  21. package/dist/pq-lifecycle.js +55 -0
  22. package/dist/pq-lifecycle.js.map +1 -0
  23. package/dist/pq-seal.d.ts +183 -0
  24. package/dist/pq-seal.d.ts.map +1 -0
  25. package/dist/pq-seal.js +345 -0
  26. package/dist/pq-seal.js.map +1 -0
  27. package/dist/pq-verify.d.ts +99 -0
  28. package/dist/pq-verify.d.ts.map +1 -0
  29. package/dist/pq-verify.js +135 -0
  30. package/dist/pq-verify.js.map +1 -0
  31. package/dist/render-pdf.d.ts +5 -5
  32. package/dist/render-pdf.d.ts.map +1 -1
  33. package/dist/render-pdf.js +51 -17
  34. package/dist/render-pdf.js.map +1 -1
  35. package/dist/sign-document.d.ts +16 -0
  36. package/dist/sign-document.d.ts.map +1 -1
  37. package/dist/sign-document.js +10 -0
  38. package/dist/sign-document.js.map +1 -1
  39. package/dist/sign-pdf.d.ts +66 -4
  40. package/dist/sign-pdf.d.ts.map +1 -1
  41. package/dist/sign-pdf.js +51 -2
  42. package/dist/sign-pdf.js.map +1 -1
  43. package/dist/types.d.ts +36 -0
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/vendor/placeholder-plain/LICENSE-signpdf.md +47 -0
  46. package/dist/vendor/placeholder-plain/createBufferPageWithAnnotation.d.ts +6 -0
  47. package/dist/vendor/placeholder-plain/createBufferPageWithAnnotation.d.ts.map +1 -0
  48. package/dist/vendor/placeholder-plain/createBufferPageWithAnnotation.js +38 -0
  49. package/dist/vendor/placeholder-plain/createBufferPageWithAnnotation.js.map +1 -0
  50. package/dist/vendor/placeholder-plain/createBufferRootWithAcroform.d.ts +6 -0
  51. package/dist/vendor/placeholder-plain/createBufferRootWithAcroform.d.ts.map +1 -0
  52. package/dist/vendor/placeholder-plain/createBufferRootWithAcroform.js +15 -0
  53. package/dist/vendor/placeholder-plain/createBufferRootWithAcroform.js.map +1 -0
  54. package/dist/vendor/placeholder-plain/createBufferTrailer.d.ts +4 -0
  55. package/dist/vendor/placeholder-plain/createBufferTrailer.d.ts.map +1 -0
  56. package/dist/vendor/placeholder-plain/createBufferTrailer.js +26 -0
  57. package/dist/vendor/placeholder-plain/createBufferTrailer.js.map +1 -0
  58. package/dist/vendor/placeholder-plain/findObject.d.ts +4 -0
  59. package/dist/vendor/placeholder-plain/findObject.d.ts.map +1 -0
  60. package/dist/vendor/placeholder-plain/findObject.js +18 -0
  61. package/dist/vendor/placeholder-plain/findObject.js.map +1 -0
  62. package/dist/vendor/placeholder-plain/getIndexFromRef.d.ts +4 -0
  63. package/dist/vendor/placeholder-plain/getIndexFromRef.d.ts.map +1 -0
  64. package/dist/vendor/placeholder-plain/getIndexFromRef.js +13 -0
  65. package/dist/vendor/placeholder-plain/getIndexFromRef.js.map +1 -0
  66. package/dist/vendor/placeholder-plain/getPageRef.d.ts +6 -0
  67. package/dist/vendor/placeholder-plain/getPageRef.d.ts.map +1 -0
  68. package/dist/vendor/placeholder-plain/getPageRef.js +18 -0
  69. package/dist/vendor/placeholder-plain/getPageRef.js.map +1 -0
  70. package/dist/vendor/placeholder-plain/getPagesDictionaryRef.d.ts +3 -0
  71. package/dist/vendor/placeholder-plain/getPagesDictionaryRef.d.ts.map +1 -0
  72. package/dist/vendor/placeholder-plain/getPagesDictionaryRef.js +12 -0
  73. package/dist/vendor/placeholder-plain/getPagesDictionaryRef.js.map +1 -0
  74. package/dist/vendor/placeholder-plain/index.d.ts +2 -0
  75. package/dist/vendor/placeholder-plain/index.d.ts.map +1 -0
  76. package/dist/vendor/placeholder-plain/index.js +4 -0
  77. package/dist/vendor/placeholder-plain/index.js.map +1 -0
  78. package/dist/vendor/placeholder-plain/pdfObject.d.ts +13 -0
  79. package/dist/vendor/placeholder-plain/pdfObject.d.ts.map +1 -0
  80. package/dist/vendor/placeholder-plain/pdfObject.js +142 -0
  81. package/dist/vendor/placeholder-plain/pdfObject.js.map +1 -0
  82. package/dist/vendor/placeholder-plain/pdfkitAddPlaceholder.d.ts +49 -0
  83. package/dist/vendor/placeholder-plain/pdfkitAddPlaceholder.d.ts.map +1 -0
  84. package/dist/vendor/placeholder-plain/pdfkitAddPlaceholder.js +115 -0
  85. package/dist/vendor/placeholder-plain/pdfkitAddPlaceholder.js.map +1 -0
  86. package/dist/vendor/placeholder-plain/plainAddPlaceholder.d.ts +41 -0
  87. package/dist/vendor/placeholder-plain/plainAddPlaceholder.d.ts.map +1 -0
  88. package/dist/vendor/placeholder-plain/plainAddPlaceholder.js +95 -0
  89. package/dist/vendor/placeholder-plain/plainAddPlaceholder.js.map +1 -0
  90. package/dist/vendor/placeholder-plain/readPdf.d.ts +20 -0
  91. package/dist/vendor/placeholder-plain/readPdf.d.ts.map +1 -0
  92. package/dist/vendor/placeholder-plain/readPdf.js +47 -0
  93. package/dist/vendor/placeholder-plain/readPdf.js.map +1 -0
  94. package/dist/vendor/placeholder-plain/readRefTable.d.ts +17 -0
  95. package/dist/vendor/placeholder-plain/readRefTable.d.ts.map +1 -0
  96. package/dist/vendor/placeholder-plain/readRefTable.js +84 -0
  97. package/dist/vendor/placeholder-plain/readRefTable.js.map +1 -0
  98. package/dist/vendor/placeholder-plain/xrefToRefMap.d.ts +3 -0
  99. package/dist/vendor/placeholder-plain/xrefToRefMap.d.ts.map +1 -0
  100. package/dist/vendor/placeholder-plain/xrefToRefMap.js +38 -0
  101. package/dist/vendor/placeholder-plain/xrefToRefMap.js.map +1 -0
  102. package/package.json +10 -8
@@ -0,0 +1,135 @@
1
+ // pq-verify.ts
2
+ //
3
+ // Verify the post-quantum hybrid seal embedded in a signed PDF, and the combined
4
+ // classical + post-quantum trust result — the "two-line" answer the product
5
+ // pitch leans on:
6
+ //
7
+ // classical (PAdES / PKCS#7 RSA): VALID — every PDF reader, incl. Acrobat
8
+ // post-quantum (ML-DSA-65, FIPS 204): VALID — quantum-resistant
9
+ //
10
+ // The seal binds to the document by covering SHA-256 of the first `coveredBytes`
11
+ // bytes (P0, the pre-seal PDF). Because the seal is embedded append-only and the
12
+ // RSA /ByteRange signature is applied on top, tampering with the document breaks
13
+ // BOTH the classical signature AND the post-quantum digest.
14
+ import crypto from "node:crypto";
15
+ import { verifyPdfSignature } from "./verify-pdf.js";
16
+ import { verifyPqSealSignatures } from "./pq-seal.js";
17
+ import { extractPqSeal } from "./pq-embed.js";
18
+ import { certMatchesPqSeal } from "./pq-cert.js";
19
+ /**
20
+ * Verify the embedded post-quantum seal against the document bytes. Never throws;
21
+ * a missing or malformed seal returns `{ present:false, ok:false }`. Pass
22
+ * `expectedMldsa65Fpr` to also pin the signer identity.
23
+ */
24
+ export function verifyPqSeal(pdf, opts = {}) {
25
+ const failures = [];
26
+ const seal = extractPqSeal(pdf);
27
+ if (!seal) {
28
+ return { present: false, ok: false, failures: ["no post-quantum seal found"] };
29
+ }
30
+ const verdict = {
31
+ present: true,
32
+ ok: false,
33
+ alg: seal.alg,
34
+ keyId: seal.keyId,
35
+ mldsa65Fpr: seal.keys?.mldsa65Fpr,
36
+ signedAt: seal.signedAt,
37
+ coveredBytes: seal.coveredBytes,
38
+ uuaid: seal.uuaid,
39
+ failures,
40
+ };
41
+ // (1) Document binding: the seal must cover a real, in-bounds prefix.
42
+ const covered = seal.coveredBytes;
43
+ let digestBinds = false;
44
+ if (!Number.isInteger(covered) || covered <= 0 || covered > pdf.length) {
45
+ failures.push(`seal coveredBytes (${covered}) is out of range for a ${pdf.length}-byte file`);
46
+ }
47
+ else {
48
+ const recomputed = crypto.createHash("sha256").update(pdf.subarray(0, covered)).digest("hex");
49
+ digestBinds = recomputed === seal.digest;
50
+ if (!digestBinds) {
51
+ failures.push("post-quantum digest does not match the document — content altered");
52
+ }
53
+ }
54
+ verdict.digestBinds = digestBinds;
55
+ // (2) Signatures: both classical Ed25519 and post-quantum ML-DSA-65 must verify.
56
+ const sigs = verifyPqSealSignatures(seal);
57
+ verdict.ed25519 = sigs.ed25519;
58
+ verdict.mldsa65 = sigs.mldsa65;
59
+ verdict.fingerprintOk = sigs.fingerprintOk;
60
+ if (!sigs.ed25519)
61
+ failures.push("Ed25519 seal signature invalid");
62
+ if (!sigs.mldsa65)
63
+ failures.push("ML-DSA-65 seal signature invalid");
64
+ if (!sigs.fingerprintOk)
65
+ failures.push("ML-DSA-65 fingerprint inconsistent with its public key");
66
+ if (!sigs.keyIdOk)
67
+ failures.push("seal keyId inconsistent with its public keys");
68
+ if (!sigs.uuaidOk)
69
+ failures.push("seal carries a malformed UUAID assertion");
70
+ // (3) Optional identity pinning (in-band TOFU assertion).
71
+ let identityOk = true;
72
+ if (opts.expectedMldsa65Fpr) {
73
+ identityOk = (verdict.mldsa65Fpr ?? "").toLowerCase() === opts.expectedMldsa65Fpr.toLowerCase();
74
+ if (!identityOk) {
75
+ failures.push("post-quantum signer fingerprint does not match the expected (pinned) identity");
76
+ }
77
+ }
78
+ // (3b) Optional UUAID assertion pinning (IAASO-0004). Pins what the seal
79
+ // CLAIMS; the uuaid -> key direction is out of band, see PqSealVerdict.uuaid.
80
+ if (opts.expectedUuaid) {
81
+ const uuaidMatches = verdict.uuaid === opts.expectedUuaid;
82
+ verdict.uuaidMatches = uuaidMatches;
83
+ if (!uuaidMatches) {
84
+ identityOk = false;
85
+ failures.push(verdict.uuaid === undefined
86
+ ? "seal asserts no UUAID but one was expected"
87
+ : "seal's asserted UUAID does not match the expected (pinned) identity");
88
+ }
89
+ }
90
+ // (4) Optional X.509 identity: a self-signed ML-DSA-65 cert bound to this key.
91
+ if (opts.signerCert) {
92
+ const certOk = certMatchesPqSeal(opts.signerCert, seal);
93
+ verdict.certIdentityOk = certOk;
94
+ if (!certOk) {
95
+ identityOk = false;
96
+ failures.push("signer certificate is invalid or does not match the seal's post-quantum key");
97
+ }
98
+ }
99
+ verdict.ok = digestBinds && sigs.ok && identityOk;
100
+ return verdict;
101
+ }
102
+ /**
103
+ * Full document verification: classical PAdES signature + post-quantum hybrid
104
+ * seal. Also asserts that the seal-covered region falls within the RSA-signed
105
+ * prefix, so the classical signature genuinely protects the seal. Pass
106
+ * `requirePq` to reject unsealed documents and `expectedMldsa65Fpr` to pin the
107
+ * post-quantum signer.
108
+ */
109
+ export function verifyDocument(pdf, opts = {}) {
110
+ const classical = verifyPdfSignature(pdf);
111
+ const postQuantum = verifyPqSeal(pdf, {
112
+ expectedMldsa65Fpr: opts.expectedMldsa65Fpr,
113
+ signerCert: opts.signerCert,
114
+ expectedUuaid: opts.expectedUuaid,
115
+ });
116
+ let sealWithinSignedRegion = true;
117
+ if (postQuantum.present && classical.byteRange && postQuantum.coveredBytes != null) {
118
+ const [a, b] = classical.byteRange;
119
+ const contentsStart = a + b; // end of the first signed chunk = start of /Contents
120
+ if (postQuantum.coveredBytes > contentsStart) {
121
+ sealWithinSignedRegion = false;
122
+ postQuantum.failures.push("seal covers bytes beyond the classically-signed region (not RSA-protected)");
123
+ postQuantum.ok = false;
124
+ }
125
+ }
126
+ if (opts.requirePq && !postQuantum.present) {
127
+ postQuantum.failures.push("post-quantum seal required but none present");
128
+ }
129
+ const pqSatisfied = postQuantum.present
130
+ ? postQuantum.ok && sealWithinSignedRegion
131
+ : !opts.requirePq;
132
+ const ok = classical.ok && pqSatisfied;
133
+ return { ok, classical, postQuantum };
134
+ }
135
+ //# sourceMappingURL=pq-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pq-verify.js","sourceRoot":"","sources":["../src/pq-verify.ts"],"names":[],"mappings":"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"}
@@ -10,11 +10,11 @@ export interface RenderHtmlToPdfOptions {
10
10
  };
11
11
  printBackground?: boolean;
12
12
  /**
13
- * Override the chromium executable path. If omitted:
14
- * - on Vercel / AWS Lambda: load @sparticuz/chromium
15
- * - on macOS: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
16
- * - on Linux: try common google-chrome / chromium paths
17
- * Set this when porting to an environment outside that matrix.
13
+ * Override the chromium executable path. If omitted, resolution order is:
14
+ * 1. ESIG_CHROME_PATH / PUPPETEER_EXECUTABLE_PATH / CHROME_PATH env vars
15
+ * 2. on Vercel / AWS Lambda: load @sparticuz/chromium
16
+ * 3. platform scan: common Chrome/Chromium/Edge/Brave install locations
17
+ * Set this (or an env var) when porting to an environment outside that matrix.
18
18
  */
19
19
  executablePath?: string;
20
20
  /** Override puppeteer launch args. Default: --no-sandbox --disable-setuid-sandbox. */
@@ -1 +1 @@
1
- {"version":3,"file":"render-pdf.d.ts","sourceRoot":"","sources":["../src/render-pdf.ts"],"names":[],"mappings":"AAMA,OAAkB,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCnF"}
1
+ {"version":3,"file":"render-pdf.d.ts","sourceRoot":"","sources":["../src/render-pdf.ts"],"names":[],"mappings":"AAMA,OAAkB,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyED,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCnF"}
@@ -4,32 +4,66 @@
4
4
  // Lambda environment to use @sparticuz/chromium, falls back to system Chrome
5
5
  // for local dev.
6
6
  import puppeteer from "puppeteer-core";
7
+ const CHROME_ENV_VARS = ["ESIG_CHROME_PATH", "PUPPETEER_EXECUTABLE_PATH", "CHROME_PATH"];
8
+ const CHROME_CANDIDATES = {
9
+ darwin: [
10
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
11
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
12
+ "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
13
+ "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
14
+ ],
15
+ linux: [
16
+ "/usr/bin/google-chrome",
17
+ "/usr/bin/google-chrome-stable",
18
+ "/usr/bin/chromium",
19
+ "/usr/bin/chromium-browser",
20
+ "/snap/bin/chromium",
21
+ "/usr/bin/microsoft-edge",
22
+ "/usr/bin/brave-browser",
23
+ ],
24
+ win32: [
25
+ "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
26
+ "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
27
+ "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
28
+ ],
29
+ };
30
+ async function isExecutable(p) {
31
+ try {
32
+ const fs = await import("node:fs");
33
+ // X_OK is meaningless on Windows; existence is the useful check there.
34
+ await fs.promises.access(p, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
35
+ return true;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
7
41
  async function resolveExecutablePath(opts) {
8
42
  if (opts.executablePath)
9
43
  return opts.executablePath;
44
+ for (const envVar of CHROME_ENV_VARS) {
45
+ const p = process.env[envVar];
46
+ if (!p)
47
+ continue;
48
+ if (await isExecutable(p))
49
+ return p;
50
+ // An explicitly set env var pointing nowhere is a config error — fail loud
51
+ // rather than silently falling through to a different browser.
52
+ throw new Error(`renderHtmlToPdf: ${envVar}="${p}" is not an executable file.`);
53
+ }
10
54
  if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.VERCEL_ENV) {
11
55
  const chromium = (await import("@sparticuz/chromium")).default;
12
56
  return await chromium.executablePath();
13
57
  }
14
- if (process.platform === "darwin") {
15
- return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
16
- }
17
- for (const p of [
18
- "/usr/bin/google-chrome",
19
- "/usr/bin/chromium",
20
- "/usr/bin/chromium-browser",
21
- "/snap/bin/chromium",
22
- ]) {
23
- try {
24
- const fs = await import("node:fs");
25
- await fs.promises.access(p, fs.constants.X_OK);
58
+ const candidates = CHROME_CANDIDATES[process.platform] ?? [];
59
+ for (const p of candidates) {
60
+ if (await isExecutable(p))
26
61
  return p;
27
- }
28
- catch {
29
- // try next
30
- }
31
62
  }
32
- throw new Error("renderHtmlToPdf: no Chrome/Chromium executable found. Install Chrome or pass options.executablePath.");
63
+ throw new Error("renderHtmlToPdf: no Chrome/Chromium executable found. Tried:\n" +
64
+ candidates.map((p) => ` - ${p}`).join("\n") +
65
+ "\nInstall Chrome/Chromium, or point to a browser with options.executablePath " +
66
+ "or the ESIG_CHROME_PATH / PUPPETEER_EXECUTABLE_PATH / CHROME_PATH env var.");
33
67
  }
34
68
  async function resolveLaunchArgs(opts) {
35
69
  if (opts.launchArgs)
@@ -1 +1 @@
1
- {"version":3,"file":"render-pdf.js","sourceRoot":"","sources":["../src/render-pdf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render-pdf.js","sourceRoot":"","sources":["../src/render-pdf.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { CertStore, AuditLogStore, PdfStorageStore, EsigAuditAction } from "./adapters.js";
2
2
  import type { TsaTransport } from "./types.js";
3
+ import type { PqSigningKeys } from "./pq-seal.js";
3
4
  export interface SignDocumentInput {
4
5
  /** Fully-rendered, signature-embedded HTML (the consumer composes this). */
5
6
  html: string;
@@ -30,6 +31,15 @@ export interface SignDocumentInput {
30
31
  signingTime?: Date;
31
32
  /** Optional RFC-3161 timestamp transport. Provide one to upgrade to CAdES-T. */
32
33
  tsa?: TsaTransport;
34
+ /**
35
+ * Optional post-quantum hybrid seal (Ed25519 + ML-DSA-65). Provide signing
36
+ * keys (e.g. from `ensureActivePqKeys` or `loadPqSigningKeys`) to embed a
37
+ * quantum-resistant seal covered by the classical PAdES signature.
38
+ */
39
+ pq?: {
40
+ keys: PqSigningKeys;
41
+ signedAt?: Date;
42
+ };
33
43
  /** Audit row fields. */
34
44
  action?: EsigAuditAction | string;
35
45
  targetTable?: string;
@@ -49,6 +59,12 @@ export interface SignDocumentResult {
49
59
  /** True when an RFC-3161 token was embedded (CAdES-T); false = CAdES-B. */
50
60
  timestamped: boolean;
51
61
  tsaError?: string;
62
+ /** True when a post-quantum hybrid seal (ML-DSA-65) was embedded. */
63
+ pqSealed: boolean;
64
+ /** Seal keyId, when post-quantum sealed. */
65
+ pqKeyId?: string;
66
+ /** ML-DSA-65 public-key fingerprint, when post-quantum sealed. */
67
+ pqMldsa65Fpr?: string;
52
68
  }
53
69
  export declare function signDocument(input: SignDocumentInput): Promise<SignDocumentResult>;
54
70
  //# sourceMappingURL=sign-document.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sign-document.d.ts","sourceRoot":"","sources":["../src/sign-document.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,eAAe,EACf,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAE5D,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,aAAa,CAAC;IAC1B,OAAO,EAAE,eAAe,CAAC;IAEzB,iGAAiG;IACjG,UAAU,EAAE,MAAM,CAAC;IAEnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,gFAAgF;IAChF,GAAG,CAAC,EAAE,YAAY,CAAC;IAEnB,wBAAwB;IACxB,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAmF7B"}
1
+ {"version":3,"file":"sign-document.d.ts","sourceRoot":"","sources":["../src/sign-document.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,eAAe,EACf,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAE5D,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,aAAa,CAAC;IAC1B,OAAO,EAAE,eAAe,CAAC;IAEzB,iGAAiG;IACjG,UAAU,EAAE,MAAM,CAAC;IAEnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,gFAAgF;IAChF,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB;;;;OAIG;IACH,EAAE,CAAC,EAAE;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;IAE9C,wBAAwB;IACxB,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CA6F7B"}
@@ -35,6 +35,7 @@ export async function signDocument(input) {
35
35
  name: input.signer.name,
36
36
  signingTime: signedAt,
37
37
  tsa: input.tsa,
38
+ pqSeal: input.pq ? { keys: input.pq.keys, signedAt: input.pq.signedAt ?? signedAt } : undefined,
38
39
  });
39
40
  // 4. Persist the signed PDF (+ optional signature image).
40
41
  const tsKey = signedAt.toISOString().replace(/[:.]/g, "-");
@@ -78,6 +79,12 @@ export async function signDocument(input) {
78
79
  degraded: !!input.tsa && !r.timestamped,
79
80
  error: r.tsaError ?? null,
80
81
  },
82
+ post_quantum: {
83
+ sealed: r.pqSealed,
84
+ ...(r.pqSealed
85
+ ? { alg: "hybrid-ed25519-ml-dsa-65", key_id: r.pqKeyId, mldsa65_fpr: r.pqMldsa65Fpr }
86
+ : {}),
87
+ },
81
88
  },
82
89
  });
83
90
  return {
@@ -88,6 +95,9 @@ export async function signDocument(input) {
88
95
  certFingerprint: cert.cert.certFingerprint,
89
96
  timestamped: r.timestamped,
90
97
  tsaError: r.tsaError,
98
+ pqSealed: r.pqSealed,
99
+ pqKeyId: r.pqKeyId,
100
+ pqMldsa65Fpr: r.pqMldsa65Fpr,
91
101
  };
92
102
  }
93
103
  //# sourceMappingURL=sign-document.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sign-document.js","sourceRoot":"","sources":["../src/sign-document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sign-document.js","sourceRoot":"","sources":["../src/sign-document.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,35 @@
1
- import type { TsaTransport } from "./types.js";
1
+ import type { ExternalSigner, TsaTransport } from "./types.js";
2
+ import { type PqSigningKeys } from "./pq-seal.js";
3
+ /**
4
+ * The /SubFilter values `signPdf` can emit. Both denote a detached PKCS#7,
5
+ * which is what `PemSigner` produces; the legacy `adbe.pkcs7.sha1` /
6
+ * `adbe.x509.rsa.sha1` forms are deliberately absent because this signer
7
+ * cannot produce them.
8
+ */
9
+ export declare const SUPPORTED_SUBFILTERS: readonly ["ETSI.CAdES.detached", "adbe.pkcs7.detached"];
10
+ export type SubFilter = (typeof SUPPORTED_SUBFILTERS)[number];
2
11
  export interface SignPdfInput {
3
12
  pdf: Buffer;
4
- keyPem: string;
5
- certPem: string;
13
+ /**
14
+ * PEM-encoded RSA private key (in-memory signing). Required unless
15
+ * `externalSigner` is provided — the two are mutually exclusive.
16
+ */
17
+ keyPem?: string;
18
+ /**
19
+ * PEM-encoded X.509 certificate. Required with `keyPem`; with
20
+ * `externalSigner` it defaults to `externalSigner.certificatePem`.
21
+ */
22
+ certPem?: string;
23
+ /**
24
+ * External signing seam (HSM / KMS): the RSA private key stays outside this
25
+ * process and the PKCS#7 signature is produced by
26
+ * `externalSigner.signRsaSha256` (sync or async — RSASSA-PKCS1-v1_5/SHA-256
27
+ * over raw bytes, e.g. PKCS#11 CKM_SHA256_RSA_PKCS). Mutually exclusive with
28
+ * `keyPem`. Output is byte-identical to the `keyPem` path for the same key.
29
+ * See `ExternalSigner` in types.ts; a PKCS#11 adapter ships as
30
+ * `@e-sig/hsm-pkcs11`.
31
+ */
32
+ externalSigner?: ExternalSigner;
6
33
  reason: string;
7
34
  location: string;
8
35
  contactInfo: string;
@@ -17,8 +44,14 @@ export interface SignPdfInput {
17
44
  /**
18
45
  * Subfilter. Default ETSI.CAdES.detached (PAdES B-B baseline). Override
19
46
  * to adbe.pkcs7.detached for legacy Adobe Reader 9+ compatibility.
47
+ *
48
+ * Restricted to the two values this signer can actually produce — a
49
+ * detached PKCS#7. Anything else is rejected: /SubFilter is written into
50
+ * the signature dictionary as a PDF name, so an unvalidated value is a
51
+ * dictionary-injection vector for any caller that feeds this from user or
52
+ * tenant input. (Defence in depth — the serializer now escapes names too.)
20
53
  */
21
- subFilter?: string;
54
+ subFilter?: SubFilter;
22
55
  /**
23
56
  * Optional RFC 3161 timestamp transport. When provided, the signature is
24
57
  * upgraded to CAdES-T and the default `signatureLength` rises to 30720. The
@@ -33,6 +66,27 @@ export interface SignPdfInput {
33
66
  * (keeps `signing-time` for backward compatibility).
34
67
  */
35
68
  padesStrict?: boolean;
69
+ /**
70
+ * Optional post-quantum hybrid seal (Ed25519 + ML-DSA-65, FIPS 204). When
71
+ * provided, a seal over SHA-256 of the pre-signature PDF is embedded FIRST (an
72
+ * append-only incremental update), so the classical RSA /ByteRange signature
73
+ * applied on top cryptographically covers it. The classical signature remains
74
+ * valid in every PDF reader; the seal is the quantum-resistant layer, verified
75
+ * by `verifyPqSeal` / `verifyDocument`.
76
+ */
77
+ pqSeal?: {
78
+ /** Hybrid signing keys (see generatePqKeyBundle / loadPqSigningKeys). */
79
+ keys: PqSigningKeys;
80
+ /** Seal timestamp. Defaults to `signingTime` or now. */
81
+ signedAt?: Date;
82
+ /**
83
+ * Optional UUAID this signer asserts as its identity (IAASO-0004
84
+ * attribution). Signed into the seal, so it is immutable once embedded —
85
+ * but it is a claim by the seal key, not proof of identity. Omit to produce
86
+ * a seal byte-identical to pre-`uuaid` output.
87
+ */
88
+ uuaid?: string;
89
+ };
36
90
  }
37
91
  export interface SignPdfResult {
38
92
  signedPdf: Buffer;
@@ -41,6 +95,14 @@ export interface SignPdfResult {
41
95
  timestamped: boolean;
42
96
  /** Present when a non-required TSA request failed (signature is CAdES-B). */
43
97
  tsaError?: string;
98
+ /** True when a post-quantum hybrid seal was embedded (and is RSA-covered). */
99
+ pqSealed: boolean;
100
+ /** Seal keyId (128-bit hex over both public keys), when sealed. */
101
+ pqKeyId?: string;
102
+ /** ML-DSA-65 public-key fingerprint (SHA-256 hex), when sealed. */
103
+ pqMldsa65Fpr?: string;
104
+ /** The UUAID asserted in the seal, when one was supplied. */
105
+ pqUuaid?: string;
44
106
  }
45
107
  export declare function signPdf(input: SignPdfInput): Promise<SignPdfResult>;
46
108
  //# sourceMappingURL=sign-pdf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sign-pdf.d.ts","sourceRoot":"","sources":["../src/sign-pdf.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW/C,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAsB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAyCzE"}
1
+ {"version":3,"file":"sign-pdf.d.ts","sourceRoot":"","sources":["../src/sign-pdf.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAsC,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAYtF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,yDAA0D,CAAC;AAE5F,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE;QACP,yEAAyE;QACzE,IAAI,EAAE,aAAa,CAAC;QACpB,wDAAwD;QACxD,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB;;;;;WAKG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAsFzE"}
package/dist/sign-pdf.js CHANGED
@@ -7,10 +7,13 @@
7
7
  // TSA is supplied the default /Contents budget is raised to fit the TST + TSA
8
8
  // cert chain, and an overflow guard rejects a result whose PKCS#7 exceeded the
9
9
  // placeholder (which @signpdf would otherwise silently truncate).
10
+ import crypto from "node:crypto";
10
11
  import { SignPdf } from "@signpdf/signpdf";
11
- import { plainAddPlaceholder } from "@signpdf/placeholder-plain";
12
+ import { plainAddPlaceholder } from "./vendor/placeholder-plain/index.js";
12
13
  import { PemSigner } from "./pem-signer.js";
13
14
  import { verifyPdfStructure } from "./verify-pdf.js";
15
+ import { buildPqSeal, publicMaterialForKeys } from "./pq-seal.js";
16
+ import { embedPqSeal } from "./pq-embed.js";
14
17
  /** Default /Contents budget (bytes) when no timestamp is embedded. */
15
18
  const DEFAULT_SIGNATURE_LENGTH = 8192;
16
19
  /**
@@ -19,12 +22,53 @@ const DEFAULT_SIGNATURE_LENGTH = 8192;
19
22
  * bytes ≈ 15 KB of DER headroom.
20
23
  */
21
24
  const TIMESTAMPED_SIGNATURE_LENGTH = 30720;
25
+ /**
26
+ * The /SubFilter values `signPdf` can emit. Both denote a detached PKCS#7,
27
+ * which is what `PemSigner` produces; the legacy `adbe.pkcs7.sha1` /
28
+ * `adbe.x509.rsa.sha1` forms are deliberately absent because this signer
29
+ * cannot produce them.
30
+ */
31
+ export const SUPPORTED_SUBFILTERS = ["ETSI.CAdES.detached", "adbe.pkcs7.detached"];
22
32
  const signpdfInstance = new SignPdf();
23
33
  export async function signPdf(input) {
34
+ if (input.externalSigner && input.keyPem) {
35
+ throw new Error("signPdf: pass either keyPem or externalSigner, not both");
36
+ }
37
+ if (!input.externalSigner && !input.keyPem) {
38
+ throw new Error("signPdf: keyPem or externalSigner is required");
39
+ }
40
+ // Runtime check, not just a type: the attack surface is JS callers passing
41
+ // an unvalidated string straight through from user/tenant input.
42
+ if (input.subFilter !== undefined &&
43
+ !SUPPORTED_SUBFILTERS.includes(input.subFilter)) {
44
+ throw new Error(`signPdf: unsupported subFilter ${JSON.stringify(input.subFilter)} — ` +
45
+ `expected one of ${SUPPORTED_SUBFILTERS.join(", ")}`);
46
+ }
24
47
  const budget = input.signatureLength ??
25
48
  (input.tsa ? TIMESTAMPED_SIGNATURE_LENGTH : DEFAULT_SIGNATURE_LENGTH);
49
+ // Post-quantum seal FIRST (append-only), so the classical /ByteRange signature
50
+ // applied below cryptographically covers it. The seal signs SHA-256 of the
51
+ // pre-seal PDF (P0); coveredBytes = P0.length locates that region in the final
52
+ // file (incremental updates never rewrite prior bytes).
53
+ let basePdf = input.pdf;
54
+ let pqKeyId;
55
+ let pqMldsa65Fpr;
56
+ if (input.pqSeal) {
57
+ const digestHex = crypto.createHash("sha256").update(input.pdf).digest("hex");
58
+ const seal = buildPqSeal({
59
+ digestHex,
60
+ coveredBytes: input.pdf.length,
61
+ keys: input.pqSeal.keys,
62
+ signedAt: input.pqSeal.signedAt ?? input.signingTime,
63
+ uuaid: input.pqSeal.uuaid,
64
+ });
65
+ basePdf = embedPqSeal(input.pdf, seal);
66
+ const pub = publicMaterialForKeys(input.pqSeal.keys);
67
+ pqKeyId = pub.keyId;
68
+ pqMldsa65Fpr = pub.mldsa65Fpr;
69
+ }
26
70
  const withPlaceholder = plainAddPlaceholder({
27
- pdfBuffer: input.pdf,
71
+ pdfBuffer: basePdf,
28
72
  reason: input.reason,
29
73
  contactInfo: input.contactInfo,
30
74
  name: input.name,
@@ -35,6 +79,7 @@ export async function signPdf(input) {
35
79
  const signer = new PemSigner({
36
80
  keyPem: input.keyPem,
37
81
  certPem: input.certPem,
82
+ externalSigner: input.externalSigner,
38
83
  tsa: input.tsa,
39
84
  padesStrict: input.padesStrict,
40
85
  });
@@ -55,6 +100,10 @@ export async function signPdf(input) {
55
100
  placeholderBudget: budget,
56
101
  timestamped: signer.lastTimestamped,
57
102
  tsaError: signer.lastTsaError,
103
+ pqSealed: !!input.pqSeal,
104
+ pqKeyId,
105
+ pqMldsa65Fpr,
106
+ pqUuaid: input.pqSeal?.uuaid,
58
107
  };
59
108
  }
60
109
  //# sourceMappingURL=sign-pdf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sign-pdf.js","sourceRoot":"","sources":["../src/sign-pdf.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,uEAAuE;AACvE,uEAAuE;AACvE,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,kEAAkE;AAElE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,sEAAsE;AACtE,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC;;;;GAIG;AACH,MAAM,4BAA4B,GAAG,KAAK,CAAC;AA+C3C,MAAM,eAAe,GAAG,IAAI,OAAO,EAAE,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAmB;IAC/C,MAAM,MAAM,GACV,KAAK,CAAC,eAAe;QACrB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,mBAAmB,CAAC;QAC1C,SAAS,EAAE,KAAK,CAAC,GAAG;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,eAAe,EAAE,MAAM;QACvB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,qBAAqB;KACpD,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAEtF,wEAAwE;IACxE,0EAA0E;IAC1E,4EAA4E;IAC5E,6EAA6E;IAC7E,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,SAAS,CAAC,eAAe,IAAI,CAAC,CAAC;IAC9C,MAAM,cAAc,GAAG,SAAS,CAAC,eAAe,IAAI,MAAM,CAAC;IAC3D,IAAI,MAAM,IAAI,cAAc,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,wCAAwC,cAAc,8BAA8B,CACtG,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,OAAO;QACL,SAAS,EAAE,MAAM;QACjB,iBAAiB,EAAE,MAAM;QACzB,WAAW,EAAE,MAAM,CAAC,eAAe;QACnC,QAAQ,EAAE,MAAM,CAAC,YAAY;KAC9B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sign-pdf.js","sourceRoot":"","sources":["../src/sign-pdf.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -24,6 +24,42 @@ export interface SignedPdfMetadata {
24
24
  /** When the signature was applied. Defaults to now. */
25
25
  signingTime?: Date;
26
26
  }
27
+ /** RSA key sizes supported by the {@link ExternalSigner} seam. */
28
+ export type ExternalSignerKeyType = "rsa-2048" | "rsa-3072" | "rsa-4096";
29
+ /**
30
+ * Caller-injected signing seam — lets the RSA private key live OUTSIDE this
31
+ * process (HSM via PKCS#11, KMS, remote signing service…). The key material
32
+ * never touches @e-sig/core; only the certificate (public) and a sign callback
33
+ * are supplied. Pass it to `signPdf({ externalSigner })` or
34
+ * `new PemSigner({ externalSigner })` in place of `keyPem`.
35
+ *
36
+ * Design note (why a single raw-bytes callback is sufficient): the PKCS#7
37
+ * signature that ends up in the PDF is ALWAYS recomputed by `PemSigner` over
38
+ * the final signed-attributes SET (after the ESS signing-certificate-v2 splice)
39
+ * — node-forge's internal sync signing pass is discarded. That recomputation
40
+ * happens in our own async code with the exact to-be-signed bytes in hand, so
41
+ * the external signer is invoked exactly once, may be async (network HSMs),
42
+ * and needs no node-forge shim.
43
+ *
44
+ * A PKCS#11 reference adapter ships as `@e-sig/hsm-pkcs11`.
45
+ */
46
+ export interface ExternalSigner {
47
+ /** RSA modulus size of the external key. Validated against `certificatePem`. */
48
+ keyType: ExternalSignerKeyType;
49
+ /**
50
+ * PEM-encoded X.509 certificate whose public key matches the external
51
+ * private key. Embedded in the PKCS#7 and used for structural validation.
52
+ */
53
+ certificatePem: string;
54
+ /**
55
+ * Sign `data` with RSASSA-PKCS1-v1_5 / SHA-256 — the signer hashes the raw
56
+ * bytes itself (PKCS#11 mechanism CKM_SHA256_RSA_PKCS does exactly this).
57
+ * This is byte-identical to what node-forge produces with `key.sign(md)` for
58
+ * the same key. Must return the raw signature, exactly modulus-sized
59
+ * (256/384/512 bytes for rsa-2048/3072/4096). Sync or async.
60
+ */
61
+ signRsaSha256(data: Uint8Array): Uint8Array | Promise<Uint8Array>;
62
+ }
27
63
  /**
28
64
  * Caller-injected RFC 3161 timestamp transport.
29
65
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,CAAC,WAAW,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,kEAAkE;AAClE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAEzE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,OAAO,EAAE,qBAAqB,CAAC;IAC/B;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,CAAC,WAAW,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}