jose 6.2.7 → 6.2.8

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.
@@ -21,6 +21,14 @@ export async function generalDecrypt(jwe, key, options) {
21
21
  catch {
22
22
  throw new JWEDecryptionFailed();
23
23
  }
24
+ if (jwe.recipients.length > 1) {
25
+ for (const { header } of jwe.recipients) {
26
+ const alg = token[0]?.alg ?? header?.alg ?? jwe.unprotected?.alg;
27
+ if (alg === 'dir' || alg === 'ECDH-ES') {
28
+ throw new JWEInvalid(`"${alg}" alg may only have a single recipient`);
29
+ }
30
+ }
31
+ }
24
32
  for (const recipient of jwe.recipients) {
25
33
  try {
26
34
  const flattened = {
@@ -125,7 +125,7 @@ export class GeneralEncrypt {
125
125
  inputs.push(input);
126
126
  checked.push(headers);
127
127
  if (headers[1] === 'dir' || headers[1] === 'ECDH-ES') {
128
- throw new JWEInvalid('"dir" and "ECDH-ES" alg may only be used with a single recipient');
128
+ throw new JWEInvalid(`"${headers[1]}" alg may only have a single recipient`);
129
129
  }
130
130
  if (!enc) {
131
131
  enc = headers[2];
@@ -1,9 +1,9 @@
1
1
  import { jwkToKey } from '../lib/jwk_to_key.js';
2
- import { maybeJWSAlgorithm } from '../lib/jws_algorithms.js';
2
+ import { JWS } from '../lib/jws_algorithms.js';
3
3
  import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
4
4
  import { isObject } from '../lib/type_checks.js';
5
5
  function signatureAlgorithm(alg) {
6
- const entry = typeof alg === 'string' ? maybeJWSAlgorithm(alg) : undefined;
6
+ const entry = typeof alg === 'string' ? JWS[alg] : undefined;
7
7
  if (!entry || entry.secret) {
8
8
  throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
9
9
  }
@@ -58,7 +58,7 @@ class LocalJWKSetImpl {
58
58
  }
59
59
  }
60
60
  async function importWithAlgCache(cache, jwk, entry) {
61
- const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk);
61
+ const cached = cache.get(jwk) || cache.set(jwk, { __proto__: null }).get(jwk);
62
62
  if (cached[entry.alg] === undefined) {
63
63
  const key = await jwkToKey(entry, { ...jwk, alg: entry.alg, ext: true });
64
64
  if (key.type !== 'public') {
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
9
9
  let USER_AGENT;
10
10
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
11
11
  const NAME = 'jose';
12
- const VERSION = 'v6.2.7';
12
+ const VERSION = 'v6.2.8';
13
13
  USER_AGENT = `${NAME}/${VERSION}`;
14
14
  }
15
15
  export const customFetch = Symbol();
@@ -1,5 +1,5 @@
1
1
  import { JOSENotSupported } from '../util/errors.js';
2
- import { keyAlgorithm } from '../lib/key_algorithm.js';
2
+ import { keyAlgorithm, unsupportedAlg, algArgument } from '../lib/key_algorithm.js';
3
3
  function getModulusLengthOption(options) {
4
4
  const modulusLength = options?.modulusLength ?? 2048;
5
5
  if (typeof modulusLength !== 'number' || modulusLength < 2048) {
@@ -8,9 +8,9 @@ function getModulusLengthOption(options) {
8
8
  return modulusLength;
9
9
  }
10
10
  export async function generateKeyPair(alg, options) {
11
- const entry = keyAlgorithm(alg);
11
+ const entry = keyAlgorithm(alg, algArgument);
12
12
  if (entry.secret) {
13
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
13
+ unsupportedAlg(algArgument);
14
14
  }
15
15
  let algorithm;
16
16
  if (entry.resolve) {
@@ -1,4 +1,4 @@
1
- import { JOSENotSupported } from '../util/errors.js';
1
+ import { unsupportedAlg, algArgument } from '../lib/key_algorithm.js';
2
2
  export async function generateSecret(alg, options) {
3
3
  let length;
4
4
  let algorithm;
@@ -34,7 +34,7 @@ export async function generateSecret(alg, options) {
34
34
  keyUsages = ['encrypt', 'decrypt'];
35
35
  break;
36
36
  default:
37
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
37
+ unsupportedAlg(algArgument);
38
38
  }
39
39
  return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages);
40
40
  }
@@ -1,7 +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
+ import { keyAlgorithm, unsupportedAlg, algArgument } from './key_algorithm.js';
5
5
  import { isCryptoKey, isKeyObject } from './is_key_like.js';
6
6
  const formatPEM = (b64, descriptor) => {
7
7
  const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
@@ -112,9 +112,9 @@ const parseECAlgorithmIdentifier = (state) => {
112
112
  throw new Error('Unsupported named curve');
113
113
  };
114
114
  const genericImport = async (keyFormat, keyData, alg, options) => {
115
- const entry = keyAlgorithm(alg);
115
+ const entry = keyAlgorithm(alg, algArgument);
116
116
  if (entry.secret) {
117
- throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
117
+ unsupportedAlg(algArgument);
118
118
  }
119
119
  const isPublic = keyFormat === 'spki';
120
120
  let algorithm;
@@ -49,7 +49,7 @@ function pbes2() {
49
49
  ops: ['deriveBits', 'deriveBits'],
50
50
  };
51
51
  }
52
- const JWE = table({
52
+ export const JWE = table({
53
53
  dir: {
54
54
  kty: ['oct'],
55
55
  secret: true,
@@ -96,21 +96,12 @@ const ENC = table({
96
96
  'A192CBC-HS384': contentEncryption(384, true),
97
97
  'A256CBC-HS512': contentEncryption(512, true),
98
98
  });
99
- const unsupportedAlg = 'Invalid or unsupported "alg" (JWE Algorithm) header value';
100
- export function jweAlgorithm(alg) {
101
- const entry = JWE[alg];
102
- if (!entry) {
103
- throw new JOSENotSupported(unsupportedAlg);
104
- }
105
- return entry;
99
+ function unsupported(parameter, name) {
100
+ throw new JOSENotSupported(`Invalid or unsupported "${parameter}" (JWE ${name}) header value`);
106
101
  }
107
- export function maybeJWEAlgorithm(alg) {
108
- return JWE[alg];
102
+ export function jweAlgorithm(alg) {
103
+ return (typeof alg === 'string' ? JWE[alg] : undefined) ?? unsupported('alg', 'Algorithm');
109
104
  }
110
105
  export function jweEncryption(enc) {
111
- const entry = ENC[enc];
112
- if (!entry) {
113
- throw new JOSENotSupported(`Unsupported JWE Algorithm: ${enc}`);
114
- }
115
- return entry;
106
+ return ((typeof enc === 'string' ? ENC[enc] : undefined) ?? unsupported('enc', 'Encryption Algorithm'));
116
107
  }
@@ -45,7 +45,7 @@ function mldsa(bits) {
45
45
  usages: sig,
46
46
  };
47
47
  }
48
- const JWS = table({
48
+ export const JWS = table({
49
49
  HS256: hmac(256),
50
50
  HS384: hmac(384),
51
51
  HS512: hmac(512),
@@ -65,12 +65,9 @@ const JWS = table({
65
65
  'ML-DSA-87': mldsa(87),
66
66
  });
67
67
  export function jwsAlgorithm(alg) {
68
- const entry = JWS[alg];
68
+ const entry = typeof alg === 'string' ? JWS[alg] : undefined;
69
69
  if (!entry) {
70
70
  throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
71
71
  }
72
72
  return entry;
73
73
  }
74
- export function maybeJWSAlgorithm(alg) {
75
- return JWS[alg];
76
- }
@@ -81,7 +81,7 @@ function cached(key, alg, value) {
81
81
  entry[alg] = value;
82
82
  }
83
83
  else {
84
- cache.set(key, { [alg]: value });
84
+ cache.set(key, { __proto__: null, [alg]: value });
85
85
  }
86
86
  }
87
87
  return value ?? entry?.[alg];
@@ -1,10 +1,10 @@
1
1
  import { JOSENotSupported } from '../util/errors.js';
2
- import { maybeJWSAlgorithm } from './jws_algorithms.js';
3
- import { maybeJWEAlgorithm } from './jwe_algorithms.js';
4
- export function keyAlgorithm(alg) {
5
- const entry = typeof alg === 'string' ? (maybeJWSAlgorithm(alg) ?? maybeJWEAlgorithm(alg)) : undefined;
6
- if (!entry) {
7
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
8
- }
9
- return entry;
2
+ import { JWS } from './jws_algorithms.js';
3
+ import { JWE } from './jwe_algorithms.js';
4
+ export const algArgument = '"alg" (Algorithm)';
5
+ export function unsupportedAlg(source = 'JWK "alg" (Algorithm) Parameter') {
6
+ throw new JOSENotSupported(`Invalid or unsupported ${source} value`);
7
+ }
8
+ export function keyAlgorithm(alg, source) {
9
+ return (typeof alg === 'string' ? (JWS[alg] ?? JWE[alg]) : undefined) ?? unsupportedAlg(source);
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jose",
3
- "version": "6.2.7",
3
+ "version": "6.2.8",
4
4
  "description": "JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes",
5
5
  "keywords": [
6
6
  "akp",