ehbp 0.0.7 → 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/README.md +84 -138
- package/dist/cjs/client.d.ts +13 -13
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +32 -52
- 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 +152 -146
- 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 +32 -52
- 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 +152 -146
- 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/esm/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/esm/identity.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { CipherSuite,
|
|
1
|
+
import { CipherSuite, KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM, } from 'hpke';
|
|
2
2
|
import { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
3
|
+
import { deriveResponseKeys, decryptChunk, hexToBytes, bytesToHex, HPKE_REQUEST_INFO, EXPORT_LABEL, EXPORT_LENGTH, RESPONSE_NONCE_LENGTH, } from './derive.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new CipherSuite for X25519/HKDF-SHA256/AES-256-GCM
|
|
6
|
+
*/
|
|
7
|
+
function createSuite() {
|
|
8
|
+
return new CipherSuite(KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM);
|
|
9
|
+
}
|
|
3
10
|
/**
|
|
4
11
|
* Identity class for managing HPKE key pairs and encryption/decryption
|
|
5
12
|
*/
|
|
@@ -16,48 +23,34 @@ export class Identity {
|
|
|
16
23
|
* Generate a new identity with X25519 key pair
|
|
17
24
|
*/
|
|
18
25
|
static async generate() {
|
|
19
|
-
const suite =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
aead: new Aes256Gcm()
|
|
23
|
-
});
|
|
24
|
-
const { publicKey, privateKey } = await suite.kem.generateKeyPair();
|
|
25
|
-
// Make sure the public key is extractable for serialization
|
|
26
|
-
const extractablePublicKey = await crypto.subtle.importKey('raw', await crypto.subtle.exportKey('raw', publicKey), { name: 'X25519' }, true, // extractable
|
|
27
|
-
[]);
|
|
28
|
-
return new Identity(suite, extractablePublicKey, privateKey);
|
|
26
|
+
const suite = createSuite();
|
|
27
|
+
const { publicKey, privateKey } = await suite.GenerateKeyPair(true); // extractable
|
|
28
|
+
return new Identity(suite, publicKey, privateKey);
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Create identity from JSON string
|
|
32
32
|
*/
|
|
33
33
|
static async fromJSON(json) {
|
|
34
34
|
const data = JSON.parse(json);
|
|
35
|
-
const suite =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
// Import public key
|
|
41
|
-
const publicKey = await crypto.subtle.importKey('raw', new Uint8Array(data.publicKey), { name: 'X25519' }, true, // extractable
|
|
42
|
-
[]);
|
|
43
|
-
// Deserialize private key using HPKE library
|
|
44
|
-
const privateKey = await suite.kem.deserializePrivateKey(new Uint8Array(data.privateKey).buffer);
|
|
35
|
+
const suite = createSuite();
|
|
36
|
+
// Deserialize keys using the suite
|
|
37
|
+
const publicKey = await suite.DeserializePublicKey(new Uint8Array(data.publicKey));
|
|
38
|
+
const privateKey = await suite.DeserializePrivateKey(new Uint8Array(data.privateKey), true);
|
|
45
39
|
return new Identity(suite, publicKey, privateKey);
|
|
46
40
|
}
|
|
47
41
|
/**
|
|
48
42
|
* Convert identity to JSON string
|
|
49
43
|
*/
|
|
50
44
|
async toJSON() {
|
|
51
|
-
const publicKeyBytes =
|
|
52
|
-
|
|
53
|
-
const privateKeyBytes = await this.suite.kem.serializePrivateKey(this.privateKey);
|
|
45
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
46
|
+
const privateKeyBytes = await this.suite.SerializePrivateKey(this.privateKey);
|
|
54
47
|
return JSON.stringify({
|
|
55
48
|
publicKey: Array.from(publicKeyBytes),
|
|
56
|
-
privateKey: Array.from(
|
|
49
|
+
privateKey: Array.from(privateKeyBytes),
|
|
57
50
|
});
|
|
58
51
|
}
|
|
59
52
|
/**
|
|
60
|
-
* Get public key
|
|
53
|
+
* Get public key
|
|
61
54
|
*/
|
|
62
55
|
getPublicKey() {
|
|
63
56
|
return this.publicKey;
|
|
@@ -66,13 +59,11 @@ export class Identity {
|
|
|
66
59
|
* Get public key as hex string
|
|
67
60
|
*/
|
|
68
61
|
async getPublicKeyHex() {
|
|
69
|
-
const exported = await
|
|
70
|
-
return
|
|
71
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
|
72
|
-
.join('');
|
|
62
|
+
const exported = await this.suite.SerializePublicKey(this.publicKey);
|
|
63
|
+
return bytesToHex(exported);
|
|
73
64
|
}
|
|
74
65
|
/**
|
|
75
|
-
* Get private key
|
|
66
|
+
* Get private key
|
|
76
67
|
*/
|
|
77
68
|
getPrivateKey() {
|
|
78
69
|
return this.privateKey;
|
|
@@ -86,7 +77,7 @@ export class Identity {
|
|
|
86
77
|
const kdfId = HPKE_CONFIG.KDF;
|
|
87
78
|
const aeadId = HPKE_CONFIG.AEAD;
|
|
88
79
|
// Export public key as raw bytes
|
|
89
|
-
const publicKeyBytes =
|
|
80
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
90
81
|
// Key ID (1 byte) + KEM ID (2 bytes) + Public Key + Cipher Suites
|
|
91
82
|
const keyId = 0;
|
|
92
83
|
const publicKeySize = publicKeyBytes.length;
|
|
@@ -96,20 +87,20 @@ export class Identity {
|
|
|
96
87
|
// Key ID
|
|
97
88
|
buffer[offset++] = keyId;
|
|
98
89
|
// KEM ID
|
|
99
|
-
buffer[offset++] = (kemId >> 8) &
|
|
100
|
-
buffer[offset++] = kemId &
|
|
90
|
+
buffer[offset++] = (kemId >> 8) & 0xff;
|
|
91
|
+
buffer[offset++] = kemId & 0xff;
|
|
101
92
|
// Public Key
|
|
102
93
|
buffer.set(publicKeyBytes, offset);
|
|
103
94
|
offset += publicKeySize;
|
|
104
95
|
// Cipher Suites Length (2 bytes)
|
|
105
|
-
buffer[offset++] = (cipherSuitesSize >> 8) &
|
|
106
|
-
buffer[offset++] = cipherSuitesSize &
|
|
96
|
+
buffer[offset++] = (cipherSuitesSize >> 8) & 0xff;
|
|
97
|
+
buffer[offset++] = cipherSuitesSize & 0xff;
|
|
107
98
|
// KDF ID
|
|
108
|
-
buffer[offset++] = (kdfId >> 8) &
|
|
109
|
-
buffer[offset++] = kdfId &
|
|
99
|
+
buffer[offset++] = (kdfId >> 8) & 0xff;
|
|
100
|
+
buffer[offset++] = kdfId & 0xff;
|
|
110
101
|
// AEAD ID
|
|
111
|
-
buffer[offset++] = (aeadId >> 8) &
|
|
112
|
-
buffer[offset++] = aeadId &
|
|
102
|
+
buffer[offset++] = (aeadId >> 8) & 0xff;
|
|
103
|
+
buffer[offset++] = aeadId & 0xff;
|
|
113
104
|
return buffer;
|
|
114
105
|
}
|
|
115
106
|
/**
|
|
@@ -144,140 +135,155 @@ export class Identity {
|
|
|
144
135
|
if (firstSuite.kdfId !== HPKE_CONFIG.KDF || firstSuite.aeadId !== HPKE_CONFIG.AEAD) {
|
|
145
136
|
throw new Error(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
146
137
|
}
|
|
147
|
-
// Create cipher suite
|
|
148
|
-
const suite =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
aead: new Aes256Gcm()
|
|
152
|
-
});
|
|
153
|
-
// Import public key using HPKE library
|
|
154
|
-
const publicKey = await suite.kem.deserializePublicKey(publicKeyBytes.buffer);
|
|
138
|
+
// Create cipher suite
|
|
139
|
+
const suite = createSuite();
|
|
140
|
+
// Import public key
|
|
141
|
+
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
155
142
|
// For server config, we only have the public key, no private key
|
|
156
143
|
// We'll create a dummy private key that won't be used
|
|
157
|
-
const dummyPrivateKey = await suite.
|
|
144
|
+
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
158
145
|
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
159
146
|
}
|
|
160
147
|
/**
|
|
161
|
-
* Encrypt request body and
|
|
148
|
+
* Encrypt request body and return context for response decryption.
|
|
149
|
+
*
|
|
150
|
+
* This method is called on the SERVER's identity (public key only).
|
|
151
|
+
* It:
|
|
152
|
+
* 1. Creates an HPKE sender context to this identity's public key
|
|
153
|
+
* 2. Encrypts the request body
|
|
154
|
+
* 3. Returns a RequestContext that must be used to decrypt the response
|
|
162
155
|
*/
|
|
163
|
-
async
|
|
156
|
+
async encryptRequestWithContext(request) {
|
|
164
157
|
const body = await request.arrayBuffer();
|
|
158
|
+
// Bodyless requests pass through unmodified - no HPKE context needed.
|
|
159
|
+
// See SPEC.md Section 5.1: "When the request has no payload body, an encrypted
|
|
160
|
+
// response is not possible (since there is no HPKE context to derive response
|
|
161
|
+
// keys from). Such requests pass through unmodified."
|
|
165
162
|
if (body.byteLength === 0) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
163
|
+
return {
|
|
164
|
+
request: new Request(request.url, {
|
|
165
|
+
method: request.method,
|
|
166
|
+
headers: request.headers,
|
|
167
|
+
body: null,
|
|
168
|
+
}),
|
|
169
|
+
context: null,
|
|
170
|
+
};
|
|
174
171
|
}
|
|
175
|
-
// Create sender for encryption
|
|
176
|
-
const
|
|
177
|
-
|
|
172
|
+
// Create sender context for encryption with info parameter for domain separation
|
|
173
|
+
const infoBytes = new TextEncoder().encode(HPKE_REQUEST_INFO);
|
|
174
|
+
const { encapsulatedSecret, ctx } = await this.suite.SetupSender(this.publicKey, {
|
|
175
|
+
info: infoBytes,
|
|
178
176
|
});
|
|
177
|
+
// Store context for response decryption
|
|
178
|
+
const context = {
|
|
179
|
+
senderContext: ctx,
|
|
180
|
+
requestEnc: encapsulatedSecret,
|
|
181
|
+
};
|
|
182
|
+
// Set headers - only encapsulated key for requests with body
|
|
183
|
+
const headers = new Headers(request.headers);
|
|
184
|
+
headers.set(PROTOCOL.ENCAPSULATED_KEY_HEADER, bytesToHex(context.requestEnc));
|
|
179
185
|
// Encrypt the body
|
|
180
|
-
const encrypted = await
|
|
181
|
-
// Get encapsulated key
|
|
182
|
-
const encapKey = sender.enc;
|
|
186
|
+
const encrypted = await ctx.Seal(new Uint8Array(body));
|
|
183
187
|
// Create chunked format: 4-byte length header + encrypted data
|
|
184
188
|
const chunkLength = new Uint8Array(4);
|
|
185
|
-
|
|
186
|
-
view.setUint32(0, encrypted.byteLength, false); // Big-endian
|
|
189
|
+
new DataView(chunkLength.buffer).setUint32(0, encrypted.byteLength, false);
|
|
187
190
|
const chunkedData = new Uint8Array(4 + encrypted.byteLength);
|
|
188
191
|
chunkedData.set(chunkLength, 0);
|
|
189
|
-
chunkedData.set(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
body: chunkedData,
|
|
200
|
-
duplex: 'half'
|
|
201
|
-
});
|
|
192
|
+
chunkedData.set(encrypted, 4);
|
|
193
|
+
return {
|
|
194
|
+
request: new Request(request.url, {
|
|
195
|
+
method: request.method,
|
|
196
|
+
headers,
|
|
197
|
+
body: chunkedData,
|
|
198
|
+
duplex: 'half',
|
|
199
|
+
}),
|
|
200
|
+
context,
|
|
201
|
+
};
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
|
-
* Decrypt response
|
|
204
|
+
* Decrypt response using keys derived from request context.
|
|
205
|
+
*
|
|
206
|
+
* This method:
|
|
207
|
+
* 1. Reads the response nonce from Ehbp-Response-Nonce header
|
|
208
|
+
* 2. Exports a secret from the HPKE sender context
|
|
209
|
+
* 3. Derives response keys using HKDF
|
|
210
|
+
* 4. Decrypts the response body
|
|
205
211
|
*/
|
|
206
|
-
async
|
|
212
|
+
async decryptResponseWithContext(response, context) {
|
|
207
213
|
if (!response.body) {
|
|
208
214
|
return response;
|
|
209
215
|
}
|
|
210
|
-
//
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
216
|
+
// Get response nonce from header
|
|
217
|
+
const responseNonceHex = response.headers.get(PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
218
|
+
if (!responseNonceHex) {
|
|
219
|
+
throw new Error(`Missing ${PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
220
|
+
}
|
|
221
|
+
const responseNonce = hexToBytes(responseNonceHex);
|
|
222
|
+
if (responseNonce.length !== RESPONSE_NONCE_LENGTH) {
|
|
223
|
+
throw new Error(`Invalid response nonce length: expected ${RESPONSE_NONCE_LENGTH}, got ${responseNonce.length}`);
|
|
224
|
+
}
|
|
225
|
+
// Export secret from request context
|
|
226
|
+
const exportLabelBytes = new TextEncoder().encode(EXPORT_LABEL);
|
|
227
|
+
const exportedSecret = await context.senderContext.Export(exportLabelBytes, EXPORT_LENGTH);
|
|
228
|
+
// Derive response keys
|
|
229
|
+
const km = await deriveResponseKeys(exportedSecret, context.requestEnc, responseNonce);
|
|
230
|
+
// Create decrypting stream
|
|
231
|
+
const decryptedStream = this.createDecryptStream(response.body, km);
|
|
232
|
+
return new Response(decryptedStream, {
|
|
233
|
+
status: response.status,
|
|
234
|
+
statusText: response.statusText,
|
|
235
|
+
headers: response.headers,
|
|
214
236
|
});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
buffer =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
continue; // Empty chunk
|
|
242
|
-
}
|
|
243
|
-
// Check if we have the complete chunk
|
|
244
|
-
if (offset + chunkLength > buffer.length) {
|
|
245
|
-
// Not enough data yet, rewind offset and wait for more
|
|
246
|
-
offset -= 4;
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
// Extract and decrypt the chunk
|
|
250
|
-
const encryptedChunk = buffer.slice(offset, offset + chunkLength);
|
|
251
|
-
offset += chunkLength;
|
|
252
|
-
try {
|
|
253
|
-
const decryptedChunk = await receiver.open(encryptedChunk.buffer);
|
|
254
|
-
controller.enqueue(new Uint8Array(decryptedChunk));
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
controller.error(new Error(`Failed to decrypt chunk: ${error}`));
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Creates a ReadableStream that decrypts response chunks.
|
|
240
|
+
*/
|
|
241
|
+
createDecryptStream(body, km) {
|
|
242
|
+
let buffer = new Uint8Array(0);
|
|
243
|
+
let seq = 0;
|
|
244
|
+
const reader = body.getReader();
|
|
245
|
+
return new ReadableStream({
|
|
246
|
+
async pull(controller) {
|
|
247
|
+
while (true) {
|
|
248
|
+
// Try to read a complete chunk from buffer
|
|
249
|
+
if (buffer.length >= 4) {
|
|
250
|
+
const chunkLength = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
|
|
251
|
+
if (chunkLength === 0) {
|
|
252
|
+
// Skip empty chunk
|
|
253
|
+
buffer = buffer.slice(4);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (buffer.length >= 4 + chunkLength) {
|
|
257
|
+
const ciphertext = buffer.slice(4, 4 + chunkLength);
|
|
258
|
+
buffer = buffer.slice(4 + chunkLength);
|
|
259
|
+
try {
|
|
260
|
+
const plaintext = await decryptChunk(km, seq++, ciphertext);
|
|
261
|
+
controller.enqueue(plaintext);
|
|
262
|
+
return;
|
|
260
263
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
offset = 0;
|
|
264
|
+
catch (error) {
|
|
265
|
+
controller.error(new Error(`Decryption failed at chunk ${seq - 1}: ${error}`));
|
|
266
|
+
return;
|
|
265
267
|
}
|
|
266
268
|
}
|
|
267
|
-
controller.close();
|
|
268
269
|
}
|
|
269
|
-
|
|
270
|
-
|
|
270
|
+
// Need more data
|
|
271
|
+
const { done, value } = await reader.read();
|
|
272
|
+
if (done) {
|
|
273
|
+
controller.close();
|
|
274
|
+
return;
|
|
271
275
|
}
|
|
276
|
+
// Append to buffer
|
|
277
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
278
|
+
newBuffer.set(buffer);
|
|
279
|
+
newBuffer.set(value, buffer.length);
|
|
280
|
+
buffer = newBuffer;
|
|
272
281
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
status: response.status,
|
|
279
|
-
statusText: response.statusText,
|
|
280
|
-
headers: response.headers
|
|
282
|
+
},
|
|
283
|
+
cancel(reason) {
|
|
284
|
+
// Release the underlying reader when the stream is cancelled
|
|
285
|
+
return reader.cancel(reason);
|
|
286
|
+
},
|
|
281
287
|
});
|
|
282
288
|
}
|
|
283
289
|
}
|
package/dist/esm/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/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/esm/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/esm/index.js
CHANGED
|
@@ -8,4 +8,6 @@
|
|
|
8
8
|
export { Identity } from './identity.js';
|
|
9
9
|
export { Transport, createTransport } from './client.js';
|
|
10
10
|
export { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
11
|
+
// Export key derivation utilities for advanced usage
|
|
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';
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEtD,qDAAqD;AACrD,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"}
|
package/dist/esm/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";
|
package/dist/esm/protocol.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const PROTOCOL = {
|
|
5
5
|
ENCAPSULATED_KEY_HEADER: 'Ehbp-Encapsulated-Key',
|
|
6
|
-
|
|
6
|
+
RESPONSE_NONCE_HEADER: 'Ehbp-Response-Nonce',
|
|
7
7
|
KEYS_MEDIA_TYPE: 'application/ohttp-keys',
|
|
8
8
|
KEYS_PATH: '/.well-known/hpke-keys',
|
|
9
|
-
FALLBACK_HEADER: 'Ehbp-Fallback'
|
|
9
|
+
FALLBACK_HEADER: 'Ehbp-Fallback',
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
12
|
* HPKE suite configuration matching the Go implementation
|
package/dist/esm/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;IACnC,eAAe,EAAE,eAAe;CACxB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,GAAG,EAAE,MAAM,EAAE,qBAAqB;IAClC,GAAG,EAAE,MAAM,EAAE,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC,cAAc;CACnB,CAAC"}
|