burnledger 0.4.0 → 0.6.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 (104) hide show
  1. package/README.md +11 -4
  2. package/dist/cjs/anchor.d.ts +71 -0
  3. package/dist/cjs/anchor.d.ts.map +1 -0
  4. package/dist/cjs/anchor.js +279 -0
  5. package/dist/cjs/anchor.js.map +1 -0
  6. package/dist/cjs/client.d.ts +26 -2
  7. package/dist/cjs/client.d.ts.map +1 -1
  8. package/dist/cjs/client.js +27 -5
  9. package/dist/cjs/client.js.map +1 -1
  10. package/dist/cjs/enclave-seal.d.ts +101 -0
  11. package/dist/cjs/enclave-seal.d.ts.map +1 -0
  12. package/dist/cjs/enclave-seal.js +479 -0
  13. package/dist/cjs/enclave-seal.js.map +1 -0
  14. package/dist/cjs/errors.d.ts +42 -1
  15. package/dist/cjs/errors.d.ts.map +1 -1
  16. package/dist/cjs/errors.js +44 -2
  17. package/dist/cjs/errors.js.map +1 -1
  18. package/dist/cjs/http.d.ts +21 -1
  19. package/dist/cjs/http.d.ts.map +1 -1
  20. package/dist/cjs/http.js +76 -12
  21. package/dist/cjs/http.js.map +1 -1
  22. package/dist/cjs/index.browser.d.ts +2 -4
  23. package/dist/cjs/index.browser.d.ts.map +1 -1
  24. package/dist/cjs/index.browser.js.map +1 -1
  25. package/dist/cjs/index.d.ts +16 -11
  26. package/dist/cjs/index.d.ts.map +1 -1
  27. package/dist/cjs/index.js +20 -1
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/keys.d.ts +66 -0
  30. package/dist/cjs/keys.d.ts.map +1 -1
  31. package/dist/cjs/keys.js +128 -3
  32. package/dist/cjs/keys.js.map +1 -1
  33. package/dist/cjs/models.d.ts +41 -3
  34. package/dist/cjs/models.d.ts.map +1 -1
  35. package/dist/cjs/models.js +25 -4
  36. package/dist/cjs/models.js.map +1 -1
  37. package/dist/cjs/verify.d.ts +72 -6
  38. package/dist/cjs/verify.d.ts.map +1 -1
  39. package/dist/cjs/verify.js +392 -62
  40. package/dist/cjs/verify.js.map +1 -1
  41. package/dist/cjs/web-verifier.d.ts +54 -5
  42. package/dist/cjs/web-verifier.d.ts.map +1 -1
  43. package/dist/cjs/web-verifier.js +36 -3
  44. package/dist/cjs/web-verifier.js.map +1 -1
  45. package/dist/esm/anchor.d.ts +71 -0
  46. package/dist/esm/anchor.d.ts.map +1 -0
  47. package/dist/esm/anchor.js +275 -0
  48. package/dist/esm/anchor.js.map +1 -0
  49. package/dist/esm/cli.d.ts +45 -14
  50. package/dist/esm/cli.d.ts.map +1 -1
  51. package/dist/esm/cli.js +357 -50
  52. package/dist/esm/cli.js.map +1 -1
  53. package/dist/esm/client.d.ts +26 -2
  54. package/dist/esm/client.d.ts.map +1 -1
  55. package/dist/esm/client.js +27 -5
  56. package/dist/esm/client.js.map +1 -1
  57. package/dist/esm/enclave-seal.d.ts +101 -0
  58. package/dist/esm/enclave-seal.d.ts.map +1 -0
  59. package/dist/esm/enclave-seal.js +472 -0
  60. package/dist/esm/enclave-seal.js.map +1 -0
  61. package/dist/esm/errors.d.ts +42 -1
  62. package/dist/esm/errors.d.ts.map +1 -1
  63. package/dist/esm/errors.js +43 -1
  64. package/dist/esm/errors.js.map +1 -1
  65. package/dist/esm/http.d.ts +21 -1
  66. package/dist/esm/http.d.ts.map +1 -1
  67. package/dist/esm/http.js +75 -12
  68. package/dist/esm/http.js.map +1 -1
  69. package/dist/esm/index.browser.d.ts +2 -4
  70. package/dist/esm/index.browser.d.ts.map +1 -1
  71. package/dist/esm/index.browser.js.map +1 -1
  72. package/dist/esm/index.d.ts +16 -11
  73. package/dist/esm/index.d.ts.map +1 -1
  74. package/dist/esm/index.js +11 -2
  75. package/dist/esm/index.js.map +1 -1
  76. package/dist/esm/keys.d.ts +66 -0
  77. package/dist/esm/keys.d.ts.map +1 -1
  78. package/dist/esm/keys.js +125 -3
  79. package/dist/esm/keys.js.map +1 -1
  80. package/dist/esm/models.d.ts +41 -3
  81. package/dist/esm/models.d.ts.map +1 -1
  82. package/dist/esm/models.js +24 -4
  83. package/dist/esm/models.js.map +1 -1
  84. package/dist/esm/verify.d.ts +72 -6
  85. package/dist/esm/verify.d.ts.map +1 -1
  86. package/dist/esm/verify.js +390 -63
  87. package/dist/esm/verify.js.map +1 -1
  88. package/dist/esm/web-verifier.d.ts +54 -5
  89. package/dist/esm/web-verifier.d.ts.map +1 -1
  90. package/dist/esm/web-verifier.js +40 -3
  91. package/dist/esm/web-verifier.js.map +1 -1
  92. package/package.json +1 -1
  93. package/src/anchor.ts +330 -0
  94. package/src/cli.ts +389 -54
  95. package/src/client.ts +46 -4
  96. package/src/enclave-seal.ts +582 -0
  97. package/src/errors.ts +47 -2
  98. package/src/http.ts +79 -12
  99. package/src/index.browser.ts +2 -2
  100. package/src/index.ts +28 -9
  101. package/src/keys.ts +176 -3
  102. package/src/models.ts +72 -7
  103. package/src/verify.ts +467 -72
  104. package/src/web-verifier.ts +58 -5
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Seal a connection config to the enclave, so the BurnLedger host never reads it.
3
+ *
4
+ * WHY THIS MODULE EXISTS. Registering a system used to mean POSTing your
5
+ * datastore credentials to the API in the clear. The host then handed them to
6
+ * the enclave to be sealed, and everything after that point was ciphertext only
7
+ * the enclave could open — but the host held the plaintext for the length of
8
+ * that request, and nothing recorded that it had. This removes that step: you
9
+ * seal the config yourself, and the host relays bytes it cannot open.
10
+ *
11
+ * WHAT MAKES IT WORK, AND WHAT WOULD MAKE IT THEATRE. The enclave publishes an
12
+ * X25519 public key inside its AWS Nitro attestation document, beside the
13
+ * Ed25519 signing key it already published. `verifyEnclaveConfigSealKey` checks
14
+ * that document — the COSE signature, the certificate chain to the pinned AWS
15
+ * Nitro root, and the image's PCR0 — and returns the key. Sealing to a key the
16
+ * API simply handed over protects nothing: the host would supply its own key,
17
+ * read the config, and re-seal to the real enclave, and your registration would
18
+ * succeed exactly as it does today. So `sealConnectionConfig` takes the
19
+ * attestation document and the PCR0 you expect, never a bare key.
20
+ *
21
+ * WHERE `expectedPcr0` COMES FROM. Not from this API. A measurement served by
22
+ * the same host that serves the document pins nothing. Take BurnLedger's
23
+ * published measurement for the enclave image out of band and pin it in your own
24
+ * configuration. That is a trust-on-first-use anchor in the operator's
25
+ * publication — the same anchor every other claim in this product rests on.
26
+ *
27
+ * WHAT IT DOES NOT DO. It stops the host reading a config in transit. It does
28
+ * not stop the host composing a config of ITS own and having the enclave seal
29
+ * that, and it does nothing if the machine running this code is compromised.
30
+ *
31
+ * NODE ONLY. Verifying an attestation document needs X.509 chain building,
32
+ * which browsers do not expose, and sealing a datastore credential is not a
33
+ * thing a browser should be doing. This module is not part of the browser entry
34
+ * point.
35
+ */
36
+ /**
37
+ * Envelope wire format (v1). Must match enclave/configsealkey.go byte for byte:
38
+ *
39
+ * magic 8 "BLCFGSL1"
40
+ * recipient 32 the X25519 key this envelope is addressed to
41
+ * ephemeral 32 this sender's one-time X25519 key
42
+ * nonce 12 AES-GCM nonce
43
+ * sealed n AES-256-GCM(plaintext), tag appended
44
+ *
45
+ * The key is HKDF-SHA256 over the X25519 shared secret salted with the whole
46
+ * header; the same header is the GCM additional data.
47
+ */
48
+ export declare const ENVELOPE_MAGIC: Uint8Array<ArrayBuffer>;
49
+ export declare const HEADER_SIZE: number;
50
+ /**
51
+ * The AWS Nitro Enclaves root CA (G1), pinned. A root fetched at runtime is not
52
+ * a pin; this is the anchor the whole verification hangs from.
53
+ */
54
+ export declare const NITRO_ROOT_G1_PEM = "-----BEGIN CERTIFICATE-----\nMIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYD\nVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4\nMTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQL\nDANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEG\nBSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb\n48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZE\nh8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkF\nR+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYC\nMQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPW\nrfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6N\nIwLz3/Y=\n-----END CERTIFICATE-----\n";
55
+ /** Raised when an attestation document is not one this client will seal to. */
56
+ export declare class EnclaveAttestationError extends Error {
57
+ constructor(message: string);
58
+ }
59
+ export interface SealOptions {
60
+ /** Hex PCR0 of the enclave image you accept, pinned out of band. Required. */
61
+ expectedPcr0: string;
62
+ /** Further PCRs to pin, hex-encoded, by index. */
63
+ expectedPcrs?: Record<number, string>;
64
+ /** The reference time the document must describe. Defaults to now. */
65
+ now?: Date;
66
+ /**
67
+ * Override the pinned AWS Nitro root. Leave unset in production — a root
68
+ * supplied per call is not a pin.
69
+ */
70
+ rootPem?: string;
71
+ }
72
+ /**
73
+ * Seal `config` to the enclave the attestation document describes. Pass the
74
+ * result as `sealed_connection_config` when registering a system.
75
+ *
76
+ * Throws {@link EnclaveAttestationError} if the document is not a genuine Nitro
77
+ * attestation from the pinned image. Nothing is sealed in that case.
78
+ */
79
+ export declare function sealConnectionConfig(config: Record<string, unknown> | string | Uint8Array, attestationDocument: Uint8Array, options: SealOptions): Promise<Uint8Array>;
80
+ /**
81
+ * Seal `plaintext` to an already-verified enclave config-seal key.
82
+ *
83
+ * Prefer {@link sealConnectionConfig}, which verifies the key for you. This is
84
+ * the lower half, for a caller that verified the document itself.
85
+ */
86
+ export declare function sealToKey(recipientPublicKey: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
87
+ /**
88
+ * Verify an enclave attestation document and return the X25519 config-seal key
89
+ * bound in it.
90
+ *
91
+ * Checks, in order: the COSE_Sign1 structure and its ES384 algorithm; the
92
+ * certificate chain from the document's leaf through its CA bundle to the
93
+ * pinned AWS Nitro root; the ES384 signature over the RFC 8152 Sig_structure;
94
+ * the document's own AWS-signed timestamp against `now`; the PCRs; and that the
95
+ * bound key is 32 bytes.
96
+ *
97
+ * PCR0 must be pinned. Without it any genuinely-signed Nitro document — including
98
+ * one from an enclave the host itself booted — would pass.
99
+ */
100
+ export declare function verifyEnclaveConfigSealKey(attestationDocument: Uint8Array, options: SealOptions): Promise<Uint8Array>;
101
+ //# sourceMappingURL=enclave-seal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enclave-seal.d.ts","sourceRoot":"","sources":["../../src/enclave-seal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,yBAAmE,CAAC;AAG/F,eAAO,MAAM,WAAW,QAAoD,CAAC;AAG7E;;;GAGG;AACH,eAAO,MAAM,iBAAiB,6xBAc7B,CAAC;AAMF,+EAA+E;AAC/E,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,sEAAsE;IACtE,GAAG,CAAC,EAAE,IAAI,CAAC;IACX;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,UAAU,EACrD,mBAAmB,EAAE,UAAU,EAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,kBAAkB,EAAE,UAAU,EAC9B,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,UAAU,CAAC,CAuCrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,0BAA0B,CAC9C,mBAAmB,EAAE,UAAU,EAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8CrB"}
@@ -0,0 +1,479 @@
1
+ "use strict";
2
+ /**
3
+ * Seal a connection config to the enclave, so the BurnLedger host never reads it.
4
+ *
5
+ * WHY THIS MODULE EXISTS. Registering a system used to mean POSTing your
6
+ * datastore credentials to the API in the clear. The host then handed them to
7
+ * the enclave to be sealed, and everything after that point was ciphertext only
8
+ * the enclave could open — but the host held the plaintext for the length of
9
+ * that request, and nothing recorded that it had. This removes that step: you
10
+ * seal the config yourself, and the host relays bytes it cannot open.
11
+ *
12
+ * WHAT MAKES IT WORK, AND WHAT WOULD MAKE IT THEATRE. The enclave publishes an
13
+ * X25519 public key inside its AWS Nitro attestation document, beside the
14
+ * Ed25519 signing key it already published. `verifyEnclaveConfigSealKey` checks
15
+ * that document — the COSE signature, the certificate chain to the pinned AWS
16
+ * Nitro root, and the image's PCR0 — and returns the key. Sealing to a key the
17
+ * API simply handed over protects nothing: the host would supply its own key,
18
+ * read the config, and re-seal to the real enclave, and your registration would
19
+ * succeed exactly as it does today. So `sealConnectionConfig` takes the
20
+ * attestation document and the PCR0 you expect, never a bare key.
21
+ *
22
+ * WHERE `expectedPcr0` COMES FROM. Not from this API. A measurement served by
23
+ * the same host that serves the document pins nothing. Take BurnLedger's
24
+ * published measurement for the enclave image out of band and pin it in your own
25
+ * configuration. That is a trust-on-first-use anchor in the operator's
26
+ * publication — the same anchor every other claim in this product rests on.
27
+ *
28
+ * WHAT IT DOES NOT DO. It stops the host reading a config in transit. It does
29
+ * not stop the host composing a config of ITS own and having the enclave seal
30
+ * that, and it does nothing if the machine running this code is compromised.
31
+ *
32
+ * NODE ONLY. Verifying an attestation document needs X.509 chain building,
33
+ * which browsers do not expose, and sealing a datastore credential is not a
34
+ * thing a browser should be doing. This module is not part of the browser entry
35
+ * point.
36
+ */
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.EnclaveAttestationError = exports.NITRO_ROOT_G1_PEM = exports.HEADER_SIZE = exports.ENVELOPE_MAGIC = void 0;
39
+ exports.sealConnectionConfig = sealConnectionConfig;
40
+ exports.sealToKey = sealToKey;
41
+ exports.verifyEnclaveConfigSealKey = verifyEnclaveConfigSealKey;
42
+ const node_crypto_1 = require("node:crypto");
43
+ /**
44
+ * Envelope wire format (v1). Must match enclave/configsealkey.go byte for byte:
45
+ *
46
+ * magic 8 "BLCFGSL1"
47
+ * recipient 32 the X25519 key this envelope is addressed to
48
+ * ephemeral 32 this sender's one-time X25519 key
49
+ * nonce 12 AES-GCM nonce
50
+ * sealed n AES-256-GCM(plaintext), tag appended
51
+ *
52
+ * The key is HKDF-SHA256 over the X25519 shared secret salted with the whole
53
+ * header; the same header is the GCM additional data.
54
+ */
55
+ exports.ENVELOPE_MAGIC = new Uint8Array([0x42, 0x4c, 0x43, 0x46, 0x47, 0x53, 0x4c, 0x31]); // "BLCFGSL1"
56
+ const KEY_SIZE = 32;
57
+ const NONCE_SIZE = 12;
58
+ exports.HEADER_SIZE = exports.ENVELOPE_MAGIC.length + 2 * KEY_SIZE + NONCE_SIZE;
59
+ const KDF_INFO = new TextEncoder().encode("burnledger/config-seal/v1");
60
+ /**
61
+ * The AWS Nitro Enclaves root CA (G1), pinned. A root fetched at runtime is not
62
+ * a pin; this is the anchor the whole verification hangs from.
63
+ */
64
+ exports.NITRO_ROOT_G1_PEM = `-----BEGIN CERTIFICATE-----
65
+ MIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTEL
66
+ MAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYD
67
+ VQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4
68
+ MTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQL
69
+ DANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEG
70
+ BSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb
71
+ 48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZE
72
+ h8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkF
73
+ R+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYC
74
+ MQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPW
75
+ rfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6N
76
+ IwLz3/Y=
77
+ -----END CERTIFICATE-----
78
+ `;
79
+ /** Same bound as enclave.MaxAttestationClockSkew. */
80
+ const MAX_CLOCK_SKEW_MS = 5 * 60 * 1000;
81
+ const COSE_ALG_ES384 = -35;
82
+ /** Raised when an attestation document is not one this client will seal to. */
83
+ class EnclaveAttestationError extends Error {
84
+ constructor(message) {
85
+ super(message);
86
+ this.name = "EnclaveAttestationError";
87
+ }
88
+ }
89
+ exports.EnclaveAttestationError = EnclaveAttestationError;
90
+ /**
91
+ * Seal `config` to the enclave the attestation document describes. Pass the
92
+ * result as `sealed_connection_config` when registering a system.
93
+ *
94
+ * Throws {@link EnclaveAttestationError} if the document is not a genuine Nitro
95
+ * attestation from the pinned image. Nothing is sealed in that case.
96
+ */
97
+ async function sealConnectionConfig(config, attestationDocument, options) {
98
+ const key = await verifyEnclaveConfigSealKey(attestationDocument, options);
99
+ return sealToKey(key, configBytes(config));
100
+ }
101
+ /**
102
+ * Seal `plaintext` to an already-verified enclave config-seal key.
103
+ *
104
+ * Prefer {@link sealConnectionConfig}, which verifies the key for you. This is
105
+ * the lower half, for a caller that verified the document itself.
106
+ */
107
+ async function sealToKey(recipientPublicKey, plaintext) {
108
+ if (recipientPublicKey.length !== KEY_SIZE) {
109
+ throw new EnclaveAttestationError(`config-seal recipient key is ${recipientPublicKey.length} bytes, want ${KEY_SIZE}`);
110
+ }
111
+ let peer;
112
+ try {
113
+ peer = await node_crypto_1.webcrypto.subtle.importKey("raw", bufferSource(recipientPublicKey), { name: "X25519" }, false, []);
114
+ }
115
+ catch (err) {
116
+ throw new EnclaveAttestationError(`config-seal recipient key: ${err.message}`);
117
+ }
118
+ const ephemeral = (await node_crypto_1.webcrypto.subtle.generateKey({ name: "X25519" }, true, [
119
+ "deriveBits",
120
+ ]));
121
+ const shared = new Uint8Array(await node_crypto_1.webcrypto.subtle.deriveBits({ name: "X25519", public: peer }, ephemeral.privateKey, 256));
122
+ const ephemeralPublic = new Uint8Array(await node_crypto_1.webcrypto.subtle.exportKey("raw", ephemeral.publicKey));
123
+ const nonce = node_crypto_1.webcrypto.getRandomValues(new Uint8Array(NONCE_SIZE));
124
+ const header = concat(exports.ENVELOPE_MAGIC, recipientPublicKey, ephemeralPublic, nonce);
125
+ const aesKey = await deriveEnvelopeKey(shared, header);
126
+ const sealed = new Uint8Array(await node_crypto_1.webcrypto.subtle.encrypt({ name: "AES-GCM", iv: nonce, additionalData: header }, aesKey, bufferSource(plaintext)));
127
+ return concat(header, sealed);
128
+ }
129
+ /**
130
+ * Verify an enclave attestation document and return the X25519 config-seal key
131
+ * bound in it.
132
+ *
133
+ * Checks, in order: the COSE_Sign1 structure and its ES384 algorithm; the
134
+ * certificate chain from the document's leaf through its CA bundle to the
135
+ * pinned AWS Nitro root; the ES384 signature over the RFC 8152 Sig_structure;
136
+ * the document's own AWS-signed timestamp against `now`; the PCRs; and that the
137
+ * bound key is 32 bytes.
138
+ *
139
+ * PCR0 must be pinned. Without it any genuinely-signed Nitro document — including
140
+ * one from an enclave the host itself booted — would pass.
141
+ */
142
+ async function verifyEnclaveConfigSealKey(attestationDocument, options) {
143
+ if (!attestationDocument || attestationDocument.length === 0) {
144
+ throw new EnclaveAttestationError("no attestation document (nothing to verify — this is not a pass)");
145
+ }
146
+ const expected = { ...(options.expectedPcrs ?? {}) };
147
+ if (options.expectedPcr0)
148
+ expected[0] = options.expectedPcr0;
149
+ if (expected[0] === undefined) {
150
+ throw new EnclaveAttestationError("no expected PCR0; refusing to accept an unpinned enclave image");
151
+ }
152
+ const now = options.now ?? new Date();
153
+ const { protected: protectedBytes, payload: payloadBytes, signature } = decodeCoseSign1(attestationDocument);
154
+ checkAlgEs384(protectedBytes);
155
+ const payload = cborDecode(payloadBytes);
156
+ if (!(payload instanceof Map)) {
157
+ throw new EnclaveAttestationError("attestation payload is not a CBOR map");
158
+ }
159
+ const leafDer = payload.get("certificate");
160
+ if (!(leafDer instanceof Uint8Array) || leafDer.length === 0) {
161
+ throw new EnclaveAttestationError("attestation payload missing certificate");
162
+ }
163
+ const pcrs = payload.get("pcrs");
164
+ if (!(pcrs instanceof Map)) {
165
+ throw new EnclaveAttestationError("attestation payload missing pcrs");
166
+ }
167
+ const leaf = verifyChain(leafDer, payload.get("cabundle"), now, options.rootPem ?? exports.NITRO_ROOT_G1_PEM);
168
+ verifyCoseSignature(leaf, protectedBytes, payloadBytes, signature);
169
+ checkClock(payload.get("timestamp"), now);
170
+ matchPcrs(pcrs, expected);
171
+ const publicKey = payload.get("public_key");
172
+ if (!(publicKey instanceof Uint8Array) || publicKey.length !== KEY_SIZE) {
173
+ const got = publicKey instanceof Uint8Array ? publicKey.length : 0;
174
+ throw new EnclaveAttestationError(`the document binds a ${got}-byte public key, want a ${KEY_SIZE}-byte X25519 ` +
175
+ "config-seal key (this enclave image may not publish one)");
176
+ }
177
+ return publicKey;
178
+ }
179
+ // --- verification internals -------------------------------------------------
180
+ /**
181
+ * Build and verify leaf -> cabundle -> pinned root, valid at `now`.
182
+ *
183
+ * The path is not general: the NSM hands over an ORDERED bundle, root first, so
184
+ * the chain is walked in order and every hop must check out. Nothing is
185
+ * searched for an alternative path — an ambiguous chain is a refusal.
186
+ */
187
+ function verifyChain(leafDer, cabundle, now, rootPem) {
188
+ let root;
189
+ try {
190
+ root = new node_crypto_1.X509Certificate(rootPem);
191
+ }
192
+ catch (err) {
193
+ throw new EnclaveAttestationError(`pinned Nitro root is unreadable: ${err.message}`);
194
+ }
195
+ if (!Array.isArray(cabundle) || cabundle.length === 0) {
196
+ throw new EnclaveAttestationError("attestation payload carries no CA bundle");
197
+ }
198
+ const chain = [];
199
+ cabundle.forEach((der, i) => {
200
+ if (!(der instanceof Uint8Array)) {
201
+ throw new EnclaveAttestationError(`cabundle[${i}] is not a byte string`);
202
+ }
203
+ try {
204
+ chain.push(new node_crypto_1.X509Certificate(Buffer.from(der)));
205
+ }
206
+ catch (err) {
207
+ throw new EnclaveAttestationError(`cabundle[${i}] is not a certificate: ${err.message}`);
208
+ }
209
+ });
210
+ let leaf;
211
+ try {
212
+ leaf = new node_crypto_1.X509Certificate(Buffer.from(leafDer));
213
+ }
214
+ catch (err) {
215
+ throw new EnclaveAttestationError(`leaf certificate is unreadable: ${err.message}`);
216
+ }
217
+ if (chain[0].fingerprint256 !== root.fingerprint256) {
218
+ throw new EnclaveAttestationError("the document's CA bundle does not start at the pinned AWS Nitro root");
219
+ }
220
+ const ordered = [...chain, leaf];
221
+ for (const cert of ordered)
222
+ checkValidity(cert, now);
223
+ for (let i = 1; i < ordered.length; i++) {
224
+ const issuer = ordered[i - 1];
225
+ const subject = ordered[i];
226
+ if (!subject.checkIssued(issuer) || !subject.verify(issuer.publicKey)) {
227
+ throw new EnclaveAttestationError(`certificate chain is broken at ${subject.subject.replace(/\n/g, ", ")}`);
228
+ }
229
+ }
230
+ return leaf;
231
+ }
232
+ function checkValidity(cert, now) {
233
+ const from = Date.parse(cert.validFrom);
234
+ const to = Date.parse(cert.validTo);
235
+ if (Number.isNaN(from) || Number.isNaN(to)) {
236
+ throw new EnclaveAttestationError(`certificate ${cert.subject.replace(/\n/g, ", ")} has an unreadable validity window`);
237
+ }
238
+ const t = now.getTime();
239
+ if (t < from || t > to) {
240
+ throw new EnclaveAttestationError(`certificate ${cert.subject.replace(/\n/g, ", ")} is not valid at ${now.toISOString()} ` +
241
+ `(valid ${new Date(from).toISOString()} to ${new Date(to).toISOString()})`);
242
+ }
243
+ }
244
+ function verifyCoseSignature(leaf, protectedBytes, payload, signature) {
245
+ if (signature.length !== 96) {
246
+ throw new EnclaveAttestationError(`signature is ${signature.length} bytes, want 96 (P-384 r||s)`);
247
+ }
248
+ const sigStructure = cborEncode(["Signature1", protectedBytes, new Uint8Array(0), payload]);
249
+ // ieee-p1363 is the raw r||s pair COSE carries; the default would expect DER.
250
+ const ok = (0, node_crypto_1.verify)("sha384", sigStructure, { key: leaf.publicKey, dsaEncoding: "ieee-p1363" }, signature);
251
+ if (!ok)
252
+ throw new EnclaveAttestationError("the attestation COSE signature is invalid");
253
+ }
254
+ function checkClock(timestamp, now) {
255
+ if (typeof timestamp !== "number" || !Number.isFinite(timestamp) || timestamp <= 0) {
256
+ throw new EnclaveAttestationError("the document carries no timestamp (nothing to check the clock against)");
257
+ }
258
+ const skew = Math.abs(now.getTime() - timestamp);
259
+ if (skew > MAX_CLOCK_SKEW_MS) {
260
+ throw new EnclaveAttestationError(`the NSM signed this document at ${new Date(timestamp).toISOString()} but it is being ` +
261
+ `verified against ${now.toISOString()} — ${Math.round(skew / 1000)}s of clock skew ` +
262
+ `exceeds the ${MAX_CLOCK_SKEW_MS / 1000}s bound`);
263
+ }
264
+ }
265
+ function matchPcrs(actual, expected) {
266
+ for (const [key, wantHex] of Object.entries(expected)) {
267
+ const index = Number(key);
268
+ const got = actual.get(index);
269
+ if (!(got instanceof Uint8Array)) {
270
+ throw new EnclaveAttestationError(`the document carries no PCR${index}`);
271
+ }
272
+ if (toHex(got) !== wantHex.toLowerCase()) {
273
+ throw new EnclaveAttestationError(`PCR${index} is ${toHex(got)}, expected ${wantHex} — this is not the enclave image you pinned`);
274
+ }
275
+ }
276
+ }
277
+ async function deriveEnvelopeKey(shared, header) {
278
+ const ikm = await node_crypto_1.webcrypto.subtle.importKey("raw", bufferSource(shared), "HKDF", false, [
279
+ "deriveKey",
280
+ ]);
281
+ return node_crypto_1.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt: header, info: KDF_INFO }, ikm, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
282
+ }
283
+ function configBytes(config) {
284
+ if (config instanceof Uint8Array)
285
+ return config;
286
+ if (typeof config === "string")
287
+ return new TextEncoder().encode(config);
288
+ return new TextEncoder().encode(JSON.stringify(config));
289
+ }
290
+ /**
291
+ * Copy into a view whose backing store TypeScript knows is a plain ArrayBuffer.
292
+ *
293
+ * WebCrypto's `BufferSource` excludes `SharedArrayBuffer`-backed views, and a
294
+ * `Uint8Array` parameter is `Uint8Array<ArrayBufferLike>`, which could be one.
295
+ * The copy is what makes that provably false rather than asserted away with a
296
+ * cast; the buffers here are a few kilobytes at most.
297
+ */
298
+ function bufferSource(b) {
299
+ return new Uint8Array(b);
300
+ }
301
+ function concat(...parts) {
302
+ const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
303
+ let offset = 0;
304
+ for (const p of parts) {
305
+ out.set(p, offset);
306
+ offset += p.length;
307
+ }
308
+ return out;
309
+ }
310
+ function toHex(b) {
311
+ return Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
312
+ }
313
+ // --- a CBOR subset ----------------------------------------------------------
314
+ //
315
+ // Enough of RFC 8949 to read an NSM attestation document and re-encode the
316
+ // fixed four-element Sig_structure. Hand-rolled because this SDK ships with no
317
+ // runtime dependencies, which is a published contract. Indefinite-length items
318
+ // are refused rather than supported: a genuine NSM document uses definite
319
+ // lengths throughout, and accepting two encodings for one value is how
320
+ // signature checks get bypassed.
321
+ function decodeCoseSign1(doc) {
322
+ const body = doc[0] === 0xd2 ? doc.subarray(1) : doc; // CBOR tag 18
323
+ const value = cborDecode(body);
324
+ if (!Array.isArray(value) || value.length !== 4) {
325
+ throw new EnclaveAttestationError("COSE_Sign1 must be a 4-element array");
326
+ }
327
+ const [prot, , payload, signature] = value;
328
+ for (const [name, item] of [
329
+ ["protected header", prot],
330
+ ["payload", payload],
331
+ ["signature", signature],
332
+ ]) {
333
+ if (!(item instanceof Uint8Array)) {
334
+ throw new EnclaveAttestationError(`COSE_Sign1 ${name} is not a byte string`);
335
+ }
336
+ }
337
+ return {
338
+ protected: prot,
339
+ payload: payload,
340
+ signature: signature,
341
+ };
342
+ }
343
+ function checkAlgEs384(protectedBytes) {
344
+ if (protectedBytes.length === 0) {
345
+ throw new EnclaveAttestationError("empty COSE protected header (no alg)");
346
+ }
347
+ const header = cborDecode(protectedBytes);
348
+ if (!(header instanceof Map) || !header.has(1)) {
349
+ throw new EnclaveAttestationError("COSE protected header missing alg");
350
+ }
351
+ const alg = header.get(1);
352
+ if (alg !== COSE_ALG_ES384) {
353
+ throw new EnclaveAttestationError(`COSE alg is ${alg}, want ES384 (${COSE_ALG_ES384})`);
354
+ }
355
+ }
356
+ function cborDecode(data) {
357
+ const [value, offset] = cborRead(data, 0);
358
+ if (offset !== data.length) {
359
+ throw new EnclaveAttestationError(`${data.length - offset} trailing bytes after the CBOR value`);
360
+ }
361
+ return value;
362
+ }
363
+ function cborRead(data, start) {
364
+ if (start >= data.length)
365
+ throw new EnclaveAttestationError("CBOR input ended mid-value");
366
+ const initial = data[start];
367
+ const major = initial >> 5;
368
+ const info = initial & 0x1f;
369
+ let i = start + 1;
370
+ let arg;
371
+ if (info < 24) {
372
+ arg = info;
373
+ }
374
+ else if (info === 24)
375
+ [arg, i] = cborUint(data, i, 1);
376
+ else if (info === 25)
377
+ [arg, i] = cborUint(data, i, 2);
378
+ else if (info === 26)
379
+ [arg, i] = cborUint(data, i, 4);
380
+ else if (info === 27)
381
+ [arg, i] = cborUint(data, i, 8);
382
+ else if (info === 31) {
383
+ throw new EnclaveAttestationError("indefinite-length CBOR items are not accepted");
384
+ }
385
+ else
386
+ throw new EnclaveAttestationError(`reserved CBOR additional information ${info}`);
387
+ switch (major) {
388
+ case 0:
389
+ return [arg, i];
390
+ case 1:
391
+ return [-1 - arg, i];
392
+ case 2:
393
+ case 3: {
394
+ const end = i + arg;
395
+ if (end > data.length) {
396
+ throw new EnclaveAttestationError("CBOR string runs past the end of the input");
397
+ }
398
+ const chunk = data.subarray(i, end);
399
+ return [major === 2 ? chunk : new TextDecoder("utf-8", { fatal: true }).decode(chunk), end];
400
+ }
401
+ case 4: {
402
+ const items = [];
403
+ for (let n = 0; n < arg; n++) {
404
+ const [item, next] = cborRead(data, i);
405
+ items.push(item);
406
+ i = next;
407
+ }
408
+ return [items, i];
409
+ }
410
+ case 5: {
411
+ const out = new Map();
412
+ for (let n = 0; n < arg; n++) {
413
+ const [key, afterKey] = cborRead(data, i);
414
+ const [val, afterVal] = cborRead(data, afterKey);
415
+ if (out.has(key)) {
416
+ // Two readers could disagree about the same document. Refuse.
417
+ throw new EnclaveAttestationError(`duplicate CBOR map key ${String(key)}`);
418
+ }
419
+ out.set(key, val);
420
+ i = afterVal;
421
+ }
422
+ return [out, i];
423
+ }
424
+ case 6: // tag: transparent, the tagged value is what matters
425
+ return cborRead(data, i);
426
+ case 7:
427
+ if (info === 20)
428
+ return [false, i];
429
+ if (info === 21)
430
+ return [true, i];
431
+ if (info === 22)
432
+ return [null, i];
433
+ throw new EnclaveAttestationError(`unsupported CBOR simple value ${info}`);
434
+ default:
435
+ throw new EnclaveAttestationError(`unsupported CBOR major type ${major}`);
436
+ }
437
+ }
438
+ function cborUint(data, i, width) {
439
+ if (i + width > data.length) {
440
+ throw new EnclaveAttestationError("CBOR integer runs past the end of the input");
441
+ }
442
+ let value = 0;
443
+ for (let n = 0; n < width; n++)
444
+ value = value * 256 + data[i + n];
445
+ if (!Number.isSafeInteger(value)) {
446
+ throw new EnclaveAttestationError("CBOR integer exceeds the safe integer range");
447
+ }
448
+ return [value, i + width];
449
+ }
450
+ function cborEncode(value) {
451
+ if (Array.isArray(value)) {
452
+ return concat(cborHead(4, value.length), ...value.map(cborEncode));
453
+ }
454
+ if (typeof value === "string") {
455
+ const raw = new TextEncoder().encode(value);
456
+ return concat(cborHead(3, raw.length), raw);
457
+ }
458
+ if (value instanceof Uint8Array) {
459
+ return concat(cborHead(2, value.length), value);
460
+ }
461
+ throw new EnclaveAttestationError(`cannot CBOR-encode ${typeof value}`);
462
+ }
463
+ function cborHead(major, arg) {
464
+ const base = major << 5;
465
+ if (arg < 24)
466
+ return new Uint8Array([base | arg]);
467
+ if (arg < 0x100)
468
+ return new Uint8Array([base | 24, arg]);
469
+ if (arg < 0x10000)
470
+ return new Uint8Array([base | 25, arg >> 8, arg & 0xff]);
471
+ return new Uint8Array([
472
+ base | 26,
473
+ (arg >>> 24) & 0xff,
474
+ (arg >>> 16) & 0xff,
475
+ (arg >>> 8) & 0xff,
476
+ arg & 0xff,
477
+ ]);
478
+ }
479
+ //# sourceMappingURL=enclave-seal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enclave-seal.js","sourceRoot":"","sources":["../../src/enclave-seal.ts"],"names":[],"mappings":"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"}
@@ -69,8 +69,49 @@ export declare class TimeoutError extends BurnLedgerError {
69
69
  }
70
70
  export declare class VerificationError extends BurnLedgerError {
71
71
  readonly reason: string;
72
- constructor(reason: string);
72
+ /**
73
+ * A stable discriminator for the one rejection a caller must be able to tell
74
+ * apart from the rest: an authentic status statement that says REVOKED.
75
+ *
76
+ * Every other rejection on the status path — unknown key, revoked key, bad
77
+ * signature, a statement about a different certificate — means the statement
78
+ * could not be authenticated, which is not the same claim and must not be
79
+ * rendered as one. `reason` is prose and may be reworded; this is not.
80
+ *
81
+ * Undefined on every rejection that is not specifically coded.
82
+ */
83
+ readonly code?: string;
84
+ constructor(reason: string, code?: string);
73
85
  }
86
+ /** {@link VerificationError.code} for a verified statement that says REVOKED. */
87
+ export declare const CERTIFICATE_REVOKED = "CERTIFICATE_REVOKED";
88
+ /**
89
+ * The record is in a format this SDK does not know how to read.
90
+ *
91
+ * This is the second rejection a caller must be able to tell apart, for the
92
+ * same reason as the first: it is not a claim about the document. Before this
93
+ * code existed, a record in a newer format fell through to the oldest payload
94
+ * shape, the rebuilt bytes did not match, and the SDK threw "certificate
95
+ * signature is invalid" - telling a holder their genuine evidence had been
96
+ * tampered with when the answer was "upgrade this library".
97
+ *
98
+ * A UI must render it as "cannot check", never as a failure.
99
+ */
100
+ export declare const UNSUPPORTED_FORMAT_VERSION = "UNSUPPORTED_FORMAT_VERSION";
101
+ /**
102
+ * The record names a signature scheme this SDK cannot check.
103
+ *
104
+ * The third rejection a caller must tell apart, for the same reason as the
105
+ * other two: it is not a claim about the document. Records below format 7.0
106
+ * name no algorithm and every verifier simply assumed Ed25519, so had Ed25519
107
+ * needed replacing, a record signed under the replacement would have been fed
108
+ * to an Ed25519 verifier, failed, and been reported as a bad signature — a
109
+ * genuine record accused of forgery for being signed with the algorithm it says
110
+ * it was signed with.
111
+ *
112
+ * A UI must render it as "cannot check", never as a failure.
113
+ */
114
+ export declare const UNSUPPORTED_ALGORITHM = "UNSUPPORTED_ALGORITHM";
74
115
  /** Parse an API error envelope and throw the appropriate exception. */
75
116
  export declare function raiseForError(statusCode: number, body: Record<string, unknown>, retryAfter?: number): never;
76
117
  //# sourceMappingURL=errors.d.ts.map