ehbp 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +158 -0
- package/dist/cjs/client.d.ts +13 -13
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +39 -50
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/derive.d.ts +63 -0
- package/dist/cjs/derive.d.ts.map +1 -0
- package/dist/cjs/derive.js +136 -0
- package/dist/cjs/derive.js.map +1 -0
- package/dist/cjs/identity.d.ts +37 -10
- package/dist/cjs/identity.d.ts.map +1 -1
- package/dist/cjs/identity.js +169 -150
- package/dist/cjs/identity.js.map +1 -1
- package/dist/cjs/index.d.ts +4 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +15 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/protocol.d.ts +1 -1
- package/dist/cjs/protocol.js +2 -2
- package/dist/cjs/protocol.js.map +1 -1
- package/dist/esm/client.d.ts +13 -13
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +39 -50
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/derive.d.ts +63 -0
- package/dist/esm/derive.d.ts.map +1 -0
- package/dist/esm/derive.js +127 -0
- package/dist/esm/derive.js.map +1 -0
- package/dist/esm/identity.d.ts +37 -10
- package/dist/esm/identity.d.ts.map +1 -1
- package/dist/esm/identity.js +169 -150
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocol.d.ts +1 -1
- package/dist/esm/protocol.js +2 -2
- package/dist/esm/protocol.js.map +1 -1
- package/dist/esm/test/client.test.js +15 -16
- package/dist/esm/test/client.test.js.map +1 -1
- package/dist/esm/test/derive.test.d.ts +2 -0
- package/dist/esm/test/derive.test.d.ts.map +1 -0
- package/dist/esm/test/derive.test.js +164 -0
- package/dist/esm/test/derive.test.js.map +1 -0
- package/dist/esm/test/security.test.d.ts +10 -0
- package/dist/esm/test/security.test.d.ts.map +1 -0
- package/dist/esm/test/security.test.js +153 -0
- package/dist/esm/test/security.test.js.map +1 -0
- package/dist/esm/test/streaming.integration.d.ts +9 -0
- package/dist/esm/test/streaming.integration.d.ts.map +1 -0
- package/dist/esm/test/streaming.integration.js +190 -0
- package/dist/esm/test/streaming.integration.js.map +1 -0
- package/package.json +6 -7
- package/dist/esm/example.d.ts +0 -6
- package/dist/esm/example.d.ts.map +0 -1
- package/dist/esm/example.js +0 -115
- package/dist/esm/example.js.map +0 -1
- package/dist/esm/streaming-test.d.ts +0 -3
- package/dist/esm/streaming-test.d.ts.map +0 -1
- package/dist/esm/streaming-test.js +0 -102
- package/dist/esm/streaming-test.js.map +0 -1
package/dist/cjs/identity.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import { CipherSuite } from '
|
|
1
|
+
import { CipherSuite, type SenderContext, type Key } from 'hpke';
|
|
2
|
+
/**
|
|
3
|
+
* Request context for response decryption.
|
|
4
|
+
* Holds the HPKE sender context needed to derive response keys.
|
|
5
|
+
*/
|
|
6
|
+
export interface RequestContext {
|
|
7
|
+
senderContext: SenderContext;
|
|
8
|
+
requestEnc: Uint8Array;
|
|
9
|
+
}
|
|
2
10
|
/**
|
|
3
11
|
* Identity class for managing HPKE key pairs and encryption/decryption
|
|
4
12
|
*/
|
|
@@ -6,7 +14,7 @@ export declare class Identity {
|
|
|
6
14
|
private suite;
|
|
7
15
|
private publicKey;
|
|
8
16
|
private privateKey;
|
|
9
|
-
constructor(suite: CipherSuite, publicKey:
|
|
17
|
+
constructor(suite: CipherSuite, publicKey: Key, privateKey: Key);
|
|
10
18
|
/**
|
|
11
19
|
* Generate a new identity with X25519 key pair
|
|
12
20
|
*/
|
|
@@ -20,17 +28,17 @@ export declare class Identity {
|
|
|
20
28
|
*/
|
|
21
29
|
toJSON(): Promise<string>;
|
|
22
30
|
/**
|
|
23
|
-
* Get public key
|
|
31
|
+
* Get public key
|
|
24
32
|
*/
|
|
25
|
-
getPublicKey():
|
|
33
|
+
getPublicKey(): Key;
|
|
26
34
|
/**
|
|
27
35
|
* Get public key as hex string
|
|
28
36
|
*/
|
|
29
37
|
getPublicKeyHex(): Promise<string>;
|
|
30
38
|
/**
|
|
31
|
-
* Get private key
|
|
39
|
+
* Get private key
|
|
32
40
|
*/
|
|
33
|
-
getPrivateKey():
|
|
41
|
+
getPrivateKey(): Key;
|
|
34
42
|
/**
|
|
35
43
|
* Marshal public key configuration for server key distribution
|
|
36
44
|
* Implements RFC 9458 format
|
|
@@ -41,12 +49,31 @@ export declare class Identity {
|
|
|
41
49
|
*/
|
|
42
50
|
static unmarshalPublicConfig(data: Uint8Array): Promise<Identity>;
|
|
43
51
|
/**
|
|
44
|
-
* Encrypt request body and
|
|
52
|
+
* Encrypt request body and return context for response decryption.
|
|
53
|
+
*
|
|
54
|
+
* This method is called on the SERVER's identity (public key only).
|
|
55
|
+
* It:
|
|
56
|
+
* 1. Creates an HPKE sender context to this identity's public key
|
|
57
|
+
* 2. Encrypts the request body
|
|
58
|
+
* 3. Returns a RequestContext that must be used to decrypt the response
|
|
59
|
+
*/
|
|
60
|
+
encryptRequestWithContext(request: Request): Promise<{
|
|
61
|
+
request: Request;
|
|
62
|
+
context: RequestContext | null;
|
|
63
|
+
}>;
|
|
64
|
+
/**
|
|
65
|
+
* Decrypt response using keys derived from request context.
|
|
66
|
+
*
|
|
67
|
+
* This method:
|
|
68
|
+
* 1. Reads the response nonce from Ehbp-Response-Nonce header
|
|
69
|
+
* 2. Exports a secret from the HPKE sender context
|
|
70
|
+
* 3. Derives response keys using HKDF
|
|
71
|
+
* 4. Decrypts the response body
|
|
45
72
|
*/
|
|
46
|
-
|
|
73
|
+
decryptResponseWithContext(response: Response, context: RequestContext): Promise<Response>;
|
|
47
74
|
/**
|
|
48
|
-
*
|
|
75
|
+
* Creates a ReadableStream that decrypts response chunks.
|
|
49
76
|
*/
|
|
50
|
-
|
|
77
|
+
private createDecryptStream;
|
|
51
78
|
}
|
|
52
79
|
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAIX,KAAK,aAAa,EAClB,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAcd;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;CACxB;AAaD;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,UAAU,CAAM;gBAEZ,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG;IAM/D;;OAEG;WACU,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAO1C;;OAEG;WACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWtD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAU/B;;OAEG;IACH,YAAY,IAAI,GAAG;IAInB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAKxC;;OAEG;IACH,aAAa,IAAI,GAAG;IAIpB;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IA0C1C;;OAEG;WACU,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqDvE;;;;;;;;OAQG;IACG,yBAAyB,CAC7B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE,CAAC;IAwDhE;;;;;;;;OAQG;IACG,0BAA0B,CAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,QAAQ,CAAC;IAmCpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAyD5B"}
|
package/dist/cjs/identity.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Identity = void 0;
|
|
4
|
-
const
|
|
4
|
+
const hpke_1 = require("hpke");
|
|
5
5
|
const protocol_js_1 = require("./protocol.js");
|
|
6
|
+
const derive_js_1 = require("./derive.js");
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new CipherSuite for X25519/HKDF-SHA256/AES-256-GCM
|
|
9
|
+
*/
|
|
10
|
+
function createSuite() {
|
|
11
|
+
return new hpke_1.CipherSuite(hpke_1.KEM_DHKEM_X25519_HKDF_SHA256, hpke_1.KDF_HKDF_SHA256, hpke_1.AEAD_AES_256_GCM);
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
14
|
* Identity class for managing HPKE key pairs and encryption/decryption
|
|
8
15
|
*/
|
|
@@ -19,48 +26,34 @@ class Identity {
|
|
|
19
26
|
* Generate a new identity with X25519 key pair
|
|
20
27
|
*/
|
|
21
28
|
static async generate() {
|
|
22
|
-
const suite =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
aead: new core_1.Aes256Gcm()
|
|
26
|
-
});
|
|
27
|
-
const { publicKey, privateKey } = await suite.kem.generateKeyPair();
|
|
28
|
-
// Make sure the public key is extractable for serialization
|
|
29
|
-
const extractablePublicKey = await crypto.subtle.importKey('raw', await crypto.subtle.exportKey('raw', publicKey), { name: 'X25519' }, true, // extractable
|
|
30
|
-
[]);
|
|
31
|
-
return new Identity(suite, extractablePublicKey, privateKey);
|
|
29
|
+
const suite = createSuite();
|
|
30
|
+
const { publicKey, privateKey } = await suite.GenerateKeyPair(true); // extractable
|
|
31
|
+
return new Identity(suite, publicKey, privateKey);
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Create identity from JSON string
|
|
35
35
|
*/
|
|
36
36
|
static async fromJSON(json) {
|
|
37
37
|
const data = JSON.parse(json);
|
|
38
|
-
const suite =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
43
|
-
// Import public key
|
|
44
|
-
const publicKey = await crypto.subtle.importKey('raw', new Uint8Array(data.publicKey), { name: 'X25519' }, true, // extractable
|
|
45
|
-
[]);
|
|
46
|
-
// Deserialize private key using HPKE library
|
|
47
|
-
const privateKey = await suite.kem.deserializePrivateKey(new Uint8Array(data.privateKey).buffer);
|
|
38
|
+
const suite = createSuite();
|
|
39
|
+
// Deserialize keys using the suite
|
|
40
|
+
const publicKey = await suite.DeserializePublicKey(new Uint8Array(data.publicKey));
|
|
41
|
+
const privateKey = await suite.DeserializePrivateKey(new Uint8Array(data.privateKey), true);
|
|
48
42
|
return new Identity(suite, publicKey, privateKey);
|
|
49
43
|
}
|
|
50
44
|
/**
|
|
51
45
|
* Convert identity to JSON string
|
|
52
46
|
*/
|
|
53
47
|
async toJSON() {
|
|
54
|
-
const publicKeyBytes =
|
|
55
|
-
|
|
56
|
-
const privateKeyBytes = await this.suite.kem.serializePrivateKey(this.privateKey);
|
|
48
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
49
|
+
const privateKeyBytes = await this.suite.SerializePrivateKey(this.privateKey);
|
|
57
50
|
return JSON.stringify({
|
|
58
51
|
publicKey: Array.from(publicKeyBytes),
|
|
59
|
-
privateKey: Array.from(
|
|
52
|
+
privateKey: Array.from(privateKeyBytes),
|
|
60
53
|
});
|
|
61
54
|
}
|
|
62
55
|
/**
|
|
63
|
-
* Get public key
|
|
56
|
+
* Get public key
|
|
64
57
|
*/
|
|
65
58
|
getPublicKey() {
|
|
66
59
|
return this.publicKey;
|
|
@@ -69,13 +62,11 @@ class Identity {
|
|
|
69
62
|
* Get public key as hex string
|
|
70
63
|
*/
|
|
71
64
|
async getPublicKeyHex() {
|
|
72
|
-
const exported = await
|
|
73
|
-
return
|
|
74
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
|
75
|
-
.join('');
|
|
65
|
+
const exported = await this.suite.SerializePublicKey(this.publicKey);
|
|
66
|
+
return (0, derive_js_1.bytesToHex)(exported);
|
|
76
67
|
}
|
|
77
68
|
/**
|
|
78
|
-
* Get private key
|
|
69
|
+
* Get private key
|
|
79
70
|
*/
|
|
80
71
|
getPrivateKey() {
|
|
81
72
|
return this.privateKey;
|
|
@@ -89,7 +80,7 @@ class Identity {
|
|
|
89
80
|
const kdfId = protocol_js_1.HPKE_CONFIG.KDF;
|
|
90
81
|
const aeadId = protocol_js_1.HPKE_CONFIG.AEAD;
|
|
91
82
|
// Export public key as raw bytes
|
|
92
|
-
const publicKeyBytes =
|
|
83
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
93
84
|
// Key ID (1 byte) + KEM ID (2 bytes) + Public Key + Cipher Suites
|
|
94
85
|
const keyId = 0;
|
|
95
86
|
const publicKeySize = publicKeyBytes.length;
|
|
@@ -99,20 +90,20 @@ class Identity {
|
|
|
99
90
|
// Key ID
|
|
100
91
|
buffer[offset++] = keyId;
|
|
101
92
|
// KEM ID
|
|
102
|
-
buffer[offset++] = (kemId >> 8) &
|
|
103
|
-
buffer[offset++] = kemId &
|
|
93
|
+
buffer[offset++] = (kemId >> 8) & 0xff;
|
|
94
|
+
buffer[offset++] = kemId & 0xff;
|
|
104
95
|
// Public Key
|
|
105
96
|
buffer.set(publicKeyBytes, offset);
|
|
106
97
|
offset += publicKeySize;
|
|
107
98
|
// Cipher Suites Length (2 bytes)
|
|
108
|
-
buffer[offset++] = (cipherSuitesSize >> 8) &
|
|
109
|
-
buffer[offset++] = cipherSuitesSize &
|
|
99
|
+
buffer[offset++] = (cipherSuitesSize >> 8) & 0xff;
|
|
100
|
+
buffer[offset++] = cipherSuitesSize & 0xff;
|
|
110
101
|
// KDF ID
|
|
111
|
-
buffer[offset++] = (kdfId >> 8) &
|
|
112
|
-
buffer[offset++] = kdfId &
|
|
102
|
+
buffer[offset++] = (kdfId >> 8) & 0xff;
|
|
103
|
+
buffer[offset++] = kdfId & 0xff;
|
|
113
104
|
// AEAD ID
|
|
114
|
-
buffer[offset++] = (aeadId >> 8) &
|
|
115
|
-
buffer[offset++] = aeadId &
|
|
105
|
+
buffer[offset++] = (aeadId >> 8) & 0xff;
|
|
106
|
+
buffer[offset++] = aeadId & 0xff;
|
|
116
107
|
return buffer;
|
|
117
108
|
}
|
|
118
109
|
/**
|
|
@@ -130,144 +121,172 @@ class Identity {
|
|
|
130
121
|
offset += publicKeySize;
|
|
131
122
|
// Read Cipher Suites Length
|
|
132
123
|
const cipherSuitesLength = (data[offset++] << 8) | data[offset++];
|
|
133
|
-
//
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
124
|
+
// Parse all cipher suites (each suite is 4 bytes: 2 for KDF, 2 for AEAD)
|
|
125
|
+
const suites = [];
|
|
126
|
+
const cipherSuitesEnd = offset + cipherSuitesLength;
|
|
127
|
+
while (offset < cipherSuitesEnd) {
|
|
128
|
+
const kdfId = (data[offset++] << 8) | data[offset++];
|
|
129
|
+
const aeadId = (data[offset++] << 8) | data[offset++];
|
|
130
|
+
suites.push({ kdfId, aeadId });
|
|
131
|
+
}
|
|
132
|
+
if (suites.length === 0) {
|
|
133
|
+
throw new Error('No cipher suites found in config');
|
|
134
|
+
}
|
|
135
|
+
// Use the first cipher suite
|
|
136
|
+
const firstSuite = suites[0];
|
|
137
|
+
// Validate that we support this cipher suite
|
|
138
|
+
if (firstSuite.kdfId !== protocol_js_1.HPKE_CONFIG.KDF || firstSuite.aeadId !== protocol_js_1.HPKE_CONFIG.AEAD) {
|
|
139
|
+
throw new Error(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
140
|
+
}
|
|
141
|
+
// Create cipher suite
|
|
142
|
+
const suite = createSuite();
|
|
143
|
+
// Import public key
|
|
144
|
+
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
145
145
|
// For server config, we only have the public key, no private key
|
|
146
146
|
// We'll create a dummy private key that won't be used
|
|
147
|
-
const dummyPrivateKey = await suite.
|
|
147
|
+
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
148
148
|
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
151
|
-
* Encrypt request body and
|
|
151
|
+
* Encrypt request body and return context for response decryption.
|
|
152
|
+
*
|
|
153
|
+
* This method is called on the SERVER's identity (public key only).
|
|
154
|
+
* It:
|
|
155
|
+
* 1. Creates an HPKE sender context to this identity's public key
|
|
156
|
+
* 2. Encrypts the request body
|
|
157
|
+
* 3. Returns a RequestContext that must be used to decrypt the response
|
|
152
158
|
*/
|
|
153
|
-
async
|
|
159
|
+
async encryptRequestWithContext(request) {
|
|
154
160
|
const body = await request.arrayBuffer();
|
|
161
|
+
// Bodyless requests pass through unmodified - no HPKE context needed.
|
|
162
|
+
// See SPEC.md Section 5.1: "When the request has no payload body, an encrypted
|
|
163
|
+
// response is not possible (since there is no HPKE context to derive response
|
|
164
|
+
// keys from). Such requests pass through unmodified."
|
|
155
165
|
if (body.byteLength === 0) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
166
|
+
return {
|
|
167
|
+
request: new Request(request.url, {
|
|
168
|
+
method: request.method,
|
|
169
|
+
headers: request.headers,
|
|
170
|
+
body: null,
|
|
171
|
+
}),
|
|
172
|
+
context: null,
|
|
173
|
+
};
|
|
164
174
|
}
|
|
165
|
-
// Create sender for encryption
|
|
166
|
-
const
|
|
167
|
-
|
|
175
|
+
// Create sender context for encryption with info parameter for domain separation
|
|
176
|
+
const infoBytes = new TextEncoder().encode(derive_js_1.HPKE_REQUEST_INFO);
|
|
177
|
+
const { encapsulatedSecret, ctx } = await this.suite.SetupSender(this.publicKey, {
|
|
178
|
+
info: infoBytes,
|
|
168
179
|
});
|
|
180
|
+
// Store context for response decryption
|
|
181
|
+
const context = {
|
|
182
|
+
senderContext: ctx,
|
|
183
|
+
requestEnc: encapsulatedSecret,
|
|
184
|
+
};
|
|
185
|
+
// Set headers - only encapsulated key for requests with body
|
|
186
|
+
const headers = new Headers(request.headers);
|
|
187
|
+
headers.set(protocol_js_1.PROTOCOL.ENCAPSULATED_KEY_HEADER, (0, derive_js_1.bytesToHex)(context.requestEnc));
|
|
169
188
|
// Encrypt the body
|
|
170
|
-
const encrypted = await
|
|
171
|
-
// Get encapsulated key
|
|
172
|
-
const encapKey = sender.enc;
|
|
189
|
+
const encrypted = await ctx.Seal(new Uint8Array(body));
|
|
173
190
|
// Create chunked format: 4-byte length header + encrypted data
|
|
174
191
|
const chunkLength = new Uint8Array(4);
|
|
175
|
-
|
|
176
|
-
view.setUint32(0, encrypted.byteLength, false); // Big-endian
|
|
192
|
+
new DataView(chunkLength.buffer).setUint32(0, encrypted.byteLength, false);
|
|
177
193
|
const chunkedData = new Uint8Array(4 + encrypted.byteLength);
|
|
178
194
|
chunkedData.set(chunkLength, 0);
|
|
179
|
-
chunkedData.set(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
body: chunkedData,
|
|
190
|
-
duplex: 'half'
|
|
191
|
-
});
|
|
195
|
+
chunkedData.set(encrypted, 4);
|
|
196
|
+
return {
|
|
197
|
+
request: new Request(request.url, {
|
|
198
|
+
method: request.method,
|
|
199
|
+
headers,
|
|
200
|
+
body: chunkedData,
|
|
201
|
+
duplex: 'half',
|
|
202
|
+
}),
|
|
203
|
+
context,
|
|
204
|
+
};
|
|
192
205
|
}
|
|
193
206
|
/**
|
|
194
|
-
* Decrypt response
|
|
207
|
+
* Decrypt response using keys derived from request context.
|
|
208
|
+
*
|
|
209
|
+
* This method:
|
|
210
|
+
* 1. Reads the response nonce from Ehbp-Response-Nonce header
|
|
211
|
+
* 2. Exports a secret from the HPKE sender context
|
|
212
|
+
* 3. Derives response keys using HKDF
|
|
213
|
+
* 4. Decrypts the response body
|
|
195
214
|
*/
|
|
196
|
-
async
|
|
215
|
+
async decryptResponseWithContext(response, context) {
|
|
197
216
|
if (!response.body) {
|
|
198
217
|
return response;
|
|
199
218
|
}
|
|
200
|
-
//
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
219
|
+
// Get response nonce from header
|
|
220
|
+
const responseNonceHex = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
221
|
+
if (!responseNonceHex) {
|
|
222
|
+
throw new Error(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
223
|
+
}
|
|
224
|
+
const responseNonce = (0, derive_js_1.hexToBytes)(responseNonceHex);
|
|
225
|
+
if (responseNonce.length !== derive_js_1.RESPONSE_NONCE_LENGTH) {
|
|
226
|
+
throw new Error(`Invalid response nonce length: expected ${derive_js_1.RESPONSE_NONCE_LENGTH}, got ${responseNonce.length}`);
|
|
227
|
+
}
|
|
228
|
+
// Export secret from request context
|
|
229
|
+
const exportLabelBytes = new TextEncoder().encode(derive_js_1.EXPORT_LABEL);
|
|
230
|
+
const exportedSecret = await context.senderContext.Export(exportLabelBytes, derive_js_1.EXPORT_LENGTH);
|
|
231
|
+
// Derive response keys
|
|
232
|
+
const km = await (0, derive_js_1.deriveResponseKeys)(exportedSecret, context.requestEnc, responseNonce);
|
|
233
|
+
// Create decrypting stream
|
|
234
|
+
const decryptedStream = this.createDecryptStream(response.body, km);
|
|
235
|
+
return new Response(decryptedStream, {
|
|
236
|
+
status: response.status,
|
|
237
|
+
statusText: response.statusText,
|
|
238
|
+
headers: response.headers,
|
|
204
239
|
});
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
buffer =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
continue; // Empty chunk
|
|
232
|
-
}
|
|
233
|
-
// Check if we have the complete chunk
|
|
234
|
-
if (offset + chunkLength > buffer.length) {
|
|
235
|
-
// Not enough data yet, rewind offset and wait for more
|
|
236
|
-
offset -= 4;
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
// Extract and decrypt the chunk
|
|
240
|
-
const encryptedChunk = buffer.slice(offset, offset + chunkLength);
|
|
241
|
-
offset += chunkLength;
|
|
242
|
-
try {
|
|
243
|
-
const decryptedChunk = await receiver.open(encryptedChunk.buffer);
|
|
244
|
-
controller.enqueue(new Uint8Array(decryptedChunk));
|
|
245
|
-
}
|
|
246
|
-
catch (error) {
|
|
247
|
-
controller.error(new Error(`Failed to decrypt chunk: ${error}`));
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Creates a ReadableStream that decrypts response chunks.
|
|
243
|
+
*/
|
|
244
|
+
createDecryptStream(body, km) {
|
|
245
|
+
let buffer = new Uint8Array(0);
|
|
246
|
+
let seq = 0;
|
|
247
|
+
const reader = body.getReader();
|
|
248
|
+
return new ReadableStream({
|
|
249
|
+
async pull(controller) {
|
|
250
|
+
while (true) {
|
|
251
|
+
// Try to read a complete chunk from buffer
|
|
252
|
+
if (buffer.length >= 4) {
|
|
253
|
+
const chunkLength = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
|
|
254
|
+
if (chunkLength === 0) {
|
|
255
|
+
// Skip empty chunk
|
|
256
|
+
buffer = buffer.slice(4);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (buffer.length >= 4 + chunkLength) {
|
|
260
|
+
const ciphertext = buffer.slice(4, 4 + chunkLength);
|
|
261
|
+
buffer = buffer.slice(4 + chunkLength);
|
|
262
|
+
try {
|
|
263
|
+
const plaintext = await (0, derive_js_1.decryptChunk)(km, seq++, ciphertext);
|
|
264
|
+
controller.enqueue(plaintext);
|
|
265
|
+
return;
|
|
250
266
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
offset = 0;
|
|
267
|
+
catch (error) {
|
|
268
|
+
controller.error(new Error(`Decryption failed at chunk ${seq - 1}: ${error}`));
|
|
269
|
+
return;
|
|
255
270
|
}
|
|
256
271
|
}
|
|
257
|
-
controller.close();
|
|
258
272
|
}
|
|
259
|
-
|
|
260
|
-
|
|
273
|
+
// Need more data
|
|
274
|
+
const { done, value } = await reader.read();
|
|
275
|
+
if (done) {
|
|
276
|
+
controller.close();
|
|
277
|
+
return;
|
|
261
278
|
}
|
|
279
|
+
// Append to buffer
|
|
280
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
281
|
+
newBuffer.set(buffer);
|
|
282
|
+
newBuffer.set(value, buffer.length);
|
|
283
|
+
buffer = newBuffer;
|
|
262
284
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
status: response.status,
|
|
269
|
-
statusText: response.statusText,
|
|
270
|
-
headers: response.headers
|
|
285
|
+
},
|
|
286
|
+
cancel(reason) {
|
|
287
|
+
// Release the underlying reader when the stream is cancelled
|
|
288
|
+
return reader.cancel(reason);
|
|
289
|
+
},
|
|
271
290
|
});
|
|
272
291
|
}
|
|
273
292
|
}
|
package/dist/cjs/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
* bodies while preserving HTTP headers for routing.
|
|
7
7
|
*/
|
|
8
8
|
export { Identity } from './identity.js';
|
|
9
|
+
export type { RequestContext } from './identity.js';
|
|
9
10
|
export { Transport, createTransport } from './client.js';
|
|
10
11
|
export { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
11
|
-
export
|
|
12
|
+
export { deriveResponseKeys, computeNonce, encryptChunk, decryptChunk, hexToBytes, bytesToHex, HPKE_REQUEST_INFO, EXPORT_LABEL, EXPORT_LENGTH, RESPONSE_NONCE_LENGTH, AES256_KEY_LENGTH, AES_GCM_NONCE_LENGTH, } from './derive.js';
|
|
13
|
+
export type { ResponseKeyMaterial } from './derive.js';
|
|
14
|
+
export type { CipherSuite, SenderContext, RecipientContext, Key } from 'hpke';
|
|
12
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGtD,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* bodies while preserving HTTP headers for routing.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.HPKE_CONFIG = exports.PROTOCOL = exports.createTransport = exports.Transport = exports.Identity = void 0;
|
|
10
|
+
exports.AES_GCM_NONCE_LENGTH = exports.AES256_KEY_LENGTH = exports.RESPONSE_NONCE_LENGTH = exports.EXPORT_LENGTH = exports.EXPORT_LABEL = exports.HPKE_REQUEST_INFO = exports.bytesToHex = exports.hexToBytes = exports.decryptChunk = exports.encryptChunk = exports.computeNonce = exports.deriveResponseKeys = exports.HPKE_CONFIG = exports.PROTOCOL = exports.createTransport = exports.Transport = exports.Identity = void 0;
|
|
11
11
|
var identity_js_1 = require("./identity.js");
|
|
12
12
|
Object.defineProperty(exports, "Identity", { enumerable: true, get: function () { return identity_js_1.Identity; } });
|
|
13
13
|
var client_js_1 = require("./client.js");
|
|
@@ -16,4 +16,18 @@ Object.defineProperty(exports, "createTransport", { enumerable: true, get: funct
|
|
|
16
16
|
var protocol_js_1 = require("./protocol.js");
|
|
17
17
|
Object.defineProperty(exports, "PROTOCOL", { enumerable: true, get: function () { return protocol_js_1.PROTOCOL; } });
|
|
18
18
|
Object.defineProperty(exports, "HPKE_CONFIG", { enumerable: true, get: function () { return protocol_js_1.HPKE_CONFIG; } });
|
|
19
|
+
// Export key derivation utilities for advanced usage
|
|
20
|
+
var derive_js_1 = require("./derive.js");
|
|
21
|
+
Object.defineProperty(exports, "deriveResponseKeys", { enumerable: true, get: function () { return derive_js_1.deriveResponseKeys; } });
|
|
22
|
+
Object.defineProperty(exports, "computeNonce", { enumerable: true, get: function () { return derive_js_1.computeNonce; } });
|
|
23
|
+
Object.defineProperty(exports, "encryptChunk", { enumerable: true, get: function () { return derive_js_1.encryptChunk; } });
|
|
24
|
+
Object.defineProperty(exports, "decryptChunk", { enumerable: true, get: function () { return derive_js_1.decryptChunk; } });
|
|
25
|
+
Object.defineProperty(exports, "hexToBytes", { enumerable: true, get: function () { return derive_js_1.hexToBytes; } });
|
|
26
|
+
Object.defineProperty(exports, "bytesToHex", { enumerable: true, get: function () { return derive_js_1.bytesToHex; } });
|
|
27
|
+
Object.defineProperty(exports, "HPKE_REQUEST_INFO", { enumerable: true, get: function () { return derive_js_1.HPKE_REQUEST_INFO; } });
|
|
28
|
+
Object.defineProperty(exports, "EXPORT_LABEL", { enumerable: true, get: function () { return derive_js_1.EXPORT_LABEL; } });
|
|
29
|
+
Object.defineProperty(exports, "EXPORT_LENGTH", { enumerable: true, get: function () { return derive_js_1.EXPORT_LENGTH; } });
|
|
30
|
+
Object.defineProperty(exports, "RESPONSE_NONCE_LENGTH", { enumerable: true, get: function () { return derive_js_1.RESPONSE_NONCE_LENGTH; } });
|
|
31
|
+
Object.defineProperty(exports, "AES256_KEY_LENGTH", { enumerable: true, get: function () { return derive_js_1.AES256_KEY_LENGTH; } });
|
|
32
|
+
Object.defineProperty(exports, "AES_GCM_NONCE_LENGTH", { enumerable: true, get: function () { return derive_js_1.AES_GCM_NONCE_LENGTH; } });
|
|
19
33
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AAEjB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,6CAAsD;AAA7C,uGAAA,QAAQ,OAAA;AAAE,0GAAA,WAAW,OAAA;AAE9B,qDAAqD;AACrD,yCAaqB;AAZnB,+GAAA,kBAAkB,OAAA;AAClB,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,8GAAA,iBAAiB,OAAA;AACjB,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AACb,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA"}
|
package/dist/cjs/protocol.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const PROTOCOL: {
|
|
5
5
|
readonly ENCAPSULATED_KEY_HEADER: "Ehbp-Encapsulated-Key";
|
|
6
|
-
readonly
|
|
6
|
+
readonly RESPONSE_NONCE_HEADER: "Ehbp-Response-Nonce";
|
|
7
7
|
readonly KEYS_MEDIA_TYPE: "application/ohttp-keys";
|
|
8
8
|
readonly KEYS_PATH: "/.well-known/hpke-keys";
|
|
9
9
|
readonly FALLBACK_HEADER: "Ehbp-Fallback";
|