@suveren/gateway 0.7.6 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/integrations/mollie.json +103 -28
- package/dist/mcp-server/http.mjs +228 -118
- package/dist/ui/assets/{index-CsrM6RQr.js → index-BFnSVa9N.js} +22 -22
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +29 -6
- package/node_modules/@hap/core/dist/index.d.ts +29 -6
- package/node_modules/@hap/core/dist/index.js +54 -8
- package/node_modules/@hap/core/dist/index.mjs +53 -8
- package/node_modules/@hap/core/package.json +2 -1
- package/node_modules/@hap/core/src/frame.ts +115 -14
- package/node_modules/@hap/core/src/gatekeeper.ts +26 -0
- package/node_modules/@hap/core/src/types.ts +7 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.buffer.d.ts +5 -0
- package/node_modules/@types/node/crypto.d.ts +0 -2
- package/node_modules/@types/node/dgram.d.ts +119 -4
- package/node_modules/@types/node/ffi.d.ts +1 -1
- package/node_modules/@types/node/fs/promises.d.ts +61 -65
- package/node_modules/@types/node/fs.d.ts +86 -76
- package/node_modules/@types/node/http.d.ts +1 -1
- package/node_modules/@types/node/http2.d.ts +2 -2
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/inspector.d.ts +2 -1
- package/node_modules/@types/node/net.d.ts +108 -16
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/quic.d.ts +37 -11
- package/node_modules/@types/node/stream/iter.d.ts +4 -4
- package/node_modules/@types/node/tls.d.ts +24 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +5 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -0
- package/node_modules/@types/node/tty.d.ts +4 -3
- package/node_modules/@types/node/vfs.d.ts +210 -0
- package/node_modules/@types/node/vm.d.ts +1 -1
- package/node_modules/express-rate-limit/dist/index.cjs +6 -3
- package/node_modules/express-rate-limit/dist/index.d.cts +11 -0
- package/node_modules/express-rate-limit/dist/index.d.mts +11 -0
- package/node_modules/express-rate-limit/dist/index.d.ts +11 -0
- package/node_modules/express-rate-limit/dist/index.mjs +6 -3
- package/node_modules/express-rate-limit/{license.md → license} +7 -6
- package/node_modules/express-rate-limit/package.json +5 -5
- package/node_modules/express-rate-limit/readme.md +1 -0
- package/node_modules/fast-uri/index.js +20 -5
- package/node_modules/fast-uri/lib/utils.js +8 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +58 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +34 -0
- package/node_modules/ip-address/README.md +92 -82
- package/node_modules/ip-address/dist/common.d.ts +20 -0
- package/node_modules/ip-address/dist/common.js +36 -0
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +50 -0
- package/node_modules/ip-address/dist/ipv4.js +75 -0
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +79 -10
- package/node_modules/ip-address/dist/ipv6.js +120 -30
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
- package/node_modules/ip-address/dist/v4/constants.js +40 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
- package/node_modules/ip-address/dist/v6/constants.js +47 -1
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +6 -17
- package/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +11 -34
- package/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +15 -35
- package/node_modules/jose/dist/types/jwk/embedded.d.ts +3 -8
- package/node_modules/jose/dist/types/jwk/thumbprint.d.ts +5 -5
- package/node_modules/jose/dist/types/jwks/local.d.ts +6 -10
- package/node_modules/jose/dist/types/jwks/remote.d.ts +13 -24
- package/node_modules/jose/dist/types/jws/compact/sign.d.ts +5 -10
- package/node_modules/jose/dist/types/jws/compact/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jws/flattened/sign.d.ts +7 -16
- package/node_modules/jose/dist/types/jws/flattened/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jws/general/sign.d.ts +11 -21
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jwt/decrypt.d.ts +10 -20
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +6 -13
- package/node_modules/jose/dist/types/jwt/sign.d.ts +5 -6
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +9 -14
- package/node_modules/jose/dist/types/jwt/verify.d.ts +9 -19
- package/node_modules/jose/dist/types/key/export.d.ts +4 -4
- package/node_modules/jose/dist/types/key/generate_key_pair.d.ts +6 -8
- package/node_modules/jose/dist/types/key/generate_secret.d.ts +4 -11
- package/node_modules/jose/dist/types/key/import.d.ts +10 -17
- package/node_modules/jose/dist/types/types.d.ts +44 -84
- package/node_modules/jose/dist/types/util/base64url.d.ts +2 -2
- package/node_modules/jose/dist/types/util/decode_jwt.d.ts +3 -10
- package/node_modules/jose/dist/types/util/decode_protected_header.d.ts +4 -4
- package/node_modules/jose/dist/types/util/errors.d.ts +26 -53
- package/node_modules/jose/dist/webapi/index.js +70 -32
- package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +7 -8
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +42 -48
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +14 -14
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +53 -64
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +38 -49
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +121 -169
- package/node_modules/jose/dist/webapi/jwk/embedded.js +30 -32
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +54 -70
- package/node_modules/jose/dist/webapi/jwks/local.js +47 -64
- package/node_modules/jose/dist/webapi/jwks/remote.js +88 -136
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +21 -21
- package/node_modules/jose/dist/webapi/jws/compact/verify.js +7 -8
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +29 -31
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +21 -24
- package/node_modules/jose/dist/webapi/jws/general/sign.js +61 -72
- package/node_modules/jose/dist/webapi/jws/general/verify.js +45 -69
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +13 -20
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +57 -70
- package/node_modules/jose/dist/webapi/jwt/sign.js +17 -16
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +32 -40
- package/node_modules/jose/dist/webapi/jwt/verify.js +12 -14
- package/node_modules/jose/dist/webapi/key/export.js +32 -37
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +40 -48
- package/node_modules/jose/dist/webapi/key/generate_secret.js +35 -40
- package/node_modules/jose/dist/webapi/key/import.js +52 -56
- package/node_modules/jose/dist/webapi/lib/asn1.js +130 -169
- package/node_modules/jose/dist/webapi/lib/base64.js +18 -20
- package/node_modules/jose/dist/webapi/lib/buffer_utils.js +34 -38
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +79 -115
- package/node_modules/jose/dist/webapi/lib/crypto_key.js +24 -25
- package/node_modules/jose/dist/webapi/lib/deflate.js +45 -47
- package/node_modules/jose/dist/webapi/lib/helpers.js +40 -37
- package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +10 -24
- package/node_modules/jose/dist/webapi/lib/is_key_like.js +17 -15
- package/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +106 -93
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +207 -230
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +104 -138
- package/node_modules/jose/dist/webapi/lib/jwk_metadata.js +17 -18
- package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +9 -16
- package/node_modules/jose/dist/webapi/lib/jws_algorithms.js +62 -61
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +50 -75
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +80 -125
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +123 -209
- package/node_modules/jose/dist/webapi/lib/key.js +84 -136
- package/node_modules/jose/dist/webapi/lib/key_algorithm.js +13 -8
- package/node_modules/jose/dist/webapi/lib/key_descriptor.js +8 -6
- package/node_modules/jose/dist/webapi/lib/key_management.js +200 -231
- package/node_modules/jose/dist/webapi/lib/key_options.js +7 -5
- package/node_modules/jose/dist/webapi/lib/options.js +55 -68
- package/node_modules/jose/dist/webapi/lib/signing.js +18 -22
- package/node_modules/jose/dist/webapi/lib/type_checks.js +26 -29
- package/node_modules/jose/dist/webapi/util/base64url.js +26 -35
- package/node_modules/jose/dist/webapi/util/decode_jwt.js +32 -31
- package/node_modules/jose/dist/webapi/util/decode_protected_header.js +18 -23
- package/node_modules/jose/dist/webapi/util/errors.js +94 -84
- package/node_modules/jose/package.json +17 -81
- package/package.json +2 -2
- package/profiles/calendar/0.5.profile.json +190 -0
- package/profiles/charge/0.5.profile.json +210 -0
- package/profiles/customers/0.7.profile.json +157 -0
- package/profiles/deploy/0.9.profile.json +176 -0
- package/profiles/email/0.6.profile.json +208 -0
- package/profiles/index.json +9 -1
- package/profiles/publish/0.5.profile.json +186 -0
- package/profiles/purchase/0.5.profile.json +231 -0
- package/profiles/records/0.5.profile.json +117 -0
|
@@ -1,262 +1,231 @@
|
|
|
1
|
-
import { encode as b64u } from
|
|
2
|
-
import { prepareKey } from
|
|
3
|
-
import { jwkToKey } from
|
|
4
|
-
import { jweAlgorithm, jweEncryption } from
|
|
5
|
-
import { JOSENotSupported, JWEInvalid } from
|
|
6
|
-
import { decodeBase64url, digest } from
|
|
7
|
-
import { generateCek, encrypt, decrypt } from
|
|
8
|
-
import { assertUint8Array, isObject } from
|
|
9
|
-
import { checkCryptoKey, checkModulusLength, checkUsage } from
|
|
10
|
-
import { concat, encode, uint32be } from
|
|
11
|
-
import { assertCryptoKey } from
|
|
1
|
+
import { encode as b64u } from "../util/base64url.js";
|
|
2
|
+
import { prepareKey } from "./key.js";
|
|
3
|
+
import { jwkToKey } from "./jwk_to_key.js";
|
|
4
|
+
import { jweAlgorithm, jweEncryption } from "./jwe_algorithms.js";
|
|
5
|
+
import { JOSENotSupported, JWEInvalid } from "../util/errors.js";
|
|
6
|
+
import { decodeBase64url, digest } from "./helpers.js";
|
|
7
|
+
import { generateCek, encrypt, decrypt } from "./content_encryption.js";
|
|
8
|
+
import { assertUint8Array, isObject } from "./type_checks.js";
|
|
9
|
+
import { checkCryptoKey, checkModulusLength, checkUsage } from "./crypto_key.js";
|
|
10
|
+
import { concat, encode, uint32be } from "./buffer_utils.js";
|
|
11
|
+
import { assertCryptoKey } from "./is_key_like.js";
|
|
12
12
|
function checkEcdhCryptoKey(key, usage) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
checkUsage(key, usage);
|
|
13
|
+
if (key.algorithm.name !== "ECDH" && key.algorithm.name !== "X25519")
|
|
14
|
+
throw new TypeError("CryptoKey does not support this operation, its algorithm.name must be ECDH or X25519");
|
|
15
|
+
checkUsage(key, usage);
|
|
17
16
|
}
|
|
18
17
|
async function aeskwCryptoKey(key, alg, usage) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
])
|
|
24
|
-
: key;
|
|
25
|
-
checkCryptoKey(cryptoKey, expected, usage);
|
|
26
|
-
return cryptoKey;
|
|
18
|
+
const expected = jweAlgorithm(alg).subtle, cryptoKey = key instanceof Uint8Array ? await crypto.subtle.importKey("raw", key, "AES-KW", !0, [
|
|
19
|
+
usage
|
|
20
|
+
]) : key;
|
|
21
|
+
return checkCryptoKey(cryptoKey, expected, usage), cryptoKey;
|
|
27
22
|
}
|
|
28
23
|
async function aeskwWrap(alg, key, cek) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return new Uint8Array(await crypto.subtle.wrapKey('raw', cryptoKeyCek, cryptoKey, 'AES-KW'));
|
|
24
|
+
const cryptoKey = await aeskwCryptoKey(key, alg, "wrapKey"), cryptoKeyCek = await crypto.subtle.importKey("raw", cek, { hash: "SHA-256", name: "HMAC" }, !0, ["sign"]);
|
|
25
|
+
return new Uint8Array(await crypto.subtle.wrapKey("raw", cryptoKeyCek, cryptoKey, "AES-KW"));
|
|
32
26
|
}
|
|
33
27
|
async function aeskwUnwrap(alg, key, encryptedKey) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return new Uint8Array(await crypto.subtle.exportKey('raw', cryptoKeyCek));
|
|
28
|
+
const cryptoKey = await aeskwCryptoKey(key, alg, "unwrapKey"), cryptoKeyCek = await crypto.subtle.unwrapKey("raw", encryptedKey, cryptoKey, "AES-KW", { hash: "SHA-256", name: "HMAC" }, !0, ["sign"]);
|
|
29
|
+
return new Uint8Array(await crypto.subtle.exportKey("raw", cryptoKeyCek));
|
|
37
30
|
}
|
|
38
31
|
function checkRsaKey(alg, key, usage) {
|
|
39
|
-
|
|
40
|
-
checkModulusLength(alg, key);
|
|
32
|
+
checkCryptoKey(key, jweAlgorithm(alg).subtle, usage), checkModulusLength(alg, key);
|
|
41
33
|
}
|
|
42
34
|
function pbes2CryptoKey(key, alg) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
]);
|
|
47
|
-
}
|
|
48
|
-
checkCryptoKey(key, jweAlgorithm(alg).subtle, 'deriveBits');
|
|
49
|
-
return key;
|
|
35
|
+
return key instanceof Uint8Array ? crypto.subtle.importKey("raw", key, "PBKDF2", !1, [
|
|
36
|
+
"deriveBits"
|
|
37
|
+
]) : (checkCryptoKey(key, jweAlgorithm(alg).subtle, "deriveBits"), key);
|
|
50
38
|
}
|
|
51
39
|
async function deriveKey(p2s, alg, p2c, key) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
name: 'PBKDF2',
|
|
64
|
-
salt,
|
|
65
|
-
};
|
|
66
|
-
const cryptoKey = await pbes2CryptoKey(key, alg);
|
|
67
|
-
return new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
|
|
40
|
+
if (!(p2s instanceof Uint8Array) || p2s.length < 8)
|
|
41
|
+
throw new JWEInvalid("PBES2 Salt Input must be 8 or more octets");
|
|
42
|
+
if (!Number.isSafeInteger(p2c) || Math.sign(p2c) !== 1)
|
|
43
|
+
throw new JWEInvalid("PBES2 Count Input must be a positive integer");
|
|
44
|
+
const salt = concat(encode(alg), Uint8Array.of(0), p2s), keylen = parseInt(alg.slice(13, 16), 10), subtleAlg = {
|
|
45
|
+
hash: `SHA-${alg.slice(8, 11)}`,
|
|
46
|
+
iterations: p2c,
|
|
47
|
+
name: "PBKDF2",
|
|
48
|
+
salt
|
|
49
|
+
}, cryptoKey = await pbes2CryptoKey(key, alg);
|
|
50
|
+
return new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
|
|
68
51
|
}
|
|
69
52
|
function lengthAndInput(input) {
|
|
70
|
-
|
|
53
|
+
return concat(uint32be(input.length), input);
|
|
71
54
|
}
|
|
72
55
|
async function concatKdf(Z, L, OtherInfo) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
dk.set(hashResult, (i - 1) * hashLen);
|
|
80
|
-
}
|
|
81
|
-
return dk.slice(0, dkLen);
|
|
56
|
+
const dkLen = L >> 3, hashLen = 32, reps = Math.ceil(dkLen / hashLen), dk = new Uint8Array(reps * hashLen);
|
|
57
|
+
for (let i = 1; i <= reps; i++) {
|
|
58
|
+
const hashResult = await digest("sha256", concat(uint32be(i), Z, OtherInfo));
|
|
59
|
+
dk.set(hashResult, (i - 1) * hashLen);
|
|
60
|
+
}
|
|
61
|
+
return dk.slice(0, dkLen);
|
|
82
62
|
}
|
|
83
63
|
async function ecdhesDeriveKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}, privateKey, publicKey.algorithm.name === 'X25519'
|
|
91
|
-
? 256
|
|
92
|
-
: Math.ceil(parseInt(publicKey.algorithm.namedCurve.slice(-3), 10) / 8) << 3));
|
|
93
|
-
return concatKdf(Z, keyLength, otherInfo);
|
|
64
|
+
checkEcdhCryptoKey(publicKey), checkEcdhCryptoKey(privateKey, "deriveBits");
|
|
65
|
+
const otherInfo = concat(lengthAndInput(encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength)), Z = new Uint8Array(await crypto.subtle.deriveBits({
|
|
66
|
+
name: publicKey.algorithm.name,
|
|
67
|
+
public: publicKey
|
|
68
|
+
}, privateKey, publicKey.algorithm.name === "X25519" ? 256 : Math.ceil(parseInt(publicKey.algorithm.namedCurve.slice(-3), 10) / 8) << 3));
|
|
69
|
+
return concatKdf(Z, keyLength, otherInfo);
|
|
94
70
|
}
|
|
95
71
|
function assertEcdhKey(key) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
72
|
+
assertCryptoKey(key);
|
|
73
|
+
const curve = key.algorithm.namedCurve;
|
|
74
|
+
if (curve !== "P-256" && curve !== "P-384" && curve !== "P-521" && key.algorithm.name !== "X25519")
|
|
75
|
+
throw new JOSENotSupported("ECDH with the provided key is not allowed or not supported by your javascript runtime");
|
|
76
|
+
}
|
|
77
|
+
function partyInfo(joseHeader, name) {
|
|
78
|
+
const value = joseHeader[name];
|
|
79
|
+
if (value !== void 0) {
|
|
80
|
+
if (typeof value != "string")
|
|
81
|
+
throw new JWEInvalid(`JOSE Header "${name}" (Agreement Party${name === "apu" ? "U" : "V"}Info) invalid`);
|
|
82
|
+
return decodeBase64url(value, name, JWEInvalid);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function checkPartyInfo(apu, apv) {
|
|
86
|
+
if (!(apu === void 0 || apv === void 0 || apu.byteLength !== apv.byteLength)) {
|
|
87
|
+
for (let i = 0; i < apu.byteLength; i++)
|
|
88
|
+
if (apu[i] !== apv[i])
|
|
89
|
+
return;
|
|
90
|
+
throw new JWEInvalid('JOSE Header "apu" and "apv" values must be distinct');
|
|
91
|
+
}
|
|
104
92
|
}
|
|
105
93
|
function assertEncryptedKey(encryptedKey) {
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
if (encryptedKey === void 0)
|
|
95
|
+
throw new JWEInvalid("JWE Encrypted Key missing");
|
|
108
96
|
}
|
|
109
97
|
function assertNoEncryptedKey(encryptedKey) {
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
if (encryptedKey !== void 0)
|
|
99
|
+
throw new JWEInvalid("Encountered unexpected JWE Encrypted Key");
|
|
100
|
+
}
|
|
101
|
+
function validateMaxPBES2Count(value) {
|
|
102
|
+
if (value !== void 0 && value !== 1 / 0 && (!Number.isSafeInteger(value) || value < 1))
|
|
103
|
+
throw new TypeError("maxPBES2Count must be a positive safe integer or Infinity");
|
|
112
104
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
async function decryptKeyManagement(entry, enc, key, encryptedKey, joseHeader, maxPBES2Count) {
|
|
106
|
+
const { alg } = entry, mode = entry.mode;
|
|
107
|
+
switch (mode) {
|
|
108
|
+
case "direct-encryption":
|
|
109
|
+
return assertNoEncryptedKey(encryptedKey), key;
|
|
110
|
+
case "direct-key-agreement":
|
|
111
|
+
case "key-wrapping":
|
|
112
|
+
case "key-encryption":
|
|
113
|
+
case "key-agreement-with-key-wrapping":
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
switch (entry.subtle.name) {
|
|
117
|
+
case "ECDH": {
|
|
118
|
+
const direct = mode === "direct-key-agreement";
|
|
119
|
+
direct && assertNoEncryptedKey(encryptedKey);
|
|
120
|
+
const { epk } = joseHeader;
|
|
121
|
+
if (!isObject(epk) || ["d", "k", "p", "q", "dp", "dq", "qi", "oth", "priv"].some((parameter) => Object.hasOwn(epk, parameter)))
|
|
122
|
+
throw new JWEInvalid('JOSE Header "epk" (Ephemeral Public Key) missing or invalid');
|
|
123
|
+
assertEcdhKey(key);
|
|
124
|
+
const ephemeralPublicKey = await jwkToKey(entry, epk), partyUInfo = partyInfo(joseHeader, "apu"), partyVInfo = partyInfo(joseHeader, "apv");
|
|
125
|
+
checkPartyInfo(partyUInfo, partyVInfo);
|
|
126
|
+
const sharedSecret = await ecdhesDeriveKey(ephemeralPublicKey, key, direct ? enc.alg : alg, direct ? enc.cekBits : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
|
|
127
|
+
return direct ? sharedSecret : (assertEncryptedKey(encryptedKey), aeskwUnwrap(alg.slice(-6), sharedSecret, encryptedKey));
|
|
118
128
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
partyUInfo = decodeBase64url(joseHeader.apu, 'apu', JWEInvalid);
|
|
133
|
-
}
|
|
134
|
-
if (joseHeader.apv !== undefined) {
|
|
135
|
-
if (typeof joseHeader.apv !== 'string')
|
|
136
|
-
throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
|
|
137
|
-
partyVInfo = decodeBase64url(joseHeader.apv, 'apv', JWEInvalid);
|
|
138
|
-
}
|
|
139
|
-
const sharedSecret = await ecdhesDeriveKey(epk, key, alg === 'ECDH-ES' ? enc.alg : alg, alg === 'ECDH-ES' ? enc.cekBits : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
|
|
140
|
-
if (alg === 'ECDH-ES')
|
|
141
|
-
return sharedSecret;
|
|
142
|
-
assertEncryptedKey(encryptedKey);
|
|
143
|
-
return aeskwUnwrap(alg.slice(-6), sharedSecret, encryptedKey);
|
|
144
|
-
}
|
|
145
|
-
case 'RSA-OAEP': {
|
|
146
|
-
assertEncryptedKey(encryptedKey);
|
|
147
|
-
assertCryptoKey(key);
|
|
148
|
-
checkRsaKey(alg, key, 'decrypt');
|
|
149
|
-
return new Uint8Array(await crypto.subtle.decrypt('RSA-OAEP', key, encryptedKey));
|
|
150
|
-
}
|
|
151
|
-
case 'PBKDF2': {
|
|
152
|
-
assertEncryptedKey(encryptedKey);
|
|
153
|
-
if (typeof joseHeader.p2c !== 'number')
|
|
154
|
-
throw new JWEInvalid(`JOSE Header "p2c" (PBES2 Count) missing or invalid`);
|
|
155
|
-
const p2cLimit = maxPBES2Count || 10_000;
|
|
156
|
-
if (joseHeader.p2c > p2cLimit)
|
|
157
|
-
throw new JWEInvalid(`JOSE Header "p2c" (PBES2 Count) out is of acceptable bounds`);
|
|
158
|
-
if (typeof joseHeader.p2s !== 'string')
|
|
159
|
-
throw new JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`);
|
|
160
|
-
const p2s = decodeBase64url(joseHeader.p2s, 'p2s', JWEInvalid);
|
|
161
|
-
const derived = await deriveKey(p2s, alg, joseHeader.p2c, key);
|
|
162
|
-
return aeskwUnwrap(alg.slice(-6), derived, encryptedKey);
|
|
163
|
-
}
|
|
164
|
-
case 'AES-KW': {
|
|
165
|
-
assertEncryptedKey(encryptedKey);
|
|
166
|
-
return aeskwUnwrap(alg, key, encryptedKey);
|
|
167
|
-
}
|
|
168
|
-
case 'AES-GCM': {
|
|
169
|
-
assertEncryptedKey(encryptedKey);
|
|
170
|
-
if (typeof joseHeader.iv !== 'string')
|
|
171
|
-
throw new JWEInvalid(`JOSE Header "iv" (Initialization Vector) missing or invalid`);
|
|
172
|
-
if (typeof joseHeader.tag !== 'string')
|
|
173
|
-
throw new JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`);
|
|
174
|
-
let iv;
|
|
175
|
-
iv = decodeBase64url(joseHeader.iv, 'iv', JWEInvalid);
|
|
176
|
-
let tag;
|
|
177
|
-
tag = decodeBase64url(joseHeader.tag, 'tag', JWEInvalid);
|
|
178
|
-
return decrypt(jweEncryption(alg.slice(0, -2)), key, encryptedKey, iv, tag, new Uint8Array());
|
|
179
|
-
}
|
|
129
|
+
case "RSA-OAEP":
|
|
130
|
+
return assertEncryptedKey(encryptedKey), assertCryptoKey(key), checkRsaKey(alg, key, "decrypt"), new Uint8Array(await crypto.subtle.decrypt("RSA-OAEP", key, encryptedKey));
|
|
131
|
+
case "PBKDF2": {
|
|
132
|
+
if (assertEncryptedKey(encryptedKey), typeof joseHeader.p2c != "number")
|
|
133
|
+
throw new JWEInvalid('JOSE Header "p2c" (PBES2 Count) missing or invalid');
|
|
134
|
+
validateMaxPBES2Count(maxPBES2Count);
|
|
135
|
+
const p2cLimit = maxPBES2Count ?? 1e4;
|
|
136
|
+
if (joseHeader.p2c > p2cLimit)
|
|
137
|
+
throw new JWEInvalid('JOSE Header "p2c" (PBES2 Count) out is of acceptable bounds');
|
|
138
|
+
if (typeof joseHeader.p2s != "string")
|
|
139
|
+
throw new JWEInvalid('JOSE Header "p2s" (PBES2 Salt) missing or invalid');
|
|
140
|
+
const p2s = decodeBase64url(joseHeader.p2s, "p2s", JWEInvalid), derived = await deriveKey(p2s, alg, joseHeader.p2c, key);
|
|
141
|
+
return aeskwUnwrap(alg.slice(-6), derived, encryptedKey);
|
|
180
142
|
}
|
|
143
|
+
case "AES-KW":
|
|
144
|
+
return assertEncryptedKey(encryptedKey), aeskwUnwrap(alg, key, encryptedKey);
|
|
145
|
+
case "AES-GCM": {
|
|
146
|
+
if (assertEncryptedKey(encryptedKey), typeof joseHeader.iv != "string")
|
|
147
|
+
throw new JWEInvalid('JOSE Header "iv" (Initialization Vector) missing or invalid');
|
|
148
|
+
if (typeof joseHeader.tag != "string")
|
|
149
|
+
throw new JWEInvalid('JOSE Header "tag" (Authentication Tag) missing or invalid');
|
|
150
|
+
let iv;
|
|
151
|
+
iv = decodeBase64url(joseHeader.iv, "iv", JWEInvalid);
|
|
152
|
+
let tag;
|
|
153
|
+
if (tag = decodeBase64url(joseHeader.tag, "tag", JWEInvalid), iv.byteLength !== 12)
|
|
154
|
+
throw new JWEInvalid("Invalid Initialization Vector length");
|
|
155
|
+
if (tag.byteLength !== 16)
|
|
156
|
+
throw new JWEInvalid("Invalid Authentication Tag length");
|
|
157
|
+
return decrypt(jweEncryption(alg.slice(0, -2)), key, encryptedKey, iv, tag, new Uint8Array());
|
|
158
|
+
}
|
|
159
|
+
}
|
|
181
160
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const derived = await deriveKey(p2s, alg, p2c, key);
|
|
243
|
-
encryptedKey = await aeskwWrap(alg.slice(-6), derived, cek);
|
|
244
|
-
parameters = { p2c, p2s: b64u(p2s) };
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
case 'AES-KW': {
|
|
248
|
-
cek = providedCek || generateCek(enc);
|
|
249
|
-
encryptedKey = await aeskwWrap(alg, key, cek);
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
case 'AES-GCM': {
|
|
253
|
-
cek = providedCek || generateCek(enc);
|
|
254
|
-
const { iv } = providedParameters;
|
|
255
|
-
const wrapped = await encrypt(jweEncryption(alg.slice(0, -2)), cek, key, iv, new Uint8Array());
|
|
256
|
-
encryptedKey = wrapped.ciphertext;
|
|
257
|
-
parameters = { iv: b64u(wrapped.iv), tag: b64u(wrapped.tag) };
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
161
|
+
async function encryptKeyManagement(entry, enc, key, joseHeader, providedCek, providedParameters = {}) {
|
|
162
|
+
let encryptedKey, parameters, cek;
|
|
163
|
+
const { alg } = entry, mode = entry.mode;
|
|
164
|
+
switch (mode) {
|
|
165
|
+
case "direct-encryption":
|
|
166
|
+
return [key, void 0, void 0];
|
|
167
|
+
case "direct-key-agreement":
|
|
168
|
+
case "key-wrapping":
|
|
169
|
+
case "key-encryption":
|
|
170
|
+
case "key-agreement-with-key-wrapping":
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
switch (entry.subtle.name) {
|
|
174
|
+
case "ECDH": {
|
|
175
|
+
assertEcdhKey(key);
|
|
176
|
+
const { apu: providedApu, apv: providedApv } = providedParameters;
|
|
177
|
+
providedApu !== void 0 && assertUint8Array(providedApu, '"apu"'), providedApv !== void 0 && assertUint8Array(providedApv, '"apv"');
|
|
178
|
+
const apu = providedApu ?? partyInfo(joseHeader, "apu"), apv = providedApv ?? partyInfo(joseHeader, "apv");
|
|
179
|
+
checkPartyInfo(apu, apv);
|
|
180
|
+
let ephemeralKey;
|
|
181
|
+
providedParameters.epk !== void 0 ? ephemeralKey = await prepareKey(entry, providedParameters.epk, "decrypt") : ephemeralKey = (await crypto.subtle.generateKey(key.algorithm, !0, ["deriveBits"])).privateKey;
|
|
182
|
+
const subtle = crypto.subtle;
|
|
183
|
+
let exportableEpk = ephemeralKey;
|
|
184
|
+
if (!exportableEpk.extractable) {
|
|
185
|
+
if (typeof subtle.getPublicKey != "function")
|
|
186
|
+
throw new TypeError('CryptoKey for "epk" must be extractable');
|
|
187
|
+
exportableEpk = await subtle.getPublicKey(ephemeralKey, []);
|
|
188
|
+
}
|
|
189
|
+
const { x, y, crv, kty } = await subtle.exportKey("jwk", exportableEpk), direct = mode === "direct-key-agreement", sharedSecret = await ecdhesDeriveKey(key, ephemeralKey, direct ? enc.alg : alg, direct ? enc.cekBits : parseInt(alg.slice(-5, -2), 10), apu, apv);
|
|
190
|
+
if (parameters = { epk: { x, crv, kty } }, kty === "EC" && (parameters.epk.y = y), providedApu !== void 0 && (parameters.apu = b64u(providedApu)), providedApv !== void 0 && (parameters.apv = b64u(providedApv)), direct) {
|
|
191
|
+
cek = sharedSecret;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
cek = providedCek ?? generateCek(enc);
|
|
195
|
+
const kwAlg = alg.slice(-6);
|
|
196
|
+
encryptedKey = await aeskwWrap(kwAlg, sharedSecret, cek);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "RSA-OAEP": {
|
|
200
|
+
cek = providedCek ?? generateCek(enc), assertCryptoKey(key), checkRsaKey(alg, key, "encrypt"), encryptedKey = new Uint8Array(await crypto.subtle.encrypt("RSA-OAEP", key, cek));
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case "PBKDF2": {
|
|
204
|
+
cek = providedCek ?? generateCek(enc);
|
|
205
|
+
const { p2c = 2048, p2s = crypto.getRandomValues(new Uint8Array(16)) } = providedParameters, derived = await deriveKey(p2s, alg, p2c, key);
|
|
206
|
+
encryptedKey = await aeskwWrap(alg.slice(-6), derived, cek), parameters = { p2c, p2s: b64u(p2s) };
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
case "AES-KW": {
|
|
210
|
+
cek = providedCek ?? generateCek(enc), encryptedKey = await aeskwWrap(alg, key, cek);
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case "AES-GCM": {
|
|
214
|
+
cek = providedCek ?? generateCek(enc);
|
|
215
|
+
const iv = providedParameters.iv === void 0 ? crypto.getRandomValues(new Uint8Array(12)) : providedParameters.iv;
|
|
216
|
+
if (!(iv instanceof Uint8Array))
|
|
217
|
+
throw new TypeError('"iv" must be an instance of Uint8Array');
|
|
218
|
+
const wrapped = await encrypt(jweEncryption(alg.slice(0, -2)), cek, key, iv, new Uint8Array());
|
|
219
|
+
encryptedKey = wrapped.ciphertext, parameters = { iv: b64u(wrapped.iv), tag: b64u(wrapped.tag) };
|
|
220
|
+
break;
|
|
260
221
|
}
|
|
261
|
-
|
|
222
|
+
}
|
|
223
|
+
if (cek === void 0)
|
|
224
|
+
throw new TypeError("Invalid JWE key management algorithm");
|
|
225
|
+
return [cek, encryptedKey, parameters];
|
|
262
226
|
}
|
|
227
|
+
export {
|
|
228
|
+
decryptKeyManagement,
|
|
229
|
+
encryptKeyManagement,
|
|
230
|
+
validateMaxPBES2Count
|
|
231
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return extractable;
|
|
1
|
+
function validateExtractableOption(extractable) {
|
|
2
|
+
if (extractable !== void 0 && typeof extractable != "boolean")
|
|
3
|
+
throw new TypeError('"extractable" option must be a boolean');
|
|
4
|
+
return extractable;
|
|
6
5
|
}
|
|
6
|
+
export {
|
|
7
|
+
validateExtractableOption
|
|
8
|
+
};
|
|
@@ -1,74 +1,61 @@
|
|
|
1
|
-
import { JOSENotSupported,
|
|
2
|
-
import { isObject } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
throw new TypeError(`"${option}" option must be an array of strings`);
|
|
9
|
-
}
|
|
10
|
-
if (!algorithms) {
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
1
|
+
import { JOSENotSupported, JWSInvalid } from "../util/errors.js";
|
|
2
|
+
import { isObject } from "./type_checks.js";
|
|
3
|
+
const JWS_RECOGNIZED = { __proto__: null, b64: !0 }, JWE_RECOGNIZED = { __proto__: null };
|
|
4
|
+
function validateAlgorithms(option, algorithms) {
|
|
5
|
+
if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s != "string")))
|
|
6
|
+
throw new TypeError(`"${option}" option must be an array of strings`);
|
|
7
|
+
if (algorithms)
|
|
13
8
|
return new Set(algorithms);
|
|
14
9
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
10
|
+
function validateCritDuplicates(Err, protectedHeader) {
|
|
11
|
+
const { crit } = protectedHeader ?? {};
|
|
12
|
+
if (Array.isArray(crit) && new Set(crit).size !== crit.length)
|
|
13
|
+
throw new Err('"crit" (Critical) Header Parameter MUST NOT contain duplicate values');
|
|
20
14
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
39
|
-
}
|
|
40
|
-
if (!Object.hasOwn(joseHeader, parameter) || joseHeader[parameter] === undefined) {
|
|
41
|
-
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
42
|
-
}
|
|
43
|
-
if (recognized[parameter] &&
|
|
44
|
-
(!Object.hasOwn(protectedHeader, parameter) || protectedHeader[parameter] === undefined)) {
|
|
45
|
-
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return protectedHeader.crit;
|
|
15
|
+
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
16
|
+
if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0)
|
|
17
|
+
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
18
|
+
if (!protectedHeader || protectedHeader.crit === void 0)
|
|
19
|
+
return [];
|
|
20
|
+
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input != "string" || input.length === 0))
|
|
21
|
+
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
|
|
22
|
+
const recognized = recognizedOption === void 0 ? recognizedDefault : { __proto__: null, ...recognizedOption, ...recognizedDefault };
|
|
23
|
+
for (const parameter of protectedHeader.crit) {
|
|
24
|
+
if (!(parameter in recognized))
|
|
25
|
+
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
26
|
+
if (!Object.hasOwn(joseHeader, parameter) || joseHeader[parameter] === void 0)
|
|
27
|
+
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
28
|
+
if (recognized[parameter] && (!Object.hasOwn(protectedHeader, parameter) || protectedHeader[parameter] === void 0))
|
|
29
|
+
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
30
|
+
}
|
|
31
|
+
return protectedHeader.crit;
|
|
49
32
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return true;
|
|
33
|
+
function validateB64(protectedHeader, extensions) {
|
|
34
|
+
if (extensions.includes("b64")) {
|
|
35
|
+
const b64 = protectedHeader.b64;
|
|
36
|
+
if (typeof b64 != "boolean")
|
|
37
|
+
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
38
|
+
return b64;
|
|
39
|
+
}
|
|
40
|
+
return !0;
|
|
59
41
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!isObject(parsed)) {
|
|
71
|
-
throw new Err('JOSE Header is not a JSON object');
|
|
72
|
-
}
|
|
73
|
-
return [parsed, serialized];
|
|
42
|
+
function serializeJoseHeader(Err, header) {
|
|
43
|
+
let serialized, parsed;
|
|
44
|
+
try {
|
|
45
|
+
serialized = JSON.stringify(header), parsed = JSON.parse(serialized);
|
|
46
|
+
} catch (cause) {
|
|
47
|
+
throw new Err("JOSE Header is not valid JSON", { cause });
|
|
48
|
+
}
|
|
49
|
+
if (!isObject(parsed))
|
|
50
|
+
throw new Err("JOSE Header is not a JSON object");
|
|
51
|
+
return [parsed, serialized];
|
|
74
52
|
}
|
|
53
|
+
export {
|
|
54
|
+
JWE_RECOGNIZED,
|
|
55
|
+
JWS_RECOGNIZED,
|
|
56
|
+
serializeJoseHeader,
|
|
57
|
+
validateAlgorithms,
|
|
58
|
+
validateB64,
|
|
59
|
+
validateCrit,
|
|
60
|
+
validateCritDuplicates
|
|
61
|
+
};
|