ehbp 0.0.2 → 0.0.4

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 (82) hide show
  1. package/dist/cjs/client.d.ts.map +1 -0
  2. package/dist/cjs/client.js +160 -0
  3. package/dist/cjs/client.js.map +1 -0
  4. package/dist/cjs/identity.d.ts.map +1 -0
  5. package/dist/cjs/identity.js +274 -0
  6. package/dist/cjs/identity.js.map +1 -0
  7. package/dist/cjs/index.d.ts.map +1 -0
  8. package/dist/cjs/index.js +19 -0
  9. package/dist/cjs/index.js.map +1 -0
  10. package/dist/cjs/package.json +1 -0
  11. package/dist/cjs/protocol.d.ts.map +1 -0
  12. package/dist/cjs/protocol.js +22 -0
  13. package/dist/cjs/protocol.js.map +1 -0
  14. package/dist/esm/client.d.ts +51 -0
  15. package/dist/esm/client.d.ts.map +1 -0
  16. package/dist/esm/client.js.map +1 -0
  17. package/dist/{example.d.ts.map → esm/example.d.ts.map} +1 -1
  18. package/dist/esm/example.js.map +1 -0
  19. package/dist/esm/identity.d.ts +52 -0
  20. package/dist/esm/identity.d.ts.map +1 -0
  21. package/dist/esm/identity.js.map +1 -0
  22. package/{src/index.ts → dist/esm/index.d.ts} +2 -4
  23. package/dist/esm/index.d.ts.map +1 -0
  24. package/dist/esm/index.js.map +1 -0
  25. package/dist/esm/package.json +1 -0
  26. package/dist/esm/protocol.d.ts +19 -0
  27. package/dist/esm/protocol.d.ts.map +1 -0
  28. package/dist/esm/protocol.js.map +1 -0
  29. package/dist/{streaming-test.d.ts.map → esm/streaming-test.d.ts.map} +1 -1
  30. package/dist/esm/streaming-test.js.map +1 -0
  31. package/dist/{test → esm/test}/client.test.d.ts.map +1 -1
  32. package/dist/esm/test/client.test.js.map +1 -0
  33. package/dist/esm/test/identity.test.d.ts.map +1 -0
  34. package/dist/esm/test/identity.test.js.map +1 -0
  35. package/dist/esm/test/streaming.test.d.ts.map +1 -0
  36. package/dist/esm/test/streaming.test.js.map +1 -0
  37. package/package.json +23 -8
  38. package/build-browser.js +0 -54
  39. package/chat.html +0 -285
  40. package/dist/client.d.ts.map +0 -1
  41. package/dist/client.js.map +0 -1
  42. package/dist/example.js.map +0 -1
  43. package/dist/identity.d.ts.map +0 -1
  44. package/dist/identity.js.map +0 -1
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/index.js.map +0 -1
  47. package/dist/protocol.d.ts.map +0 -1
  48. package/dist/protocol.js.map +0 -1
  49. package/dist/streaming-test.js.map +0 -1
  50. package/dist/test/client.test.js.map +0 -1
  51. package/dist/test/identity.test.d.ts.map +0 -1
  52. package/dist/test/identity.test.js.map +0 -1
  53. package/dist/test/streaming.test.d.ts.map +0 -1
  54. package/dist/test/streaming.test.js.map +0 -1
  55. package/src/client.ts +0 -181
  56. package/src/example.ts +0 -126
  57. package/src/identity.ts +0 -339
  58. package/src/protocol.ts +0 -19
  59. package/src/streaming-test.ts +0 -118
  60. package/src/test/client.test.ts +0 -93
  61. package/src/test/identity.test.ts +0 -46
  62. package/src/test/streaming.test.ts +0 -85
  63. package/test.html +0 -271
  64. package/tsconfig.json +0 -19
  65. /package/dist/{client.d.ts → cjs/client.d.ts} +0 -0
  66. /package/dist/{identity.d.ts → cjs/identity.d.ts} +0 -0
  67. /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
  68. /package/dist/{protocol.d.ts → cjs/protocol.d.ts} +0 -0
  69. /package/dist/{client.js → esm/client.js} +0 -0
  70. /package/dist/{example.d.ts → esm/example.d.ts} +0 -0
  71. /package/dist/{example.js → esm/example.js} +0 -0
  72. /package/dist/{identity.js → esm/identity.js} +0 -0
  73. /package/dist/{index.js → esm/index.js} +0 -0
  74. /package/dist/{protocol.js → esm/protocol.js} +0 -0
  75. /package/dist/{streaming-test.d.ts → esm/streaming-test.d.ts} +0 -0
  76. /package/dist/{streaming-test.js → esm/streaming-test.js} +0 -0
  77. /package/dist/{test → esm/test}/client.test.d.ts +0 -0
  78. /package/dist/{test → esm/test}/client.test.js +0 -0
  79. /package/dist/{test → esm/test}/identity.test.d.ts +0 -0
  80. /package/dist/{test → esm/test}/identity.test.js +0 -0
  81. /package/dist/{test → esm/test}/streaming.test.d.ts +0 -0
  82. /package/dist/{test → esm/test}/streaming.test.js +0 -0
@@ -1 +0,0 @@
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,wBAAwB,EAAE,wBAAwB;IAClD,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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming-test.js","sourceRoot":"","sources":["../src/streaming-test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/test/client.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../../src/test/identity.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.test.js","sourceRoot":"","sources":["../../src/test/identity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAE3C,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,SAAS,EAAE,kCAAkC,CAAC,CAAC;QACzF,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,SAAS,EAAE,mCAAmC,CAAC,CAAC;QAC3F,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,oCAAoC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QACrD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QACrD,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,0BAA0B,CAAC,CAAC;QAChE,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,SAAS,EAAE,mCAAmC,CAAC,CAAC;QAC3F,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,SAAS,EAAE,mCAAmC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;QAE9C,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,4BAA4B,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,iCAAiC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,gCAAgC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAE9D,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QACrD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QACrD,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,0BAA0B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming.test.d.ts","sourceRoot":"","sources":["../../src/test/streaming.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming.test.js","sourceRoot":"","sources":["../../src/test/streaming.test.ts"],"names":[],"mappings":"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"}
package/src/client.ts DELETED
@@ -1,181 +0,0 @@
1
- import { Identity } from './identity.js';
2
- import { PROTOCOL } from './protocol.js';
3
-
4
- /**
5
- * HTTP transport for EHBP
6
- */
7
- export class Transport {
8
- private clientIdentity: Identity;
9
- private serverHost: string;
10
- private serverPublicKey: CryptoKey;
11
-
12
- constructor(clientIdentity: Identity, serverHost: string, serverPublicKey: CryptoKey) {
13
- this.clientIdentity = clientIdentity;
14
- this.serverHost = serverHost;
15
- this.serverPublicKey = serverPublicKey;
16
- }
17
-
18
- /**
19
- * Create a new transport by fetching server public key
20
- */
21
- static async create(serverURL: string, clientIdentity: Identity): Promise<Transport> {
22
- const url = new URL(serverURL);
23
- const serverHost = url.host;
24
-
25
- // Fetch server public key
26
- const keysURL = new URL(PROTOCOL.KEYS_PATH, serverURL);
27
- const response = await fetch(keysURL.toString());
28
-
29
- if (!response.ok) {
30
- throw new Error(`Failed to get server public key: ${response.status}`);
31
- }
32
-
33
- const contentType = response.headers.get('content-type');
34
- if (contentType !== PROTOCOL.KEYS_MEDIA_TYPE) {
35
- throw new Error(`Invalid content type: ${contentType}`);
36
- }
37
-
38
- const keysData = new Uint8Array(await response.arrayBuffer());
39
- const serverIdentity = await Identity.unmarshalPublicConfig(keysData);
40
- const serverPublicKey = serverIdentity.getPublicKey();
41
-
42
- return new Transport(clientIdentity, serverHost, serverPublicKey);
43
- }
44
-
45
- /**
46
- * Get the server public key
47
- */
48
- getServerPublicKey(): CryptoKey {
49
- return this.serverPublicKey;
50
- }
51
-
52
- /**
53
- * Get the server public key as hex string
54
- */
55
- async getServerPublicKeyHex(): Promise<string> {
56
- const exported = await crypto.subtle.exportKey('raw', this.serverPublicKey);
57
- const keyBytes = new Uint8Array(exported);
58
- return Array.from(keyBytes)
59
- .map(b => b.toString(16).padStart(2, '0'))
60
- .join('');
61
- }
62
-
63
- /**
64
- * Get the client public key
65
- */
66
- getClientPublicKey(): CryptoKey {
67
- return this.clientIdentity.getPublicKey();
68
- }
69
-
70
- /**
71
- * Make an encrypted HTTP request
72
- */
73
- async request(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
74
- // Extract body from init or original request before creating Request object
75
- let requestBody: BodyInit | null = null;
76
-
77
- if (input instanceof Request) {
78
- // If input is a Request, extract its body
79
- if (input.body) {
80
- requestBody = await input.arrayBuffer();
81
- }
82
- } else {
83
- // If input is URL/string, get body from init
84
- requestBody = init?.body || null;
85
- }
86
-
87
- // Create the URL with correct host
88
- let url: URL;
89
- let method: string;
90
- let headers: HeadersInit;
91
-
92
- if (input instanceof Request) {
93
- url = new URL(input.url);
94
- method = input.method;
95
- headers = input.headers;
96
- } else {
97
- url = new URL(input);
98
- method = init?.method || 'GET';
99
- headers = init?.headers || {};
100
- }
101
-
102
- url.host = this.serverHost;
103
-
104
- let request = new Request(url.toString(), {
105
- method,
106
- headers,
107
- body: requestBody,
108
- duplex: 'half'
109
- } as RequestInit);
110
-
111
- // Encrypt request body if present (check the original requestBody, not request.body)
112
- if (requestBody !== null && requestBody !== undefined) {
113
- request = await this.clientIdentity.encryptRequest(request, this.serverPublicKey);
114
- } else {
115
- // No body, just set client public key header
116
- const headers = new Headers(request.headers);
117
- headers.set(PROTOCOL.CLIENT_PUBLIC_KEY_HEADER, await this.clientIdentity.getPublicKeyHex());
118
- request = new Request(request.url, {
119
- method: request.method,
120
- headers,
121
- body: null
122
- });
123
- }
124
-
125
- // Make the request
126
- const response = await fetch(request);
127
-
128
- if (!response.ok) {
129
- console.warn(`Server returned non-OK status: ${response.status}`);
130
- }
131
-
132
- // Check for encapsulated key header
133
- const encapKeyHeader = response.headers.get(PROTOCOL.ENCAPSULATED_KEY_HEADER);
134
- if (!encapKeyHeader) {
135
- throw new Error(`Missing ${PROTOCOL.ENCAPSULATED_KEY_HEADER} encapsulated key header`);
136
- }
137
-
138
- // Decode encapsulated key
139
- const serverEncapKey = new Uint8Array(
140
- encapKeyHeader.match(/.{2}/g)!.map(byte => parseInt(byte, 16))
141
- );
142
-
143
- // Decrypt response
144
- return await this.clientIdentity.decryptResponse(response, serverEncapKey);
145
- }
146
-
147
- /**
148
- * Convenience method for GET requests
149
- */
150
- async get(url: string | URL, init?: RequestInit): Promise<Response> {
151
- return this.request(url, { ...init, method: 'GET' });
152
- }
153
-
154
- /**
155
- * Convenience method for POST requests
156
- */
157
- async post(url: string | URL, body?: BodyInit, init?: RequestInit): Promise<Response> {
158
- return this.request(url, { ...init, method: 'POST', body });
159
- }
160
-
161
- /**
162
- * Convenience method for PUT requests
163
- */
164
- async put(url: string | URL, body?: BodyInit, init?: RequestInit): Promise<Response> {
165
- return this.request(url, { ...init, method: 'PUT', body });
166
- }
167
-
168
- /**
169
- * Convenience method for DELETE requests
170
- */
171
- async delete(url: string | URL, init?: RequestInit): Promise<Response> {
172
- return this.request(url, { ...init, method: 'DELETE' });
173
- }
174
- }
175
-
176
- /**
177
- * Create a new transport instance
178
- */
179
- export async function createTransport(serverURL: string, clientIdentity: Identity): Promise<Transport> {
180
- return Transport.create(serverURL, clientIdentity);
181
- }
package/src/example.ts DELETED
@@ -1,126 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Example usage of the EHBP JavaScript client
5
- */
6
-
7
- import { Identity, createTransport } from './index.js';
8
-
9
- async function main() {
10
- console.log('EHBP JavaScript Client Example');
11
- console.log('==============================');
12
-
13
- try {
14
- // Create client identity
15
- console.log('Creating client identity...');
16
- const clientIdentity = await Identity.generate();
17
- console.log('Client public key:', await clientIdentity.getPublicKeyHex());
18
-
19
- // Create transport (this will fetch server public key)
20
- console.log('Creating transport...');
21
- const serverURL = 'http://localhost:8080'; // Adjust as needed
22
- const transport = await createTransport(serverURL, clientIdentity);
23
- console.log('Transport created successfully');
24
-
25
- // Example 1: GET request to secure endpoint
26
- console.log('\n--- GET Request ---');
27
- try {
28
- const getResponse = await transport.get(`${serverURL}/secure`);
29
- console.log('GET Response status:', getResponse.status);
30
- if (getResponse.ok) {
31
- const getData = await getResponse.text();
32
- console.log('GET Response:', getData);
33
- } else {
34
- console.log('GET Request failed with status:', getResponse.status);
35
- }
36
- } catch (error) {
37
- console.log('GET Request failed:', error instanceof Error ? error.message : String(error));
38
- }
39
-
40
- // Example 2: POST request with JSON data
41
- console.log('\n--- POST Request ---');
42
- try {
43
- const postData = { message: 'Hello from JavaScript client!', timestamp: new Date().toISOString() };
44
- const postResponse = await transport.post(
45
- `${serverURL}/secure`,
46
- JSON.stringify(postData),
47
- { headers: { 'Content-Type': 'application/json' } }
48
- );
49
- console.log('POST Response status:', postResponse.status);
50
- if (postResponse.ok) {
51
- const responseData = await postResponse.text();
52
- console.log('POST Response:', responseData);
53
- } else {
54
- console.log('POST Request failed with status:', postResponse.status);
55
- }
56
- } catch (error) {
57
- console.log('POST Request failed:', error instanceof Error ? error.message : String(error));
58
- }
59
-
60
- // Example 3: PUT request
61
- console.log('\n--- PUT Request ---');
62
- try {
63
- const putData = { id: 1, name: 'Updated Item' };
64
- const putResponse = await transport.put(
65
- `${serverURL}/secure`,
66
- JSON.stringify(putData),
67
- { headers: { 'Content-Type': 'application/json' } }
68
- );
69
- console.log('PUT Response status:', putResponse.status);
70
- if (putResponse.ok) {
71
- const putResponseData = await putResponse.text();
72
- console.log('PUT Response:', putResponseData);
73
- } else {
74
- console.log('PUT Request failed with status:', putResponse.status);
75
- }
76
- } catch (error) {
77
- console.log('PUT Request failed:', error instanceof Error ? error.message : String(error));
78
- }
79
-
80
- // Example 4: Streaming request
81
- console.log('\n--- Streaming Request ---');
82
- try {
83
- const streamResponse = await transport.get(`${serverURL}/stream`);
84
- console.log('Stream Response status:', streamResponse.status);
85
- if (streamResponse.ok) {
86
- console.log('Streaming response (should show numbers 1-20):');
87
- const reader = streamResponse.body?.getReader();
88
- if (reader) {
89
- const decoder = new TextDecoder();
90
- let chunkCount = 0;
91
-
92
- while (true) {
93
- const { done, value } = await reader.read();
94
- if (done) break;
95
-
96
- const text = decoder.decode(value, { stream: true });
97
- process.stdout.write(text);
98
- chunkCount++;
99
- }
100
-
101
- console.log(`\nStream completed with ${chunkCount} chunks`);
102
- } else {
103
- console.log('No readable stream available');
104
- }
105
- } else {
106
- console.log('Stream Request failed with status:', streamResponse.status);
107
- }
108
- } catch (error) {
109
- console.log('Stream Request failed:', error instanceof Error ? error.message : String(error));
110
- }
111
-
112
- console.log('\nExample completed successfully!');
113
- console.log('\nTo test with a real server:');
114
- console.log('1. Start the Go server: go run pkg/server/main.go');
115
- console.log('2. Run this example: npm run example');
116
-
117
- } catch (error) {
118
- console.error('Error:', error);
119
- process.exit(1);
120
- }
121
- }
122
-
123
- // Run the example
124
- if (import.meta.url === `file://${process.argv[1]}`) {
125
- main().catch(console.error);
126
- }
package/src/identity.ts DELETED
@@ -1,339 +0,0 @@
1
- import { CipherSuite, DhkemX25519HkdfSha256, HkdfSha256, Aes256Gcm } from '@hpke/core';
2
- import { PROTOCOL, HPKE_CONFIG } from './protocol.js';
3
-
4
- /**
5
- * Identity class for managing HPKE key pairs and encryption/decryption
6
- */
7
- export class Identity {
8
- private suite: CipherSuite;
9
- private publicKey: CryptoKey;
10
- private privateKey: CryptoKey;
11
-
12
- constructor(suite: CipherSuite, publicKey: CryptoKey, privateKey: CryptoKey) {
13
- this.suite = suite;
14
- this.publicKey = publicKey;
15
- this.privateKey = privateKey;
16
- }
17
-
18
- /**
19
- * Generate a new identity with X25519 key pair
20
- */
21
- static async generate(): Promise<Identity> {
22
- const suite = new CipherSuite({
23
- kem: new DhkemX25519HkdfSha256(),
24
- kdf: new HkdfSha256(),
25
- aead: new Aes256Gcm()
26
- });
27
-
28
- const { publicKey, privateKey } = await suite.kem.generateKeyPair();
29
-
30
- // Make sure the public key is extractable for serialization
31
- const extractablePublicKey = await crypto.subtle.importKey(
32
- 'raw',
33
- await crypto.subtle.exportKey('raw', publicKey),
34
- { name: 'X25519' },
35
- true, // extractable
36
- []
37
- );
38
-
39
- return new Identity(suite, extractablePublicKey, privateKey);
40
- }
41
-
42
-
43
- /**
44
- * Create identity from JSON string
45
- */
46
- static async fromJSON(json: string): Promise<Identity> {
47
- const data = JSON.parse(json);
48
- const suite = new CipherSuite({
49
- kem: new DhkemX25519HkdfSha256(),
50
- kdf: new HkdfSha256(),
51
- aead: new Aes256Gcm()
52
- });
53
-
54
- // Import public key
55
- const publicKey = await crypto.subtle.importKey(
56
- 'raw',
57
- new Uint8Array(data.publicKey),
58
- { name: 'X25519' },
59
- true, // extractable
60
- []
61
- );
62
-
63
- // Deserialize private key using HPKE library
64
- const privateKey = await suite.kem.deserializePrivateKey(new Uint8Array(data.privateKey).buffer);
65
-
66
- return new Identity(suite, publicKey, privateKey);
67
- }
68
-
69
-
70
- /**
71
- * Convert identity to JSON string
72
- */
73
- async toJSON(): Promise<string> {
74
- const publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', this.publicKey));
75
-
76
- // For X25519, we need to use the HPKE library's serialization for private keys
77
- const privateKeyBytes = await this.suite.kem.serializePrivateKey(this.privateKey);
78
-
79
- return JSON.stringify({
80
- publicKey: Array.from(publicKeyBytes),
81
- privateKey: Array.from(new Uint8Array(privateKeyBytes))
82
- });
83
- }
84
-
85
- /**
86
- * Get public key as CryptoKey
87
- */
88
- getPublicKey(): CryptoKey {
89
- return this.publicKey;
90
- }
91
-
92
- /**
93
- * Get public key as hex string
94
- */
95
- async getPublicKeyHex(): Promise<string> {
96
- const exported = await crypto.subtle.exportKey('raw', this.publicKey);
97
- return Array.from(new Uint8Array(exported))
98
- .map(b => b.toString(16).padStart(2, '0'))
99
- .join('');
100
- }
101
-
102
- /**
103
- * Get private key as CryptoKey
104
- */
105
- getPrivateKey(): CryptoKey {
106
- return this.privateKey;
107
- }
108
-
109
- /**
110
- * Marshal public key configuration for server key distribution
111
- * Implements RFC 9458 format
112
- */
113
- async marshalConfig(): Promise<Uint8Array> {
114
- const kemId = HPKE_CONFIG.KEM;
115
- const kdfId = HPKE_CONFIG.KDF;
116
- const aeadId = HPKE_CONFIG.AEAD;
117
-
118
- // Export public key as raw bytes
119
- const publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', this.publicKey));
120
-
121
- // Key ID (1 byte) + KEM ID (2 bytes) + Public Key + Cipher Suites
122
- const keyId = 0;
123
- const publicKeySize = publicKeyBytes.length;
124
- const cipherSuitesSize = 2 + 2; // KDF ID + AEAD ID
125
-
126
- const buffer = new Uint8Array(1 + 2 + publicKeySize + 2 + cipherSuitesSize);
127
- let offset = 0;
128
-
129
- // Key ID
130
- buffer[offset++] = keyId;
131
-
132
- // KEM ID
133
- buffer[offset++] = (kemId >> 8) & 0xFF;
134
- buffer[offset++] = kemId & 0xFF;
135
-
136
- // Public Key
137
- buffer.set(publicKeyBytes, offset);
138
- offset += publicKeySize;
139
-
140
- // Cipher Suites Length (2 bytes)
141
- buffer[offset++] = (cipherSuitesSize >> 8) & 0xFF;
142
- buffer[offset++] = cipherSuitesSize & 0xFF;
143
-
144
- // KDF ID
145
- buffer[offset++] = (kdfId >> 8) & 0xFF;
146
- buffer[offset++] = kdfId & 0xFF;
147
-
148
- // AEAD ID
149
- buffer[offset++] = (aeadId >> 8) & 0xFF;
150
- buffer[offset++] = aeadId & 0xFF;
151
-
152
- return buffer;
153
- }
154
-
155
- /**
156
- * Unmarshal public configuration from server
157
- */
158
- static async unmarshalPublicConfig(data: Uint8Array): Promise<Identity> {
159
- let offset = 0;
160
-
161
- // Read Key ID
162
- const keyId = data[offset++];
163
-
164
- // Read KEM ID
165
- const kemId = (data[offset++] << 8) | data[offset++];
166
-
167
- // Read Public Key (32 bytes for X25519)
168
- const publicKeySize = 32;
169
- const publicKeyBytes = data.slice(offset, offset + publicKeySize);
170
- offset += publicKeySize;
171
-
172
- // Read Cipher Suites Length
173
- const cipherSuitesLength = (data[offset++] << 8) | data[offset++];
174
-
175
- // Read KDF ID
176
- const kdfId = (data[offset++] << 8) | data[offset++];
177
-
178
- // Read AEAD ID
179
- const aeadId = (data[offset++] << 8) | data[offset++];
180
-
181
- // Create suite (assuming X25519 for now)
182
- const suite = new CipherSuite({
183
- kem: new DhkemX25519HkdfSha256(),
184
- kdf: new HkdfSha256(),
185
- aead: new Aes256Gcm()
186
- });
187
-
188
- // Import public key using HPKE library
189
- const publicKey = await suite.kem.deserializePublicKey(publicKeyBytes.buffer);
190
-
191
- // For server config, we only have the public key, no private key
192
- // We'll create a dummy private key that won't be used
193
- const dummyPrivateKey = await suite.kem.deserializePrivateKey(new Uint8Array(32).buffer);
194
-
195
- return new Identity(suite, publicKey, dummyPrivateKey);
196
- }
197
-
198
- /**
199
- * Encrypt request body and set appropriate headers
200
- */
201
- async encryptRequest(request: Request, serverPublicKey: CryptoKey): Promise<Request> {
202
- const body = await request.arrayBuffer();
203
- if (body.byteLength === 0) {
204
- // No body to encrypt, just set client public key header
205
- const headers = new Headers(request.headers);
206
- headers.set(PROTOCOL.CLIENT_PUBLIC_KEY_HEADER, await this.getPublicKeyHex());
207
- return new Request(request.url, {
208
- method: request.method,
209
- headers,
210
- body: null
211
- });
212
- }
213
-
214
- // Create sender for encryption
215
- const sender = await this.suite.createSenderContext({
216
- recipientPublicKey: serverPublicKey
217
- });
218
-
219
- // Encrypt the body
220
- const encrypted = await sender.seal(body);
221
-
222
- // Get encapsulated key
223
- const encapKey = sender.enc;
224
-
225
- // Create chunked format: 4-byte length header + encrypted data
226
- const chunkLength = new Uint8Array(4);
227
- const view = new DataView(chunkLength.buffer);
228
- view.setUint32(0, encrypted.byteLength, false); // Big-endian
229
-
230
- const chunkedData = new Uint8Array(4 + encrypted.byteLength);
231
- chunkedData.set(chunkLength, 0);
232
- chunkedData.set(new Uint8Array(encrypted), 4);
233
-
234
- // Create new request with encrypted body and headers
235
- const headers = new Headers(request.headers);
236
- headers.set(PROTOCOL.CLIENT_PUBLIC_KEY_HEADER, await this.getPublicKeyHex());
237
- headers.set(PROTOCOL.ENCAPSULATED_KEY_HEADER, Array.from(new Uint8Array(encapKey))
238
- .map(b => b.toString(16).padStart(2, '0'))
239
- .join(''));
240
-
241
- return new Request(request.url, {
242
- method: request.method,
243
- headers,
244
- body: chunkedData,
245
- duplex: 'half'
246
- } as RequestInit);
247
- }
248
-
249
- /**
250
- * Decrypt response body
251
- */
252
- async decryptResponse(response: Response, serverEncapKey: Uint8Array): Promise<Response> {
253
- if (!response.body) {
254
- return response;
255
- }
256
-
257
- // Create receiver for decryption
258
- const receiver = await this.suite.createRecipientContext({
259
- recipientKey: this.privateKey,
260
- enc: serverEncapKey.buffer as ArrayBuffer
261
- });
262
-
263
- // Create a readable stream that decrypts chunks as they arrive
264
- const decryptedStream = new ReadableStream({
265
- start(controller) {
266
- const reader = response.body!.getReader();
267
- let buffer = new Uint8Array(0);
268
- let offset = 0;
269
-
270
- async function pump() {
271
- try {
272
- while (true) {
273
- const { done, value } = await reader.read();
274
- if (done) break;
275
-
276
- // Append new data to buffer
277
- const newBuffer = new Uint8Array(buffer.length + value.length);
278
- newBuffer.set(buffer);
279
- newBuffer.set(value, buffer.length);
280
- buffer = newBuffer;
281
-
282
- // Process complete chunks
283
- while (offset + 4 <= buffer.length) {
284
- // Read chunk length (4 bytes big-endian)
285
- const chunkLength = (buffer[offset] << 24) |
286
- (buffer[offset + 1] << 16) |
287
- (buffer[offset + 2] << 8) |
288
- buffer[offset + 3];
289
- offset += 4;
290
-
291
- if (chunkLength === 0) {
292
- continue; // Empty chunk
293
- }
294
-
295
- // Check if we have the complete chunk
296
- if (offset + chunkLength > buffer.length) {
297
- // Not enough data yet, wait for more
298
- break;
299
- }
300
-
301
- // Extract and decrypt the chunk
302
- const encryptedChunk = buffer.slice(offset, offset + chunkLength);
303
- offset += chunkLength;
304
-
305
- try {
306
- const decryptedChunk = await receiver.open(encryptedChunk.buffer);
307
- controller.enqueue(new Uint8Array(decryptedChunk));
308
- } catch (error) {
309
- controller.error(new Error(`Failed to decrypt chunk: ${error}`));
310
- return;
311
- }
312
- }
313
-
314
- // Remove processed data from buffer
315
- if (offset > 0) {
316
- buffer = buffer.slice(offset);
317
- offset = 0;
318
- }
319
- }
320
-
321
- controller.close();
322
- } catch (error) {
323
- controller.error(error);
324
- }
325
- }
326
-
327
- pump();
328
- }
329
- });
330
-
331
- // Create new response with decrypted stream
332
- return new Response(decryptedStream, {
333
- status: response.status,
334
- statusText: response.statusText,
335
- headers: response.headers
336
- });
337
- }
338
-
339
- }