@suveren/gateway 0.7.4 → 0.7.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/control-plane/index.mjs +248 -58
- package/dist/mcp-server/http.mjs +408 -65
- package/dist/ui/assets/{index-CkWaRck1.css → index-BYVb_0oG.css} +1 -1
- package/dist/ui/assets/index-CsrM6RQr.js +110 -0
- package/dist/ui/index.html +2 -2
- package/node_modules/@hap/core/dist/index.d.mts +258 -9
- package/node_modules/@hap/core/dist/index.d.ts +258 -9
- package/node_modules/@hap/core/dist/index.js +227 -5
- package/node_modules/@hap/core/dist/index.mjs +213 -4
- package/node_modules/@hap/core/package.json +3 -2
- package/node_modules/@hap/core/src/did-key.ts +126 -0
- package/node_modules/@hap/core/src/identity.ts +21 -5
- package/node_modules/@hap/core/src/index.ts +3 -0
- package/node_modules/@hap/core/src/mandate.ts +207 -0
- package/node_modules/@hap/core/src/receipt.ts +74 -0
- package/node_modules/@hap/core/src/types.ts +81 -5
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/package.json +16 -10
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.buffer.d.ts +5 -5
- package/node_modules/@types/node/crypto.d.ts +2 -2
- package/node_modules/@types/node/http.d.ts +16 -0
- package/node_modules/@types/node/http2.d.ts +10 -2
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +52 -0
- package/node_modules/@types/node/quic.d.ts +210 -28
- package/node_modules/@types/node/sqlite.d.ts +6 -2
- package/node_modules/@types/node/test.d.ts +36 -0
- package/node_modules/fast-uri/index.js +201 -48
- package/node_modules/fast-uri/lib/schemes.js +9 -4
- package/node_modules/fast-uri/lib/utils.js +388 -91
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +105 -0
- package/node_modules/fast-uri/test/equal.test.js +31 -3
- package/node_modules/fast-uri/test/fixtures/uri-js-parse.json +2 -0
- package/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +90 -0
- package/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
- package/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
- package/node_modules/fast-uri/test/parse.test.js +7 -3
- package/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
- package/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
- package/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
- package/node_modules/fast-uri/test/security-normalization.test.js +101 -0
- package/node_modules/fast-uri/test/security.test.js +75 -3
- package/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
- package/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
- package/node_modules/hono/dist/cjs/client/client.js +25 -11
- package/node_modules/hono/dist/cjs/client/utils.js +4 -1
- package/node_modules/hono/dist/cjs/context.js +4 -0
- package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/cjs/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/cjs/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/etag/digest.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/cjs/request.js +8 -4
- package/node_modules/hono/dist/cjs/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/cjs/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +10 -3
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +47 -83
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/cjs/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/cjs/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/cjs/router/utils.js +27 -0
- package/node_modules/hono/dist/cjs/utils/body.js +15 -3
- package/node_modules/hono/dist/cjs/utils/cookie.js +1 -1
- package/node_modules/hono/dist/cjs/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/cjs/utils/stream.js +7 -1
- package/node_modules/hono/dist/cjs/utils/url.js +9 -1
- package/node_modules/hono/dist/client/client.js +25 -11
- package/node_modules/hono/dist/client/utils.js +4 -1
- package/node_modules/hono/dist/context.js +4 -0
- package/node_modules/hono/dist/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/middleware/etag/digest.js +1 -1
- package/node_modules/hono/dist/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/request.js +8 -4
- package/node_modules/hono/dist/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/router/reg-exp-router/node.js +6 -2
- package/node_modules/hono/dist/router/reg-exp-router/router.js +53 -84
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/router/utils.js +5 -0
- package/node_modules/hono/dist/types/context.d.ts +4 -0
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +3 -0
- package/node_modules/hono/dist/types/router/trie-router/node.d.ts +1 -2
- package/node_modules/hono/dist/types/router/trie-router/router.d.ts +0 -1
- package/node_modules/hono/dist/types/router/utils.d.ts +1 -0
- package/node_modules/hono/dist/types/utils/url.d.ts +4 -0
- package/node_modules/hono/dist/utils/body.js +15 -3
- package/node_modules/hono/dist/utils/cookie.js +1 -1
- package/node_modules/hono/dist/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/utils/stream.js +7 -1
- package/node_modules/hono/dist/utils/url.js +9 -1
- package/node_modules/hono/package.json +1 -1
- package/node_modules/is-plain-object/README.md +39 -95
- package/node_modules/is-plain-object/dist/is-plain-object.js +0 -2
- package/node_modules/is-plain-object/is-plain-object.d.ts +6 -1
- package/node_modules/is-plain-object/package.json +8 -34
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwks/remote.d.ts +4 -4
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +3 -3
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +12 -17
- package/node_modules/jose/dist/types/jwt/sign.d.ts +8 -14
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +9 -15
- package/node_modules/jose/dist/types/types.d.ts +4 -2
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +30 -8
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +8 -4
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +6 -13
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +19 -19
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +32 -21
- package/node_modules/jose/dist/webapi/jwk/embedded.js +15 -1
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +11 -5
- package/node_modules/jose/dist/webapi/jwks/local.js +45 -53
- package/node_modules/jose/dist/webapi/jwks/remote.js +82 -103
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +10 -9
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +2 -1
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +8 -7
- package/node_modules/jose/dist/webapi/jws/general/sign.js +5 -3
- package/node_modules/jose/dist/webapi/jws/general/verify.js +51 -21
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +7 -9
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +21 -50
- package/node_modules/jose/dist/webapi/jwt/sign.js +8 -41
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +21 -42
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +6 -2
- package/node_modules/jose/dist/webapi/key/generate_secret.js +7 -6
- package/node_modules/jose/dist/webapi/key/import.js +16 -12
- package/node_modules/jose/dist/webapi/lib/asn1.js +7 -2
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +7 -15
- package/node_modules/jose/dist/webapi/lib/deflate.js +8 -0
- package/node_modules/jose/dist/webapi/lib/helpers.js +1 -1
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +85 -28
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +45 -13
- package/node_modules/jose/dist/webapi/lib/jwk_metadata.js +20 -0
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +47 -36
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +77 -45
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +82 -47
- package/node_modules/jose/dist/webapi/lib/key.js +24 -9
- package/node_modules/jose/dist/webapi/lib/key_management.js +10 -4
- package/node_modules/jose/dist/webapi/lib/key_options.js +6 -0
- package/node_modules/jose/dist/webapi/lib/options.js +26 -0
- package/node_modules/jose/dist/webapi/lib/type_checks.js +11 -13
- package/node_modules/jose/package.json +1 -1
- package/package.json +2 -2
- package/dist/ui/assets/index-0Q2eNytX.js +0 -110
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/HISTORY.md +0 -114
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
|
|
1
|
+
import { createJWE } from '../lib/jwe_encrypt.js';
|
|
2
|
+
import { JWTClaimsBuilder, jwtClaim, jwtData } from '../lib/jwt_claims_set.js';
|
|
3
3
|
import { assertNotSet } from '../lib/helpers.js';
|
|
4
|
-
|
|
4
|
+
const EncryptJWT_base = JWTClaimsBuilder;
|
|
5
|
+
export class EncryptJWT extends EncryptJWT_base {
|
|
5
6
|
#cek;
|
|
6
7
|
#iv;
|
|
7
8
|
#keyManagementParameters;
|
|
@@ -9,38 +10,6 @@ export class EncryptJWT {
|
|
|
9
10
|
#replicateIssuerAsHeader;
|
|
10
11
|
#replicateSubjectAsHeader;
|
|
11
12
|
#replicateAudienceAsHeader;
|
|
12
|
-
#jwt;
|
|
13
|
-
constructor(payload = {}) {
|
|
14
|
-
this.#jwt = new JWTClaimsBuilder(payload);
|
|
15
|
-
}
|
|
16
|
-
setIssuer(issuer) {
|
|
17
|
-
this.#jwt.iss = issuer;
|
|
18
|
-
return this;
|
|
19
|
-
}
|
|
20
|
-
setSubject(subject) {
|
|
21
|
-
this.#jwt.sub = subject;
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
setAudience(audience) {
|
|
25
|
-
this.#jwt.aud = audience;
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
setJti(jwtId) {
|
|
29
|
-
this.#jwt.jti = jwtId;
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
setNotBefore(input) {
|
|
33
|
-
this.#jwt.nbf = input;
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
setExpirationTime(input) {
|
|
37
|
-
this.#jwt.exp = input;
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
setIssuedAt(input) {
|
|
41
|
-
this.#jwt.iat = input;
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
13
|
setProtectedHeader(protectedHeader) {
|
|
45
14
|
assertNotSet(this.#protectedHeader, 'setProtectedHeader');
|
|
46
15
|
this.#protectedHeader = protectedHeader;
|
|
@@ -74,28 +43,30 @@ export class EncryptJWT {
|
|
|
74
43
|
return this;
|
|
75
44
|
}
|
|
76
45
|
async encrypt(key, options) {
|
|
77
|
-
const
|
|
46
|
+
const plaintext = jwtData(this);
|
|
78
47
|
if (this.#protectedHeader &&
|
|
79
48
|
(this.#replicateIssuerAsHeader ||
|
|
80
49
|
this.#replicateSubjectAsHeader ||
|
|
81
50
|
this.#replicateAudienceAsHeader)) {
|
|
82
51
|
this.#protectedHeader = {
|
|
83
52
|
...this.#protectedHeader,
|
|
84
|
-
iss: this.#replicateIssuerAsHeader ? this
|
|
85
|
-
sub: this.#replicateSubjectAsHeader ? this
|
|
86
|
-
aud: this.#replicateAudienceAsHeader ? this
|
|
53
|
+
iss: this.#replicateIssuerAsHeader ? jwtClaim(this, 'iss') : undefined,
|
|
54
|
+
sub: this.#replicateSubjectAsHeader ? jwtClaim(this, 'sub') : undefined,
|
|
55
|
+
aud: this.#replicateAudienceAsHeader ? jwtClaim(this, 'aud') : undefined,
|
|
87
56
|
};
|
|
88
57
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
58
|
+
const jwe = await createJWE([
|
|
59
|
+
plaintext,
|
|
60
|
+
this.#protectedHeader,
|
|
61
|
+
undefined,
|
|
62
|
+
undefined,
|
|
63
|
+
undefined,
|
|
64
|
+
this.#cek,
|
|
65
|
+
this.#iv,
|
|
66
|
+
this.#keyManagementParameters,
|
|
67
|
+
undefined,
|
|
68
|
+
false,
|
|
69
|
+
], key, options);
|
|
70
|
+
return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.');
|
|
100
71
|
}
|
|
101
72
|
}
|
|
@@ -1,51 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { unencodedPayload } from '../lib/jws_sign.js';
|
|
1
|
+
import { createCompactSignature } from '../lib/jws_sign.js';
|
|
3
2
|
import { JWTInvalid } from '../util/errors.js';
|
|
4
|
-
import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
|
|
5
|
-
|
|
3
|
+
import { JWTClaimsBuilder, jwtData } from '../lib/jwt_claims_set.js';
|
|
4
|
+
import { assertNotSet } from '../lib/helpers.js';
|
|
5
|
+
const SignJWT_base = JWTClaimsBuilder;
|
|
6
|
+
export class SignJWT extends SignJWT_base {
|
|
6
7
|
#protectedHeader;
|
|
7
|
-
#jwt;
|
|
8
|
-
constructor(payload = {}) {
|
|
9
|
-
this.#jwt = new JWTClaimsBuilder(payload);
|
|
10
|
-
}
|
|
11
|
-
setIssuer(issuer) {
|
|
12
|
-
this.#jwt.iss = issuer;
|
|
13
|
-
return this;
|
|
14
|
-
}
|
|
15
|
-
setSubject(subject) {
|
|
16
|
-
this.#jwt.sub = subject;
|
|
17
|
-
return this;
|
|
18
|
-
}
|
|
19
|
-
setAudience(audience) {
|
|
20
|
-
this.#jwt.aud = audience;
|
|
21
|
-
return this;
|
|
22
|
-
}
|
|
23
|
-
setJti(jwtId) {
|
|
24
|
-
this.#jwt.jti = jwtId;
|
|
25
|
-
return this;
|
|
26
|
-
}
|
|
27
|
-
setNotBefore(input) {
|
|
28
|
-
this.#jwt.nbf = input;
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
setExpirationTime(input) {
|
|
32
|
-
this.#jwt.exp = input;
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
setIssuedAt(input) {
|
|
36
|
-
this.#jwt.iat = input;
|
|
37
|
-
return this;
|
|
38
|
-
}
|
|
39
8
|
setProtectedHeader(protectedHeader) {
|
|
9
|
+
assertNotSet(this.#protectedHeader, 'setProtectedHeader');
|
|
40
10
|
this.#protectedHeader = protectedHeader;
|
|
41
11
|
return this;
|
|
42
12
|
}
|
|
43
13
|
async sign(key, options) {
|
|
44
|
-
|
|
45
|
-
sig.setProtectedHeader(this.#protectedHeader);
|
|
46
|
-
if (unencodedPayload(this.#protectedHeader)) {
|
|
14
|
+
return createCompactSignature(jwtData(this), this.#protectedHeader, options?.crit, key, () => {
|
|
47
15
|
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
48
|
-
}
|
|
49
|
-
return sig.sign(key, options);
|
|
16
|
+
});
|
|
50
17
|
}
|
|
51
18
|
}
|
|
@@ -1,46 +1,15 @@
|
|
|
1
1
|
import * as b64u from '../util/base64url.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
constructor(payload = {}) {
|
|
9
|
-
this.#jwt = new JWTClaimsBuilder(payload);
|
|
10
|
-
}
|
|
2
|
+
import { decodeBase64url, parseJoseHeader } from '../lib/helpers.js';
|
|
3
|
+
import { JWSInvalid, JWTInvalid } from '../util/errors.js';
|
|
4
|
+
import { validateClaimsSet, JWTClaimsBuilder, jwtData } from '../lib/jwt_claims_set.js';
|
|
5
|
+
import { JWS_RECOGNIZED, validateB64, validateCrit } from '../lib/options.js';
|
|
6
|
+
const UnsecuredJWT_base = JWTClaimsBuilder;
|
|
7
|
+
export class UnsecuredJWT extends UnsecuredJWT_base {
|
|
11
8
|
encode() {
|
|
12
9
|
const header = b64u.encode(JSON.stringify({ alg: 'none' }));
|
|
13
|
-
const payload = b64u.encode(this
|
|
10
|
+
const payload = b64u.encode(jwtData(this));
|
|
14
11
|
return `${header}.${payload}.`;
|
|
15
12
|
}
|
|
16
|
-
setIssuer(issuer) {
|
|
17
|
-
this.#jwt.iss = issuer;
|
|
18
|
-
return this;
|
|
19
|
-
}
|
|
20
|
-
setSubject(subject) {
|
|
21
|
-
this.#jwt.sub = subject;
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
setAudience(audience) {
|
|
25
|
-
this.#jwt.aud = audience;
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
setJti(jwtId) {
|
|
29
|
-
this.#jwt.jti = jwtId;
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
setNotBefore(input) {
|
|
33
|
-
this.#jwt.nbf = input;
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
setExpirationTime(input) {
|
|
37
|
-
this.#jwt.exp = input;
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
setIssuedAt(input) {
|
|
41
|
-
this.#jwt.iat = input;
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
13
|
static decode(jwt, options) {
|
|
45
14
|
if (typeof jwt !== 'string') {
|
|
46
15
|
throw new JWTInvalid('Unsecured JWT must be a string');
|
|
@@ -50,14 +19,24 @@ export class UnsecuredJWT {
|
|
|
50
19
|
throw new JWTInvalid('Invalid Unsecured JWT');
|
|
51
20
|
}
|
|
52
21
|
let header;
|
|
22
|
+
let b64;
|
|
53
23
|
try {
|
|
54
|
-
header =
|
|
55
|
-
|
|
56
|
-
|
|
24
|
+
header = parseJoseHeader(encodedHeader, JWSInvalid, 'JWS Protected Header is invalid');
|
|
25
|
+
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, undefined, header, header);
|
|
26
|
+
b64 = validateB64(header, extensions);
|
|
57
27
|
}
|
|
58
|
-
catch {
|
|
28
|
+
catch (cause) {
|
|
29
|
+
if (!(cause instanceof JWSInvalid)) {
|
|
30
|
+
throw cause;
|
|
31
|
+
}
|
|
32
|
+
throw new JWTInvalid('Invalid Unsecured JWT', { cause });
|
|
33
|
+
}
|
|
34
|
+
if (header.alg !== 'none') {
|
|
59
35
|
throw new JWTInvalid('Invalid Unsecured JWT');
|
|
60
36
|
}
|
|
37
|
+
if (!b64) {
|
|
38
|
+
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
39
|
+
}
|
|
61
40
|
const payload = validateClaimsSet(header, decodeBase64url(encodedPayload, 'payload', JWTInvalid), options);
|
|
62
41
|
return { payload, header };
|
|
63
42
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
|
+
import { validateExtractableOption } from '../lib/key_options.js';
|
|
2
3
|
import { keyAlgorithm, unsupportedAlg, algArgument } from '../lib/key_algorithm.js';
|
|
3
4
|
function getModulusLengthOption(options) {
|
|
4
5
|
const modulusLength = options?.modulusLength ?? 2048;
|
|
5
|
-
if (typeof modulusLength !== 'number' ||
|
|
6
|
+
if (typeof modulusLength !== 'number' ||
|
|
7
|
+
!Number.isInteger(modulusLength) ||
|
|
8
|
+
modulusLength < 2048) {
|
|
6
9
|
throw new JOSENotSupported('Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used');
|
|
7
10
|
}
|
|
8
11
|
return modulusLength;
|
|
9
12
|
}
|
|
10
13
|
export async function generateKeyPair(alg, options) {
|
|
14
|
+
const extractable = validateExtractableOption(options?.extractable);
|
|
11
15
|
const entry = keyAlgorithm(alg, algArgument);
|
|
12
16
|
if (entry.secret) {
|
|
13
17
|
unsupportedAlg(algArgument);
|
|
@@ -41,7 +45,7 @@ export async function generateKeyPair(alg, options) {
|
|
|
41
45
|
}
|
|
42
46
|
: entry.subtle;
|
|
43
47
|
}
|
|
44
|
-
return crypto.subtle.generateKey(algorithm,
|
|
48
|
+
return crypto.subtle.generateKey(algorithm, extractable ?? false, [
|
|
45
49
|
...entry.usages[1],
|
|
46
50
|
...entry.usages[0],
|
|
47
51
|
]);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { unsupportedAlg, algArgument } from '../lib/key_algorithm.js';
|
|
2
|
+
import { validateExtractableOption } from '../lib/key_options.js';
|
|
2
3
|
export async function generateSecret(alg, options) {
|
|
4
|
+
const extractable = validateExtractableOption(options?.extractable);
|
|
3
5
|
let length;
|
|
4
6
|
let algorithm;
|
|
5
7
|
let keyUsages;
|
|
@@ -7,19 +9,18 @@ export async function generateSecret(alg, options) {
|
|
|
7
9
|
case 'HS256':
|
|
8
10
|
case 'HS384':
|
|
9
11
|
case 'HS512':
|
|
10
|
-
length =
|
|
12
|
+
length = +alg.slice(-3);
|
|
11
13
|
algorithm = { name: 'HMAC', hash: `SHA-${length}`, length };
|
|
12
14
|
keyUsages = ['sign', 'verify'];
|
|
13
15
|
break;
|
|
14
16
|
case 'A128CBC-HS256':
|
|
15
17
|
case 'A192CBC-HS384':
|
|
16
18
|
case 'A256CBC-HS512':
|
|
17
|
-
|
|
18
|
-
return crypto.getRandomValues(new Uint8Array(length >> 3));
|
|
19
|
+
return crypto.getRandomValues(new Uint8Array(+alg.slice(-3) >> 3));
|
|
19
20
|
case 'A128KW':
|
|
20
21
|
case 'A192KW':
|
|
21
22
|
case 'A256KW':
|
|
22
|
-
length =
|
|
23
|
+
length = +alg.slice(1, 4);
|
|
23
24
|
algorithm = { name: 'AES-KW', length };
|
|
24
25
|
keyUsages = ['wrapKey', 'unwrapKey'];
|
|
25
26
|
break;
|
|
@@ -29,12 +30,12 @@ export async function generateSecret(alg, options) {
|
|
|
29
30
|
case 'A128GCM':
|
|
30
31
|
case 'A192GCM':
|
|
31
32
|
case 'A256GCM':
|
|
32
|
-
length =
|
|
33
|
+
length = +alg.slice(1, 4);
|
|
33
34
|
algorithm = { name: 'AES-GCM', length };
|
|
34
35
|
keyUsages = ['encrypt', 'decrypt'];
|
|
35
36
|
break;
|
|
36
37
|
default:
|
|
37
38
|
unsupportedAlg(algArgument);
|
|
38
39
|
}
|
|
39
|
-
return crypto.subtle.generateKey(algorithm,
|
|
40
|
+
return crypto.subtle.generateKey(algorithm, extractable ?? false, keyUsages);
|
|
40
41
|
}
|
|
@@ -4,6 +4,8 @@ import { jwkToKey } from '../lib/jwk_to_key.js';
|
|
|
4
4
|
import { keyAlgorithm } from '../lib/key_algorithm.js';
|
|
5
5
|
import { JOSENotSupported } from '../util/errors.js';
|
|
6
6
|
import { isObject } from '../lib/type_checks.js';
|
|
7
|
+
import { validateExtractableOption } from '../lib/key_options.js';
|
|
8
|
+
import { normalizeJwk } from '../lib/jwk_metadata.js';
|
|
7
9
|
export async function importSPKI(spki, alg, options) {
|
|
8
10
|
if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {
|
|
9
11
|
throw new TypeError('"spki" must be SPKI formatted string');
|
|
@@ -26,31 +28,33 @@ export async function importJWK(jwk, alg, options) {
|
|
|
26
28
|
if (!isObject(jwk)) {
|
|
27
29
|
throw new TypeError('JWK must be an object');
|
|
28
30
|
}
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
31
|
+
const normalized = normalizeJwk(jwk);
|
|
32
|
+
const extractable = validateExtractableOption(options?.extractable);
|
|
33
|
+
const { alg: jwkAlg } = normalized;
|
|
34
|
+
alg ??= jwkAlg;
|
|
35
|
+
const ext = extractable ?? normalized.ext;
|
|
36
|
+
if (normalized.kty !== 'oct' && !alg) {
|
|
32
37
|
throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
|
|
33
38
|
}
|
|
34
|
-
switch (
|
|
39
|
+
switch (normalized.kty) {
|
|
35
40
|
case 'oct':
|
|
36
|
-
if (typeof
|
|
41
|
+
if (typeof normalized.k !== 'string') {
|
|
37
42
|
throw new TypeError('missing "k" (Key Value) Parameter value');
|
|
38
43
|
}
|
|
39
|
-
return decodeBase64URL(
|
|
40
|
-
case 'RSA':
|
|
41
|
-
return jwkToKey(keyAlgorithm(alg), { ...jwk, alg, ext });
|
|
44
|
+
return decodeBase64URL(normalized.k);
|
|
42
45
|
case 'AKP': {
|
|
43
|
-
if (typeof
|
|
46
|
+
if (typeof jwkAlg !== 'string' || !jwkAlg) {
|
|
44
47
|
throw new TypeError('missing "alg" (Algorithm) Parameter value');
|
|
45
48
|
}
|
|
46
|
-
if (alg !==
|
|
49
|
+
if (alg !== jwkAlg) {
|
|
47
50
|
throw new TypeError('JWK alg and alg option value mismatch');
|
|
48
51
|
}
|
|
49
|
-
return jwkToKey(keyAlgorithm(
|
|
52
|
+
return jwkToKey(keyAlgorithm(alg), { ...normalized, ext });
|
|
50
53
|
}
|
|
54
|
+
case 'RSA':
|
|
51
55
|
case 'EC':
|
|
52
56
|
case 'OKP':
|
|
53
|
-
return jwkToKey(keyAlgorithm(alg), { ...
|
|
57
|
+
return jwkToKey(keyAlgorithm(alg), { ...normalized, alg, ext });
|
|
54
58
|
default:
|
|
55
59
|
throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
|
56
60
|
}
|
|
@@ -3,6 +3,7 @@ import { encodeBase64, decodeBase64 } from '../lib/base64.js';
|
|
|
3
3
|
import { JOSENotSupported } from '../util/errors.js';
|
|
4
4
|
import { keyAlgorithm, unsupportedAlg, algArgument } from './key_algorithm.js';
|
|
5
5
|
import { isCryptoKey, isKeyObject } from './is_key_like.js';
|
|
6
|
+
import { validateExtractableOption } from './key_options.js';
|
|
6
7
|
const formatPEM = (b64, descriptor) => {
|
|
7
8
|
const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
|
|
8
9
|
return `-----BEGIN ${descriptor}-----\n${newlined}\n-----END ${descriptor}-----`;
|
|
@@ -112,6 +113,7 @@ const parseECAlgorithmIdentifier = (state) => {
|
|
|
112
113
|
throw new Error('Unsupported named curve');
|
|
113
114
|
};
|
|
114
115
|
const genericImport = async (keyFormat, keyData, alg, options) => {
|
|
116
|
+
const extractable = validateExtractableOption(options?.extractable);
|
|
115
117
|
const entry = keyAlgorithm(alg, algArgument);
|
|
116
118
|
if (entry.secret) {
|
|
117
119
|
unsupportedAlg(algArgument);
|
|
@@ -131,7 +133,7 @@ const genericImport = async (keyFormat, keyData, alg, options) => {
|
|
|
131
133
|
else {
|
|
132
134
|
algorithm = entry.subtle;
|
|
133
135
|
}
|
|
134
|
-
return crypto.subtle.importKey(keyFormat, keyData, algorithm,
|
|
136
|
+
return crypto.subtle.importKey(keyFormat, keyData, algorithm, extractable ?? isPublic, entry.usages[isPublic ? 0 : 1]);
|
|
135
137
|
};
|
|
136
138
|
const processPEMData = (pem, pattern) => {
|
|
137
139
|
return decodeBase64(pem.replace(pattern, ''));
|
|
@@ -147,7 +149,10 @@ export const fromSPKI = (pem, alg, options) => {
|
|
|
147
149
|
function spkiFromX509(buf) {
|
|
148
150
|
const state = createASN1State(buf);
|
|
149
151
|
expectTag(state, 0x30, 'Invalid certificate structure');
|
|
150
|
-
parseLength(state);
|
|
152
|
+
const certificateLength = parseLength(state);
|
|
153
|
+
if (certificateLength < 0 || state.pos + certificateLength > state.data.length) {
|
|
154
|
+
throw new Error('Unexpected end of ASN.1 input');
|
|
155
|
+
}
|
|
151
156
|
expectTag(state, 0x30, 'Invalid tbsCertificate structure');
|
|
152
157
|
parseLength(state);
|
|
153
158
|
if (buf[state.pos] === 0xa0) {
|
|
@@ -51,25 +51,14 @@ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
|
|
|
51
51
|
const [encKey, macKey, keySize] = await cbcKeySetup(enc, cek, 'decrypt');
|
|
52
52
|
const macData = concat(aad, iv, ciphertext, uint64be(aad.length * 8));
|
|
53
53
|
const expectedTag = await cbcHmacTag(macKey, macData, keySize);
|
|
54
|
-
let macCheckPassed;
|
|
55
54
|
try {
|
|
56
|
-
|
|
55
|
+
if (await timingSafeEqual(tag, expectedTag)) {
|
|
56
|
+
return new Uint8Array(await crypto.subtle.decrypt({ iv: iv, name: 'AES-CBC' }, encKey, ciphertext));
|
|
57
|
+
}
|
|
57
58
|
}
|
|
58
59
|
catch {
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
-
throw new JWEDecryptionFailed();
|
|
62
|
-
}
|
|
63
|
-
let plaintext;
|
|
64
|
-
try {
|
|
65
|
-
plaintext = new Uint8Array(await crypto.subtle.decrypt({ iv: iv, name: 'AES-CBC' }, encKey, ciphertext));
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
}
|
|
69
|
-
if (!plaintext) {
|
|
70
|
-
throw new JWEDecryptionFailed();
|
|
71
|
-
}
|
|
72
|
-
return plaintext;
|
|
61
|
+
throw new JWEDecryptionFailed();
|
|
73
62
|
}
|
|
74
63
|
async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
75
64
|
const encKey = cek instanceof Uint8Array
|
|
@@ -132,6 +121,9 @@ export async function decrypt(enc, cek, ciphertext, iv, tag, aad) {
|
|
|
132
121
|
if (!tag) {
|
|
133
122
|
throw new JWEInvalid('JWE Authentication Tag missing');
|
|
134
123
|
}
|
|
124
|
+
if (!enc.cbc && tag.length !== 16) {
|
|
125
|
+
throw new JWEInvalid('Invalid Authentication Tag length');
|
|
126
|
+
}
|
|
135
127
|
checkIvLength(enc, iv);
|
|
136
128
|
if (cek instanceof Uint8Array) {
|
|
137
129
|
checkCekLength(cek, enc.cekBits);
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
|
|
2
2
|
import { concat } from './buffer_utils.js';
|
|
3
|
+
export function validateZip(joseHeader, protectedHeader) {
|
|
4
|
+
if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {
|
|
5
|
+
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value.');
|
|
6
|
+
}
|
|
7
|
+
if (joseHeader.zip !== undefined && !protectedHeader?.zip) {
|
|
8
|
+
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header Parameter MUST be in a protected header.');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
3
11
|
function supported(name) {
|
|
4
12
|
if (typeof globalThis[name] === 'undefined') {
|
|
5
13
|
throw new JOSENotSupported(`JWE "zip" (Compression Algorithm) Header Parameter requires the ${name} API.`);
|
|
@@ -3,7 +3,7 @@ import { encode, strictDecoder } from './buffer_utils.js';
|
|
|
3
3
|
import { isObject } from './type_checks.js';
|
|
4
4
|
export const unprotected = Symbol();
|
|
5
5
|
export function assertNotSet(value, name) {
|
|
6
|
-
if (value) {
|
|
6
|
+
if (value !== undefined) {
|
|
7
7
|
throw new TypeError(`${name} can only be called once`);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -7,35 +7,75 @@ import { concat, decoder, encode } from './buffer_utils.js';
|
|
|
7
7
|
import { validateCrit, validateAlgorithms, JWE_RECOGNIZED } from './options.js';
|
|
8
8
|
import { prepareKey } from './key.js';
|
|
9
9
|
import { jweAlgorithm, jweEncryption } from './jwe_algorithms.js';
|
|
10
|
-
import { decompress } from './deflate.js';
|
|
11
|
-
export function
|
|
12
|
-
const { ciphertext, protected: encodedProtected, unprotected } = jwe;
|
|
13
|
-
if (
|
|
10
|
+
import { decompress, validateZip } from './deflate.js';
|
|
11
|
+
export function snapshotSharedJWE(jwe) {
|
|
12
|
+
const { aad, ciphertext, iv, protected: encodedProtected, tag, unprotected } = jwe;
|
|
13
|
+
if (iv !== undefined && typeof iv !== 'string') {
|
|
14
14
|
throw new JWEInvalid('JWE Initialization Vector incorrect type');
|
|
15
15
|
}
|
|
16
16
|
if (typeof ciphertext !== 'string') {
|
|
17
17
|
throw new JWEInvalid('JWE Ciphertext missing or incorrect type');
|
|
18
18
|
}
|
|
19
|
-
if (
|
|
19
|
+
if (tag !== undefined && typeof tag !== 'string') {
|
|
20
20
|
throw new JWEInvalid('JWE Authentication Tag incorrect type');
|
|
21
21
|
}
|
|
22
22
|
if (encodedProtected !== undefined && typeof encodedProtected !== 'string') {
|
|
23
23
|
throw new JWEInvalid('JWE Protected Header incorrect type');
|
|
24
24
|
}
|
|
25
|
-
if (
|
|
25
|
+
if (aad !== undefined && (typeof aad !== 'string' || !aad)) {
|
|
26
26
|
throw new JWEInvalid('JWE AAD incorrect type');
|
|
27
27
|
}
|
|
28
28
|
if (unprotected !== undefined && !isObject(unprotected)) {
|
|
29
29
|
throw new JWEInvalid('JWE Shared Unprotected Header incorrect type');
|
|
30
30
|
}
|
|
31
|
+
return {
|
|
32
|
+
aad,
|
|
33
|
+
ciphertext,
|
|
34
|
+
iv,
|
|
35
|
+
protected: encodedProtected,
|
|
36
|
+
tag,
|
|
37
|
+
unprotected: unprotected === undefined ? undefined : { ...unprotected },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function snapshotRecipientJWE(recipient) {
|
|
41
|
+
let header;
|
|
42
|
+
let headerAlg;
|
|
43
|
+
try {
|
|
44
|
+
const { header: inputHeader } = recipient;
|
|
45
|
+
if (isObject(inputHeader)) {
|
|
46
|
+
headerAlg = inputHeader.alg;
|
|
47
|
+
const parameters = Object.keys(inputHeader);
|
|
48
|
+
if (!parameters.includes('alg'))
|
|
49
|
+
headerAlg = undefined;
|
|
50
|
+
header = Object.fromEntries(parameters.map((parameter) => [
|
|
51
|
+
parameter,
|
|
52
|
+
parameter === 'alg' ? headerAlg : inputHeader[parameter],
|
|
53
|
+
]));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
header = inputHeader;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return [undefined, headerAlg, error];
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const { encrypted_key: encryptedKey } = recipient;
|
|
64
|
+
return [{ encrypted_key: encryptedKey, header }, headerAlg];
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return [undefined, headerAlg, error];
|
|
68
|
+
}
|
|
31
69
|
}
|
|
32
70
|
export function checkRecipient(jwe) {
|
|
33
71
|
const { encrypted_key: encryptedKey, header } = jwe;
|
|
34
72
|
if (encryptedKey !== undefined && typeof encryptedKey !== 'string') {
|
|
35
73
|
throw new JWEInvalid('JWE Encrypted Key incorrect type');
|
|
36
74
|
}
|
|
37
|
-
if (header !== undefined
|
|
38
|
-
|
|
75
|
+
if (header !== undefined) {
|
|
76
|
+
if (!isObject(header)) {
|
|
77
|
+
throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');
|
|
78
|
+
}
|
|
39
79
|
}
|
|
40
80
|
if (jwe.protected === undefined && header === undefined && jwe.unprotected === undefined) {
|
|
41
81
|
throw new JWEInvalid('JOSE Header missing');
|
|
@@ -44,7 +84,7 @@ export function checkRecipient(jwe) {
|
|
|
44
84
|
export function shareJWE(jwe) {
|
|
45
85
|
const { protected: encodedProtected, ciphertext, iv, tag, aad } = jwe;
|
|
46
86
|
let parsedProt;
|
|
47
|
-
if (encodedProtected) {
|
|
87
|
+
if (encodedProtected !== undefined) {
|
|
48
88
|
parsedProt = parseJoseHeader(encodedProtected, JWEInvalid, 'JWE Protected Header is invalid');
|
|
49
89
|
}
|
|
50
90
|
const protectedHeader = encodedProtected !== undefined ? encode(encodedProtected) : new Uint8Array();
|
|
@@ -84,13 +124,14 @@ export function prepareDecrypt(options) {
|
|
|
84
124
|
options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms),
|
|
85
125
|
options &&
|
|
86
126
|
validateAlgorithms('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms),
|
|
87
|
-
options,
|
|
127
|
+
options?.crit,
|
|
128
|
+
options?.maxPBES2Count,
|
|
129
|
+
options?.maxDecompressedLength,
|
|
88
130
|
];
|
|
89
131
|
}
|
|
90
132
|
export async function decryptRecipient(jwe, token, shared, key) {
|
|
91
|
-
const [
|
|
92
|
-
const
|
|
93
|
-
const { encrypted_key: encodedKey, header, unprotected } = jwe;
|
|
133
|
+
const [parsedProt] = token;
|
|
134
|
+
const { header, unprotected } = jwe;
|
|
94
135
|
let joseHeader;
|
|
95
136
|
if (header !== undefined || unprotected !== undefined) {
|
|
96
137
|
if (!isDisjoint(parsedProt, header, unprotected)) {
|
|
@@ -101,13 +142,14 @@ export async function decryptRecipient(jwe, token, shared, key) {
|
|
|
101
142
|
else {
|
|
102
143
|
joseHeader = parsedProt ?? {};
|
|
103
144
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
145
|
+
return decryptRecipientCore(jwe, token, shared, key, joseHeader);
|
|
146
|
+
}
|
|
147
|
+
async function decryptRecipientCore(jwe, token, shared, key, joseHeader) {
|
|
148
|
+
const [keyManagementAlgorithms, contentEncryptionAlgorithms, crit, maxPBES2Count, maxDecompressedLength,] = shared;
|
|
149
|
+
const [parsedProt, ciphertext, iv, tag, additionalData] = token;
|
|
150
|
+
const { encrypted_key: encodedKey } = jwe;
|
|
151
|
+
validateCrit(JWEInvalid, JWE_RECOGNIZED, crit, parsedProt, joseHeader);
|
|
152
|
+
validateZip(joseHeader, parsedProt);
|
|
111
153
|
const { alg, enc } = joseHeader;
|
|
112
154
|
if (typeof alg !== 'string' || !alg) {
|
|
113
155
|
throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
|
|
@@ -136,7 +178,12 @@ export async function decryptRecipient(jwe, token, shared, key) {
|
|
|
136
178
|
const k = await prepareKey(alg === 'dir' ? encEntry : algEntry, key, 'decrypt');
|
|
137
179
|
let cek;
|
|
138
180
|
try {
|
|
139
|
-
cek = await decryptKeyManagement(alg, encEntry, k, encryptedKey, joseHeader,
|
|
181
|
+
cek = await decryptKeyManagement(alg, encEntry, k, encryptedKey, joseHeader, maxPBES2Count);
|
|
182
|
+
if (encodedKey !== undefined &&
|
|
183
|
+
cek instanceof Uint8Array &&
|
|
184
|
+
cek.byteLength << 3 !== encEntry.cekBits) {
|
|
185
|
+
cek = generateCek(encEntry);
|
|
186
|
+
}
|
|
140
187
|
}
|
|
141
188
|
catch (err) {
|
|
142
189
|
if (err instanceof TypeError || err instanceof JWEInvalid || err instanceof JOSENotSupported) {
|
|
@@ -146,15 +193,15 @@ export async function decryptRecipient(jwe, token, shared, key) {
|
|
|
146
193
|
}
|
|
147
194
|
let plaintext = await decrypt(encEntry, cek, ciphertext, iv, tag, additionalData);
|
|
148
195
|
if (joseHeader.zip === 'DEF') {
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
196
|
+
const decompressionLimit = maxDecompressedLength ?? 250_000;
|
|
197
|
+
if (decompressionLimit === 0) {
|
|
151
198
|
throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
|
|
152
199
|
}
|
|
153
|
-
if (
|
|
154
|
-
(!Number.isSafeInteger(
|
|
200
|
+
if (decompressionLimit !== Infinity &&
|
|
201
|
+
(!Number.isSafeInteger(decompressionLimit) || decompressionLimit < 1)) {
|
|
155
202
|
throw new TypeError('maxDecompressedLength must be 0, a positive safe integer, or Infinity');
|
|
156
203
|
}
|
|
157
|
-
plaintext = await decompress(plaintext,
|
|
204
|
+
plaintext = await decompress(plaintext, decompressionLimit).catch((cause) => {
|
|
158
205
|
if (cause instanceof JWEInvalid)
|
|
159
206
|
throw cause;
|
|
160
207
|
throw new JWEInvalid('Failed to decompress plaintext', { cause });
|
|
@@ -176,11 +223,21 @@ export async function decryptCompact(jwe, shared, key) {
|
|
|
176
223
|
if (length !== 5) {
|
|
177
224
|
throw new JWEInvalid('Invalid Compact JWE');
|
|
178
225
|
}
|
|
179
|
-
|
|
226
|
+
const flattened = {
|
|
180
227
|
ciphertext,
|
|
181
228
|
iv: iv || undefined,
|
|
182
229
|
protected: protectedHeader,
|
|
183
230
|
tag: tag || undefined,
|
|
184
231
|
encrypted_key: encryptedKey || undefined,
|
|
185
|
-
}
|
|
232
|
+
};
|
|
233
|
+
const parsedProt = parseJoseHeader(protectedHeader, JWEInvalid, 'JWE Protected Header is invalid');
|
|
234
|
+
const protectedBytes = encode(protectedHeader);
|
|
235
|
+
const token = [
|
|
236
|
+
parsedProt,
|
|
237
|
+
decodeBase64url(ciphertext, 'ciphertext', JWEInvalid),
|
|
238
|
+
iv ? decodeBase64url(iv, 'iv', JWEInvalid) : undefined,
|
|
239
|
+
tag ? decodeBase64url(tag, 'tag', JWEInvalid) : undefined,
|
|
240
|
+
protectedBytes,
|
|
241
|
+
];
|
|
242
|
+
return decryptRecipientCore(flattened, token, shared, key, parsedProt);
|
|
186
243
|
}
|