ehbp 0.1.5 → 0.1.6
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/dist/cjs/client.d.ts +2 -0
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +28 -5
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/errors.d.ts +32 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +48 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/identity.d.ts +9 -0
- package/dist/cjs/identity.d.ts.map +1 -1
- package/dist/cjs/identity.js +21 -20
- package/dist/cjs/identity.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/protocol.d.ts +2 -0
- package/dist/cjs/protocol.d.ts.map +1 -1
- package/dist/cjs/protocol.js +2 -0
- package/dist/cjs/protocol.js.map +1 -1
- package/dist/esm/client.d.ts +2 -0
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +28 -5
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/errors.d.ts +32 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +41 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/identity.d.ts +9 -0
- package/dist/esm/identity.d.ts.map +1 -1
- package/dist/esm/identity.js +21 -20
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocol.d.ts +2 -0
- package/dist/esm/protocol.d.ts.map +1 -1
- package/dist/esm/protocol.js +2 -0
- package/dist/esm/protocol.js.map +1 -1
- package/dist/esm/test/client.test.js +123 -1
- package/dist/esm/test/client.test.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/client.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Transport {
|
|
|
11
11
|
* Create a new transport by fetching server public key.
|
|
12
12
|
*/
|
|
13
13
|
static create(serverURL: string): Promise<Transport>;
|
|
14
|
+
private static isProblemJSONContentType;
|
|
15
|
+
private static checkKeyConfigMismatch;
|
|
14
16
|
/**
|
|
15
17
|
* Get the server identity
|
|
16
18
|
*/
|
package/dist/cjs/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAOhC;;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,OAAO,CAAC,MAAM,CAAC,wBAAwB;mBAQlB,sBAAsB;IAiB3C;;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;IAsE9E;;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"}
|
package/dist/cjs/client.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Transport = void 0;
|
|
|
4
4
|
exports.createTransport = createTransport;
|
|
5
5
|
const identity_js_1 = require("./identity.js");
|
|
6
6
|
const protocol_js_1 = require("./protocol.js");
|
|
7
|
+
const errors_js_1 = require("./errors.js");
|
|
7
8
|
/**
|
|
8
9
|
* HTTP transport for EHBP
|
|
9
10
|
*/
|
|
@@ -34,6 +35,29 @@ class Transport {
|
|
|
34
35
|
const serverIdentity = await identity_js_1.Identity.unmarshalPublicConfig(keysData);
|
|
35
36
|
return new Transport(serverIdentity, serverHost);
|
|
36
37
|
}
|
|
38
|
+
static isProblemJSONContentType(contentType) {
|
|
39
|
+
if (!contentType) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const mediaType = contentType.split(';', 1)[0]?.trim().toLowerCase() ?? '';
|
|
43
|
+
return mediaType === protocol_js_1.PROTOCOL.PROBLEM_JSON_MEDIA_TYPE;
|
|
44
|
+
}
|
|
45
|
+
static async checkKeyConfigMismatch(response) {
|
|
46
|
+
if (response.status !== 422)
|
|
47
|
+
return;
|
|
48
|
+
if (!Transport.isProblemJSONContentType(response.headers.get('content-type')))
|
|
49
|
+
return;
|
|
50
|
+
let problem;
|
|
51
|
+
try {
|
|
52
|
+
problem = (await response.clone().json());
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return; // Not valid JSON — not a key config mismatch
|
|
56
|
+
}
|
|
57
|
+
if (problem?.type === protocol_js_1.PROTOCOL.KEY_CONFIG_PROBLEM_TYPE) {
|
|
58
|
+
throw new errors_js_1.KeyConfigMismatchError(typeof problem.title === 'string' ? problem.title : undefined);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
37
61
|
/**
|
|
38
62
|
* Get the server identity
|
|
39
63
|
*/
|
|
@@ -88,7 +112,7 @@ class Transport {
|
|
|
88
112
|
headers = init?.headers || {};
|
|
89
113
|
}
|
|
90
114
|
url.host = this.serverHost;
|
|
91
|
-
|
|
115
|
+
const request = new Request(url.toString(), {
|
|
92
116
|
method,
|
|
93
117
|
headers,
|
|
94
118
|
body: requestBody,
|
|
@@ -99,17 +123,16 @@ class Transport {
|
|
|
99
123
|
const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
|
|
100
124
|
// Make the request
|
|
101
125
|
const response = await fetch(encryptedRequest);
|
|
102
|
-
if (!response.ok) {
|
|
103
|
-
console.warn(`Server returned non-OK status: ${response.status}`);
|
|
104
|
-
}
|
|
105
126
|
// Bodyless requests: context is null, response is plaintext
|
|
106
127
|
if (context === null) {
|
|
107
128
|
return response;
|
|
108
129
|
}
|
|
130
|
+
// Throws KeyConfigMismatchError if server returned 422 key-config mismatch
|
|
131
|
+
await Transport.checkKeyConfigMismatch(response);
|
|
109
132
|
// Check for response nonce header (required for response decryption)
|
|
110
133
|
const responseNonceHeader = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
111
134
|
if (!responseNonceHeader) {
|
|
112
|
-
throw new
|
|
135
|
+
throw new errors_js_1.ProtocolError(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
113
136
|
}
|
|
114
137
|
// Decrypt response
|
|
115
138
|
return await this.serverIdentity.decryptResponseWithContext(response, context);
|
package/dist/cjs/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EHBP error hierarchy:
|
|
3
|
+
*
|
|
4
|
+
* EhbpError (base)
|
|
5
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
6
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
7
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
8
|
+
*/
|
|
9
|
+
export declare class EhbpError extends Error {
|
|
10
|
+
constructor(message: string, options?: {
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
16
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
17
|
+
*/
|
|
18
|
+
export declare class KeyConfigMismatchError extends EhbpError {
|
|
19
|
+
readonly title: string;
|
|
20
|
+
constructor(title?: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class ProtocolError extends EhbpError {
|
|
23
|
+
constructor(message: string, options?: {
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export declare class DecryptionError extends EhbpError {
|
|
28
|
+
constructor(message: string, options?: {
|
|
29
|
+
cause?: unknown;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK3D;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,SAAgB,KAAK,EAAE,MAAM,CAAC;gBAClB,KAAK,CAAC,EAAE,MAAM;CAK3B;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EHBP error hierarchy:
|
|
4
|
+
*
|
|
5
|
+
* EhbpError (base)
|
|
6
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
7
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
8
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DecryptionError = exports.ProtocolError = exports.KeyConfigMismatchError = exports.EhbpError = void 0;
|
|
12
|
+
class EhbpError extends Error {
|
|
13
|
+
constructor(message, options) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'EhbpError';
|
|
16
|
+
if (options?.cause)
|
|
17
|
+
this.cause = options.cause;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.EhbpError = EhbpError;
|
|
21
|
+
/**
|
|
22
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
23
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
24
|
+
*/
|
|
25
|
+
class KeyConfigMismatchError extends EhbpError {
|
|
26
|
+
title;
|
|
27
|
+
constructor(title) {
|
|
28
|
+
super(title || 'Server key configuration mismatch');
|
|
29
|
+
this.name = 'KeyConfigMismatchError';
|
|
30
|
+
this.title = title || '';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.KeyConfigMismatchError = KeyConfigMismatchError;
|
|
34
|
+
class ProtocolError extends EhbpError {
|
|
35
|
+
constructor(message, options) {
|
|
36
|
+
super(message, options);
|
|
37
|
+
this.name = 'ProtocolError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.ProtocolError = ProtocolError;
|
|
41
|
+
class DecryptionError extends EhbpError {
|
|
42
|
+
constructor(message, options) {
|
|
43
|
+
super(message, options);
|
|
44
|
+
this.name = 'DecryptionError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.DecryptionError = DecryptionError;
|
|
48
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,MAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,OAAO,EAAE,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACjD,CAAC;CACF;AAND,8BAMC;AAED;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,SAAS;IACnC,KAAK,CAAS;IAC9B,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,IAAI,mCAAmC,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAPD,wDAOC;AAED,MAAa,aAAc,SAAQ,SAAS;IAC1C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC;AAED,MAAa,eAAgB,SAAQ,SAAS;IAC5C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC"}
|
package/dist/cjs/identity.d.ts
CHANGED
|
@@ -56,6 +56,15 @@ export declare class Identity {
|
|
|
56
56
|
* and don't need to fetch it.
|
|
57
57
|
*/
|
|
58
58
|
static fromPublicKeyHex(publicKeyHex: string): Promise<Identity>;
|
|
59
|
+
/**
|
|
60
|
+
* Create an Identity from raw public key bytes.
|
|
61
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
62
|
+
*
|
|
63
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
64
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
65
|
+
* a private key for client-side use.
|
|
66
|
+
*/
|
|
67
|
+
private static fromPublicKeyBytes;
|
|
59
68
|
/**
|
|
60
69
|
* Encrypt request body and return context for response decryption.
|
|
61
70
|
*
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAed;;;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;IA2CvE;;;;;;OAMG;WACU,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAStE;;;;;;;OAOG;mBACkB,kBAAkB;IAQvC;;;;;;;;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;CA4D5B"}
|
package/dist/cjs/identity.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Identity = void 0;
|
|
|
4
4
|
const hpke_1 = require("hpke");
|
|
5
5
|
const protocol_js_1 = require("./protocol.js");
|
|
6
6
|
const derive_js_1 = require("./derive.js");
|
|
7
|
+
const errors_js_1 = require("./errors.js");
|
|
7
8
|
/**
|
|
8
9
|
* Creates a new CipherSuite for X25519/HKDF-SHA256/AES-256-GCM
|
|
9
10
|
*/
|
|
@@ -130,22 +131,15 @@ class Identity {
|
|
|
130
131
|
suites.push({ kdfId, aeadId });
|
|
131
132
|
}
|
|
132
133
|
if (suites.length === 0) {
|
|
133
|
-
throw new
|
|
134
|
+
throw new errors_js_1.ProtocolError('No cipher suites found in config');
|
|
134
135
|
}
|
|
135
136
|
// Use the first cipher suite
|
|
136
137
|
const firstSuite = suites[0];
|
|
137
138
|
// Validate that we support this cipher suite
|
|
138
139
|
if (firstSuite.kdfId !== protocol_js_1.HPKE_CONFIG.KDF || firstSuite.aeadId !== protocol_js_1.HPKE_CONFIG.AEAD) {
|
|
139
|
-
throw new
|
|
140
|
+
throw new errors_js_1.ProtocolError(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
140
141
|
}
|
|
141
|
-
|
|
142
|
-
const suite = createSuite();
|
|
143
|
-
// Import public key
|
|
144
|
-
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
145
|
-
// For server config, we only have the public key, no private key
|
|
146
|
-
// We'll create a dummy private key that won't be used
|
|
147
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
148
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
142
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
149
143
|
}
|
|
150
144
|
/**
|
|
151
145
|
* Create an Identity from a raw public key hex string.
|
|
@@ -157,16 +151,23 @@ class Identity {
|
|
|
157
151
|
static async fromPublicKeyHex(publicKeyHex) {
|
|
158
152
|
const publicKeyBytes = (0, derive_js_1.hexToBytes)(publicKeyHex);
|
|
159
153
|
if (publicKeyBytes.length !== 32) {
|
|
160
|
-
throw new
|
|
154
|
+
throw new errors_js_1.ProtocolError(`Invalid public key length: expected 32, got ${publicKeyBytes.length}`);
|
|
161
155
|
}
|
|
156
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Create an Identity from raw public key bytes.
|
|
160
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
161
|
+
*
|
|
162
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
163
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
164
|
+
* a private key for client-side use.
|
|
165
|
+
*/
|
|
166
|
+
static async fromPublicKeyBytes(publicKeyBytes) {
|
|
162
167
|
const suite = createSuite();
|
|
163
168
|
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// TODO: maybe refactor Identity to not require a private key for
|
|
167
|
-
// client-side use?
|
|
168
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
169
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
169
|
+
const placeholderPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
170
|
+
return new Identity(suite, publicKey, placeholderPrivateKey);
|
|
170
171
|
}
|
|
171
172
|
/**
|
|
172
173
|
* Encrypt request body and return context for response decryption.
|
|
@@ -240,11 +241,11 @@ class Identity {
|
|
|
240
241
|
// Get response nonce from header
|
|
241
242
|
const responseNonceHex = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
242
243
|
if (!responseNonceHex) {
|
|
243
|
-
throw new
|
|
244
|
+
throw new errors_js_1.ProtocolError(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
244
245
|
}
|
|
245
246
|
const responseNonce = (0, derive_js_1.hexToBytes)(responseNonceHex);
|
|
246
247
|
if (responseNonce.length !== derive_js_1.RESPONSE_NONCE_LENGTH) {
|
|
247
|
-
throw new
|
|
248
|
+
throw new errors_js_1.ProtocolError(`Invalid response nonce length: expected ${derive_js_1.RESPONSE_NONCE_LENGTH}, got ${responseNonce.length}`);
|
|
248
249
|
}
|
|
249
250
|
// Export secret from request context
|
|
250
251
|
const exportLabelBytes = new TextEncoder().encode(derive_js_1.EXPORT_LABEL);
|
|
@@ -286,7 +287,7 @@ class Identity {
|
|
|
286
287
|
return;
|
|
287
288
|
}
|
|
288
289
|
catch (error) {
|
|
289
|
-
controller.error(new
|
|
290
|
+
controller.error(new errors_js_1.DecryptionError(`Decryption failed at chunk ${seq - 1}`, { cause: error }));
|
|
290
291
|
return;
|
|
291
292
|
}
|
|
292
293
|
}
|
package/dist/cjs/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":";;;AAAA,+BAOc;AACd,+CAAsD;AACtD,2CAUqB;
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":";;;AAAA,+BAOc;AACd,+CAAsD;AACtD,2CAUqB;AACrB,2CAA6D;AAW7D;;GAEG;AACH,SAAS,WAAW;IAClB,OAAO,IAAI,kBAAW,CACpB,mCAA4B,EAC5B,sBAAe,EACf,uBAAgB,CACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAa,QAAQ;IACX,KAAK,CAAc;IACnB,SAAS,CAAM;IACf,UAAU,CAAM;IAExB,YAAY,KAAkB,EAAE,SAAc,EAAE,UAAe;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ;QACnB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;QAEnF,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAY;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAE5B,mCAAmC;QACnC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACnF,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAE5F,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3E,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE9E,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;YACrC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;SACxC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,OAAO,IAAA,sBAAU,EAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,yBAAW,CAAC,GAAG,CAAC;QAC9B,MAAM,KAAK,GAAG,yBAAW,CAAC,GAAG,CAAC;QAC9B,MAAM,MAAM,GAAG,yBAAW,CAAC,IAAI,CAAC;QAEhC,iCAAiC;QACjC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3E,kEAAkE;QAClE,MAAM,KAAK,GAAG,CAAC,CAAC;QAChB,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC;QAC5C,MAAM,gBAAgB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;QAEnD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC;QAC5E,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;QAEzB,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACvC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;QAEhC,aAAa;QACb,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,aAAa,CAAC;QAExB,iCAAiC;QACjC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QAClD,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,gBAAgB,GAAG,IAAI,CAAC;QAE3C,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACvC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;QAEhC,UAAU;QACV,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACxC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;QAEjC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAgB;QACjD,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,cAAc;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAE7B,cAAc;QACd,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAErD,wCAAwC;QACxC,MAAM,aAAa,GAAG,EAAE,CAAC;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;QAClE,MAAM,IAAI,aAAa,CAAC;QAExB,4BAA4B;QAC5B,MAAM,kBAAkB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAElE,yEAAyE;QACzE,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,MAAM,eAAe,GAAG,MAAM,GAAG,kBAAkB,CAAC;QACpD,OAAO,MAAM,GAAG,eAAe,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,yBAAa,CAAC,kCAAkC,CAAC,CAAC;QAC9D,CAAC;QAED,6BAA6B;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAE7B,6CAA6C;QAC7C,IAAI,UAAU,CAAC,KAAK,KAAK,yBAAW,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,KAAK,yBAAW,CAAC,IAAI,EAAE,CAAC;YACnF,MAAM,IAAI,yBAAa,CACrB,mCAAmC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAC7G,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,YAAoB;QAChD,MAAM,cAAc,GAAG,IAAA,sBAAU,EAAC,YAAY,CAAC,CAAC;QAChD,IAAI,cAAc,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,yBAAa,CAAC,+CAA+C,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO,QAAQ,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;OAOG;IACK,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,cAA0B;QAChE,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACnE,MAAM,qBAAqB,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAE3F,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,yBAAyB,CAC7B,OAAgB;QAEhB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QAEzC,sEAAsE;QACtE,+EAA+E;QAC/E,8EAA8E;QAC9E,sDAAsD;QACtD,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;oBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,IAAI,EAAE,IAAI;iBACX,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,iFAAiF;QACjF,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,6BAAiB,CAAC,CAAC;QAC9D,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE;YAC/E,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,OAAO,GAAmB;YAC9B,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,kBAAkB;SAC/B,CAAC;QAEF,6DAA6D;QAC7D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,sBAAQ,CAAC,uBAAuB,EAAE,IAAA,sBAAU,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QAE9E,mBAAmB;QACnB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAEvD,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE3E,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QAC7D,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAChC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAE9B,OAAO;YACL,OAAO,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO;gBACP,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,MAAM;aACA,CAAC;YACjB,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,0BAA0B,CAC9B,QAAkB,EAClB,OAAuB;QAEvB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAQ,CAAC,qBAAqB,CAAC,CAAC;QAC9E,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,yBAAa,CAAC,WAAW,sBAAQ,CAAC,qBAAqB,SAAS,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,aAAa,GAAG,IAAA,sBAAU,EAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,aAAa,CAAC,MAAM,KAAK,iCAAqB,EAAE,CAAC;YACnD,MAAM,IAAI,yBAAa,CACrB,2CAA2C,iCAAqB,SAAS,aAAa,CAAC,MAAM,EAAE,CAChG,CAAC;QACJ,CAAC;QAED,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,wBAAY,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,EAAE,yBAAa,CAAC,CAAC;QAE3F,uBAAuB;QACvB,MAAM,EAAE,GAAG,MAAM,IAAA,8BAAkB,EAAC,cAAc,EAAE,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEvF,2BAA2B;QAC3B,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEpE,OAAO,IAAI,QAAQ,CAAC,eAAe,EAAE;YACnC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB,CACzB,IAAgC,EAChC,EAAuB;QAEvB,IAAI,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAEhC,OAAO,IAAI,cAAc,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,UAAU;gBACnB,OAAO,IAAI,EAAE,CAAC;oBACZ,2CAA2C;oBAC3C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACvB,MAAM,WAAW,GACf,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;wBAEvE,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;4BACtB,mBAAmB;4BACnB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;4BACzB,SAAS;wBACX,CAAC;wBAED,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC;4BACrC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;4BACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;4BAEvC,IAAI,CAAC;gCACH,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAY,EAAC,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;gCAC5D,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gCAC9B,OAAO;4BACT,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,UAAU,CAAC,KAAK,CAAC,IAAI,2BAAe,CAClC,8BAA8B,GAAG,GAAG,CAAC,EAAE,EACvC,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC,CAAC;gCACH,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,iBAAiB;oBACjB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;oBAC5C,IAAI,IAAI,EAAE,CAAC;wBACT,UAAU,CAAC,KAAK,EAAE,CAAC;wBACnB,OAAO;oBACT,CAAC;oBAED,mBAAmB;oBACnB,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC/D,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBACtB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;oBACpC,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,MAAM,CAAC,MAAM;gBACX,6DAA6D;gBAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAnXD,4BAmXC"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { Identity } from './identity.js';
|
|
|
9
9
|
export type { RequestContext } from './identity.js';
|
|
10
10
|
export { Transport, createTransport } from './client.js';
|
|
11
11
|
export { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
12
|
+
export { EhbpError, KeyConfigMismatchError, ProtocolError, DecryptionError, } from './errors.js';
|
|
12
13
|
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
14
|
export type { ResponseKeyMaterial } from './derive.js';
|
|
14
15
|
export type { CipherSuite, SenderContext, RecipientContext, Key } from 'hpke';
|
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,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;
|
|
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;AACtD,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,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.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;
|
|
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.DecryptionError = exports.ProtocolError = exports.KeyConfigMismatchError = exports.EhbpError = 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,6 +16,11 @@ 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
|
+
var errors_js_1 = require("./errors.js");
|
|
20
|
+
Object.defineProperty(exports, "EhbpError", { enumerable: true, get: function () { return errors_js_1.EhbpError; } });
|
|
21
|
+
Object.defineProperty(exports, "KeyConfigMismatchError", { enumerable: true, get: function () { return errors_js_1.KeyConfigMismatchError; } });
|
|
22
|
+
Object.defineProperty(exports, "ProtocolError", { enumerable: true, get: function () { return errors_js_1.ProtocolError; } });
|
|
23
|
+
Object.defineProperty(exports, "DecryptionError", { enumerable: true, get: function () { return errors_js_1.DecryptionError; } });
|
|
19
24
|
// Export key derivation utilities for advanced usage
|
|
20
25
|
var derive_js_1 = require("./derive.js");
|
|
21
26
|
Object.defineProperty(exports, "deriveResponseKeys", { enumerable: true, get: function () { return derive_js_1.deriveResponseKeys; } });
|
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;AAEjB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,6CAAsD;AAA7C,uGAAA,QAAQ,OAAA;AAAE,0GAAA,WAAW,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;AAC9B,yCAKqB;AAJnB,sGAAA,SAAS,OAAA;AACT,mHAAA,sBAAsB,OAAA;AACtB,0GAAA,aAAa,OAAA;AACb,4GAAA,eAAe,OAAA;AAGjB,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
|
@@ -6,6 +6,8 @@ export declare const PROTOCOL: {
|
|
|
6
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
|
+
readonly PROBLEM_JSON_MEDIA_TYPE: "application/problem+json";
|
|
10
|
+
readonly KEY_CONFIG_PROBLEM_TYPE: "urn:ietf:params:ehbp:error:key-config";
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* HPKE suite configuration matching the Go implementation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;CAOX,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAId,CAAC"}
|
package/dist/cjs/protocol.js
CHANGED
|
@@ -9,6 +9,8 @@ exports.PROTOCOL = {
|
|
|
9
9
|
RESPONSE_NONCE_HEADER: 'Ehbp-Response-Nonce',
|
|
10
10
|
KEYS_MEDIA_TYPE: 'application/ohttp-keys',
|
|
11
11
|
KEYS_PATH: '/.well-known/hpke-keys',
|
|
12
|
+
PROBLEM_JSON_MEDIA_TYPE: 'application/problem+json',
|
|
13
|
+
KEY_CONFIG_PROBLEM_TYPE: 'urn:ietf:params:ehbp:error:key-config',
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* HPKE suite configuration matching the Go implementation
|
package/dist/cjs/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;IACnC,uBAAuB,EAAE,0BAA0B;IACnD,uBAAuB,EAAE,uCAAuC;CACxD,CAAC;AAEX;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,GAAG,EAAE,MAAM,EAAE,qBAAqB;IAClC,GAAG,EAAE,MAAM,EAAE,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC,cAAc;CACnB,CAAC"}
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Transport {
|
|
|
11
11
|
* Create a new transport by fetching server public key.
|
|
12
12
|
*/
|
|
13
13
|
static create(serverURL: string): Promise<Transport>;
|
|
14
|
+
private static isProblemJSONContentType;
|
|
15
|
+
private static checkKeyConfigMismatch;
|
|
14
16
|
/**
|
|
15
17
|
* Get the server identity
|
|
16
18
|
*/
|
package/dist/esm/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAOhC;;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,OAAO,CAAC,MAAM,CAAC,wBAAwB;mBAQlB,sBAAsB;IAiB3C;;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;IAsE9E;;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"}
|
package/dist/esm/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Identity } from './identity.js';
|
|
2
2
|
import { PROTOCOL } from './protocol.js';
|
|
3
|
+
import { KeyConfigMismatchError, ProtocolError } from './errors.js';
|
|
3
4
|
/**
|
|
4
5
|
* HTTP transport for EHBP
|
|
5
6
|
*/
|
|
@@ -30,6 +31,29 @@ export class Transport {
|
|
|
30
31
|
const serverIdentity = await Identity.unmarshalPublicConfig(keysData);
|
|
31
32
|
return new Transport(serverIdentity, serverHost);
|
|
32
33
|
}
|
|
34
|
+
static isProblemJSONContentType(contentType) {
|
|
35
|
+
if (!contentType) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const mediaType = contentType.split(';', 1)[0]?.trim().toLowerCase() ?? '';
|
|
39
|
+
return mediaType === PROTOCOL.PROBLEM_JSON_MEDIA_TYPE;
|
|
40
|
+
}
|
|
41
|
+
static async checkKeyConfigMismatch(response) {
|
|
42
|
+
if (response.status !== 422)
|
|
43
|
+
return;
|
|
44
|
+
if (!Transport.isProblemJSONContentType(response.headers.get('content-type')))
|
|
45
|
+
return;
|
|
46
|
+
let problem;
|
|
47
|
+
try {
|
|
48
|
+
problem = (await response.clone().json());
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return; // Not valid JSON — not a key config mismatch
|
|
52
|
+
}
|
|
53
|
+
if (problem?.type === PROTOCOL.KEY_CONFIG_PROBLEM_TYPE) {
|
|
54
|
+
throw new KeyConfigMismatchError(typeof problem.title === 'string' ? problem.title : undefined);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
33
57
|
/**
|
|
34
58
|
* Get the server identity
|
|
35
59
|
*/
|
|
@@ -84,7 +108,7 @@ export class Transport {
|
|
|
84
108
|
headers = init?.headers || {};
|
|
85
109
|
}
|
|
86
110
|
url.host = this.serverHost;
|
|
87
|
-
|
|
111
|
+
const request = new Request(url.toString(), {
|
|
88
112
|
method,
|
|
89
113
|
headers,
|
|
90
114
|
body: requestBody,
|
|
@@ -95,17 +119,16 @@ export class Transport {
|
|
|
95
119
|
const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
|
|
96
120
|
// Make the request
|
|
97
121
|
const response = await fetch(encryptedRequest);
|
|
98
|
-
if (!response.ok) {
|
|
99
|
-
console.warn(`Server returned non-OK status: ${response.status}`);
|
|
100
|
-
}
|
|
101
122
|
// Bodyless requests: context is null, response is plaintext
|
|
102
123
|
if (context === null) {
|
|
103
124
|
return response;
|
|
104
125
|
}
|
|
126
|
+
// Throws KeyConfigMismatchError if server returned 422 key-config mismatch
|
|
127
|
+
await Transport.checkKeyConfigMismatch(response);
|
|
105
128
|
// Check for response nonce header (required for response decryption)
|
|
106
129
|
const responseNonceHeader = response.headers.get(PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
107
130
|
if (!responseNonceHeader) {
|
|
108
|
-
throw new
|
|
131
|
+
throw new ProtocolError(`Missing ${PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
109
132
|
}
|
|
110
133
|
// Decrypt response
|
|
111
134
|
return await this.serverIdentity.decryptResponseWithContext(response, context);
|
package/dist/esm/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EHBP error hierarchy:
|
|
3
|
+
*
|
|
4
|
+
* EhbpError (base)
|
|
5
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
6
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
7
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
8
|
+
*/
|
|
9
|
+
export declare class EhbpError extends Error {
|
|
10
|
+
constructor(message: string, options?: {
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
16
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
17
|
+
*/
|
|
18
|
+
export declare class KeyConfigMismatchError extends EhbpError {
|
|
19
|
+
readonly title: string;
|
|
20
|
+
constructor(title?: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class ProtocolError extends EhbpError {
|
|
23
|
+
constructor(message: string, options?: {
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export declare class DecryptionError extends EhbpError {
|
|
28
|
+
constructor(message: string, options?: {
|
|
29
|
+
cause?: unknown;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK3D;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,SAAgB,KAAK,EAAE,MAAM,CAAC;gBAClB,KAAK,CAAC,EAAE,MAAM;CAK3B;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EHBP error hierarchy:
|
|
3
|
+
*
|
|
4
|
+
* EhbpError (base)
|
|
5
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
6
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
7
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
8
|
+
*/
|
|
9
|
+
export class EhbpError extends Error {
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'EhbpError';
|
|
13
|
+
if (options?.cause)
|
|
14
|
+
this.cause = options.cause;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
19
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
20
|
+
*/
|
|
21
|
+
export class KeyConfigMismatchError extends EhbpError {
|
|
22
|
+
title;
|
|
23
|
+
constructor(title) {
|
|
24
|
+
super(title || 'Server key configuration mismatch');
|
|
25
|
+
this.name = 'KeyConfigMismatchError';
|
|
26
|
+
this.title = title || '';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class ProtocolError extends EhbpError {
|
|
30
|
+
constructor(message, options) {
|
|
31
|
+
super(message, options);
|
|
32
|
+
this.name = 'ProtocolError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class DecryptionError extends EhbpError {
|
|
36
|
+
constructor(message, options) {
|
|
37
|
+
super(message, options);
|
|
38
|
+
this.name = 'DecryptionError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,OAAO,EAAE,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACjD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,SAAS;IACnC,KAAK,CAAS;IAC9B,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,IAAI,mCAAmC,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,SAAS;IAC5C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF"}
|
package/dist/esm/identity.d.ts
CHANGED
|
@@ -56,6 +56,15 @@ export declare class Identity {
|
|
|
56
56
|
* and don't need to fetch it.
|
|
57
57
|
*/
|
|
58
58
|
static fromPublicKeyHex(publicKeyHex: string): Promise<Identity>;
|
|
59
|
+
/**
|
|
60
|
+
* Create an Identity from raw public key bytes.
|
|
61
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
62
|
+
*
|
|
63
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
64
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
65
|
+
* a private key for client-side use.
|
|
66
|
+
*/
|
|
67
|
+
private static fromPublicKeyBytes;
|
|
59
68
|
/**
|
|
60
69
|
* Encrypt request body and return context for response decryption.
|
|
61
70
|
*
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAed;;;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;IA2CvE;;;;;;OAMG;WACU,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAStE;;;;;;;OAOG;mBACkB,kBAAkB;IAQvC;;;;;;;;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;CA4D5B"}
|
package/dist/esm/identity.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
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
3
|
import { deriveResponseKeys, decryptChunk, hexToBytes, bytesToHex, HPKE_REQUEST_INFO, EXPORT_LABEL, EXPORT_LENGTH, RESPONSE_NONCE_LENGTH, } from './derive.js';
|
|
4
|
+
import { ProtocolError, DecryptionError } from './errors.js';
|
|
4
5
|
/**
|
|
5
6
|
* Creates a new CipherSuite for X25519/HKDF-SHA256/AES-256-GCM
|
|
6
7
|
*/
|
|
@@ -127,22 +128,15 @@ export class Identity {
|
|
|
127
128
|
suites.push({ kdfId, aeadId });
|
|
128
129
|
}
|
|
129
130
|
if (suites.length === 0) {
|
|
130
|
-
throw new
|
|
131
|
+
throw new ProtocolError('No cipher suites found in config');
|
|
131
132
|
}
|
|
132
133
|
// Use the first cipher suite
|
|
133
134
|
const firstSuite = suites[0];
|
|
134
135
|
// Validate that we support this cipher suite
|
|
135
136
|
if (firstSuite.kdfId !== HPKE_CONFIG.KDF || firstSuite.aeadId !== HPKE_CONFIG.AEAD) {
|
|
136
|
-
throw new
|
|
137
|
+
throw new ProtocolError(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
-
const suite = createSuite();
|
|
140
|
-
// Import public key
|
|
141
|
-
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
142
|
-
// For server config, we only have the public key, no private key
|
|
143
|
-
// We'll create a dummy private key that won't be used
|
|
144
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
145
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
139
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
146
140
|
}
|
|
147
141
|
/**
|
|
148
142
|
* Create an Identity from a raw public key hex string.
|
|
@@ -154,16 +148,23 @@ export class Identity {
|
|
|
154
148
|
static async fromPublicKeyHex(publicKeyHex) {
|
|
155
149
|
const publicKeyBytes = hexToBytes(publicKeyHex);
|
|
156
150
|
if (publicKeyBytes.length !== 32) {
|
|
157
|
-
throw new
|
|
151
|
+
throw new ProtocolError(`Invalid public key length: expected 32, got ${publicKeyBytes.length}`);
|
|
158
152
|
}
|
|
153
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Create an Identity from raw public key bytes.
|
|
157
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
158
|
+
*
|
|
159
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
160
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
161
|
+
* a private key for client-side use.
|
|
162
|
+
*/
|
|
163
|
+
static async fromPublicKeyBytes(publicKeyBytes) {
|
|
159
164
|
const suite = createSuite();
|
|
160
165
|
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// TODO: maybe refactor Identity to not require a private key for
|
|
164
|
-
// client-side use?
|
|
165
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
166
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
166
|
+
const placeholderPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
167
|
+
return new Identity(suite, publicKey, placeholderPrivateKey);
|
|
167
168
|
}
|
|
168
169
|
/**
|
|
169
170
|
* Encrypt request body and return context for response decryption.
|
|
@@ -237,11 +238,11 @@ export class Identity {
|
|
|
237
238
|
// Get response nonce from header
|
|
238
239
|
const responseNonceHex = response.headers.get(PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
239
240
|
if (!responseNonceHex) {
|
|
240
|
-
throw new
|
|
241
|
+
throw new ProtocolError(`Missing ${PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
241
242
|
}
|
|
242
243
|
const responseNonce = hexToBytes(responseNonceHex);
|
|
243
244
|
if (responseNonce.length !== RESPONSE_NONCE_LENGTH) {
|
|
244
|
-
throw new
|
|
245
|
+
throw new ProtocolError(`Invalid response nonce length: expected ${RESPONSE_NONCE_LENGTH}, got ${responseNonce.length}`);
|
|
245
246
|
}
|
|
246
247
|
// Export secret from request context
|
|
247
248
|
const exportLabelBytes = new TextEncoder().encode(EXPORT_LABEL);
|
|
@@ -283,7 +284,7 @@ export class Identity {
|
|
|
283
284
|
return;
|
|
284
285
|
}
|
|
285
286
|
catch (error) {
|
|
286
|
-
controller.error(new
|
|
287
|
+
controller.error(new DecryptionError(`Decryption failed at chunk ${seq - 1}`, { cause: error }));
|
|
287
288
|
return;
|
|
288
289
|
}
|
|
289
290
|
}
|
package/dist/esm/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,4BAA4B,EAC5B,eAAe,EACf,gBAAgB,GAGjB,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,qBAAqB,GAEtB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,4BAA4B,EAC5B,eAAe,EACf,gBAAgB,GAGjB,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,qBAAqB,GAEtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAW7D;;GAEG;AACH,SAAS,WAAW;IAClB,OAAO,IAAI,WAAW,CACpB,4BAA4B,EAC5B,eAAe,EACf,gBAAgB,CACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,QAAQ;IACX,KAAK,CAAc;IACnB,SAAS,CAAM;IACf,UAAU,CAAM;IAExB,YAAY,KAAkB,EAAE,SAAc,EAAE,UAAe;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ;QACnB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;QAEnF,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAY;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAE5B,mCAAmC;QACnC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACnF,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAE5F,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3E,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE9E,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;YACrC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;SACxC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC;QAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC;QAEhC,iCAAiC;QACjC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3E,kEAAkE;QAClE,MAAM,KAAK,GAAG,CAAC,CAAC;QAChB,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC;QAC5C,MAAM,gBAAgB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;QAEnD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC;QAC5E,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;QAEzB,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACvC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;QAEhC,aAAa;QACb,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,aAAa,CAAC;QAExB,iCAAiC;QACjC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QAClD,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,gBAAgB,GAAG,IAAI,CAAC;QAE3C,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACvC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;QAEhC,UAAU;QACV,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACxC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;QAEjC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAgB;QACjD,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,cAAc;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAE7B,cAAc;QACd,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAErD,wCAAwC;QACxC,MAAM,aAAa,GAAG,EAAE,CAAC;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;QAClE,MAAM,IAAI,aAAa,CAAC;QAExB,4BAA4B;QAC5B,MAAM,kBAAkB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAElE,yEAAyE;QACzE,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,MAAM,eAAe,GAAG,MAAM,GAAG,kBAAkB,CAAC;QACpD,OAAO,MAAM,GAAG,eAAe,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,aAAa,CAAC,kCAAkC,CAAC,CAAC;QAC9D,CAAC;QAED,6BAA6B;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAE7B,6CAA6C;QAC7C,IAAI,UAAU,CAAC,KAAK,KAAK,WAAW,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;YACnF,MAAM,IAAI,aAAa,CACrB,mCAAmC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAC7G,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,YAAoB;QAChD,MAAM,cAAc,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,cAAc,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,aAAa,CAAC,+CAA+C,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO,QAAQ,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;OAOG;IACK,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,cAA0B;QAChE,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACnE,MAAM,qBAAqB,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAE3F,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,yBAAyB,CAC7B,OAAgB;QAEhB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QAEzC,sEAAsE;QACtE,+EAA+E;QAC/E,8EAA8E;QAC9E,sDAAsD;QACtD,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;oBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,IAAI,EAAE,IAAI;iBACX,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,iFAAiF;QACjF,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC9D,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE;YAC/E,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,OAAO,GAAmB;YAC9B,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,kBAAkB;SAC/B,CAAC;QAEF,6DAA6D;QAC7D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,uBAAuB,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QAE9E,mBAAmB;QACnB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAEvD,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE3E,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QAC7D,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAChC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAE9B,OAAO;YACL,OAAO,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO;gBACP,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,MAAM;aACA,CAAC;YACjB,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,0BAA0B,CAC9B,QAAkB,EAClB,OAAuB;QAEvB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;QAC9E,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,aAAa,CAAC,WAAW,QAAQ,CAAC,qBAAqB,SAAS,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,aAAa,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,aAAa,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;YACnD,MAAM,IAAI,aAAa,CACrB,2CAA2C,qBAAqB,SAAS,aAAa,CAAC,MAAM,EAAE,CAChG,CAAC;QACJ,CAAC;QAED,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;QAE3F,uBAAuB;QACvB,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEvF,2BAA2B;QAC3B,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEpE,OAAO,IAAI,QAAQ,CAAC,eAAe,EAAE;YACnC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB,CACzB,IAAgC,EAChC,EAAuB;QAEvB,IAAI,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAEhC,OAAO,IAAI,cAAc,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,UAAU;gBACnB,OAAO,IAAI,EAAE,CAAC;oBACZ,2CAA2C;oBAC3C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACvB,MAAM,WAAW,GACf,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;wBAEvE,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;4BACtB,mBAAmB;4BACnB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;4BACzB,SAAS;wBACX,CAAC;wBAED,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC;4BACrC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;4BACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;4BAEvC,IAAI,CAAC;gCACH,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;gCAC5D,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gCAC9B,OAAO;4BACT,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,UAAU,CAAC,KAAK,CAAC,IAAI,eAAe,CAClC,8BAA8B,GAAG,GAAG,CAAC,EAAE,EACvC,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC,CAAC;gCACH,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,iBAAiB;oBACjB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;oBAC5C,IAAI,IAAI,EAAE,CAAC;wBACT,UAAU,CAAC,KAAK,EAAE,CAAC;wBACnB,OAAO;oBACT,CAAC;oBAED,mBAAmB;oBACnB,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC/D,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBACtB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;oBACpC,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,MAAM,CAAC,MAAM;gBACX,6DAA6D;gBAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { Identity } from './identity.js';
|
|
|
9
9
|
export type { RequestContext } from './identity.js';
|
|
10
10
|
export { Transport, createTransport } from './client.js';
|
|
11
11
|
export { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
12
|
+
export { EhbpError, KeyConfigMismatchError, ProtocolError, DecryptionError, } from './errors.js';
|
|
12
13
|
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
14
|
export type { ResponseKeyMaterial } from './derive.js';
|
|
14
15
|
export type { CipherSuite, SenderContext, RecipientContext, Key } from 'hpke';
|
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,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;
|
|
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;AACtD,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,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,6 +8,7 @@
|
|
|
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 { EhbpError, KeyConfigMismatchError, ProtocolError, DecryptionError, } from './errors.js';
|
|
11
12
|
// Export key derivation utilities for advanced usage
|
|
12
13
|
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
14
|
//# 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;AAEzC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,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;AACtD,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,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
|
@@ -6,6 +6,8 @@ export declare const PROTOCOL: {
|
|
|
6
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
|
+
readonly PROBLEM_JSON_MEDIA_TYPE: "application/problem+json";
|
|
10
|
+
readonly KEY_CONFIG_PROBLEM_TYPE: "urn:ietf:params:ehbp:error:key-config";
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* HPKE suite configuration matching the Go implementation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;CAOX,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAId,CAAC"}
|
package/dist/esm/protocol.js
CHANGED
|
@@ -6,6 +6,8 @@ export const PROTOCOL = {
|
|
|
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
|
+
PROBLEM_JSON_MEDIA_TYPE: 'application/problem+json',
|
|
10
|
+
KEY_CONFIG_PROBLEM_TYPE: 'urn:ietf:params:ehbp:error:key-config',
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* 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,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;
|
|
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,uBAAuB,EAAE,0BAA0B;IACnD,uBAAuB,EAAE,uCAAuC;CACxD,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,7 +1,52 @@
|
|
|
1
1
|
import { describe, it, before } from 'node:test';
|
|
2
2
|
import assert from 'node:assert';
|
|
3
|
-
import { Identity, Transport, createTransport } from '../index.js';
|
|
3
|
+
import { Identity, Transport, createTransport, KeyConfigMismatchError } from '../index.js';
|
|
4
4
|
import { PROTOCOL } from '../protocol.js';
|
|
5
|
+
import { CipherSuite, KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM, } from 'hpke';
|
|
6
|
+
import { bytesToHex, deriveResponseKeys, encryptChunk, hexToBytes, EXPORT_LABEL, EXPORT_LENGTH, HPKE_REQUEST_INFO, RESPONSE_NONCE_LENGTH, } from '../derive.js';
|
|
7
|
+
function encodeSingleChunk(payload) {
|
|
8
|
+
const chunkLength = new Uint8Array(4);
|
|
9
|
+
new DataView(chunkLength.buffer).setUint32(0, payload.byteLength, false);
|
|
10
|
+
const body = new Uint8Array(4 + payload.byteLength);
|
|
11
|
+
body.set(chunkLength, 0);
|
|
12
|
+
body.set(payload, 4);
|
|
13
|
+
return body;
|
|
14
|
+
}
|
|
15
|
+
function toArrayBuffer(bytes) {
|
|
16
|
+
const copy = new Uint8Array(bytes.byteLength);
|
|
17
|
+
copy.set(bytes);
|
|
18
|
+
return copy.buffer;
|
|
19
|
+
}
|
|
20
|
+
async function buildEncryptedResponse(request, serverIdentity) {
|
|
21
|
+
const requestEncHex = request.headers.get(PROTOCOL.ENCAPSULATED_KEY_HEADER);
|
|
22
|
+
assert(requestEncHex, `Missing ${PROTOCOL.ENCAPSULATED_KEY_HEADER} header`);
|
|
23
|
+
const requestEnc = hexToBytes(requestEncHex);
|
|
24
|
+
const encryptedRequestBody = new Uint8Array(await request.arrayBuffer());
|
|
25
|
+
assert(encryptedRequestBody.byteLength >= 4, 'Encrypted request body must include chunk length');
|
|
26
|
+
const chunkLength = new DataView(encryptedRequestBody.buffer, encryptedRequestBody.byteOffset, encryptedRequestBody.byteLength).getUint32(0, false);
|
|
27
|
+
assert.strictEqual(encryptedRequestBody.byteLength, 4 + chunkLength, 'Expected exactly one encrypted request chunk');
|
|
28
|
+
const ciphertext = encryptedRequestBody.slice(4);
|
|
29
|
+
const suite = new CipherSuite(KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM);
|
|
30
|
+
const infoBytes = new TextEncoder().encode(HPKE_REQUEST_INFO);
|
|
31
|
+
const recipientContext = await suite.SetupRecipient(serverIdentity.getPrivateKey(), requestEnc, {
|
|
32
|
+
info: infoBytes,
|
|
33
|
+
});
|
|
34
|
+
const decryptedRequest = await recipientContext.Open(ciphertext);
|
|
35
|
+
const decryptedText = new TextDecoder().decode(decryptedRequest);
|
|
36
|
+
const responseText = `processed:${decryptedText}`;
|
|
37
|
+
const responseNonce = new Uint8Array(RESPONSE_NONCE_LENGTH);
|
|
38
|
+
crypto.getRandomValues(responseNonce);
|
|
39
|
+
const exportLabelBytes = new TextEncoder().encode(EXPORT_LABEL);
|
|
40
|
+
const exportedSecret = await recipientContext.Export(exportLabelBytes, EXPORT_LENGTH);
|
|
41
|
+
const keyMaterial = await deriveResponseKeys(exportedSecret, requestEnc, responseNonce);
|
|
42
|
+
const responseCiphertext = await encryptChunk(keyMaterial, 0, new TextEncoder().encode(responseText));
|
|
43
|
+
return new Response(toArrayBuffer(encodeSingleChunk(responseCiphertext)), {
|
|
44
|
+
status: 200,
|
|
45
|
+
headers: {
|
|
46
|
+
[PROTOCOL.RESPONSE_NONCE_HEADER]: bytesToHex(responseNonce),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
5
50
|
describe('Transport', () => {
|
|
6
51
|
let serverIdentity;
|
|
7
52
|
before(async () => {
|
|
@@ -66,5 +111,82 @@ describe('Transport', () => {
|
|
|
66
111
|
assert.strictEqual(responseText, `Hello, ${testName}`, 'Server should respond with Hello, {name}');
|
|
67
112
|
console.log(`✓ Integration test passed: ${responseText}`);
|
|
68
113
|
});
|
|
114
|
+
it('should throw KeyConfigMismatchError on 422 key mismatch response', async () => {
|
|
115
|
+
const serverURL = 'https://server.test';
|
|
116
|
+
const serverIdentity = await Identity.generate();
|
|
117
|
+
const config = await serverIdentity.marshalConfig();
|
|
118
|
+
const originalFetch = globalThis.fetch;
|
|
119
|
+
globalThis.fetch = (async (input) => {
|
|
120
|
+
const request = input instanceof Request ? input : new Request(input);
|
|
121
|
+
const requestURL = new URL(request.url);
|
|
122
|
+
if (requestURL.pathname === PROTOCOL.KEYS_PATH) {
|
|
123
|
+
return new Response(toArrayBuffer(config), {
|
|
124
|
+
status: 200,
|
|
125
|
+
headers: { 'content-type': PROTOCOL.KEYS_MEDIA_TYPE },
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
// Server returns 422 key-config mismatch
|
|
129
|
+
return new Response(JSON.stringify({
|
|
130
|
+
type: PROTOCOL.KEY_CONFIG_PROBLEM_TYPE,
|
|
131
|
+
title: 'key configuration mismatch',
|
|
132
|
+
}), {
|
|
133
|
+
status: 422,
|
|
134
|
+
headers: {
|
|
135
|
+
'content-type': `${PROTOCOL.PROBLEM_JSON_MEDIA_TYPE}; charset=utf-8`,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
const transport = await createTransport(serverURL);
|
|
141
|
+
await assert.rejects(() => transport.post(`${serverURL}/secure`, 'hello'), (err) => {
|
|
142
|
+
assert(err instanceof KeyConfigMismatchError, `Expected KeyConfigMismatchError, got ${err.constructor.name}`);
|
|
143
|
+
assert.strictEqual(err.title, 'key configuration mismatch');
|
|
144
|
+
return true;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
globalThis.fetch = originalFetch;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
it('should not throw KeyConfigMismatchError for 422 without problem+json', async () => {
|
|
152
|
+
const serverIdentity = await Identity.generate();
|
|
153
|
+
const transport = new Transport(serverIdentity, 'server.test');
|
|
154
|
+
const originalFetch = globalThis.fetch;
|
|
155
|
+
globalThis.fetch = (async () => {
|
|
156
|
+
// 422 without problem+json content type — not a key mismatch
|
|
157
|
+
return new Response('Unprocessable', {
|
|
158
|
+
status: 422,
|
|
159
|
+
headers: { 'content-type': 'text/plain' },
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
try {
|
|
163
|
+
// Should not throw KeyConfigMismatchError — but will throw ProtocolError
|
|
164
|
+
// because the response has no Ehbp-Response-Nonce header
|
|
165
|
+
await assert.rejects(() => transport.post('https://server.test/secure', 'hello'), (err) => {
|
|
166
|
+
assert(!(err instanceof KeyConfigMismatchError), 'Should not be KeyConfigMismatchError');
|
|
167
|
+
return true;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
globalThis.fetch = originalFetch;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
it('should encrypt, send, and decrypt a full round-trip', async () => {
|
|
175
|
+
const serverIdentity = await Identity.generate();
|
|
176
|
+
const transport = new Transport(serverIdentity, 'server.test');
|
|
177
|
+
const originalFetch = globalThis.fetch;
|
|
178
|
+
globalThis.fetch = (async (input) => {
|
|
179
|
+
const request = input instanceof Request ? input : new Request(input);
|
|
180
|
+
return buildEncryptedResponse(request, serverIdentity);
|
|
181
|
+
});
|
|
182
|
+
try {
|
|
183
|
+
const response = await transport.post('https://server.test/secure', 'hello');
|
|
184
|
+
const responseText = await response.text();
|
|
185
|
+
assert.strictEqual(responseText, 'processed:hello');
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
globalThis.fetch = originalFetch;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
69
191
|
});
|
|
70
192
|
//# sourceMappingURL=client.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../src/test/client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../src/test/client.test.ts"],"names":[],"mappings":"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"}
|