ehbp 0.0.7 → 0.1.1

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 (64) hide show
  1. package/README.md +84 -138
  2. package/dist/cjs/client.d.ts +13 -13
  3. package/dist/cjs/client.d.ts.map +1 -1
  4. package/dist/cjs/client.js +30 -55
  5. package/dist/cjs/client.js.map +1 -1
  6. package/dist/cjs/derive.d.ts +63 -0
  7. package/dist/cjs/derive.d.ts.map +1 -0
  8. package/dist/cjs/derive.js +136 -0
  9. package/dist/cjs/derive.js.map +1 -0
  10. package/dist/cjs/identity.d.ts +37 -10
  11. package/dist/cjs/identity.d.ts.map +1 -1
  12. package/dist/cjs/identity.js +152 -146
  13. package/dist/cjs/identity.js.map +1 -1
  14. package/dist/cjs/index.d.ts +4 -1
  15. package/dist/cjs/index.d.ts.map +1 -1
  16. package/dist/cjs/index.js +15 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/protocol.d.ts +1 -2
  19. package/dist/cjs/protocol.d.ts.map +1 -1
  20. package/dist/cjs/protocol.js +1 -2
  21. package/dist/cjs/protocol.js.map +1 -1
  22. package/dist/esm/client.d.ts +13 -13
  23. package/dist/esm/client.d.ts.map +1 -1
  24. package/dist/esm/client.js +30 -55
  25. package/dist/esm/client.js.map +1 -1
  26. package/dist/esm/derive.d.ts +63 -0
  27. package/dist/esm/derive.d.ts.map +1 -0
  28. package/dist/esm/derive.js +127 -0
  29. package/dist/esm/derive.js.map +1 -0
  30. package/dist/esm/identity.d.ts +37 -10
  31. package/dist/esm/identity.d.ts.map +1 -1
  32. package/dist/esm/identity.js +152 -146
  33. package/dist/esm/identity.js.map +1 -1
  34. package/dist/esm/index.d.ts +4 -1
  35. package/dist/esm/index.d.ts.map +1 -1
  36. package/dist/esm/index.js +2 -0
  37. package/dist/esm/index.js.map +1 -1
  38. package/dist/esm/protocol.d.ts +1 -2
  39. package/dist/esm/protocol.d.ts.map +1 -1
  40. package/dist/esm/protocol.js +1 -2
  41. package/dist/esm/protocol.js.map +1 -1
  42. package/dist/esm/test/client.test.js +15 -16
  43. package/dist/esm/test/client.test.js.map +1 -1
  44. package/dist/esm/test/derive.test.d.ts +2 -0
  45. package/dist/esm/test/derive.test.d.ts.map +1 -0
  46. package/dist/esm/test/derive.test.js +164 -0
  47. package/dist/esm/test/derive.test.js.map +1 -0
  48. package/dist/esm/test/security.test.d.ts +10 -0
  49. package/dist/esm/test/security.test.d.ts.map +1 -0
  50. package/dist/esm/test/security.test.js +153 -0
  51. package/dist/esm/test/security.test.js.map +1 -0
  52. package/dist/esm/test/streaming.integration.d.ts +9 -0
  53. package/dist/esm/test/streaming.integration.d.ts.map +1 -0
  54. package/dist/esm/test/streaming.integration.js +190 -0
  55. package/dist/esm/test/streaming.integration.js.map +1 -0
  56. package/package.json +6 -7
  57. package/dist/esm/example.d.ts +0 -6
  58. package/dist/esm/example.d.ts.map +0 -1
  59. package/dist/esm/example.js +0 -115
  60. package/dist/esm/example.js.map +0 -1
  61. package/dist/esm/streaming-test.d.ts +0 -3
  62. package/dist/esm/streaming-test.d.ts.map +0 -1
  63. package/dist/esm/streaming-test.js +0 -102
  64. package/dist/esm/streaming-test.js.map +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  JavaScript/TypeScript client for [Encrypted HTTP Body Protocol (EHBP)](https://github.com/tinfoilsh/encrypted-http-body-protocol).
4
4
 
5
- EHBP encrypts HTTP message bodies end-to-end using HPKE (RFC 9180) while leaving headers in cleartext for routing.
5
+ EHBP encrypts HTTP request and response bodies end-to-end using HPKE ([RFC 9180](https://datatracker.ietf.org/doc/rfc9180/)) while leaving headers in cleartext for routing.
6
6
 
7
7
  ## Installation
8
8
 
@@ -15,198 +15,144 @@ npm install ehbp
15
15
  - Node.js 20+
16
16
  - Works in both Node.js and modern browsers
17
17
 
18
+
18
19
  ## Quick Start
19
20
 
20
21
  ```javascript
21
- import { Identity, createTransport } from 'ehbp';
22
-
23
- async function main() {
24
- // Create client identity
25
- const clientIdentity = await Identity.generate();
22
+ import { createTransport } from 'ehbp';
26
23
 
27
- // Create transport (fetches server public key automatically)
28
- const transport = await createTransport('http://localhost:8080', clientIdentity);
24
+ // Create transport (fetches server public key automatically)
25
+ const transport = await createTransport('https://example.com');
29
26
 
30
- // Make encrypted requests
31
- const response = await transport.post('/secure', 'Hello, World!');
32
- const data = await response.text();
33
- console.log('Response:', data);
34
- }
27
+ // Make encrypted requests - works like fetch()
28
+ const response = await transport.post('/api/data', JSON.stringify({ message: 'hello' }), {
29
+ headers: { 'Content-Type': 'application/json' }
30
+ });
35
31
 
36
- main();
32
+ const data = await response.json();
37
33
  ```
38
34
 
39
- ## API Reference
40
-
41
- ### `Identity`
35
+ ## API
42
36
 
43
- Manages HPKE key pairs for encryption/decryption.
37
+ ### `createTransport(serverURL: string): Promise<Transport>`
44
38
 
45
- #### `Identity.generate(): Promise<Identity>`
46
-
47
- Generates a new identity with X25519 key pair.
39
+ Creates a transport that automatically encrypts requests and decrypts responses.
48
40
 
49
41
  ```javascript
50
- const identity = await Identity.generate();
42
+ const transport = await createTransport('https://example.com');
51
43
  ```
52
44
 
53
- #### `identity.toJSON(): Promise<string>`
45
+ ### `transport.request(input, init?): Promise<Response>`
54
46
 
55
- Serializes the identity to JSON for storage.
47
+ General-purpose method supporting all fetch options.
56
48
 
57
49
  ```javascript
58
- const identityJSON = await identity.toJSON();
59
- await writeFile('identity.json', identityJSON);
50
+ const response = await transport.request('/api/data', {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ body: JSON.stringify({ key: 'value' })
54
+ });
60
55
  ```
61
56
 
62
- #### `Identity.fromJSON(json: string): Promise<Identity>`
63
-
64
- Loads an identity from JSON.
57
+ ### Convenience Methods
65
58
 
66
59
  ```javascript
67
- const json = await readFile('identity.json', 'utf-8');
68
- const identity = await Identity.fromJSON(json);
60
+ await transport.get('/users');
61
+ await transport.post('/users', body, options);
62
+ await transport.put('/users/123', body, options);
63
+ await transport.delete('/users/123');
69
64
  ```
70
65
 
71
- #### `identity.getPublicKeyHex(): Promise<string>`
66
+ ## Browser Usage
72
67
 
73
- Returns the public key as a hex string.
68
+ ```html
69
+ <script type="module">
70
+ import { createTransport } from './dist/browser.js';
74
71
 
75
- ```javascript
76
- const pubKeyHex = await identity.getPublicKeyHex();
77
- console.log('Public key:', pubKeyHex);
72
+ const transport = await createTransport('https://example.com');
73
+ const response = await transport.post('/api', 'Hello!');
74
+ console.log(await response.text());
75
+ </script>
78
76
  ```
79
77
 
80
- ### `Transport`
81
-
82
- HTTP transport that encrypts requests and decrypts responses.
83
-
84
- #### `createTransport(serverURL: string, clientIdentity: Identity): Promise<Transport>`
85
-
86
- Creates a new transport instance.
87
-
88
- ```javascript
89
- const transport = await createTransport('http://localhost:8080', clientIdentity);
90
- ```
78
+ ## Requirements
91
79
 
92
- #### `transport.request(input: RequestInfo | URL, init?: RequestInit): Promise<Response>`
80
+ - Node.js 20+ or modern browsers with Web Crypto API
93
81
 
94
- Makes an encrypted HTTP request. Supports all standard fetch options.
82
+ ## Development
95
83
 
96
- ```javascript
97
- const response = await transport.request('/api/data', {
98
- method: 'POST',
99
- headers: { 'Content-Type': 'application/json' },
100
- body: JSON.stringify({ message: 'hello' })
101
- });
84
+ ```sh
85
+ npm install
86
+ npm run build
87
+ npm test
88
+ npm run build:browser # Browser bundle
102
89
  ```
103
90
 
104
- #### Convenience Methods
91
+ ### Running Examples (Node.js)
105
92
 
106
- - `transport.get(url: string | URL, init?: RequestInit): Promise<Response>`
107
- - `transport.post(url: string | URL, body?: BodyInit, init?: RequestInit): Promise<Response>`
108
- - `transport.put(url: string | URL, body?: BodyInit, init?: RequestInit): Promise<Response>`
109
- - `transport.delete(url: string | URL, init?: RequestInit): Promise<Response>`
93
+ The Node.js example requires a build and an EHBP server running at `http://localhost:8080`:
110
94
 
111
- ## Examples
112
-
113
- ### Saving and Loading Identities
114
-
115
- ```javascript
116
- import { Identity } from 'ehbp';
117
- import { writeFile, readFile } from 'fs/promises';
95
+ ```sh
96
+ # Build first
97
+ npm run build
118
98
 
119
- // Generate and save
120
- const identity = await Identity.generate();
121
- const identityJSON = await identity.toJSON();
122
- await writeFile('client_identity.json', identityJSON);
99
+ # Start the Go server (from parent directory)
100
+ go run pkg/server/main.go
123
101
 
124
- // Load from file
125
- const loadedJSON = await readFile('client_identity.json', 'utf-8');
126
- const loadedIdentity = await Identity.fromJSON(loadedJSON);
102
+ # Run the example (in another terminal)
103
+ npm run example
127
104
  ```
128
105
 
129
- ### Making Different Request Types
106
+ ### Running Examples (Browser)
130
107
 
131
- ```javascript
132
- // GET request
133
- const getResponse = await transport.get('/api/users');
134
- const users = await getResponse.json();
135
-
136
- // POST with JSON
137
- const postResponse = await transport.post(
138
- '/api/users',
139
- JSON.stringify({ name: 'Alice' }),
140
- { headers: { 'Content-Type': 'application/json' } }
141
- );
142
-
143
- // PUT request
144
- const putResponse = await transport.put(
145
- '/api/users/123',
146
- JSON.stringify({ name: 'Bob' }),
147
- { headers: { 'Content-Type': 'application/json' } }
148
- );
149
-
150
- // DELETE request
151
- const deleteResponse = await transport.delete('/api/users/123');
152
- ```
108
+ Browser examples are located in `examples/` and require the browser bundle:
109
+
110
+ ```sh
111
+ # Build the browser bundle
112
+ npm run build:browser
153
113
 
154
- ### Error Handling
114
+ # Start the local dev server
115
+ npm run serve
155
116
 
156
- ```javascript
157
- try {
158
- const response = await transport.post('/secure', 'data');
159
- if (!response.ok) {
160
- console.error('Request failed:', response.status, response.statusText);
161
- }
162
- const data = await response.text();
163
- console.log('Success:', data);
164
- } catch (error) {
165
- console.error('Transport error:', error.message);
166
- }
117
+ # Start the Go EHBP server (from parent directory, in another terminal)
118
+ go run pkg/server/main.go
167
119
  ```
168
120
 
169
- ### Browser Usage
121
+ Then open in your browser:
170
122
 
171
- ```html
172
- <script type="module">
173
- import { Identity, createTransport } from './dist/browser/ehbp.js';
123
+ | Example | URL | Description |
124
+ |---------|-----|-------------|
125
+ | `test.html` | http://localhost:3000/examples/test.html | POST and streaming tests (server: `localhost:8080`) |
126
+ | `chat.html` | http://localhost:3000/examples/chat.html | Chat interface demo (server: `localhost:8443`) |
174
127
 
175
- const identity = await Identity.generate();
176
- const transport = await createTransport('http://localhost:8080', identity);
128
+ **Note:** `chat.html` connects to port 8443 and expects an OpenAI-compatible chat completions API.
177
129
 
178
- const response = await transport.post('/secure', 'Hello from browser!');
179
- const data = await response.text();
180
- console.log(data);
181
- </script>
182
- ```
130
+ ### Running Integration Tests
183
131
 
184
- ## Development
132
+ Integration tests verify streaming functionality against a live server:
185
133
 
186
134
  ```sh
187
- # Install dependencies
188
- npm install
135
+ # Start the Go server (from parent directory)
136
+ go run pkg/server/main.go
189
137
 
190
- # Build
138
+ # Run integration tests (in another terminal)
191
139
  npm run build
192
-
193
- # Run tests
194
- npm test
195
-
196
- # Build browser bundle
197
- npm run build:browser
140
+ npm run test:integration
198
141
  ```
199
142
 
200
- ## Protocol Details
201
-
202
- For the complete protocol specification, see [SPEC.md](../SPEC.md) in the root of the repository.
143
+ ### Commands
203
144
 
204
- ## Reporting Vulnerabilities
145
+ | Command | Description |
146
+ |---------|-------------|
147
+ | `npm test` | Run unit tests (no server required) |
148
+ | `npm run test:integration` | Run streaming integration tests (requires server) |
149
+ | `npm run example` | Run Node.js API demo (requires server) |
150
+ | `npm run serve` | Start local server for browser examples |
205
151
 
206
- Please report security vulnerabilities by either:
152
+ ## Protocol
207
153
 
208
- - Emailing [security@tinfoil.sh](mailto:security@tinfoil.sh)
154
+ See [SPEC.md](../SPEC.md) for the complete protocol specification.
209
155
 
210
- - Opening an issue on GitHub on this repository
156
+ ## Security
211
157
 
212
- We aim to respond to (legitimate) security reports within 24 hours.
158
+ Report vulnerabilities to [security@tinfoil.sh](mailto:security@tinfoil.sh) or open a GitHub issue.
@@ -1,30 +1,30 @@
1
1
  import { Identity } from './identity.js';
2
+ import type { Key } from 'hpke';
2
3
  /**
3
4
  * HTTP transport for EHBP
4
5
  */
5
6
  export declare class Transport {
6
- private clientIdentity;
7
+ private serverIdentity;
7
8
  private serverHost;
8
- private serverPublicKey;
9
- constructor(clientIdentity: Identity, serverHost: string, serverPublicKey: CryptoKey);
9
+ constructor(serverIdentity: Identity, serverHost: string);
10
10
  /**
11
- * Create a new transport by fetching server public key
11
+ * Create a new transport by fetching server public key.
12
12
  */
13
- static create(serverURL: string, clientIdentity: Identity): Promise<Transport>;
13
+ static create(serverURL: string): Promise<Transport>;
14
+ /**
15
+ * Get the server identity
16
+ */
17
+ getServerIdentity(): Identity;
14
18
  /**
15
19
  * Get the server public key
16
20
  */
17
- getServerPublicKey(): CryptoKey;
21
+ getServerPublicKey(): Key;
18
22
  /**
19
23
  * Get the server public key as hex string
20
24
  */
21
25
  getServerPublicKeyHex(): Promise<string>;
22
26
  /**
23
- * Get the client public key
24
- */
25
- getClientPublicKey(): CryptoKey;
26
- /**
27
- * Make an encrypted HTTP request
27
+ * Make an encrypted HTTP request.
28
28
  */
29
29
  request(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
30
30
  /**
@@ -45,7 +45,7 @@ export declare class Transport {
45
45
  delete(url: string | URL, init?: RequestInit): Promise<Response>;
46
46
  }
47
47
  /**
48
- * Create a new transport instance
48
+ * Create a new transport instance.
49
49
  */
50
- export declare function createTransport(serverURL: string, clientIdentity: Identity): Promise<Transport>;
50
+ export declare function createTransport(serverURL: string): Promise<Transport>;
51
51
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAY;gBAEvB,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS;IAMpF;;OAEG;WACU,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAwBpF;;OAEG;IACH,kBAAkB,IAAI,SAAS;IAI/B;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ9C;;OAEG;IACH,kBAAkB,IAAI,SAAS;IAI/B;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IA2F9E;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAInE;;OAEG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIrF;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIpF;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGvE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAErG"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,UAAU,CAAS;gBAEf,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM;IAKxD;;OAEG;WACU,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB1D;;OAEG;IACH,iBAAiB,IAAI,QAAQ;IAI7B;;OAEG;IACH,kBAAkB,IAAI,GAAG;IAIzB;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI9C;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuE9E;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAInE;;OAEG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIrF;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIpF;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGvE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAE3E"}
@@ -8,18 +8,16 @@ const protocol_js_1 = require("./protocol.js");
8
8
  * HTTP transport for EHBP
9
9
  */
10
10
  class Transport {
11
- clientIdentity;
11
+ serverIdentity;
12
12
  serverHost;
13
- serverPublicKey;
14
- constructor(clientIdentity, serverHost, serverPublicKey) {
15
- this.clientIdentity = clientIdentity;
13
+ constructor(serverIdentity, serverHost) {
14
+ this.serverIdentity = serverIdentity;
16
15
  this.serverHost = serverHost;
17
- this.serverPublicKey = serverPublicKey;
18
16
  }
19
17
  /**
20
- * Create a new transport by fetching server public key
18
+ * Create a new transport by fetching server public key.
21
19
  */
22
- static async create(serverURL, clientIdentity) {
20
+ static async create(serverURL) {
23
21
  const url = new URL(serverURL);
24
22
  const serverHost = url.host;
25
23
  // Fetch server public key
@@ -34,33 +32,28 @@ class Transport {
34
32
  }
35
33
  const keysData = new Uint8Array(await response.arrayBuffer());
36
34
  const serverIdentity = await identity_js_1.Identity.unmarshalPublicConfig(keysData);
37
- const serverPublicKey = serverIdentity.getPublicKey();
38
- return new Transport(clientIdentity, serverHost, serverPublicKey);
35
+ return new Transport(serverIdentity, serverHost);
36
+ }
37
+ /**
38
+ * Get the server identity
39
+ */
40
+ getServerIdentity() {
41
+ return this.serverIdentity;
39
42
  }
40
43
  /**
41
44
  * Get the server public key
42
45
  */
43
46
  getServerPublicKey() {
44
- return this.serverPublicKey;
47
+ return this.serverIdentity.getPublicKey();
45
48
  }
46
49
  /**
47
50
  * Get the server public key as hex string
48
51
  */
49
52
  async getServerPublicKeyHex() {
50
- const exported = await crypto.subtle.exportKey('raw', this.serverPublicKey);
51
- const keyBytes = new Uint8Array(exported);
52
- return Array.from(keyBytes)
53
- .map(b => b.toString(16).padStart(2, '0'))
54
- .join('');
55
- }
56
- /**
57
- * Get the client public key
58
- */
59
- getClientPublicKey() {
60
- return this.clientIdentity.getPublicKey();
53
+ return this.serverIdentity.getPublicKeyHex();
61
54
  }
62
55
  /**
63
- * Make an encrypted HTTP request
56
+ * Make an encrypted HTTP request.
64
57
  */
65
58
  async request(input, init) {
66
59
  // Skip EHBP for non-network URLs (data:, blob:)
@@ -99,45 +92,27 @@ class Transport {
99
92
  method,
100
93
  headers,
101
94
  body: requestBody,
102
- duplex: 'half'
95
+ duplex: 'half',
103
96
  });
104
- // Encrypt request body if present (check the original requestBody, not request.body)
105
- if (requestBody !== null && requestBody !== undefined) {
106
- request = await this.clientIdentity.encryptRequest(request, this.serverPublicKey);
107
- }
108
- else {
109
- // No body, just set client public key header
110
- const headers = new Headers(request.headers);
111
- headers.set(protocol_js_1.PROTOCOL.CLIENT_PUBLIC_KEY_HEADER, await this.clientIdentity.getPublicKeyHex());
112
- request = new Request(request.url, {
113
- method: request.method,
114
- headers,
115
- body: null
116
- });
117
- }
97
+ // Encrypt request (returns context for response decryption)
98
+ // For bodyless requests, context will be null and request passes through unmodified
99
+ const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
118
100
  // Make the request
119
- const response = await fetch(request);
101
+ const response = await fetch(encryptedRequest);
120
102
  if (!response.ok) {
121
103
  console.warn(`Server returned non-OK status: ${response.status}`);
122
104
  }
123
- // Check for fallback header - if set, server returned unencrypted response
124
- const fallbackHeader = response.headers.get(protocol_js_1.PROTOCOL.FALLBACK_HEADER);
125
- if (fallbackHeader === '1') {
105
+ // Bodyless requests: context is null, response is plaintext
106
+ if (context === null) {
126
107
  return response;
127
108
  }
128
- // Check for encapsulated key header
129
- const encapKeyHeader = response.headers.get(protocol_js_1.PROTOCOL.ENCAPSULATED_KEY_HEADER);
130
- if (!encapKeyHeader) {
131
- throw new Error(`Missing ${protocol_js_1.PROTOCOL.ENCAPSULATED_KEY_HEADER} encapsulated key header`);
132
- }
133
- // Validate hex encoding
134
- if (!/^[0-9a-fA-F]+$/.test(encapKeyHeader) || encapKeyHeader.length % 2 !== 0) {
135
- throw new Error(`Invalid ${protocol_js_1.PROTOCOL.ENCAPSULATED_KEY_HEADER} header: must be valid hex string with even length`);
109
+ // Check for response nonce header (required for response decryption)
110
+ const responseNonceHeader = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
111
+ if (!responseNonceHeader) {
112
+ throw new Error(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
136
113
  }
137
- // Decode encapsulated key
138
- const serverEncapKey = new Uint8Array(encapKeyHeader.match(/.{2}/g).map(byte => parseInt(byte, 16)));
139
114
  // Decrypt response
140
- return await this.clientIdentity.decryptResponse(response, serverEncapKey);
115
+ return await this.serverIdentity.decryptResponseWithContext(response, context);
141
116
  }
142
117
  /**
143
118
  * Convenience method for GET requests
@@ -166,9 +141,9 @@ class Transport {
166
141
  }
167
142
  exports.Transport = Transport;
168
143
  /**
169
- * Create a new transport instance
144
+ * Create a new transport instance.
170
145
  */
171
- async function createTransport(serverURL, clientIdentity) {
172
- return Transport.create(serverURL, clientIdentity);
146
+ async function createTransport(serverURL) {
147
+ return Transport.create(serverURL);
173
148
  }
174
149
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Response key derivation for EHBP
3
+ *
4
+ * This module implements the key derivation matching the Go implementation.
5
+ *
6
+ * The derivation follows OHTTP (RFC 9458):
7
+ * salt = concat(enc, response_nonce)
8
+ * prk = Extract(salt, secret)
9
+ * aead_key = Expand(prk, "key", Nk)
10
+ * aead_nonce = Expand(prk, "nonce", Nn)
11
+ */
12
+ export declare const HPKE_REQUEST_INFO = "ehbp request";
13
+ export declare const EXPORT_LABEL = "ehbp response";
14
+ export declare const EXPORT_LENGTH = 32;
15
+ export declare const RESPONSE_NONCE_LENGTH = 32;
16
+ export declare const AES256_KEY_LENGTH = 32;
17
+ export declare const AES_GCM_NONCE_LENGTH = 12;
18
+ export declare const REQUEST_ENC_LENGTH = 32;
19
+ /**
20
+ * Response key material for encryption/decryption
21
+ */
22
+ export interface ResponseKeyMaterial {
23
+ /** Raw key bytes for AEAD operations */
24
+ keyBytes: Uint8Array;
25
+ /** 12 bytes, XORed with sequence number for each chunk */
26
+ nonceBase: Uint8Array;
27
+ }
28
+ /**
29
+ * Derives response encryption keys from the HPKE exported secret.
30
+ *
31
+ * salt = concat(enc, response_nonce)
32
+ * prk = Extract(salt, secret)
33
+ * key = Expand(prk, "key", 32)
34
+ * nonceBase = Expand(prk, "nonce", 12)
35
+ *
36
+ * @param exportedSecret - 32 bytes exported from HPKE context
37
+ * @param requestEnc - 32 bytes encapsulated key from request
38
+ * @param responseNonce - 32 bytes random nonce from response
39
+ * @returns Key material for response encryption/decryption
40
+ */
41
+ export declare function deriveResponseKeys(exportedSecret: Uint8Array, requestEnc: Uint8Array, responseNonce: Uint8Array): Promise<ResponseKeyMaterial>;
42
+ /**
43
+ * Computes the nonce for a specific sequence number.
44
+ * nonce = nonceBase XOR sequence_number (big-endian in last 8 bytes)
45
+ */
46
+ export declare function computeNonce(nonceBase: Uint8Array, seq: number): Uint8Array;
47
+ /**
48
+ * Encrypts a chunk using the response key material
49
+ */
50
+ export declare function encryptChunk(km: ResponseKeyMaterial, seq: number, plaintext: Uint8Array): Promise<Uint8Array>;
51
+ /**
52
+ * Decrypts a chunk using the response key material
53
+ */
54
+ export declare function decryptChunk(km: ResponseKeyMaterial, seq: number, ciphertext: Uint8Array): Promise<Uint8Array>;
55
+ /**
56
+ * Utility: Convert hex string to Uint8Array
57
+ */
58
+ export declare function hexToBytes(hex: string): Uint8Array;
59
+ /**
60
+ * Utility: Convert Uint8Array to hex string
61
+ */
62
+ export declare function bytesToHex(bytes: Uint8Array): string;
63
+ //# sourceMappingURL=derive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAC5C,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,QAAQ,EAAE,UAAU,CAAC;IACrB,0DAA0D;IAC1D,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,UAAU,EAC1B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,UAAU,GACxB,OAAO,CAAC,mBAAmB,CAAC,CA2B9B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAyB3E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,mBAAmB,EACvB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,mBAAmB,EACvB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAYlD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}