@zuplo/cli 6.73.27 → 6.73.28

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 (92) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/README.md +13 -13
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/index.d.ts +6 -5
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +17 -11
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +7 -19
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +17 -11
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +7 -19
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +18 -13
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +20 -21
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwk/embedded.d.ts +8 -12
  10. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwk/thumbprint.d.ts +0 -15
  11. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwks/local.d.ts +12 -21
  12. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwks/remote.d.ts +34 -165
  13. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/compact/sign.d.ts +2 -13
  14. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/compact/verify.d.ts +17 -13
  15. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/flattened/sign.d.ts +2 -13
  16. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/flattened/verify.d.ts +17 -13
  17. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/general/sign.d.ts +16 -17
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jws/general/verify.d.ts +18 -15
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/decrypt.d.ts +17 -11
  20. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/encrypt.d.ts +10 -34
  21. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/sign.d.ts +2 -13
  22. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/unsecured.d.ts +4 -13
  23. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/verify.d.ts +14 -13
  24. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/key/export.d.ts +0 -14
  25. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/key/generate_key_pair.d.ts +7 -14
  26. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/key/generate_secret.d.ts +16 -14
  27. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/key/import.d.ts +18 -28
  28. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/types.d.ts +242 -223
  29. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/base64url.d.ts +11 -4
  30. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -9
  31. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_protected_header.d.ts +0 -8
  32. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/errors.d.ts +128 -121
  33. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +3 -21
  34. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +5 -153
  35. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +16 -111
  36. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/general/decrypt.js +15 -3
  37. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/general/encrypt.js +33 -48
  38. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwk/embedded.js +5 -3
  39. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/local.js +27 -47
  40. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +3 -3
  41. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/compact/sign.js +5 -2
  42. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/compact/verify.js +3 -15
  43. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/flattened/sign.js +7 -57
  44. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/flattened/verify.js +3 -89
  45. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/sign.js +18 -5
  46. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/verify.js +21 -3
  47. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/decrypt.js +4 -4
  48. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/sign.js +2 -3
  49. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/unsecured.js +4 -3
  50. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/verify.js +5 -5
  51. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/export.js +34 -1
  52. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/generate_key_pair.js +32 -82
  53. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/import.js +8 -8
  54. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/asn1.js +29 -65
  55. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/buffer_utils.js +1 -0
  56. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/content_encryption.js +20 -77
  57. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/crypto_key.js +13 -127
  58. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/helpers.js +23 -0
  59. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +143 -0
  60. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +181 -0
  61. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +109 -0
  62. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwk_to_key.js +11 -96
  63. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_algorithms.js +74 -0
  64. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_sign.js +68 -0
  65. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_verify.js +108 -0
  66. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +9 -8
  67. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key.js +170 -0
  68. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_algorithm.js +16 -0
  69. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_descriptor.js +7 -0
  70. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_management.js +186 -29
  71. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/{validate_crit.js → options.js} +18 -0
  72. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/signing.js +20 -52
  73. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/base64url.js +11 -3
  74. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/decode_jwt.js +2 -2
  75. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/decode_protected_header.js +5 -15
  76. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/errors.js +1 -1
  77. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +2 -4
  78. package/node_modules/@zuplo/core/package.json +1 -1
  79. package/node_modules/@zuplo/graphql/package.json +1 -1
  80. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  81. package/node_modules/@zuplo/otel/package.json +1 -1
  82. package/node_modules/@zuplo/runtime/package.json +1 -1
  83. package/package.json +6 -6
  84. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/aesgcmkw.js +0 -15
  85. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/aeskw.js +0 -25
  86. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/check_key_type.js +0 -122
  87. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/ecdhes.js +0 -52
  88. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_to_jwk.js +0 -34
  89. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/normalize_key.js +0 -166
  90. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/pbes2kw.js +0 -42
  91. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/rsaes.js +0 -24
  92. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/validate_algorithms.js +0 -10
@@ -1,14 +1,6 @@
1
- import { decode as b64u } from '../../util/base64url.js';
2
- import { verify } from '../../lib/signing.js';
3
- import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
4
- import { concat, encoder, decoder, encode } from '../../lib/buffer_utils.js';
5
- import { decodeBase64url } from '../../lib/helpers.js';
6
- import { isDisjoint } from '../../lib/type_checks.js';
1
+ import { JWSInvalid } from '../../util/errors.js';
7
2
  import { isObject } from '../../lib/type_checks.js';
8
- import { checkKeyType } from '../../lib/check_key_type.js';
9
- import { validateCrit } from '../../lib/validate_crit.js';
10
- import { validateAlgorithms } from '../../lib/validate_algorithms.js';
11
- import { normalizeKey } from '../../lib/normalize_key.js';
3
+ import { prepareVerify, verifySignature, verifyResult } from '../../lib/jws_verify.js';
12
4
  export async function flattenedVerify(jws, key, options) {
13
5
  if (!isObject(jws)) {
14
6
  throw new JWSInvalid('Flattened JWS must be an object');
@@ -28,83 +20,5 @@ export async function flattenedVerify(jws, key, options) {
28
20
  if (jws.header !== undefined && !isObject(jws.header)) {
29
21
  throw new JWSInvalid('JWS Unprotected Header incorrect type');
30
22
  }
31
- let parsedProt = {};
32
- if (jws.protected) {
33
- try {
34
- const protectedHeader = b64u(jws.protected);
35
- parsedProt = JSON.parse(decoder.decode(protectedHeader));
36
- }
37
- catch {
38
- throw new JWSInvalid('JWS Protected Header is invalid');
39
- }
40
- }
41
- if (!isDisjoint(parsedProt, jws.header)) {
42
- throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
43
- }
44
- const joseHeader = {
45
- ...parsedProt,
46
- ...jws.header,
47
- };
48
- const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, parsedProt, joseHeader);
49
- let b64 = true;
50
- if (extensions.has('b64')) {
51
- b64 = parsedProt.b64;
52
- if (typeof b64 !== 'boolean') {
53
- throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
54
- }
55
- }
56
- const { alg } = joseHeader;
57
- if (typeof alg !== 'string' || !alg) {
58
- throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
59
- }
60
- const algorithms = options && validateAlgorithms('algorithms', options.algorithms);
61
- if (algorithms && !algorithms.has(alg)) {
62
- throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
63
- }
64
- if (b64) {
65
- if (typeof jws.payload !== 'string') {
66
- throw new JWSInvalid('JWS Payload must be a string');
67
- }
68
- }
69
- else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {
70
- throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
71
- }
72
- let resolvedKey = false;
73
- if (typeof key === 'function') {
74
- key = await key(parsedProt, jws);
75
- resolvedKey = true;
76
- }
77
- checkKeyType(alg, key, 'verify');
78
- const data = concat(jws.protected !== undefined ? encode(jws.protected) : new Uint8Array(), encode('.'), typeof jws.payload === 'string'
79
- ? b64
80
- ? encode(jws.payload)
81
- : encoder.encode(jws.payload)
82
- : jws.payload);
83
- const signature = decodeBase64url(jws.signature, 'signature', JWSInvalid);
84
- const k = await normalizeKey(key, alg);
85
- const verified = await verify(alg, k, signature, data);
86
- if (!verified) {
87
- throw new JWSSignatureVerificationFailed();
88
- }
89
- let payload;
90
- if (b64) {
91
- payload = decodeBase64url(jws.payload, 'payload', JWSInvalid);
92
- }
93
- else if (typeof jws.payload === 'string') {
94
- payload = encoder.encode(jws.payload);
95
- }
96
- else {
97
- payload = jws.payload;
98
- }
99
- const result = { payload };
100
- if (jws.protected !== undefined) {
101
- result.protectedHeader = parsedProt;
102
- }
103
- if (jws.header !== undefined) {
104
- result.unprotectedHeader = jws.header;
105
- }
106
- if (resolvedKey) {
107
- return { ...result, key: k };
108
- }
109
- return result;
23
+ return verifyResult(jws, await verifySignature(jws, prepareVerify(options), key));
110
24
  }
@@ -1,4 +1,4 @@
1
- import { FlattenedSign } from '../flattened/sign.js';
1
+ import { createSignature } from '../../lib/jws_sign.js';
2
2
  import { JWSInvalid } from '../../util/errors.js';
3
3
  import { assertNotSet } from '../../lib/helpers.js';
4
4
  class IndividualSignature {
@@ -47,16 +47,29 @@ export class GeneralSign {
47
47
  if (!this.#signatures.length) {
48
48
  throw new JWSInvalid('at least one signature must be added');
49
49
  }
50
+ if (!(this.#payload instanceof Uint8Array)) {
51
+ throw new TypeError('payload must be an instance of Uint8Array');
52
+ }
50
53
  const jws = {
51
54
  signatures: [],
52
55
  payload: '',
53
56
  };
57
+ const encoded = {};
54
58
  for (let i = 0; i < this.#signatures.length; i++) {
55
59
  const signature = this.#signatures[i];
56
- const flattened = new FlattenedSign(this.#payload);
57
- flattened.setProtectedHeader(signature.protectedHeader);
58
- flattened.setUnprotectedHeader(signature.unprotectedHeader);
59
- const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
60
+ if (!signature.protectedHeader && !signature.unprotectedHeader) {
61
+ throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
62
+ }
63
+ const { payload, ...rest } = await createSignature({
64
+ payload: this.#payload,
65
+ protectedHeader: signature.protectedHeader,
66
+ unprotectedHeader: signature.unprotectedHeader,
67
+ crit: signature.options?.crit,
68
+ encoded,
69
+ }, signature.key);
70
+ if (signature.unprotectedHeader) {
71
+ rest.header = signature.unprotectedHeader;
72
+ }
60
73
  if (i === 0) {
61
74
  jws.payload = payload;
62
75
  }
@@ -1,4 +1,4 @@
1
- import { flattenedVerify } from '../flattened/verify.js';
1
+ import { prepareVerify, verifySignature, verifyResult } from '../../lib/jws_verify.js';
2
2
  import { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
3
3
  import { isObject } from '../../lib/type_checks.js';
4
4
  export async function generalVerify(jws, key, options) {
@@ -8,14 +8,32 @@ export async function generalVerify(jws, key, options) {
8
8
  if (!Array.isArray(jws.signatures) || !jws.signatures.every(isObject)) {
9
9
  throw new JWSInvalid('JWS Signatures missing or incorrect type');
10
10
  }
11
+ let shared;
12
+ try {
13
+ if (jws.payload === undefined)
14
+ throw new Error();
15
+ shared = prepareVerify(options);
16
+ }
17
+ catch {
18
+ throw new JWSSignatureVerificationFailed();
19
+ }
11
20
  for (const signature of jws.signatures) {
12
21
  try {
13
- return await flattenedVerify({
22
+ if (signature.protected === undefined && signature.header === undefined)
23
+ throw new Error();
24
+ if (signature.protected !== undefined && typeof signature.protected !== 'string') {
25
+ throw new Error();
26
+ }
27
+ if (typeof signature.signature !== 'string')
28
+ throw new Error();
29
+ if (signature.header !== undefined && !isObject(signature.header))
30
+ throw new Error();
31
+ return verifyResult(signature, await verifySignature({
14
32
  header: signature.header,
15
33
  payload: jws.payload,
16
34
  protected: signature.protected,
17
35
  signature: signature.signature,
18
- }, key, options);
36
+ }, shared, key));
19
37
  }
20
38
  catch {
21
39
  }
@@ -1,10 +1,10 @@
1
- import { compactDecrypt } from '../jwe/compact/decrypt.js';
1
+ import { prepareDecrypt, decryptCompact } from '../lib/jwe_decrypt.js';
2
2
  import { validateClaimsSet } from '../lib/jwt_claims_set.js';
3
3
  import { JWTClaimValidationFailed } from '../util/errors.js';
4
4
  export async function jwtDecrypt(jwt, key, options) {
5
- const decrypted = await compactDecrypt(jwt, key, options);
6
- const payload = validateClaimsSet(decrypted.protectedHeader, decrypted.plaintext, options);
7
- const { protectedHeader } = decrypted;
5
+ const decrypted = await decryptCompact(jwt, prepareDecrypt(options), key);
6
+ const protectedHeader = decrypted.parsedProt;
7
+ const payload = validateClaimsSet(protectedHeader, decrypted.plaintext, options);
8
8
  if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
9
9
  throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', payload, 'iss', 'mismatch');
10
10
  }
@@ -1,4 +1,5 @@
1
1
  import { CompactSign } from '../jws/compact/sign.js';
2
+ import { unencodedPayload } from '../lib/jws_sign.js';
2
3
  import { JWTInvalid } from '../util/errors.js';
3
4
  import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
4
5
  export class SignJWT {
@@ -42,9 +43,7 @@ export class SignJWT {
42
43
  async sign(key, options) {
43
44
  const sig = new CompactSign(this.#jwt.data());
44
45
  sig.setProtectedHeader(this.#protectedHeader);
45
- if (Array.isArray(this.#protectedHeader?.crit) &&
46
- this.#protectedHeader.crit.includes('b64') &&
47
- this.#protectedHeader.b64 === false) {
46
+ if (unencodedPayload(this.#protectedHeader)) {
48
47
  throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
49
48
  }
50
49
  return sig.sign(key, options);
@@ -1,5 +1,6 @@
1
1
  import * as b64u from '../util/base64url.js';
2
- import { decoder } from '../lib/buffer_utils.js';
2
+ import { strictDecoder } from '../lib/buffer_utils.js';
3
+ import { decodeBase64url } from '../lib/helpers.js';
3
4
  import { JWTInvalid } from '../util/errors.js';
4
5
  import { validateClaimsSet, JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
5
6
  export class UnsecuredJWT {
@@ -50,14 +51,14 @@ export class UnsecuredJWT {
50
51
  }
51
52
  let header;
52
53
  try {
53
- header = JSON.parse(decoder.decode(b64u.decode(encodedHeader)));
54
+ header = JSON.parse(strictDecoder.decode(b64u.decode(encodedHeader)));
54
55
  if (header.alg !== 'none')
55
56
  throw new Error();
56
57
  }
57
58
  catch {
58
59
  throw new JWTInvalid('Invalid Unsecured JWT');
59
60
  }
60
- const payload = validateClaimsSet(header, b64u.decode(encodedPayload), options);
61
+ const payload = validateClaimsSet(header, decodeBase64url(encodedPayload, 'payload', JWTInvalid), options);
61
62
  return { payload, header };
62
63
  }
63
64
  }
@@ -1,13 +1,13 @@
1
- import { compactVerify } from '../jws/compact/verify.js';
1
+ import { prepareVerify, verifyCompact } from '../lib/jws_verify.js';
2
2
  import { validateClaimsSet } from '../lib/jwt_claims_set.js';
3
3
  import { JWTInvalid } from '../util/errors.js';
4
4
  export async function jwtVerify(jwt, key, options) {
5
- const verified = await compactVerify(jwt, key, options);
6
- if (verified.protectedHeader.crit?.includes('b64') && verified.protectedHeader.b64 === false) {
5
+ const verified = await verifyCompact(jwt, prepareVerify(options), key);
6
+ if (!verified.b64) {
7
7
  throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
8
8
  }
9
- const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
10
- const result = { payload, protectedHeader: verified.protectedHeader };
9
+ const payload = validateClaimsSet(verified.parsedProt, verified.payload, options);
10
+ const result = { payload, protectedHeader: verified.parsedProt };
11
11
  if (typeof key === 'function') {
12
12
  return { ...result, key: verified.key };
13
13
  }
@@ -1,5 +1,38 @@
1
1
  import { toSPKI as exportPublic, toPKCS8 as exportPrivate } from '../lib/asn1.js';
2
- import { keyToJWK } from '../lib/key_to_jwk.js';
2
+ import { invalidKeyInput } from '../lib/invalid_key_input.js';
3
+ import { encode as b64u } from '../util/base64url.js';
4
+ import { isCryptoKey, isKeyObject } from '../lib/is_key_like.js';
5
+ function omitUndefinedProperties(jwk) {
6
+ return Object.fromEntries(Object.entries(jwk).filter(([, value]) => value !== undefined));
7
+ }
8
+ async function keyToJWK(key) {
9
+ if (isKeyObject(key)) {
10
+ if (key.type === 'secret') {
11
+ key = key.export();
12
+ }
13
+ else {
14
+ return key.export({ format: 'jwk' });
15
+ }
16
+ }
17
+ if (key instanceof Uint8Array) {
18
+ return {
19
+ kty: 'oct',
20
+ k: b64u(key),
21
+ };
22
+ }
23
+ if (!isCryptoKey(key)) {
24
+ throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'Uint8Array'));
25
+ }
26
+ if (!key.extractable) {
27
+ throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK');
28
+ }
29
+ const { ext, key_ops, alg, use, ...jwk } = omitUndefinedProperties(await crypto.subtle.exportKey('jwk', key));
30
+ if (jwk.kty === 'AKP') {
31
+ ;
32
+ jwk.alg = alg;
33
+ }
34
+ return jwk;
35
+ }
3
36
  export async function exportSPKI(key) {
4
37
  return exportPublic(key);
5
38
  }
@@ -1,4 +1,5 @@
1
1
  import { JOSENotSupported } from '../util/errors.js';
2
+ import { keyAlgorithm } from '../lib/key_algorithm.js';
2
3
  function getModulusLengthOption(options) {
3
4
  const modulusLength = options?.modulusLength ?? 2048;
4
5
  if (typeof modulusLength !== 'number' || modulusLength < 2048) {
@@ -7,91 +8,40 @@ function getModulusLengthOption(options) {
7
8
  return modulusLength;
8
9
  }
9
10
  export async function generateKeyPair(alg, options) {
11
+ const entry = keyAlgorithm(alg);
12
+ if (entry.symmetric) {
13
+ throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
14
+ }
10
15
  let algorithm;
11
- let keyUsages;
12
- switch (alg) {
13
- case 'PS256':
14
- case 'PS384':
15
- case 'PS512':
16
- algorithm = {
17
- name: 'RSA-PSS',
18
- hash: `SHA-${alg.slice(-3)}`,
19
- publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
20
- modulusLength: getModulusLengthOption(options),
21
- };
22
- keyUsages = ['sign', 'verify'];
23
- break;
24
- case 'RS256':
25
- case 'RS384':
26
- case 'RS512':
27
- algorithm = {
28
- name: 'RSASSA-PKCS1-v1_5',
29
- hash: `SHA-${alg.slice(-3)}`,
30
- publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
31
- modulusLength: getModulusLengthOption(options),
32
- };
33
- keyUsages = ['sign', 'verify'];
34
- break;
35
- case 'RSA-OAEP':
36
- case 'RSA-OAEP-256':
37
- case 'RSA-OAEP-384':
38
- case 'RSA-OAEP-512':
39
- algorithm = {
40
- name: 'RSA-OAEP',
41
- hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
42
- publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
43
- modulusLength: getModulusLengthOption(options),
44
- };
45
- keyUsages = ['decrypt', 'unwrapKey', 'encrypt', 'wrapKey'];
46
- break;
47
- case 'ES256':
48
- algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
49
- keyUsages = ['sign', 'verify'];
50
- break;
51
- case 'ES384':
52
- algorithm = { name: 'ECDSA', namedCurve: 'P-384' };
53
- keyUsages = ['sign', 'verify'];
54
- break;
55
- case 'ES512':
56
- algorithm = { name: 'ECDSA', namedCurve: 'P-521' };
57
- keyUsages = ['sign', 'verify'];
58
- break;
59
- case 'Ed25519':
60
- case 'EdDSA': {
61
- keyUsages = ['sign', 'verify'];
62
- algorithm = { name: 'Ed25519' };
63
- break;
16
+ if (entry.subtleFor) {
17
+ switch (options?.crv ?? 'P-256') {
18
+ case 'P-256':
19
+ case 'P-384':
20
+ case 'P-521':
21
+ algorithm = { name: 'ECDH', namedCurve: options?.crv ?? 'P-256' };
22
+ break;
23
+ case 'X25519':
24
+ algorithm = { name: 'X25519' };
25
+ break;
26
+ default:
27
+ throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519');
64
28
  }
65
- case 'ML-DSA-44':
66
- case 'ML-DSA-65':
67
- case 'ML-DSA-87': {
68
- keyUsages = ['sign', 'verify'];
69
- algorithm = { name: alg };
70
- break;
29
+ }
30
+ else {
31
+ if (entry.crv !== undefined && options?.crv !== undefined && options.crv !== entry.crv) {
32
+ throw new JOSENotSupported(`Invalid or unsupported crv option provided, the only supported value for ${alg} is ${entry.crv}`);
71
33
  }
72
- case 'ECDH-ES':
73
- case 'ECDH-ES+A128KW':
74
- case 'ECDH-ES+A192KW':
75
- case 'ECDH-ES+A256KW': {
76
- keyUsages = ['deriveBits'];
77
- const crv = options?.crv ?? 'P-256';
78
- switch (crv) {
79
- case 'P-256':
80
- case 'P-384':
81
- case 'P-521': {
82
- algorithm = { name: 'ECDH', namedCurve: crv };
83
- break;
34
+ algorithm =
35
+ entry.kty[0] === 'RSA'
36
+ ? {
37
+ ...entry.subtle,
38
+ publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
39
+ modulusLength: getModulusLengthOption(options),
84
40
  }
85
- case 'X25519':
86
- algorithm = { name: 'X25519' };
87
- break;
88
- default:
89
- throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519');
90
- }
91
- break;
92
- }
93
- default:
94
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
41
+ : entry.subtle;
95
42
  }
96
- return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages);
43
+ return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, [
44
+ ...entry.usages.private,
45
+ ...entry.usages.public,
46
+ ]);
97
47
  }
@@ -1,6 +1,7 @@
1
1
  import { decode as decodeBase64URL } from '../util/base64url.js';
2
2
  import { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js';
3
3
  import { jwkToKey } from '../lib/jwk_to_key.js';
4
+ import { keyAlgorithm } from '../lib/key_algorithm.js';
4
5
  import { JOSENotSupported } from '../util/errors.js';
5
6
  import { isObject } from '../lib/type_checks.js';
6
7
  export async function importSPKI(spki, alg, options) {
@@ -25,9 +26,11 @@ export async function importJWK(jwk, alg, options) {
25
26
  if (!isObject(jwk)) {
26
27
  throw new TypeError('JWK must be an object');
27
28
  }
28
- let ext;
29
29
  alg ??= jwk.alg;
30
- ext ??= options?.extractable ?? jwk.ext;
30
+ const ext = options?.extractable ?? jwk.ext;
31
+ if (jwk.kty !== 'oct' && !alg) {
32
+ throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
33
+ }
31
34
  switch (jwk.kty) {
32
35
  case 'oct':
33
36
  if (typeof jwk.k !== 'string' || !jwk.k) {
@@ -35,10 +38,7 @@ export async function importJWK(jwk, alg, options) {
35
38
  }
36
39
  return decodeBase64URL(jwk.k);
37
40
  case 'RSA':
38
- if ('oth' in jwk && jwk.oth !== undefined) {
39
- throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
40
- }
41
- return jwkToKey({ ...jwk, alg, ext });
41
+ return jwkToKey(keyAlgorithm(alg), { ...jwk, alg, ext });
42
42
  case 'AKP': {
43
43
  if (typeof jwk.alg !== 'string' || !jwk.alg) {
44
44
  throw new TypeError('missing "alg" (Algorithm) Parameter value');
@@ -46,11 +46,11 @@ export async function importJWK(jwk, alg, options) {
46
46
  if (alg !== undefined && alg !== jwk.alg) {
47
47
  throw new TypeError('JWK alg and alg option value mismatch');
48
48
  }
49
- return jwkToKey({ ...jwk, ext });
49
+ return jwkToKey(keyAlgorithm(jwk.alg), { ...jwk, ext });
50
50
  }
51
51
  case 'EC':
52
52
  case 'OKP':
53
- return jwkToKey({ ...jwk, alg, ext });
53
+ return jwkToKey(keyAlgorithm(alg), { ...jwk, alg, ext });
54
54
  default:
55
55
  throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
56
56
  }
@@ -1,6 +1,7 @@
1
1
  import { invalidKeyInput } from './invalid_key_input.js';
2
2
  import { encodeBase64, decodeBase64 } from '../lib/base64.js';
3
3
  import { JOSENotSupported } from '../util/errors.js';
4
+ import { keyAlgorithm } from './key_algorithm.js';
4
5
  import { isCryptoKey, isKeyObject } from './is_key_like.js';
5
6
  const formatPEM = (b64, descriptor) => {
6
7
  const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
@@ -36,13 +37,20 @@ const bytesEqual = (a, b) => {
36
37
  return true;
37
38
  };
38
39
  const createASN1State = (data) => ({ data, pos: 0 });
40
+ const readByte = (state) => {
41
+ const byte = state.data[state.pos++];
42
+ if (byte === undefined) {
43
+ throw new Error('Unexpected end of ASN.1 input');
44
+ }
45
+ return byte;
46
+ };
39
47
  const parseLength = (state) => {
40
- const first = state.data[state.pos++];
48
+ const first = readByte(state);
41
49
  if (first & 0x80) {
42
50
  const lengthOfLen = first & 0x7f;
43
51
  let length = 0;
44
52
  for (let i = 0; i < lengthOfLen; i++) {
45
- length = (length << 8) | state.data[state.pos++];
53
+ length = (length << 8) | readByte(state);
46
54
  }
47
55
  return length;
48
56
  }
@@ -59,11 +67,14 @@ const skipElement = (state, count = 1) => {
59
67
  }
60
68
  };
61
69
  const expectTag = (state, expectedTag, errorMessage) => {
62
- if (state.data[state.pos++] !== expectedTag) {
70
+ if (readByte(state) !== expectedTag) {
63
71
  throw new Error(errorMessage);
64
72
  }
65
73
  };
66
74
  const getSubarray = (state, length) => {
75
+ if (length < 0 || state.pos + length > state.data.length) {
76
+ throw new Error('Unexpected end of ASN.1 input');
77
+ }
67
78
  const result = state.data.subarray(state.pos, state.pos + length);
68
79
  state.pos += length;
69
80
  return result;
@@ -115,71 +126,24 @@ const parseECAlgorithmIdentifier = (state) => {
115
126
  throw new Error('Unsupported named curve');
116
127
  };
117
128
  const genericImport = async (keyFormat, keyData, alg, options) => {
118
- let algorithm;
119
- let keyUsages;
129
+ const entry = keyAlgorithm(alg);
130
+ if (entry.symmetric) {
131
+ throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
132
+ }
120
133
  const isPublic = keyFormat === 'spki';
121
- const getSigUsages = () => (isPublic ? ['verify'] : ['sign']);
122
- const getEncUsages = () => isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];
123
- switch (alg) {
124
- case 'PS256':
125
- case 'PS384':
126
- case 'PS512':
127
- algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };
128
- keyUsages = getSigUsages();
129
- break;
130
- case 'RS256':
131
- case 'RS384':
132
- case 'RS512':
133
- algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };
134
- keyUsages = getSigUsages();
135
- break;
136
- case 'RSA-OAEP':
137
- case 'RSA-OAEP-256':
138
- case 'RSA-OAEP-384':
139
- case 'RSA-OAEP-512':
140
- algorithm = {
141
- name: 'RSA-OAEP',
142
- hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
143
- };
144
- keyUsages = getEncUsages();
145
- break;
146
- case 'ES256':
147
- case 'ES384':
148
- case 'ES512': {
149
- const curveMap = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' };
150
- algorithm = { name: 'ECDSA', namedCurve: curveMap[alg] };
151
- keyUsages = getSigUsages();
152
- break;
134
+ let algorithm;
135
+ if (entry.subtleFor) {
136
+ try {
137
+ algorithm = entry.subtleFor({ crv: options.getNamedCurve(keyData) });
153
138
  }
154
- case 'ECDH-ES':
155
- case 'ECDH-ES+A128KW':
156
- case 'ECDH-ES+A192KW':
157
- case 'ECDH-ES+A256KW': {
158
- try {
159
- const namedCurve = options.getNamedCurve(keyData);
160
- algorithm = namedCurve === 'X25519' ? { name: 'X25519' } : { name: 'ECDH', namedCurve };
161
- }
162
- catch (cause) {
163
- throw new JOSENotSupported('Invalid or unsupported key format');
164
- }
165
- keyUsages = isPublic ? [] : ['deriveBits'];
166
- break;
139
+ catch (cause) {
140
+ throw new JOSENotSupported('Invalid or unsupported key format');
167
141
  }
168
- case 'Ed25519':
169
- case 'EdDSA':
170
- algorithm = { name: 'Ed25519' };
171
- keyUsages = getSigUsages();
172
- break;
173
- case 'ML-DSA-44':
174
- case 'ML-DSA-65':
175
- case 'ML-DSA-87':
176
- algorithm = { name: alg };
177
- keyUsages = getSigUsages();
178
- break;
179
- default:
180
- throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
181
- }
182
- return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), keyUsages);
142
+ }
143
+ else {
144
+ algorithm = entry.subtle;
145
+ }
146
+ return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), isPublic ? entry.usages.public : entry.usages.private);
183
147
  };
184
148
  const processPEMData = (pem, pattern) => {
185
149
  return decodeBase64(pem.replace(pattern, ''));
@@ -1,5 +1,6 @@
1
1
  export const encoder = new TextEncoder();
2
2
  export const decoder = new TextDecoder();
3
+ export const strictDecoder = new TextDecoder('utf-8', { fatal: true });
3
4
  const MAX_INT32 = 2 ** 32;
4
5
  export function concat(...buffers) {
5
6
  const size = buffers.reduce((acc, { length }) => acc + length, 0);