@zuplo/cli 6.74.2 → 6.74.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.
Files changed (64) hide show
  1. package/dist/cmds/test.d.ts.map +1 -1
  2. package/dist/cmds/test.js +8 -0
  3. package/dist/cmds/test.js.map +1 -1
  4. package/dist/common/utils/pnpm-lifecycle.d.ts.map +1 -1
  5. package/dist/common/utils/pnpm-lifecycle.js +1 -4
  6. package/dist/common/utils/pnpm-lifecycle.js.map +1 -1
  7. package/dist/common/utils/pnpm-lifecycle.test.js +23 -4
  8. package/dist/common/utils/pnpm-lifecycle.test.js.map +1 -1
  9. package/dist/test/handler.d.ts +2 -1
  10. package/dist/test/handler.d.ts.map +1 -1
  11. package/dist/test/handler.js.map +1 -1
  12. package/dist/test/invoke-test.d.ts +3 -2
  13. package/dist/test/invoke-test.d.ts.map +1 -1
  14. package/dist/test/invoke-test.js +26 -0
  15. package/dist/test/invoke-test.js.map +1 -1
  16. package/dist/test/invoke-test.test.js +16 -0
  17. package/dist/test/invoke-test.test.js.map +1 -1
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +2 -2
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +12 -12
  20. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/general/encrypt.js +50 -51
  21. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/local.js +10 -31
  22. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +17 -26
  23. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/compact/verify.js +2 -2
  24. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/flattened/sign.js +1 -9
  25. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/sign.js +12 -21
  26. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/verify.js +13 -11
  27. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/decrypt.js +3 -3
  28. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/verify.js +4 -4
  29. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/export.js +3 -3
  30. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/generate_key_pair.js +7 -6
  31. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/asn1.js +29 -62
  32. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/content_encryption.js +16 -34
  33. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/crypto_key.js +6 -0
  34. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/invalid_key_input.js +0 -1
  35. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +44 -71
  36. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +46 -41
  37. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +14 -13
  38. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwk_to_key.js +5 -10
  39. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_algorithms.js +20 -18
  40. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_sign.js +12 -6
  41. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_verify.js +26 -27
  42. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +60 -102
  43. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key.js +61 -99
  44. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_algorithm.js +2 -8
  45. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_descriptor.js +1 -1
  46. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_management.js +74 -161
  47. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/options.js +11 -14
  48. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/signing.js +6 -16
  49. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/type_checks.js +13 -18
  50. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/base64url.js +4 -3
  51. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
  52. package/node_modules/@zuplo/core/package.json +1 -1
  53. package/node_modules/@zuplo/graphql/package.json +1 -1
  54. package/node_modules/@zuplo/openapi-tools/package.json +3 -3
  55. package/node_modules/@zuplo/otel/package.json +1 -1
  56. package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js → chunk-CKGECOOJ.js} +88 -88
  57. package/node_modules/@zuplo/runtime/out/esm/chunk-CKGECOOJ.js.map +1 -0
  58. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  59. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  60. package/node_modules/@zuplo/runtime/out/types/index.d.ts +5 -1
  61. package/node_modules/@zuplo/runtime/package.json +1 -1
  62. package/package.json +6 -6
  63. package/node_modules/@zuplo/runtime/out/esm/chunk-B5LJC45G.js.map +0 -1
  64. /package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js.LEGAL.txt → chunk-CKGECOOJ.js.LEGAL.txt} +0 -0
@@ -57,13 +57,10 @@ const parseLength = (state) => {
57
57
  return first;
58
58
  };
59
59
  const skipElement = (state, count = 1) => {
60
- if (count <= 0)
61
- return;
62
- state.pos++;
63
- const length = parseLength(state);
64
- state.pos += length;
65
- if (count > 1) {
66
- skipElement(state, count - 1);
60
+ while (count-- > 0) {
61
+ state.pos++;
62
+ const length = parseLength(state);
63
+ state.pos += length;
67
64
  }
68
65
  };
69
66
  const expectTag = (state, expectedTag, errorMessage) => {
@@ -84,24 +81,16 @@ const parseAlgorithmOID = (state) => {
84
81
  const oidLen = parseLength(state);
85
82
  return getSubarray(state, oidLen);
86
83
  };
87
- function parsePKCS8Header(state) {
88
- expectTag(state, 0x30, 'Invalid PKCS#8 structure');
84
+ function parseKeyHeader(state, keyFormat) {
85
+ expectTag(state, 0x30, `Invalid ${keyFormat === 'spki' ? 'SPKI' : 'PKCS#8'} structure`);
89
86
  parseLength(state);
90
- expectTag(state, 0x02, 'Expected version field');
91
- const verLen = parseLength(state);
92
- state.pos += verLen;
87
+ if (keyFormat === 'pkcs8') {
88
+ expectTag(state, 0x02, 'Expected version field');
89
+ const length = parseLength(state);
90
+ state.pos += length;
91
+ }
93
92
  expectTag(state, 0x30, 'Expected algorithm identifier');
94
- const algIdLen = parseLength(state);
95
- const algIdStart = state.pos;
96
- return { algIdStart, algIdLength: algIdLen };
97
- }
98
- function parseSPKIHeader(state) {
99
- expectTag(state, 0x30, 'Invalid SPKI structure');
100
93
  parseLength(state);
101
- expectTag(state, 0x30, 'Expected algorithm identifier');
102
- const algIdLen = parseLength(state);
103
- const algIdStart = state.pos;
104
- return { algIdStart, algIdLength: algIdLen };
105
94
  }
106
95
  const parseECAlgorithmIdentifier = (state) => {
107
96
  const algOid = parseAlgorithmOID(state);
@@ -114,65 +103,46 @@ const parseECAlgorithmIdentifier = (state) => {
114
103
  expectTag(state, 0x06, 'Expected curve OID');
115
104
  const curveOidLen = parseLength(state);
116
105
  const curveOid = getSubarray(state, curveOidLen);
117
- for (const { name, oid } of [
118
- { name: 'P-256', oid: [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07] },
119
- { name: 'P-384', oid: [0x2b, 0x81, 0x04, 0x00, 0x22] },
120
- { name: 'P-521', oid: [0x2b, 0x81, 0x04, 0x00, 0x23] },
121
- ]) {
122
- if (bytesEqual(curveOid, oid)) {
123
- return name;
124
- }
125
- }
106
+ if (bytesEqual(curveOid, [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]))
107
+ return 'P-256';
108
+ if (bytesEqual(curveOid, [0x2b, 0x81, 0x04, 0x00, 0x22]))
109
+ return 'P-384';
110
+ if (bytesEqual(curveOid, [0x2b, 0x81, 0x04, 0x00, 0x23]))
111
+ return 'P-521';
126
112
  throw new Error('Unsupported named curve');
127
113
  };
128
114
  const genericImport = async (keyFormat, keyData, alg, options) => {
129
115
  const entry = keyAlgorithm(alg);
130
- if (entry.symmetric) {
116
+ if (entry.secret) {
131
117
  throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
132
118
  }
133
119
  const isPublic = keyFormat === 'spki';
134
120
  let algorithm;
135
- if (entry.subtleFor) {
121
+ if (entry.resolve) {
136
122
  try {
137
- algorithm = entry.subtleFor({ crv: options.getNamedCurve(keyData) });
123
+ const state = createASN1State(keyData);
124
+ parseKeyHeader(state, keyFormat);
125
+ algorithm = entry.resolve({ crv: parseECAlgorithmIdentifier(state) });
138
126
  }
139
- catch (cause) {
127
+ catch {
140
128
  throw new JOSENotSupported('Invalid or unsupported key format');
141
129
  }
142
130
  }
143
131
  else {
144
132
  algorithm = entry.subtle;
145
133
  }
146
- return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), isPublic ? entry.usages.public : entry.usages.private);
134
+ return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? isPublic, entry.usages[isPublic ? 0 : 1]);
147
135
  };
148
136
  const processPEMData = (pem, pattern) => {
149
137
  return decodeBase64(pem.replace(pattern, ''));
150
138
  };
151
139
  export const fromPKCS8 = (pem, alg, options) => {
152
140
  const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g);
153
- let opts = options;
154
- if (alg?.startsWith?.('ECDH-ES')) {
155
- opts ||= {};
156
- opts.getNamedCurve = (keyData) => {
157
- const state = createASN1State(keyData);
158
- parsePKCS8Header(state);
159
- return parseECAlgorithmIdentifier(state);
160
- };
161
- }
162
- return genericImport('pkcs8', keyData, alg, opts);
141
+ return genericImport('pkcs8', keyData, alg, options);
163
142
  };
164
143
  export const fromSPKI = (pem, alg, options) => {
165
144
  const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g);
166
- let opts = options;
167
- if (alg?.startsWith?.('ECDH-ES')) {
168
- opts ||= {};
169
- opts.getNamedCurve = (keyData) => {
170
- const state = createASN1State(keyData);
171
- parseSPKIHeader(state);
172
- return parseECAlgorithmIdentifier(state);
173
- };
174
- }
175
- return genericImport('spki', keyData, alg, opts);
145
+ return genericImport('spki', keyData, alg, options);
176
146
  };
177
147
  function spkiFromX509(buf) {
178
148
  const state = createASN1State(buf);
@@ -191,17 +161,14 @@ function spkiFromX509(buf) {
191
161
  const spkiContentLen = parseLength(state);
192
162
  return buf.subarray(spkiStart, spkiStart + spkiContentLen + (state.pos - spkiStart));
193
163
  }
194
- function extractX509SPKI(x509) {
195
- const derBytes = processPEMData(x509, /(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g);
196
- return spkiFromX509(derBytes);
197
- }
198
164
  export const fromX509 = (pem, alg, options) => {
199
165
  let spki;
200
166
  try {
201
- spki = extractX509SPKI(pem);
167
+ const certificate = processPEMData(pem, /(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g);
168
+ spki = spkiFromX509(certificate);
202
169
  }
203
170
  catch (cause) {
204
171
  throw new TypeError('Failed to parse the X.509 certificate', { cause });
205
172
  }
206
- return fromSPKI(formatPEM(encodeBase64(spki), 'PUBLIC KEY'), alg, options);
173
+ return genericImport('spki', spki, alg, options);
207
174
  };
@@ -26,13 +26,13 @@ async function cbcKeySetup(enc, cek, usage) {
26
26
  hash: `SHA-${keySize << 1}`,
27
27
  name: 'HMAC',
28
28
  }, false, ['sign']);
29
- return { encKey, macKey, keySize };
29
+ return [encKey, macKey, keySize];
30
30
  }
31
31
  async function cbcHmacTag(macKey, macData, keySize) {
32
32
  return new Uint8Array((await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3));
33
33
  }
34
34
  async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
35
- const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'encrypt');
35
+ const [encKey, macKey, keySize] = await cbcKeySetup(enc, cek, 'encrypt');
36
36
  const ciphertext = new Uint8Array(await crypto.subtle.encrypt({
37
37
  iv: iv,
38
38
  name: 'AES-CBC',
@@ -42,25 +42,13 @@ async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
42
42
  return { ciphertext, tag, iv };
43
43
  }
44
44
  async function timingSafeEqual(a, b) {
45
- if (!(a instanceof Uint8Array)) {
46
- throw new TypeError('First argument must be a buffer');
47
- }
48
- if (!(b instanceof Uint8Array)) {
49
- throw new TypeError('Second argument must be a buffer');
50
- }
51
45
  const algorithm = { name: 'HMAC', hash: 'SHA-256' };
52
- const key = (await crypto.subtle.generateKey(algorithm, false, ['sign']));
53
- const aHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, a));
54
- const bHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, b));
55
- let out = 0;
56
- let i = -1;
57
- while (++i < 32) {
58
- out |= aHmac[i] ^ bHmac[i];
59
- }
60
- return out === 0;
46
+ const key = (await crypto.subtle.generateKey(algorithm, false, ['sign', 'verify']));
47
+ const aHmac = await crypto.subtle.sign(algorithm, key, a);
48
+ return crypto.subtle.verify(algorithm, key, aHmac, b);
61
49
  }
62
50
  async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
63
- const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'decrypt');
51
+ const [encKey, macKey, keySize] = await cbcKeySetup(enc, cek, 'decrypt');
64
52
  const macData = concat(aad, iv, ciphertext, uint64be(aad.length * 8));
65
53
  const expectedTag = await cbcHmacTag(macKey, macData, keySize);
66
54
  let macCheckPassed;
@@ -84,14 +72,11 @@ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
84
72
  return plaintext;
85
73
  }
86
74
  async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
87
- let encKey;
88
- if (cek instanceof Uint8Array) {
89
- encKey = await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, ['encrypt']);
90
- }
91
- else {
92
- checkCryptoKey(cek, enc.subtle, 'encrypt');
93
- encKey = cek;
94
- }
75
+ const encKey = cek instanceof Uint8Array
76
+ ? await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, [
77
+ 'encrypt',
78
+ ])
79
+ : (checkCryptoKey(cek, enc.subtle, 'encrypt'), cek);
95
80
  const encrypted = new Uint8Array(await crypto.subtle.encrypt({
96
81
  additionalData: aad,
97
82
  iv: iv,
@@ -103,14 +88,11 @@ async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
103
88
  return { ciphertext, tag, iv };
104
89
  }
105
90
  async function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
106
- let encKey;
107
- if (cek instanceof Uint8Array) {
108
- encKey = await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, ['decrypt']);
109
- }
110
- else {
111
- checkCryptoKey(cek, enc.subtle, 'decrypt');
112
- encKey = cek;
113
- }
91
+ const encKey = cek instanceof Uint8Array
92
+ ? await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, [
93
+ 'decrypt',
94
+ ])
95
+ : (checkCryptoKey(cek, enc.subtle, 'decrypt'), cek);
114
96
  try {
115
97
  return new Uint8Array(await crypto.subtle.decrypt({
116
98
  additionalData: aad,
@@ -4,6 +4,12 @@ export function checkUsage(key, usage) {
4
4
  throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
5
5
  }
6
6
  }
7
+ export function checkModulusLength(alg, key) {
8
+ const { modulusLength } = key.algorithm;
9
+ if (typeof modulusLength !== 'number' || modulusLength < 2048) {
10
+ throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
11
+ }
12
+ }
7
13
  export function checkCryptoKey(key, expected, usage) {
8
14
  const algorithm = key.algorithm;
9
15
  if (algorithm.name !== expected.name) {
@@ -1,5 +1,4 @@
1
1
  function message(msg, actual, ...types) {
2
- types = types.filter(Boolean);
3
2
  if (types.length > 2) {
4
3
  const last = types.pop();
5
4
  msg += `one of type ${types.join(', ')}, or ${last}.`;
@@ -1,25 +1,24 @@
1
1
  import { JOSENotSupported } from '../util/errors.js';
2
2
  import { table } from './key_descriptor.js';
3
- const wrap = {
4
- public: ['encrypt', 'wrapKey'],
5
- private: ['decrypt', 'unwrapKey'],
6
- };
7
- const derive = { public: [], private: ['deriveBits'] };
8
- const none = { public: [], private: [] };
3
+ const wrap = [
4
+ ['encrypt', 'wrapKey'],
5
+ ['decrypt', 'unwrapKey'],
6
+ ];
7
+ const derive = [[], ['deriveBits']];
8
+ const none = [[], []];
9
9
  function rsaes(bits) {
10
10
  return {
11
11
  kty: ['RSA'],
12
12
  subtle: { name: 'RSA-OAEP', hash: `SHA-${bits}` },
13
13
  usages: wrap,
14
- minModulusLength: 2048,
15
- keyOps: { encrypt: 'wrapKey', decrypt: 'unwrapKey' },
14
+ ops: ['wrapKey', 'unwrapKey'],
16
15
  };
17
16
  }
18
- function ecdh(kwBits) {
17
+ function ecdh() {
19
18
  return {
20
19
  kty: ['EC', 'OKP'],
21
20
  subtle: { name: 'ECDH' },
22
- subtleFor: ({ kty, crv, asymmetricKeyType }) => {
21
+ resolve: ({ kty, crv, asymmetricKeyType }) => {
23
22
  if (crv === 'X25519' || asymmetricKeyType === 'x25519') {
24
23
  return { name: 'X25519' };
25
24
  }
@@ -29,105 +28,79 @@ function ecdh(kwBits) {
29
28
  return { name: 'ECDH', namedCurve: crv };
30
29
  },
31
30
  usages: derive,
32
- kwBits,
33
- keyOps: { decrypt: 'deriveBits' },
31
+ ops: [undefined, 'deriveBits'],
34
32
  };
35
33
  }
36
- function aeskw(bits) {
34
+ function aeskw(bits, gcm = false) {
37
35
  return {
38
36
  kty: ['oct'],
39
- symmetric: true,
40
- subtle: { name: 'AES-KW', length: bits },
37
+ secret: true,
38
+ subtle: { name: gcm ? 'AES-GCM' : 'AES-KW', length: bits },
41
39
  usages: none,
42
- keyOps: { encrypt: 'wrapKey', decrypt: 'unwrapKey' },
40
+ ops: gcm ? ['encrypt', 'decrypt'] : ['wrapKey', 'unwrapKey'],
43
41
  };
44
42
  }
45
- function aesgcmkw(bits) {
43
+ function pbes2() {
46
44
  return {
47
45
  kty: ['oct'],
48
- symmetric: true,
49
- subtle: { name: 'AES-GCM', length: bits },
50
- usages: none,
51
- gcmkw: `A${bits}GCM`,
52
- keyOps: { encrypt: 'encrypt', decrypt: 'decrypt' },
53
- };
54
- }
55
- function pbes2(bits, kwBits) {
56
- return {
57
- kty: ['oct'],
58
- symmetric: true,
46
+ secret: true,
59
47
  subtle: { name: 'PBKDF2' },
60
48
  usages: none,
61
- pbes2Hash: `SHA-${bits}`,
62
- kwBits,
63
- keyOps: { encrypt: 'deriveBits', decrypt: 'deriveBits' },
49
+ ops: ['deriveBits', 'deriveBits'],
64
50
  };
65
51
  }
66
52
  const JWE = table({
67
53
  dir: {
68
54
  kty: ['oct'],
69
- symmetric: true,
55
+ secret: true,
70
56
  subtle: { name: 'AES-GCM' },
71
57
  usages: none,
72
- keyOps: { encrypt: 'encrypt', decrypt: 'decrypt' },
58
+ ops: ['encrypt', 'decrypt'],
73
59
  },
74
60
  'RSA-OAEP': rsaes(1),
75
61
  'RSA-OAEP-256': rsaes(256),
76
62
  'RSA-OAEP-384': rsaes(384),
77
63
  'RSA-OAEP-512': rsaes(512),
78
64
  'ECDH-ES': ecdh(),
79
- 'ECDH-ES+A128KW': ecdh(128),
80
- 'ECDH-ES+A192KW': ecdh(192),
81
- 'ECDH-ES+A256KW': ecdh(256),
65
+ 'ECDH-ES+A128KW': ecdh(),
66
+ 'ECDH-ES+A192KW': ecdh(),
67
+ 'ECDH-ES+A256KW': ecdh(),
82
68
  A128KW: aeskw(128),
83
69
  A192KW: aeskw(192),
84
70
  A256KW: aeskw(256),
85
- A128GCMKW: aesgcmkw(128),
86
- A192GCMKW: aesgcmkw(192),
87
- A256GCMKW: aesgcmkw(256),
88
- 'PBES2-HS256+A128KW': pbes2(256, 128),
89
- 'PBES2-HS384+A192KW': pbes2(384, 192),
90
- 'PBES2-HS512+A256KW': pbes2(512, 256),
71
+ A128GCMKW: aeskw(128, true),
72
+ A192GCMKW: aeskw(192, true),
73
+ A256GCMKW: aeskw(256, true),
74
+ 'PBES2-HS256+A128KW': pbes2(),
75
+ 'PBES2-HS384+A192KW': pbes2(),
76
+ 'PBES2-HS512+A256KW': pbes2(),
91
77
  });
92
- const content = { public: [], private: [] };
93
- const contentOps = { encrypt: 'encrypt', decrypt: 'decrypt' };
94
- function gcm(bits) {
78
+ const contentOps = ['encrypt', 'decrypt'];
79
+ function contentEncryption(bits, cbc = false) {
95
80
  return {
96
81
  kty: ['oct'],
97
- symmetric: true,
98
- subtle: { name: 'AES-GCM', length: bits },
99
- usages: content,
100
- keyOps: contentOps,
101
- cekBits: bits,
102
- ivBits: 96,
103
- cbc: false,
104
- };
105
- }
106
- function cbc(bits) {
107
- return {
108
- kty: ['oct'],
109
- symmetric: true,
110
- subtle: { name: 'AES-CBC', length: bits },
111
- usages: content,
112
- keyOps: contentOps,
82
+ secret: true,
83
+ subtle: { name: cbc ? 'AES-CBC' : 'AES-GCM', length: bits },
84
+ usages: none,
85
+ ops: contentOps,
113
86
  cekBits: bits,
114
- ivBits: 128,
115
- cbc: true,
87
+ ivBits: cbc ? 128 : 96,
88
+ cbc,
116
89
  };
117
90
  }
118
91
  const ENC = table({
119
- A128GCM: gcm(128),
120
- A192GCM: gcm(192),
121
- A256GCM: gcm(256),
122
- 'A128CBC-HS256': cbc(256),
123
- 'A192CBC-HS384': cbc(384),
124
- 'A256CBC-HS512': cbc(512),
92
+ A128GCM: contentEncryption(128),
93
+ A192GCM: contentEncryption(192),
94
+ A256GCM: contentEncryption(256),
95
+ 'A128CBC-HS256': contentEncryption(256, true),
96
+ 'A192CBC-HS384': contentEncryption(384, true),
97
+ 'A256CBC-HS512': contentEncryption(512, true),
125
98
  });
126
- const unsupportedAlgHeader = 'Invalid or unsupported "alg" (JWE Algorithm) header value';
99
+ const unsupportedAlg = 'Invalid or unsupported "alg" (JWE Algorithm) header value';
127
100
  export function jweAlgorithm(alg) {
128
101
  const entry = JWE[alg];
129
102
  if (!entry) {
130
- throw new JOSENotSupported(unsupportedAlgHeader);
103
+ throw new JOSENotSupported(unsupportedAlg);
131
104
  }
132
105
  return entry;
133
106
  }
@@ -9,88 +9,94 @@ import { prepareKey } from './key.js';
9
9
  import { jweAlgorithm, jweEncryption } from './jwe_algorithms.js';
10
10
  import { decompress } from './deflate.js';
11
11
  export function checkShared(jwe) {
12
+ const { ciphertext, protected: encodedProtected, unprotected } = jwe;
12
13
  if (jwe.iv !== undefined && typeof jwe.iv !== 'string') {
13
14
  throw new JWEInvalid('JWE Initialization Vector incorrect type');
14
15
  }
15
- if (typeof jwe.ciphertext !== 'string') {
16
+ if (typeof ciphertext !== 'string') {
16
17
  throw new JWEInvalid('JWE Ciphertext missing or incorrect type');
17
18
  }
18
19
  if (jwe.tag !== undefined && typeof jwe.tag !== 'string') {
19
20
  throw new JWEInvalid('JWE Authentication Tag incorrect type');
20
21
  }
21
- if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
22
+ if (encodedProtected !== undefined && typeof encodedProtected !== 'string') {
22
23
  throw new JWEInvalid('JWE Protected Header incorrect type');
23
24
  }
24
25
  if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
25
26
  throw new JWEInvalid('JWE AAD incorrect type');
26
27
  }
27
- if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {
28
+ if (unprotected !== undefined && !isObject(unprotected)) {
28
29
  throw new JWEInvalid('JWE Shared Unprotected Header incorrect type');
29
30
  }
30
31
  }
31
32
  export function checkRecipient(jwe) {
32
- if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
33
+ const { encrypted_key: encryptedKey, header } = jwe;
34
+ if (encryptedKey !== undefined && typeof encryptedKey !== 'string') {
33
35
  throw new JWEInvalid('JWE Encrypted Key incorrect type');
34
36
  }
35
- if (jwe.header !== undefined && !isObject(jwe.header)) {
37
+ if (header !== undefined && !isObject(header)) {
36
38
  throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');
37
39
  }
38
- if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
40
+ if (jwe.protected === undefined && header === undefined && jwe.unprotected === undefined) {
39
41
  throw new JWEInvalid('JOSE Header missing');
40
42
  }
41
43
  }
42
44
  export function shareJWE(jwe) {
45
+ const { protected: encodedProtected, ciphertext, iv, tag, aad } = jwe;
43
46
  let parsedProt;
44
- if (jwe.protected) {
45
- parsedProt = parseJoseHeader(jwe.protected, JWEInvalid, 'JWE Protected Header is invalid');
47
+ if (encodedProtected) {
48
+ parsedProt = parseJoseHeader(encodedProtected, JWEInvalid, 'JWE Protected Header is invalid');
46
49
  }
47
- const protectedHeader = jwe.protected !== undefined ? encode(jwe.protected) : new Uint8Array();
48
- return {
50
+ const protectedHeader = encodedProtected !== undefined ? encode(encodedProtected) : new Uint8Array();
51
+ return [
49
52
  parsedProt,
50
- ciphertext: decodeBase64url(jwe.ciphertext, 'ciphertext', JWEInvalid),
51
- iv: jwe.iv !== undefined ? decodeBase64url(jwe.iv, 'iv', JWEInvalid) : undefined,
52
- tag: jwe.tag !== undefined ? decodeBase64url(jwe.tag, 'tag', JWEInvalid) : undefined,
53
- additionalData: jwe.aad !== undefined
54
- ? concat(protectedHeader, encode('.'), encodeBase64url(jwe.aad, 'aad', JWEInvalid))
53
+ decodeBase64url(ciphertext, 'ciphertext', JWEInvalid),
54
+ iv !== undefined ? decodeBase64url(iv, 'iv', JWEInvalid) : undefined,
55
+ tag !== undefined ? decodeBase64url(tag, 'tag', JWEInvalid) : undefined,
56
+ aad !== undefined
57
+ ? concat(protectedHeader, encode('.'), encodeBase64url(aad, 'aad', JWEInvalid))
55
58
  : protectedHeader,
56
- };
59
+ ];
57
60
  }
58
61
  export function decryptResult(jwe, decrypted) {
59
- const result = { plaintext: decrypted.plaintext };
60
- if (jwe.protected !== undefined) {
61
- result.protectedHeader = decrypted.parsedProt;
62
+ const [plaintext, parsedProt, key, resolvedKey] = decrypted;
63
+ const { protected: encodedProtected, aad, unprotected, header } = jwe;
64
+ const result = { plaintext };
65
+ if (encodedProtected !== undefined) {
66
+ result.protectedHeader = parsedProt;
62
67
  }
63
- if (jwe.aad !== undefined) {
64
- result.additionalAuthenticatedData = decodeBase64url(jwe.aad, 'aad', JWEInvalid);
68
+ if (aad !== undefined) {
69
+ result.additionalAuthenticatedData = decodeBase64url(aad, 'aad', JWEInvalid);
65
70
  }
66
- if (jwe.unprotected !== undefined) {
67
- result.sharedUnprotectedHeader = jwe.unprotected;
71
+ if (unprotected !== undefined) {
72
+ result.sharedUnprotectedHeader = unprotected;
68
73
  }
69
- if (jwe.header !== undefined) {
70
- result.unprotectedHeader = jwe.header;
74
+ if (header !== undefined) {
75
+ result.unprotectedHeader = header;
71
76
  }
72
- if (decrypted.resolvedKey) {
73
- return { ...result, key: decrypted.key };
77
+ if (resolvedKey) {
78
+ return { ...result, key };
74
79
  }
75
80
  return result;
76
81
  }
77
82
  export function prepareDecrypt(options) {
78
- return {
79
- keyManagementAlgorithms: options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms),
80
- contentEncryptionAlgorithms: options &&
83
+ return [
84
+ options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms),
85
+ options &&
81
86
  validateAlgorithms('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms),
82
87
  options,
83
- };
88
+ ];
84
89
  }
85
90
  export async function decryptRecipient(jwe, token, shared, key) {
86
- const { options } = shared;
87
- const { parsedProt } = token;
91
+ const [keyManagementAlgorithms, contentEncryptionAlgorithms, options] = shared;
92
+ const [parsedProt, ciphertext, iv, tag, additionalData] = token;
93
+ const { encrypted_key: encodedKey, header, unprotected } = jwe;
88
94
  let joseHeader;
89
- if (jwe.header !== undefined || jwe.unprotected !== undefined) {
90
- if (!isDisjoint(parsedProt, jwe.header, jwe.unprotected)) {
95
+ if (header !== undefined || unprotected !== undefined) {
96
+ if (!isDisjoint(parsedProt, header, unprotected)) {
91
97
  throw new JWEInvalid('JWE Protected, JWE Unprotected Header, and JWE Per-Recipient Unprotected Header Parameter names must be disjoint');
92
98
  }
93
- joseHeader = { ...parsedProt, ...jwe.header, ...jwe.unprotected };
99
+ joseHeader = { ...parsedProt, ...header, ...unprotected };
94
100
  }
95
101
  else {
96
102
  joseHeader = parsedProt ?? {};
@@ -109,7 +115,6 @@ export async function decryptRecipient(jwe, token, shared, key) {
109
115
  if (typeof enc !== 'string' || !enc) {
110
116
  throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');
111
117
  }
112
- const { keyManagementAlgorithms, contentEncryptionAlgorithms } = shared;
113
118
  if ((keyManagementAlgorithms && !keyManagementAlgorithms.has(alg)) ||
114
119
  (!keyManagementAlgorithms && alg.startsWith('PBES2'))) {
115
120
  throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
@@ -119,8 +124,8 @@ export async function decryptRecipient(jwe, token, shared, key) {
119
124
  }
120
125
  const encEntry = jweEncryption(enc);
121
126
  let encryptedKey;
122
- if (jwe.encrypted_key !== undefined) {
123
- encryptedKey = decodeBase64url(jwe.encrypted_key, 'encrypted_key', JWEInvalid);
127
+ if (encodedKey !== undefined) {
128
+ encryptedKey = decodeBase64url(encodedKey, 'encrypted_key', JWEInvalid);
124
129
  }
125
130
  let resolvedKey = false;
126
131
  if (typeof key === 'function') {
@@ -139,7 +144,7 @@ export async function decryptRecipient(jwe, token, shared, key) {
139
144
  }
140
145
  cek = generateCek(encEntry);
141
146
  }
142
- let plaintext = await decrypt(encEntry, cek, token.ciphertext, token.iv, token.tag, token.additionalData);
147
+ let plaintext = await decrypt(encEntry, cek, ciphertext, iv, tag, additionalData);
143
148
  if (joseHeader.zip === 'DEF') {
144
149
  const maxDecompressedLength = options?.maxDecompressedLength ?? 250_000;
145
150
  if (maxDecompressedLength === 0) {
@@ -155,7 +160,7 @@ export async function decryptRecipient(jwe, token, shared, key) {
155
160
  throw new JWEInvalid('Failed to decompress plaintext', { cause });
156
161
  });
157
162
  }
158
- return { plaintext, parsedProt, key: k, resolvedKey };
163
+ return [plaintext, parsedProt, k, resolvedKey];
159
164
  }
160
165
  export async function decryptJWE(jwe, shared, key) {
161
166
  return decryptRecipient(jwe, shareJWE(jwe), shared, key);