@psavelis/enterprise-blockchain 0.1.0 → 1.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.
Files changed (295) hide show
  1. package/dist/aid-settlement/application/reconciler.d.ts +13 -0
  2. package/dist/aid-settlement/application/reconciler.d.ts.map +1 -0
  3. package/dist/aid-settlement/application/reconciler.js +77 -0
  4. package/dist/aid-settlement/domain/entities.d.ts +24 -0
  5. package/dist/aid-settlement/domain/entities.d.ts.map +1 -0
  6. package/dist/aid-settlement/domain/entities.js +1 -0
  7. package/dist/aid-settlement/domain/ports.d.ts +10 -0
  8. package/dist/aid-settlement/domain/ports.d.ts.map +1 -0
  9. package/dist/aid-settlement/domain/ports.js +1 -0
  10. package/dist/aid-settlement/index.d.ts +19 -0
  11. package/dist/aid-settlement/index.d.ts.map +1 -0
  12. package/dist/aid-settlement/index.js +23 -0
  13. package/dist/aid-settlement/infrastructure/in-memory-store.d.ts +12 -0
  14. package/dist/aid-settlement/infrastructure/in-memory-store.d.ts.map +1 -0
  15. package/dist/aid-settlement/infrastructure/in-memory-store.js +17 -0
  16. package/dist/credentialing/application/clearance-evaluator.d.ts +10 -0
  17. package/dist/credentialing/application/clearance-evaluator.d.ts.map +1 -0
  18. package/dist/credentialing/application/clearance-evaluator.js +63 -0
  19. package/dist/credentialing/domain/entities.d.ts +28 -0
  20. package/dist/credentialing/domain/entities.d.ts.map +1 -0
  21. package/dist/credentialing/domain/entities.js +1 -0
  22. package/dist/credentialing/domain/ports.d.ts +9 -0
  23. package/dist/credentialing/domain/ports.d.ts.map +1 -0
  24. package/dist/credentialing/domain/ports.js +1 -0
  25. package/dist/credentialing/index.d.ts +19 -0
  26. package/dist/credentialing/index.d.ts.map +1 -0
  27. package/dist/credentialing/index.js +23 -0
  28. package/dist/credentialing/infrastructure/in-memory-store.d.ts +11 -0
  29. package/dist/credentialing/infrastructure/in-memory-store.d.ts.map +1 -0
  30. package/dist/credentialing/infrastructure/in-memory-store.js +14 -0
  31. package/dist/hsm/application/asymmetric-key-service.d.ts +23 -0
  32. package/dist/hsm/application/asymmetric-key-service.d.ts.map +1 -0
  33. package/dist/hsm/application/asymmetric-key-service.js +109 -0
  34. package/dist/hsm/application/envelope-encryption-service.d.ts +18 -0
  35. package/dist/hsm/application/envelope-encryption-service.d.ts.map +1 -0
  36. package/dist/hsm/application/envelope-encryption-service.js +59 -0
  37. package/dist/hsm/application/symmetric-key-service.d.ts +34 -0
  38. package/dist/hsm/application/symmetric-key-service.d.ts.map +1 -0
  39. package/dist/hsm/application/symmetric-key-service.js +107 -0
  40. package/dist/hsm/domain/entities.d.ts +104 -0
  41. package/dist/hsm/domain/entities.d.ts.map +1 -0
  42. package/dist/hsm/domain/entities.js +10 -0
  43. package/dist/hsm/domain/ports.d.ts +20 -0
  44. package/dist/hsm/domain/ports.d.ts.map +1 -0
  45. package/dist/hsm/domain/ports.js +1 -0
  46. package/dist/hsm/index.d.ts +48 -0
  47. package/dist/hsm/index.d.ts.map +1 -0
  48. package/dist/hsm/index.js +97 -0
  49. package/dist/hsm/infrastructure/audit-log-factory.d.ts +59 -0
  50. package/dist/hsm/infrastructure/audit-log-factory.d.ts.map +1 -0
  51. package/dist/hsm/infrastructure/audit-log-factory.js +95 -0
  52. package/dist/hsm/infrastructure/audit-log.d.ts +8 -0
  53. package/dist/hsm/infrastructure/audit-log.d.ts.map +1 -0
  54. package/dist/hsm/infrastructure/audit-log.js +18 -0
  55. package/dist/hsm/infrastructure/file-audit-log.d.ts +55 -0
  56. package/dist/hsm/infrastructure/file-audit-log.d.ts.map +1 -0
  57. package/dist/hsm/infrastructure/file-audit-log.js +128 -0
  58. package/dist/hsm/infrastructure/key-store.d.ts +9 -0
  59. package/dist/hsm/infrastructure/key-store.d.ts.map +1 -0
  60. package/dist/hsm/infrastructure/key-store.js +12 -0
  61. package/dist/hsm/infrastructure/syslog-audit-log.d.ts +64 -0
  62. package/dist/hsm/infrastructure/syslog-audit-log.d.ts.map +1 -0
  63. package/dist/hsm/infrastructure/syslog-audit-log.js +167 -0
  64. package/dist/index.d.ts +22 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +37 -0
  67. package/dist/integrations/besu-client/error-mapper.d.ts +9 -0
  68. package/dist/integrations/besu-client/error-mapper.d.ts.map +1 -0
  69. package/dist/integrations/besu-client/error-mapper.js +22 -0
  70. package/dist/integrations/besu-client/index.d.ts +65 -0
  71. package/dist/integrations/besu-client/index.d.ts.map +1 -0
  72. package/dist/integrations/besu-client/index.js +276 -0
  73. package/dist/integrations/besu-client/ports.d.ts +44 -0
  74. package/dist/integrations/besu-client/ports.d.ts.map +1 -0
  75. package/dist/integrations/besu-client/ports.js +1 -0
  76. package/dist/integrations/corda-gateway/index.d.ts +37 -0
  77. package/dist/integrations/corda-gateway/index.d.ts.map +1 -0
  78. package/dist/integrations/corda-gateway/index.js +234 -0
  79. package/dist/integrations/corda-gateway/ports.d.ts +33 -0
  80. package/dist/integrations/corda-gateway/ports.d.ts.map +1 -0
  81. package/dist/integrations/corda-gateway/ports.js +1 -0
  82. package/dist/integrations/fabric-gateway/index.d.ts +78 -0
  83. package/dist/integrations/fabric-gateway/index.d.ts.map +1 -0
  84. package/dist/integrations/fabric-gateway/index.js +214 -0
  85. package/dist/integrations/fabric-gateway/ports.d.ts +50 -0
  86. package/dist/integrations/fabric-gateway/ports.d.ts.map +1 -0
  87. package/dist/integrations/fabric-gateway/ports.js +1 -0
  88. package/dist/integrations/index.d.ts +19 -0
  89. package/dist/integrations/index.d.ts.map +1 -0
  90. package/dist/integrations/index.js +19 -0
  91. package/dist/integrations/shared/env.d.ts +4 -0
  92. package/dist/integrations/shared/env.d.ts.map +1 -0
  93. package/dist/integrations/shared/env.js +24 -0
  94. package/dist/integrations/shared/retry.d.ts +79 -0
  95. package/dist/integrations/shared/retry.d.ts.map +1 -0
  96. package/dist/integrations/shared/retry.js +315 -0
  97. package/dist/mpc/adapters.d.ts +36 -0
  98. package/dist/mpc/adapters.d.ts.map +1 -0
  99. package/dist/mpc/adapters.js +46 -0
  100. package/dist/mpc/crypto.d.ts +2 -0
  101. package/dist/mpc/crypto.d.ts.map +1 -0
  102. package/dist/mpc/crypto.js +2 -0
  103. package/dist/mpc/dsa.d.ts +134 -0
  104. package/dist/mpc/dsa.d.ts.map +1 -0
  105. package/dist/mpc/dsa.js +127 -0
  106. package/dist/mpc/field.d.ts +127 -0
  107. package/dist/mpc/field.d.ts.map +1 -0
  108. package/dist/mpc/field.js +209 -0
  109. package/dist/mpc/hybrid-kem.d.ts +96 -0
  110. package/dist/mpc/hybrid-kem.d.ts.map +1 -0
  111. package/dist/mpc/hybrid-kem.js +136 -0
  112. package/dist/mpc/index.d.ts +135 -0
  113. package/dist/mpc/index.d.ts.map +1 -0
  114. package/dist/mpc/index.js +348 -0
  115. package/dist/mpc/kyber.d.ts +134 -0
  116. package/dist/mpc/kyber.d.ts.map +1 -0
  117. package/dist/mpc/kyber.js +143 -0
  118. package/dist/mpc/ports.d.ts +67 -0
  119. package/dist/mpc/ports.d.ts.map +1 -0
  120. package/dist/mpc/ports.js +9 -0
  121. package/dist/mpc/quantum.d.ts +80 -0
  122. package/dist/mpc/quantum.d.ts.map +1 -0
  123. package/dist/mpc/quantum.js +180 -0
  124. package/dist/p2mr/adapters.d.ts +31 -0
  125. package/dist/p2mr/adapters.d.ts.map +1 -0
  126. package/dist/p2mr/adapters.js +35 -0
  127. package/dist/p2mr/index.d.ts +63 -0
  128. package/dist/p2mr/index.d.ts.map +1 -0
  129. package/dist/p2mr/index.js +59 -0
  130. package/dist/p2mr/merkle-tree.d.ts +109 -0
  131. package/dist/p2mr/merkle-tree.d.ts.map +1 -0
  132. package/dist/p2mr/merkle-tree.js +239 -0
  133. package/dist/p2mr/p2mr-output.d.ts +142 -0
  134. package/dist/p2mr/p2mr-output.d.ts.map +1 -0
  135. package/dist/p2mr/p2mr-output.js +150 -0
  136. package/dist/p2mr/ports.d.ts +52 -0
  137. package/dist/p2mr/ports.d.ts.map +1 -0
  138. package/dist/p2mr/ports.js +9 -0
  139. package/dist/p2mr/script-interpreter.d.ts +92 -0
  140. package/dist/p2mr/script-interpreter.d.ts.map +1 -0
  141. package/dist/p2mr/script-interpreter.js +535 -0
  142. package/dist/p2mr/script-leaf.d.ts +70 -0
  143. package/dist/p2mr/script-leaf.d.ts.map +1 -0
  144. package/dist/p2mr/script-leaf.js +203 -0
  145. package/dist/p2mr/spend-proof.d.ts +95 -0
  146. package/dist/p2mr/spend-proof.d.ts.map +1 -0
  147. package/dist/p2mr/spend-proof.js +358 -0
  148. package/dist/p2mr/types.d.ts +209 -0
  149. package/dist/p2mr/types.d.ts.map +1 -0
  150. package/dist/p2mr/types.js +9 -0
  151. package/dist/privacy/application/view-projector.d.ts +13 -0
  152. package/dist/privacy/application/view-projector.d.ts.map +1 -0
  153. package/dist/privacy/application/view-projector.js +85 -0
  154. package/dist/privacy/domain/entities.d.ts +26 -0
  155. package/dist/privacy/domain/entities.d.ts.map +1 -0
  156. package/dist/privacy/domain/entities.js +1 -0
  157. package/dist/privacy/domain/ports.d.ts +7 -0
  158. package/dist/privacy/domain/ports.d.ts.map +1 -0
  159. package/dist/privacy/domain/ports.js +1 -0
  160. package/dist/privacy/index.d.ts +21 -0
  161. package/dist/privacy/index.d.ts.map +1 -0
  162. package/dist/privacy/index.js +25 -0
  163. package/dist/privacy/infrastructure/in-memory-store.d.ts +8 -0
  164. package/dist/privacy/infrastructure/in-memory-store.d.ts.map +1 -0
  165. package/dist/privacy/infrastructure/in-memory-store.js +7 -0
  166. package/dist/protocols/besu-port.d.ts +80 -0
  167. package/dist/protocols/besu-port.d.ts.map +1 -0
  168. package/dist/protocols/besu-port.js +1 -0
  169. package/dist/protocols/corda-port.d.ts +103 -0
  170. package/dist/protocols/corda-port.d.ts.map +1 -0
  171. package/dist/protocols/corda-port.js +9 -0
  172. package/dist/protocols/credentialing-port.d.ts +11 -0
  173. package/dist/protocols/credentialing-port.d.ts.map +1 -0
  174. package/dist/protocols/credentialing-port.js +1 -0
  175. package/dist/protocols/fabric-port.d.ts +89 -0
  176. package/dist/protocols/fabric-port.d.ts.map +1 -0
  177. package/dist/protocols/fabric-port.js +9 -0
  178. package/dist/protocols/index.d.ts +14 -0
  179. package/dist/protocols/index.d.ts.map +1 -0
  180. package/dist/protocols/index.js +7 -0
  181. package/dist/protocols/p2mr-port.d.ts +159 -0
  182. package/dist/protocols/p2mr-port.d.ts.map +1 -0
  183. package/dist/protocols/p2mr-port.js +12 -0
  184. package/dist/protocols/privacy-port.d.ts +9 -0
  185. package/dist/protocols/privacy-port.d.ts.map +1 -0
  186. package/dist/protocols/privacy-port.js +1 -0
  187. package/dist/protocols/traceability-port.d.ts +12 -0
  188. package/dist/protocols/traceability-port.d.ts.map +1 -0
  189. package/dist/protocols/traceability-port.js +1 -0
  190. package/dist/shared/collection-store.d.ts +12 -0
  191. package/dist/shared/collection-store.d.ts.map +1 -0
  192. package/dist/shared/collection-store.js +26 -0
  193. package/dist/shared/commit.d.ts +24 -0
  194. package/dist/shared/commit.d.ts.map +1 -0
  195. package/dist/shared/commit.js +50 -0
  196. package/dist/shared/crypto.d.ts +2 -0
  197. package/dist/shared/crypto.d.ts.map +1 -0
  198. package/dist/shared/crypto.js +4 -0
  199. package/dist/shared/date.d.ts +2 -0
  200. package/dist/shared/date.d.ts.map +1 -0
  201. package/dist/shared/date.js +3 -0
  202. package/dist/shared/index.d.ts +9 -0
  203. package/dist/shared/index.d.ts.map +1 -0
  204. package/dist/shared/index.js +11 -0
  205. package/dist/shared/logger.d.ts +37 -0
  206. package/dist/shared/logger.d.ts.map +1 -0
  207. package/dist/shared/logger.js +45 -0
  208. package/dist/shared/store.d.ts +25 -0
  209. package/dist/shared/store.d.ts.map +1 -0
  210. package/dist/shared/store.js +18 -0
  211. package/dist/shared/telemetry-sdk.d.ts +26 -0
  212. package/dist/shared/telemetry-sdk.d.ts.map +1 -0
  213. package/dist/shared/telemetry-sdk.js +97 -0
  214. package/dist/shared/telemetry.d.ts +86 -0
  215. package/dist/shared/telemetry.d.ts.map +1 -0
  216. package/dist/shared/telemetry.js +137 -0
  217. package/dist/stark-settlement/application/aggregator-service.d.ts +112 -0
  218. package/dist/stark-settlement/application/aggregator-service.d.ts.map +1 -0
  219. package/dist/stark-settlement/application/aggregator-service.js +256 -0
  220. package/dist/stark-settlement/application/ledger-service.d.ts +114 -0
  221. package/dist/stark-settlement/application/ledger-service.d.ts.map +1 -0
  222. package/dist/stark-settlement/application/ledger-service.js +318 -0
  223. package/dist/stark-settlement/application/settlement-service.d.ts +104 -0
  224. package/dist/stark-settlement/application/settlement-service.d.ts.map +1 -0
  225. package/dist/stark-settlement/application/settlement-service.js +251 -0
  226. package/dist/stark-settlement/domain/entities.d.ts +365 -0
  227. package/dist/stark-settlement/domain/entities.d.ts.map +1 -0
  228. package/dist/stark-settlement/domain/entities.js +29 -0
  229. package/dist/stark-settlement/domain/ports.d.ts +485 -0
  230. package/dist/stark-settlement/domain/ports.d.ts.map +1 -0
  231. package/dist/stark-settlement/domain/ports.js +14 -0
  232. package/dist/stark-settlement/domain/value-objects.d.ts +268 -0
  233. package/dist/stark-settlement/domain/value-objects.d.ts.map +1 -0
  234. package/dist/stark-settlement/domain/value-objects.js +500 -0
  235. package/dist/stark-settlement/index.d.ts +172 -0
  236. package/dist/stark-settlement/index.d.ts.map +1 -0
  237. package/dist/stark-settlement/index.js +193 -0
  238. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts +52 -0
  239. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts.map +1 -0
  240. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.js +154 -0
  241. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts +88 -0
  242. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts.map +1 -0
  243. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.js +187 -0
  244. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts +59 -0
  245. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts.map +1 -0
  246. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.js +85 -0
  247. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts +60 -0
  248. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts.map +1 -0
  249. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.js +104 -0
  250. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts +115 -0
  251. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts.map +1 -0
  252. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.js +191 -0
  253. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts +65 -0
  254. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts.map +1 -0
  255. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.js +207 -0
  256. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts +73 -0
  257. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts.map +1 -0
  258. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.js +287 -0
  259. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts +78 -0
  260. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts.map +1 -0
  261. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.js +172 -0
  262. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts +56 -0
  263. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts.map +1 -0
  264. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.js +261 -0
  265. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts +125 -0
  266. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts.map +1 -0
  267. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.js +416 -0
  268. package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts +68 -0
  269. package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts.map +1 -0
  270. package/dist/stark-settlement/infrastructure/persistence/ledger-store.js +238 -0
  271. package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts +30 -0
  272. package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts.map +1 -0
  273. package/dist/stark-settlement/infrastructure/persistence/offset-store.js +57 -0
  274. package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts +45 -0
  275. package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts.map +1 -0
  276. package/dist/stark-settlement/infrastructure/persistence/outbox-store.js +171 -0
  277. package/dist/traceability/application/recall-assessor.d.ts +13 -0
  278. package/dist/traceability/application/recall-assessor.d.ts.map +1 -0
  279. package/dist/traceability/application/recall-assessor.js +74 -0
  280. package/dist/traceability/domain/entities.d.ts +23 -0
  281. package/dist/traceability/domain/entities.d.ts.map +1 -0
  282. package/dist/traceability/domain/entities.js +1 -0
  283. package/dist/traceability/domain/ports.d.ts +23 -0
  284. package/dist/traceability/domain/ports.d.ts.map +1 -0
  285. package/dist/traceability/domain/ports.js +1 -0
  286. package/dist/traceability/domain/recall.d.ts +12 -0
  287. package/dist/traceability/domain/recall.d.ts.map +1 -0
  288. package/dist/traceability/domain/recall.js +1 -0
  289. package/dist/traceability/index.d.ts +22 -0
  290. package/dist/traceability/index.d.ts.map +1 -0
  291. package/dist/traceability/index.js +26 -0
  292. package/dist/traceability/infrastructure/in-memory-store.d.ts +13 -0
  293. package/dist/traceability/infrastructure/in-memory-store.d.ts.map +1 -0
  294. package/dist/traceability/infrastructure/in-memory-store.js +24 -0
  295. package/package.json +4 -3
@@ -0,0 +1,59 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2
+ /**
3
+ * DEK/KEK envelope encryption — ephemeral DEK wrapped by a stored KEK.
4
+ *
5
+ * The resulting ciphertext is suitable for storage on a distributed ledger:
6
+ * - encryptedRecord = AES-256-GCM ciphertext of the payload
7
+ * - wrappedDek = GCM-wrapped DEK (only the HSM can unwrap it)
8
+ */
9
+ export class EnvelopeEncryptionService {
10
+ symmetric;
11
+ audit;
12
+ constructor(symmetric, audit) {
13
+ this.symmetric = symmetric;
14
+ this.audit = audit;
15
+ }
16
+ encrypt(kekLabel, plaintext) {
17
+ const dek = randomBytes(32);
18
+ const payloadIv = randomBytes(12);
19
+ const payloadCipher = createCipheriv("aes-256-gcm", dek, payloadIv);
20
+ const ciphertextBuf = Buffer.concat([
21
+ payloadCipher.update(plaintext, "utf8"),
22
+ payloadCipher.final(),
23
+ ]);
24
+ const payloadAuthTag = payloadCipher.getAuthTag();
25
+ const encryptedRecord = {
26
+ ciphertext: ciphertextBuf.toString("hex"),
27
+ iv: payloadIv.toString("hex"),
28
+ authTag: payloadAuthTag.toString("hex"),
29
+ algorithm: "aes-256-gcm",
30
+ };
31
+ const wrappedDek = this.symmetric.wrapKey(dek, kekLabel);
32
+ dek.fill(0);
33
+ this.audit.record("encryptWithEnvelope", kekLabel, "success");
34
+ return { encryptedRecord, wrappedDek };
35
+ }
36
+ decrypt(wrappedDek, encryptedRecord) {
37
+ const dek = this.symmetric.unwrapKey(wrappedDek);
38
+ const iv = Buffer.from(encryptedRecord.iv, "hex");
39
+ const authTag = Buffer.from(encryptedRecord.authTag, "hex");
40
+ const ciphertext = Buffer.from(encryptedRecord.ciphertext, "hex");
41
+ try {
42
+ const decipher = createDecipheriv("aes-256-gcm", dek, iv);
43
+ decipher.setAuthTag(authTag);
44
+ const plaintext = Buffer.concat([
45
+ decipher.update(ciphertext),
46
+ decipher.final(),
47
+ ]).toString("utf8");
48
+ this.audit.record("decryptWithEnvelope", wrappedDek.kekLabel, "success");
49
+ return plaintext;
50
+ }
51
+ catch {
52
+ this.audit.record("decryptWithEnvelope", wrappedDek.kekLabel, "failed", "GCM authentication failed");
53
+ throw new Error("HSM decryptWithEnvelope: GCM authentication failed");
54
+ }
55
+ finally {
56
+ dek.fill(0);
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,34 @@
1
+ import type { SymmetricKeyEntry, WrappedKey } from "../domain/entities.js";
2
+ import type { AuditLog, KeyStore } from "../domain/ports.js";
3
+ /**
4
+ * AES-256-GCM symmetric operations — key generation, wrapping, unwrapping.
5
+ *
6
+ * The raw key is stored as Uint8Array in the domain entity to enable
7
+ * explicit zeroization. In a production HSM the key never leaves
8
+ * hardware-protected storage. Do not persist or log the key bytes.
9
+ *
10
+ * SECURITY: Intermediate key buffers are zeroized after use to minimize
11
+ * key material exposure in memory.
12
+ */
13
+ export declare class SymmetricKeyService {
14
+ private readonly keyStore;
15
+ private readonly audit;
16
+ constructor(keyStore: KeyStore, audit: AuditLog);
17
+ generateSymmetricKey(keyLabel: string): void;
18
+ /**
19
+ * Wrap a DEK (data encryption key) using the KEK (key encryption key).
20
+ *
21
+ * SECURITY: The kekBuffer is zeroized after use.
22
+ */
23
+ wrapKey(plaintextDek: Buffer, kekLabel: string): WrappedKey;
24
+ /**
25
+ * Unwrap a DEK using the KEK.
26
+ *
27
+ * SECURITY: The kekBuffer is zeroized after use.
28
+ * CALLER RESPONSIBILITY: The returned DEK buffer MUST be zeroized
29
+ * after use via `dekBuffer.fill(0)`.
30
+ */
31
+ unwrapKey(wrapped: WrappedKey): Buffer;
32
+ requireSymmetric(kekLabel: string): SymmetricKeyEntry;
33
+ }
34
+ //# sourceMappingURL=symmetric-key-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symmetric-key-service.d.ts","sourceRoot":"","sources":["../../../src/hsm/application/symmetric-key-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE7D;;;;;;;;;GASG;AACH,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,QAAQ;IAGlC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAc5C;;;;OAIG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IA6B3D;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IA8BtC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB;CAYtD"}
@@ -0,0 +1,107 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2
+ /**
3
+ * AES-256-GCM symmetric operations — key generation, wrapping, unwrapping.
4
+ *
5
+ * The raw key is stored as Uint8Array in the domain entity to enable
6
+ * explicit zeroization. In a production HSM the key never leaves
7
+ * hardware-protected storage. Do not persist or log the key bytes.
8
+ *
9
+ * SECURITY: Intermediate key buffers are zeroized after use to minimize
10
+ * key material exposure in memory.
11
+ */
12
+ export class SymmetricKeyService {
13
+ keyStore;
14
+ audit;
15
+ constructor(keyStore, audit) {
16
+ this.keyStore = keyStore;
17
+ this.audit = audit;
18
+ }
19
+ generateSymmetricKey(keyLabel) {
20
+ if (this.keyStore.has(keyLabel)) {
21
+ throw new Error(`HSM key already exists: ${keyLabel}`);
22
+ }
23
+ this.keyStore.set(keyLabel, {
24
+ kind: "symmetric",
25
+ keyLabel,
26
+ // Buffer is a Uint8Array subclass; no copy needed
27
+ keyBytes: randomBytes(32),
28
+ createdAt: new Date().toISOString(),
29
+ });
30
+ this.audit.record("generateSymmetricKey", keyLabel, "success");
31
+ }
32
+ /**
33
+ * Wrap a DEK (data encryption key) using the KEK (key encryption key).
34
+ *
35
+ * SECURITY: The kekBuffer is zeroized after use.
36
+ */
37
+ wrapKey(plaintextDek, kekLabel) {
38
+ const kek = this.requireSymmetric(kekLabel);
39
+ const kekBuffer = Buffer.from(kek.keyBytes);
40
+ const iv = randomBytes(12);
41
+ try {
42
+ const cipher = createCipheriv("aes-256-gcm", kekBuffer, iv);
43
+ const wrappedDek = Buffer.concat([
44
+ cipher.update(plaintextDek),
45
+ cipher.final(),
46
+ ]);
47
+ const authTag = cipher.getAuthTag();
48
+ this.audit.record("wrapKey", kekLabel, "success");
49
+ return {
50
+ algorithm: "aes-256-gcm",
51
+ wrappedDek: wrappedDek.toString("hex"),
52
+ iv: iv.toString("hex"),
53
+ authTag: authTag.toString("hex"),
54
+ kekLabel,
55
+ wrappedAt: new Date().toISOString(),
56
+ };
57
+ }
58
+ finally {
59
+ // Zeroize intermediate key material
60
+ kekBuffer.fill(0);
61
+ }
62
+ }
63
+ /**
64
+ * Unwrap a DEK using the KEK.
65
+ *
66
+ * SECURITY: The kekBuffer is zeroized after use.
67
+ * CALLER RESPONSIBILITY: The returned DEK buffer MUST be zeroized
68
+ * after use via `dekBuffer.fill(0)`.
69
+ */
70
+ unwrapKey(wrapped) {
71
+ const kek = this.requireSymmetric(wrapped.kekLabel);
72
+ const kekBuffer = Buffer.from(kek.keyBytes);
73
+ const iv = Buffer.from(wrapped.iv, "hex");
74
+ const authTag = Buffer.from(wrapped.authTag, "hex");
75
+ const wrappedBuf = Buffer.from(wrapped.wrappedDek, "hex");
76
+ try {
77
+ const decipher = createDecipheriv("aes-256-gcm", kekBuffer, iv);
78
+ decipher.setAuthTag(authTag);
79
+ const plaintext = Buffer.concat([
80
+ decipher.update(wrappedBuf),
81
+ decipher.final(),
82
+ ]);
83
+ this.audit.record("unwrapKey", wrapped.kekLabel, "success");
84
+ return plaintext;
85
+ }
86
+ catch {
87
+ this.audit.record("unwrapKey", wrapped.kekLabel, "failed", "GCM authentication failed");
88
+ throw new Error("HSM unwrapKey: GCM authentication failed");
89
+ }
90
+ finally {
91
+ // Zeroize intermediate key material
92
+ kekBuffer.fill(0);
93
+ }
94
+ }
95
+ requireSymmetric(kekLabel) {
96
+ const entry = this.keyStore.get(kekLabel);
97
+ if (!entry) {
98
+ this.audit.record("keyLookup", kekLabel, "failed", "key not found");
99
+ throw new Error(`HSM key not found: ${kekLabel}`);
100
+ }
101
+ if (entry.kind !== "symmetric") {
102
+ this.audit.record("keyLookup", kekLabel, "failed", "unexpected key type");
103
+ throw new Error(`HSM key '${kekLabel}' is not a symmetric key`);
104
+ }
105
+ return entry;
106
+ }
107
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * HSM Domain Entities
3
+ *
4
+ * These types define the HSM domain model. They MUST NOT depend on
5
+ * infrastructure types (like node:crypto KeyObject) to maintain
6
+ * hexagonal architecture purity.
7
+ *
8
+ * @see docs/adr/ADR-0001-hexagonal-architecture.md
9
+ */
10
+ export interface HsmSlotConfig {
11
+ slotId: string;
12
+ label: string;
13
+ }
14
+ export interface HsmKeyPair {
15
+ keyLabel: string;
16
+ keyType: "EC";
17
+ namedCurve: "P-256";
18
+ publicKeyPem: string;
19
+ privateKeyHandle: string;
20
+ createdAt: string;
21
+ }
22
+ export interface HsmSignatureResult {
23
+ keyLabel: string;
24
+ algorithm: "ecdsa-sha256";
25
+ signature: string;
26
+ publicKeyPem: string;
27
+ timestamp: string;
28
+ hsmAttestation: string;
29
+ }
30
+ export interface WrappedKey {
31
+ algorithm: "aes-256-gcm";
32
+ wrappedDek: string;
33
+ iv: string;
34
+ authTag: string;
35
+ kekLabel: string;
36
+ wrappedAt: string;
37
+ }
38
+ export interface EncryptedRecord {
39
+ ciphertext: string;
40
+ iv: string;
41
+ authTag: string;
42
+ algorithm: "aes-256-gcm";
43
+ }
44
+ export interface EnvelopeEncryptionResult {
45
+ encryptedRecord: EncryptedRecord;
46
+ wrappedDek: WrappedKey;
47
+ }
48
+ export interface HsmAuditEntry {
49
+ timestamp: string;
50
+ operation: string;
51
+ keyLabel: string;
52
+ result: "success" | "failed";
53
+ detail?: string;
54
+ }
55
+ /**
56
+ * Opaque handle for asymmetric keys.
57
+ *
58
+ * The domain should not know about the underlying key representation.
59
+ * The handle contains PEM-encoded keys which are portable and
60
+ * infrastructure-agnostic.
61
+ */
62
+ export interface AsymmetricKeyHandle {
63
+ /** PEM-encoded private key (PKCS#8 format) */
64
+ privateKeyPem: string;
65
+ /** PEM-encoded public key (SPKI format) */
66
+ publicKeyPem: string;
67
+ }
68
+ /**
69
+ * Internal key store entry for asymmetric keys.
70
+ *
71
+ * Uses PEM strings instead of KeyObject to keep domain types
72
+ * infrastructure-agnostic. The infrastructure layer converts
73
+ * to/from KeyObject as needed.
74
+ */
75
+ export interface AsymmetricKeyEntry {
76
+ kind: "asymmetric";
77
+ keyLabel: string;
78
+ /** PEM-encoded private key */
79
+ privateKeyPem: string;
80
+ /** PEM-encoded public key */
81
+ publicKeyPem: string;
82
+ namedCurve: "P-256";
83
+ createdAt: string;
84
+ }
85
+ export interface SymmetricKeyEntry {
86
+ kind: "symmetric";
87
+ keyLabel: string;
88
+ /**
89
+ * Raw key material as a byte array.
90
+ *
91
+ * Using Uint8Array instead of a base64 string enables explicit zeroization
92
+ * of in-memory key material. The infrastructure layer handles encoding/decoding
93
+ * at boundaries.
94
+ *
95
+ * SECURITY: This field represents the long-lived stored key material managed
96
+ * by the key store. Callers MUST NOT mutate or zeroize this buffer directly.
97
+ * Instead, create an ephemeral copy (e.g. `const key = Buffer.from(entry.keyBytes);`)
98
+ * for cryptographic operations, and securely zeroize that ephemeral copy after use.
99
+ */
100
+ keyBytes: Uint8Array;
101
+ createdAt: string;
102
+ }
103
+ export type KeyEntry = AsymmetricKeyEntry | SymmetricKeyEntry;
104
+ //# sourceMappingURL=entities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../../src/hsm/domain/entities.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,IAAI,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,kBAAkB,GAAG,iBAAiB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HSM Domain Entities
3
+ *
4
+ * These types define the HSM domain model. They MUST NOT depend on
5
+ * infrastructure types (like node:crypto KeyObject) to maintain
6
+ * hexagonal architecture purity.
7
+ *
8
+ * @see docs/adr/ADR-0001-hexagonal-architecture.md
9
+ */
10
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { HsmAuditEntry, KeyEntry } from "./entities.js";
2
+ /**
3
+ * Port for the HSM key store — decouples domain services from storage.
4
+ */
5
+ export interface KeyStore {
6
+ has(label: string): boolean;
7
+ get(label: string): KeyEntry | undefined;
8
+ set(label: string, entry: KeyEntry): void;
9
+ }
10
+ /**
11
+ * Port for the HSM audit log.
12
+ *
13
+ * Ref: NIST SP 800-57 Part 1, §8.1 — key management lifecycle auditing
14
+ * https://csrc.nist.gov/pubs/sp/800-57/pt1/r5/final
15
+ */
16
+ export interface AuditLog {
17
+ record(operation: string, keyLabel: string, result: "success" | "failed", detail?: string): void;
18
+ entries(): readonly HsmAuditEntry[];
19
+ }
20
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../src/hsm/domain/ports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAAC;IACR,OAAO,IAAI,SAAS,aAAa,EAAE,CAAC;CACrC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ export type { HsmSlotConfig, HsmKeyPair, HsmSignatureResult, WrappedKey, EncryptedRecord, EnvelopeEncryptionResult, HsmAuditEntry, } from "./domain/entities.js";
2
+ export type { KeyStore, AuditLog } from "./domain/ports.js";
3
+ export { AsymmetricKeyService } from "./application/asymmetric-key-service.js";
4
+ export { SymmetricKeyService } from "./application/symmetric-key-service.js";
5
+ export { EnvelopeEncryptionService } from "./application/envelope-encryption-service.js";
6
+ export { InMemoryAuditLog } from "./infrastructure/audit-log.js";
7
+ export { InMemoryKeyStore } from "./infrastructure/key-store.js";
8
+ export { FileAuditLog } from "./infrastructure/file-audit-log.js";
9
+ export type { ChainedAuditEntry } from "./infrastructure/file-audit-log.js";
10
+ export { SyslogAuditLog, DEFAULT_SYSLOG_CONFIG, } from "./infrastructure/syslog-audit-log.js";
11
+ export type { SyslogConfig, SyslogSeverity, SyslogFacility, } from "./infrastructure/syslog-audit-log.js";
12
+ export { AuditLogFactory, AUDIT_LOG_ENV, } from "./infrastructure/audit-log-factory.js";
13
+ export type { AuditLogType, AuditLogFactoryConfig, } from "./infrastructure/audit-log-factory.js";
14
+ import type { HsmSlotConfig, HsmKeyPair, HsmSignatureResult, WrappedKey, EncryptedRecord, EnvelopeEncryptionResult, HsmAuditEntry } from "./domain/entities.js";
15
+ /**
16
+ * Software simulation of a PKCS#11-style HSM.
17
+ *
18
+ * Private keys and raw symmetric material are stored inside the object and
19
+ * never returned to callers — only opaque handles or PEM public keys are
20
+ * surfaced externally. All operations are appended to an immutable audit log.
21
+ *
22
+ * Ref: PKCS#11 v3.1 — https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.1/pkcs11-curr-v3.1.html
23
+ */
24
+ export declare class HsmClient {
25
+ private initialized;
26
+ private slotId;
27
+ private readonly store;
28
+ private readonly audit;
29
+ private asymmetric;
30
+ private symmetric;
31
+ private envelope;
32
+ initialize(config: HsmSlotConfig): void;
33
+ generateKeyPair(keyLabel: string): HsmKeyPair;
34
+ sign(keyLabel: string, data: string): HsmSignatureResult;
35
+ verify(keyLabel: string, data: string, signature: string): boolean;
36
+ exportPublicKey(keyLabel: string): string;
37
+ generateSymmetricKey(keyLabel: string): void;
38
+ wrapKey(plaintextDek: Buffer, kekLabel: string): WrappedKey;
39
+ unwrapKey(wrapped: WrappedKey): Buffer;
40
+ encryptWithEnvelope(kekLabel: string, plaintext: string): EnvelopeEncryptionResult;
41
+ decryptWithEnvelope(wrappedDek: WrappedKey, encryptedRecord: EncryptedRecord): string;
42
+ getAuditLog(): readonly HsmAuditEntry[];
43
+ private requireAsymmetric;
44
+ private requireSymmetric;
45
+ private requireEnvelope;
46
+ private assertInitialized;
47
+ }
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hsm/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AAGzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EACV,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,aAAa,GACd,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,YAAY,EACZ,qBAAqB,GACtB,MAAM,uCAAuC,CAAC;AAS/C,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,EACd,MAAM,sBAAsB,CAAC;AAO9B;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,QAAQ,CAA0C;IAE1D,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAwBvC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAI7C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB;IAIxD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAIlE,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIzC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5C,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAI3D,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IAItC,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,wBAAwB;IAI3B,mBAAmB,CACjB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,GAC/B,MAAM;IAIT,WAAW,IAAI,SAAS,aAAa,EAAE;IAIvC,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,iBAAiB;CAK1B"}
@@ -0,0 +1,97 @@
1
+ // Application
2
+ export { AsymmetricKeyService } from "./application/asymmetric-key-service.js";
3
+ export { SymmetricKeyService } from "./application/symmetric-key-service.js";
4
+ export { EnvelopeEncryptionService } from "./application/envelope-encryption-service.js";
5
+ // Infrastructure
6
+ export { InMemoryAuditLog } from "./infrastructure/audit-log.js";
7
+ export { InMemoryKeyStore } from "./infrastructure/key-store.js";
8
+ export { FileAuditLog } from "./infrastructure/file-audit-log.js";
9
+ export { SyslogAuditLog, DEFAULT_SYSLOG_CONFIG, } from "./infrastructure/syslog-audit-log.js";
10
+ export { AuditLogFactory, AUDIT_LOG_ENV, } from "./infrastructure/audit-log-factory.js";
11
+ import { AsymmetricKeyService } from "./application/asymmetric-key-service.js";
12
+ import { SymmetricKeyService } from "./application/symmetric-key-service.js";
13
+ import { EnvelopeEncryptionService } from "./application/envelope-encryption-service.js";
14
+ import { InMemoryAuditLog } from "./infrastructure/audit-log.js";
15
+ import { InMemoryKeyStore } from "./infrastructure/key-store.js";
16
+ /**
17
+ * Software simulation of a PKCS#11-style HSM.
18
+ *
19
+ * Private keys and raw symmetric material are stored inside the object and
20
+ * never returned to callers — only opaque handles or PEM public keys are
21
+ * surfaced externally. All operations are appended to an immutable audit log.
22
+ *
23
+ * Ref: PKCS#11 v3.1 — https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.1/pkcs11-curr-v3.1.html
24
+ */
25
+ export class HsmClient {
26
+ initialized = false;
27
+ slotId = "";
28
+ store = new InMemoryKeyStore();
29
+ audit = new InMemoryAuditLog();
30
+ asymmetric = null;
31
+ symmetric = null;
32
+ envelope = null;
33
+ initialize(config) {
34
+ if (config.slotId.trim().length === 0) {
35
+ throw new Error("HSM initialize: slotId must not be empty");
36
+ }
37
+ if (config.label.trim().length === 0) {
38
+ throw new Error("HSM initialize: label must not be empty");
39
+ }
40
+ if (this.initialized) {
41
+ throw new Error(`HSM already initialized on slot '${this.slotId}' — create a new HsmClient instance for a different slot`);
42
+ }
43
+ this.slotId = config.slotId;
44
+ this.asymmetric = new AsymmetricKeyService(this.store, this.audit, this.slotId);
45
+ this.symmetric = new SymmetricKeyService(this.store, this.audit);
46
+ this.envelope = new EnvelopeEncryptionService(this.symmetric, this.audit);
47
+ this.initialized = true;
48
+ this.audit.record("initialize", config.slotId, "success", config.label);
49
+ }
50
+ generateKeyPair(keyLabel) {
51
+ return this.requireAsymmetric().generateKeyPair(keyLabel);
52
+ }
53
+ sign(keyLabel, data) {
54
+ return this.requireAsymmetric().sign(keyLabel, data);
55
+ }
56
+ verify(keyLabel, data, signature) {
57
+ return this.requireAsymmetric().verify(keyLabel, data, signature);
58
+ }
59
+ exportPublicKey(keyLabel) {
60
+ return this.requireAsymmetric().exportPublicKey(keyLabel);
61
+ }
62
+ generateSymmetricKey(keyLabel) {
63
+ this.requireSymmetric().generateSymmetricKey(keyLabel);
64
+ }
65
+ wrapKey(plaintextDek, kekLabel) {
66
+ return this.requireSymmetric().wrapKey(plaintextDek, kekLabel);
67
+ }
68
+ unwrapKey(wrapped) {
69
+ return this.requireSymmetric().unwrapKey(wrapped);
70
+ }
71
+ encryptWithEnvelope(kekLabel, plaintext) {
72
+ return this.requireEnvelope().encrypt(kekLabel, plaintext);
73
+ }
74
+ decryptWithEnvelope(wrappedDek, encryptedRecord) {
75
+ return this.requireEnvelope().decrypt(wrappedDek, encryptedRecord);
76
+ }
77
+ getAuditLog() {
78
+ return this.audit.entries();
79
+ }
80
+ requireAsymmetric() {
81
+ this.assertInitialized();
82
+ return this.asymmetric;
83
+ }
84
+ requireSymmetric() {
85
+ this.assertInitialized();
86
+ return this.symmetric;
87
+ }
88
+ requireEnvelope() {
89
+ this.assertInitialized();
90
+ return this.envelope;
91
+ }
92
+ assertInitialized() {
93
+ if (!this.initialized) {
94
+ throw new Error("HSM not initialized: call initialize() first");
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,59 @@
1
+ import type { AuditLog } from "../domain/ports.js";
2
+ import { type SyslogConfig } from "./syslog-audit-log.js";
3
+ /**
4
+ * Audit log adapter types supported by the factory.
5
+ */
6
+ export type AuditLogType = "memory" | "file" | "syslog";
7
+ /**
8
+ * Configuration for creating audit log instances.
9
+ */
10
+ export interface AuditLogFactoryConfig {
11
+ /** Type of audit log adapter. Default: "memory" */
12
+ type: AuditLogType;
13
+ /** File path for FileAuditLog (required when type is "file") */
14
+ filePath?: string;
15
+ /** Syslog configuration for SyslogAuditLog (optional when type is "syslog") */
16
+ syslogConfig?: Partial<SyslogConfig>;
17
+ }
18
+ /**
19
+ * Environment variable names for audit log configuration.
20
+ */
21
+ export declare const AUDIT_LOG_ENV: {
22
+ readonly TYPE: "HSM_AUDIT_LOG_TYPE";
23
+ readonly FILE_PATH: "HSM_AUDIT_LOG_PATH";
24
+ readonly SYSLOG_HOST: "HSM_SYSLOG_HOST";
25
+ readonly SYSLOG_PORT: "HSM_SYSLOG_PORT";
26
+ readonly SYSLOG_FACILITY: "HSM_SYSLOG_FACILITY";
27
+ readonly SYSLOG_APP_NAME: "HSM_SYSLOG_APP_NAME";
28
+ };
29
+ /**
30
+ * Factory for creating audit log instances based on configuration.
31
+ *
32
+ * Supports three adapter types:
33
+ * - "memory": In-memory (default, for development/testing)
34
+ * - "file": Append-only file with cryptographic chaining
35
+ * - "syslog": RFC 5424 syslog for enterprise SIEM integration
36
+ *
37
+ * Configuration can be provided via:
38
+ * - Direct config object
39
+ * - Environment variables (for production)
40
+ */
41
+ export declare class AuditLogFactory {
42
+ /**
43
+ * Create an audit log instance from explicit configuration.
44
+ */
45
+ static create(config: AuditLogFactoryConfig): AuditLog;
46
+ /**
47
+ * Create an audit log instance from environment variables.
48
+ *
49
+ * Environment variables:
50
+ * - HSM_AUDIT_LOG_TYPE: "memory" | "file" | "syslog" (default: "memory")
51
+ * - HSM_AUDIT_LOG_PATH: file path for FileAuditLog
52
+ * - HSM_SYSLOG_HOST: syslog server hostname
53
+ * - HSM_SYSLOG_PORT: syslog server port
54
+ * - HSM_SYSLOG_FACILITY: syslog facility name
55
+ * - HSM_SYSLOG_APP_NAME: application name for syslog
56
+ */
57
+ static createFromEnv(env?: NodeJS.ProcessEnv): AuditLog;
58
+ }
59
+ //# sourceMappingURL=audit-log-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log-factory.d.ts","sourceRoot":"","sources":["../../../src/hsm/infrastructure/audit-log-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,IAAI,EAAE,YAAY,CAAC;IACnB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;CAOhB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,QAAQ;IAuBtD;;;;;;;;;;OAUG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,QAAQ;CA8CrE"}
@@ -0,0 +1,95 @@
1
+ import { InMemoryAuditLog } from "./audit-log.js";
2
+ import { FileAuditLog } from "./file-audit-log.js";
3
+ import { SyslogAuditLog } from "./syslog-audit-log.js";
4
+ /**
5
+ * Environment variable names for audit log configuration.
6
+ */
7
+ export const AUDIT_LOG_ENV = {
8
+ TYPE: "HSM_AUDIT_LOG_TYPE",
9
+ FILE_PATH: "HSM_AUDIT_LOG_PATH",
10
+ SYSLOG_HOST: "HSM_SYSLOG_HOST",
11
+ SYSLOG_PORT: "HSM_SYSLOG_PORT",
12
+ SYSLOG_FACILITY: "HSM_SYSLOG_FACILITY",
13
+ SYSLOG_APP_NAME: "HSM_SYSLOG_APP_NAME",
14
+ };
15
+ /**
16
+ * Factory for creating audit log instances based on configuration.
17
+ *
18
+ * Supports three adapter types:
19
+ * - "memory": In-memory (default, for development/testing)
20
+ * - "file": Append-only file with cryptographic chaining
21
+ * - "syslog": RFC 5424 syslog for enterprise SIEM integration
22
+ *
23
+ * Configuration can be provided via:
24
+ * - Direct config object
25
+ * - Environment variables (for production)
26
+ */
27
+ export class AuditLogFactory {
28
+ /**
29
+ * Create an audit log instance from explicit configuration.
30
+ */
31
+ static create(config) {
32
+ switch (config.type) {
33
+ case "memory":
34
+ return new InMemoryAuditLog();
35
+ case "file":
36
+ if (!config.filePath) {
37
+ throw new Error("AuditLogFactory: filePath is required when type is 'file'");
38
+ }
39
+ return new FileAuditLog(config.filePath);
40
+ case "syslog":
41
+ return new SyslogAuditLog(config.syslogConfig);
42
+ default:
43
+ throw new Error(`AuditLogFactory: unknown audit log type '${config.type}'`);
44
+ }
45
+ }
46
+ /**
47
+ * Create an audit log instance from environment variables.
48
+ *
49
+ * Environment variables:
50
+ * - HSM_AUDIT_LOG_TYPE: "memory" | "file" | "syslog" (default: "memory")
51
+ * - HSM_AUDIT_LOG_PATH: file path for FileAuditLog
52
+ * - HSM_SYSLOG_HOST: syslog server hostname
53
+ * - HSM_SYSLOG_PORT: syslog server port
54
+ * - HSM_SYSLOG_FACILITY: syslog facility name
55
+ * - HSM_SYSLOG_APP_NAME: application name for syslog
56
+ */
57
+ static createFromEnv(env = process.env) {
58
+ const type = env[AUDIT_LOG_ENV.TYPE] || "memory";
59
+ const config = { type };
60
+ if (type === "file") {
61
+ const filePath = env[AUDIT_LOG_ENV.FILE_PATH];
62
+ if (filePath) {
63
+ config.filePath = filePath;
64
+ }
65
+ }
66
+ if (type === "syslog") {
67
+ const syslogConfig = {};
68
+ const host = env[AUDIT_LOG_ENV.SYSLOG_HOST];
69
+ if (host) {
70
+ syslogConfig.host = host;
71
+ }
72
+ const port = env[AUDIT_LOG_ENV.SYSLOG_PORT];
73
+ if (port) {
74
+ const parsedPort = parseInt(port, 10);
75
+ if (!Number.isFinite(parsedPort) ||
76
+ !Number.isInteger(parsedPort) ||
77
+ parsedPort < 1 ||
78
+ parsedPort > 65535) {
79
+ throw new Error(`AuditLogFactory: invalid ${AUDIT_LOG_ENV.SYSLOG_PORT} value '${port}'. Expected an integer between 1 and 65535`);
80
+ }
81
+ syslogConfig.port = parsedPort;
82
+ }
83
+ const facility = env[AUDIT_LOG_ENV.SYSLOG_FACILITY];
84
+ if (facility) {
85
+ syslogConfig.facility = facility;
86
+ }
87
+ const appName = env[AUDIT_LOG_ENV.SYSLOG_APP_NAME];
88
+ if (appName) {
89
+ syslogConfig.appName = appName;
90
+ }
91
+ config.syslogConfig = syslogConfig;
92
+ }
93
+ return this.create(config);
94
+ }
95
+ }