jose 4.3.7 → 4.5.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.
Files changed (69) hide show
  1. package/README.md +5 -3
  2. package/dist/browser/index.js +2 -0
  3. package/dist/browser/jwks/local.js +97 -0
  4. package/dist/browser/jwks/remote.js +29 -82
  5. package/dist/browser/lib/aesgcmkw.js +2 -2
  6. package/dist/browser/lib/crypto_key.js +7 -7
  7. package/dist/browser/lib/decrypt_key_management.js +2 -2
  8. package/dist/browser/lib/encrypt_key_management.js +6 -4
  9. package/dist/browser/runtime/aeskw.js +1 -1
  10. package/dist/browser/runtime/asn1.js +21 -20
  11. package/dist/browser/runtime/decrypt.js +3 -3
  12. package/dist/browser/runtime/digest.js +1 -1
  13. package/dist/browser/runtime/ecdhes.js +8 -9
  14. package/dist/browser/runtime/encrypt.js +3 -3
  15. package/dist/browser/runtime/generate.js +7 -7
  16. package/dist/browser/runtime/get_sign_verify_key.js +1 -1
  17. package/dist/browser/runtime/jwk_to_key.js +4 -4
  18. package/dist/browser/runtime/pbes2kw.js +4 -4
  19. package/dist/browser/runtime/sign.js +1 -1
  20. package/dist/browser/runtime/subtle_dsa.js +7 -6
  21. package/dist/browser/runtime/verify.js +1 -1
  22. package/dist/browser/util/decode_jwt.js +32 -0
  23. package/dist/node/cjs/index.js +5 -1
  24. package/dist/node/cjs/jwks/local.js +103 -0
  25. package/dist/node/cjs/jwks/remote.js +28 -81
  26. package/dist/node/cjs/lib/aesgcmkw.js +2 -2
  27. package/dist/node/cjs/lib/crypto_key.js +7 -7
  28. package/dist/node/cjs/lib/decrypt_key_management.js +2 -2
  29. package/dist/node/cjs/lib/encrypt_key_management.js +6 -4
  30. package/dist/node/cjs/runtime/aeskw.js +3 -3
  31. package/dist/node/cjs/runtime/base64url.js +4 -4
  32. package/dist/node/cjs/runtime/check_cek_length.js +2 -2
  33. package/dist/node/cjs/runtime/decrypt.js +3 -3
  34. package/dist/node/cjs/runtime/ecdhes.js +7 -7
  35. package/dist/node/cjs/runtime/encrypt.js +3 -3
  36. package/dist/node/cjs/runtime/generate.js +2 -2
  37. package/dist/node/cjs/runtime/get_named_curve.js +2 -2
  38. package/dist/node/cjs/runtime/jwk_to_key.js +1 -1
  39. package/dist/node/cjs/runtime/key_to_jwk.js +1 -1
  40. package/dist/node/cjs/runtime/node_key.js +2 -2
  41. package/dist/node/cjs/runtime/pbes2kw.js +6 -6
  42. package/dist/node/cjs/runtime/verify.js +1 -1
  43. package/dist/node/cjs/util/decode_jwt.js +36 -0
  44. package/dist/node/esm/index.js +2 -0
  45. package/dist/node/esm/jwks/local.js +97 -0
  46. package/dist/node/esm/jwks/remote.js +29 -82
  47. package/dist/node/esm/lib/aesgcmkw.js +2 -2
  48. package/dist/node/esm/lib/crypto_key.js +7 -7
  49. package/dist/node/esm/lib/decrypt_key_management.js +2 -2
  50. package/dist/node/esm/lib/encrypt_key_management.js +6 -4
  51. package/dist/node/esm/runtime/aeskw.js +3 -3
  52. package/dist/node/esm/runtime/base64url.js +4 -4
  53. package/dist/node/esm/runtime/check_cek_length.js +2 -2
  54. package/dist/node/esm/runtime/decrypt.js +3 -3
  55. package/dist/node/esm/runtime/ecdhes.js +7 -7
  56. package/dist/node/esm/runtime/encrypt.js +3 -3
  57. package/dist/node/esm/runtime/generate.js +2 -2
  58. package/dist/node/esm/runtime/get_named_curve.js +2 -2
  59. package/dist/node/esm/runtime/jwk_to_key.js +1 -1
  60. package/dist/node/esm/runtime/key_to_jwk.js +1 -1
  61. package/dist/node/esm/runtime/node_key.js +2 -2
  62. package/dist/node/esm/runtime/pbes2kw.js +6 -6
  63. package/dist/node/esm/runtime/verify.js +1 -1
  64. package/dist/node/esm/util/decode_jwt.js +32 -0
  65. package/dist/types/index.d.ts +3 -1
  66. package/dist/types/jwks/local.d.ts +9 -0
  67. package/dist/types/types.d.ts +3 -0
  68. package/dist/types/util/decode_jwt.d.ts +2 -0
  69. package/package.json +1 -1
@@ -12,13 +12,13 @@ import invalidKeyInput from '../lib/invalid_key_input.js';
12
12
  import supported from './ciphers.js';
13
13
  import { types } from './is_key_like.js';
14
14
  function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
15
- const keySize = parseInt(enc.substr(1, 3), 10);
15
+ const keySize = parseInt(enc.slice(1, 4), 10);
16
16
  if (isKeyObject(cek)) {
17
17
  cek = cek.export();
18
18
  }
19
19
  const encKey = cek.subarray(keySize >> 3);
20
20
  const macKey = cek.subarray(0, keySize >> 3);
21
- const macSize = parseInt(enc.substr(-3), 10);
21
+ const macSize = parseInt(enc.slice(-3), 10);
22
22
  const algorithm = `aes-${keySize}-cbc`;
23
23
  if (!supported(algorithm)) {
24
24
  throw new JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`);
@@ -46,7 +46,7 @@ function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
46
46
  return plaintext;
47
47
  }
48
48
  function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
49
- const keySize = parseInt(enc.substr(1, 3), 10);
49
+ const keySize = parseInt(enc.slice(1, 4), 10);
50
50
  const algorithm = `aes-${keySize}-gcm`;
51
51
  if (!supported(algorithm)) {
52
52
  throw new JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`);
@@ -10,7 +10,7 @@ import isKeyObject from './is_key_object.js';
10
10
  import invalidKeyInput from '../lib/invalid_key_input.js';
11
11
  import { types } from './is_key_like.js';
12
12
  const generateKeyPair = promisify(generateKeyPairCb);
13
- export const deriveKey = (publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) => {
13
+ export async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
14
14
  let publicKey;
15
15
  if (isCryptoKey(publicKee)) {
16
16
  checkEncCryptoKey(publicKee, 'ECDH-ES');
@@ -36,8 +36,8 @@ export const deriveKey = (publicKee, privateKee, algorithm, keyLength, apu = new
36
36
  const value = concat(lengthAndInput(encoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength));
37
37
  const sharedSecret = diffieHellman({ privateKey, publicKey });
38
38
  return concatKdf(digest, sharedSecret, keyLength, value);
39
- };
40
- export const generateEpk = async (kee) => {
39
+ }
40
+ export async function generateEpk(kee) {
41
41
  let key;
42
42
  if (isCryptoKey(kee)) {
43
43
  key = KeyObject.from(kee);
@@ -50,16 +50,16 @@ export const generateEpk = async (kee) => {
50
50
  }
51
51
  switch (key.asymmetricKeyType) {
52
52
  case 'x25519':
53
- return (await generateKeyPair('x25519')).privateKey;
53
+ return generateKeyPair('x25519');
54
54
  case 'x448': {
55
- return (await generateKeyPair('x448')).privateKey;
55
+ return generateKeyPair('x448');
56
56
  }
57
57
  case 'ec': {
58
58
  const namedCurve = getNamedCurve(key);
59
- return (await generateKeyPair('ec', { namedCurve })).privateKey;
59
+ return generateKeyPair('ec', { namedCurve });
60
60
  }
61
61
  default:
62
62
  throw new JOSENotSupported('Invalid or unsupported EPK');
63
63
  }
64
- };
64
+ }
65
65
  export const ecdhAllowed = (key) => ['P-256', 'P-384', 'P-521', 'X25519', 'X448'].includes(getNamedCurve(key));
@@ -11,7 +11,7 @@ import { JOSENotSupported } from '../util/errors.js';
11
11
  import supported from './ciphers.js';
12
12
  import { types } from './is_key_like.js';
13
13
  function cbcEncrypt(enc, plaintext, cek, iv, aad) {
14
- const keySize = parseInt(enc.substr(1, 3), 10);
14
+ const keySize = parseInt(enc.slice(1, 4), 10);
15
15
  if (isKeyObject(cek)) {
16
16
  cek = cek.export();
17
17
  }
@@ -23,12 +23,12 @@ function cbcEncrypt(enc, plaintext, cek, iv, aad) {
23
23
  }
24
24
  const cipher = createCipheriv(algorithm, encKey, iv);
25
25
  const ciphertext = concat(cipher.update(plaintext), cipher.final());
26
- const macSize = parseInt(enc.substr(-3), 10);
26
+ const macSize = parseInt(enc.slice(-3), 10);
27
27
  const tag = cbcTag(aad, iv, ciphertext, macSize, macKey, keySize);
28
28
  return { ciphertext, tag };
29
29
  }
30
30
  function gcmEncrypt(enc, plaintext, cek, iv, aad) {
31
- const keySize = parseInt(enc.substr(1, 3), 10);
31
+ const keySize = parseInt(enc.slice(1, 4), 10);
32
32
  const algorithm = `aes-${keySize}-gcm`;
33
33
  if (!supported(algorithm)) {
34
34
  throw new JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`);
@@ -13,7 +13,7 @@ export async function generateSecret(alg, options) {
13
13
  case 'A128CBC-HS256':
14
14
  case 'A192CBC-HS384':
15
15
  case 'A256CBC-HS512':
16
- length = parseInt(alg.substr(-3), 10);
16
+ length = parseInt(alg.slice(-3), 10);
17
17
  break;
18
18
  case 'A128KW':
19
19
  case 'A192KW':
@@ -24,7 +24,7 @@ export async function generateSecret(alg, options) {
24
24
  case 'A128GCM':
25
25
  case 'A192GCM':
26
26
  case 'A256GCM':
27
- length = parseInt(alg.substring(1, 4), 10);
27
+ length = parseInt(alg.slice(1, 4), 10);
28
28
  break;
29
29
  default:
30
30
  throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
@@ -42,10 +42,10 @@ const getNamedCurve = (kee, raw) => {
42
42
  switch (key.asymmetricKeyType) {
43
43
  case 'ed25519':
44
44
  case 'ed448':
45
- return `Ed${key.asymmetricKeyType.substr(2)}`;
45
+ return `Ed${key.asymmetricKeyType.slice(2)}`;
46
46
  case 'x25519':
47
47
  case 'x448':
48
- return `X${key.asymmetricKeyType.substr(1)}`;
48
+ return `X${key.asymmetricKeyType.slice(1)}`;
49
49
  case 'ec': {
50
50
  if (weakMap.has(key)) {
51
51
  return weakMap.get(key);
@@ -6,7 +6,7 @@ import { setCurve } from './get_named_curve.js';
6
6
  import { setModulusLength } from './check_modulus_length.js';
7
7
  import Asn1SequenceEncoder from './asn1_sequence_encoder.js';
8
8
  const [major, minor] = process.version
9
- .substr(1)
9
+ .slice(1)
10
10
  .split('.')
11
11
  .map((str) => parseInt(str, 10));
12
12
  const jwkImportSupported = major >= 16 || (major === 15 && minor >= 12);
@@ -8,7 +8,7 @@ import isKeyObject from './is_key_object.js';
8
8
  import invalidKeyInput from '../lib/invalid_key_input.js';
9
9
  import { types } from './is_key_like.js';
10
10
  const [major, minor] = process.version
11
- .substr(1)
11
+ .slice(1)
12
12
  .split('.')
13
13
  .map((str) => parseInt(str, 10));
14
14
  const jwkExportSupported = major >= 16 || (major === 15 && minor >= 9);
@@ -3,7 +3,7 @@ import getNamedCurve from './get_named_curve.js';
3
3
  import { JOSENotSupported } from '../util/errors.js';
4
4
  import checkModulusLength from './check_modulus_length.js';
5
5
  const [major, minor] = process.version
6
- .substr(1)
6
+ .slice(1)
7
7
  .split('.')
8
8
  .map((str) => parseInt(str, 10));
9
9
  const electron = 'electron' in process.versions;
@@ -38,7 +38,7 @@ export default function keyForCrypto(alg, key) {
38
38
  case rsaPssParams && 'PS512':
39
39
  if (key.asymmetricKeyType === 'rsa-pss') {
40
40
  const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails;
41
- const length = parseInt(alg.substr(-3), 10);
41
+ const length = parseInt(alg.slice(-3), 10);
42
42
  if (hashAlgorithm !== undefined &&
43
43
  (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm)) {
44
44
  throw new TypeError(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${alg}`);
@@ -27,17 +27,17 @@ function getPassword(key, alg) {
27
27
  export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
28
28
  checkP2s(p2s);
29
29
  const salt = concatSalt(alg, p2s);
30
- const keylen = parseInt(alg.substr(13, 3), 10) >> 3;
30
+ const keylen = parseInt(alg.slice(13, 16), 10) >> 3;
31
31
  const password = getPassword(key, alg);
32
- const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.substr(8, 3)}`);
33
- const encryptedKey = await wrap(alg.substr(-6), derivedKey, cek);
32
+ const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.slice(8, 11)}`);
33
+ const encryptedKey = await wrap(alg.slice(-6), derivedKey, cek);
34
34
  return { encryptedKey, p2c, p2s: base64url(p2s) };
35
35
  };
36
36
  export const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
37
37
  checkP2s(p2s);
38
38
  const salt = concatSalt(alg, p2s);
39
- const keylen = parseInt(alg.substr(13, 3), 10) >> 3;
39
+ const keylen = parseInt(alg.slice(13, 16), 10) >> 3;
40
40
  const password = getPassword(key, alg);
41
- const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.substr(8, 3)}`);
42
- return unwrap(alg.substr(-6), derivedKey, encryptedKey);
41
+ const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.slice(8, 11)}`);
42
+ return unwrap(alg.slice(-6), derivedKey, encryptedKey);
43
43
  };
@@ -5,7 +5,7 @@ import nodeKey from './node_key.js';
5
5
  import sign from './sign.js';
6
6
  import getVerifyKey from './get_sign_verify_key.js';
7
7
  const [major, minor] = process.version
8
- .substr(1)
8
+ .slice(1)
9
9
  .split('.')
10
10
  .map((str) => parseInt(str, 10));
11
11
  const oneShotCallbackSupported = major >= 16 || (major === 15 && minor >= 13);
@@ -0,0 +1,32 @@
1
+ import { decode as base64url } from './base64url.js';
2
+ import { decoder } from '../lib/buffer_utils.js';
3
+ import isObject from '../lib/is_object.js';
4
+ import { JWTInvalid } from './errors.js';
5
+ export function decodeJwt(jwt) {
6
+ if (typeof jwt !== 'string')
7
+ throw new JWTInvalid('JWTs must use Compact JWS serialization, JWT must be a string');
8
+ const { 1: payload, length } = jwt.split('.');
9
+ if (length === 5)
10
+ throw new JWTInvalid('Only JWTs using Compact JWS serialization can be decoded');
11
+ if (length !== 3)
12
+ throw new JWTInvalid('Invalid JWT');
13
+ if (!payload)
14
+ throw new JWTInvalid('JWTs must contain a payload');
15
+ let decoded;
16
+ try {
17
+ decoded = base64url(payload);
18
+ }
19
+ catch {
20
+ throw new JWTInvalid('Failed to parse the base64url encoded payload');
21
+ }
22
+ let result;
23
+ try {
24
+ result = JSON.parse(decoder.decode(decoded));
25
+ }
26
+ catch {
27
+ throw new JWTInvalid('Failed to parse the decoded payload as JSON');
28
+ }
29
+ if (!isObject(result))
30
+ throw new JWTInvalid('Invalid JWT Claims Set');
31
+ return result;
32
+ }
@@ -27,6 +27,7 @@ export { SignJWT } from './jwt/sign';
27
27
  export { EncryptJWT } from './jwt/encrypt';
28
28
  export { calculateJwkThumbprint } from './jwk/thumbprint';
29
29
  export { EmbeddedJWK } from './jwk/embedded';
30
+ export { createLocalJWKSet } from './jwks/local';
30
31
  export { createRemoteJWKSet } from './jwks/remote';
31
32
  export type { RemoteJWKSetOptions } from './jwks/remote';
32
33
  export { UnsecuredJWT } from './jwt/unsecured';
@@ -35,6 +36,7 @@ export { exportPKCS8, exportSPKI, exportJWK } from './key/export';
35
36
  export { importSPKI, importPKCS8, importX509, importJWK } from './key/import';
36
37
  export type { PEMImportOptions } from './key/import';
37
38
  export { decodeProtectedHeader } from './util/decode_protected_header';
39
+ export { decodeJwt } from './util/decode_jwt';
38
40
  export type { ProtectedHeaderParameters } from './util/decode_protected_header';
39
41
  export * as errors from './util/errors';
40
42
  export { generateKeyPair } from './key/generate_key_pair';
@@ -42,4 +44,4 @@ export type { GenerateKeyPairResult, GenerateKeyPairOptions } from './key/genera
42
44
  export { generateSecret } from './key/generate_secret';
43
45
  export type { GenerateSecretOptions } from './key/generate_secret';
44
46
  export * as base64url from './util/base64url';
45
- export type { KeyLike, JWK, FlattenedJWSInput, GeneralJWSInput, FlattenedJWS, GeneralJWS, JoseHeaderParameters, JWSHeaderParameters, JWEKeyManagementHeaderParameters, FlattenedJWE, GeneralJWE, JWEHeaderParameters, CritOption, DeflateOption, DecryptOptions, EncryptOptions, JWTClaimVerificationOptions, VerifyOptions, SignOptions, JWTPayload, DeflateFunction, InflateFunction, FlattenedDecryptResult, GeneralDecryptResult, CompactDecryptResult, FlattenedVerifyResult, GeneralVerifyResult, CompactVerifyResult, JWTVerifyResult, JWTDecryptResult, ResolvedKey, CompactJWEHeaderParameters, CompactJWSHeaderParameters, JWTHeaderParameters, } from './types';
47
+ export type { KeyLike, JWK, FlattenedJWSInput, GeneralJWSInput, FlattenedJWS, GeneralJWS, JoseHeaderParameters, JWSHeaderParameters, JWEKeyManagementHeaderParameters, FlattenedJWE, GeneralJWE, JWEHeaderParameters, CritOption, DeflateOption, DecryptOptions, EncryptOptions, JWTClaimVerificationOptions, VerifyOptions, SignOptions, JWTPayload, DeflateFunction, InflateFunction, FlattenedDecryptResult, GeneralDecryptResult, CompactDecryptResult, FlattenedVerifyResult, GeneralVerifyResult, CompactVerifyResult, JWTVerifyResult, JWTDecryptResult, ResolvedKey, CompactJWEHeaderParameters, CompactJWSHeaderParameters, JWTHeaderParameters, JSONWebKeySet, } from './types';
@@ -0,0 +1,9 @@
1
+ import type { KeyLike, JWSHeaderParameters, JSONWebKeySet, FlattenedJWSInput, GetKeyFunction } from '../types';
2
+ export declare function isJWKSLike(jwks: unknown): jwks is JSONWebKeySet;
3
+ export declare class LocalJWKSet {
4
+ protected _jwks?: JSONWebKeySet;
5
+ private _cached;
6
+ constructor(jwks: unknown);
7
+ getKey(protectedHeader: JWSHeaderParameters, token: FlattenedJWSInput): Promise<KeyLike>;
8
+ }
9
+ export declare function createLocalJWKSet(jwks: JSONWebKeySet): GetKeyFunction<JWSHeaderParameters, FlattenedJWSInput>;
@@ -268,3 +268,6 @@ export interface CompactJWEHeaderParameters extends JWEHeaderParameters {
268
268
  alg: string
269
269
  enc: string
270
270
  }
271
+ export interface JSONWebKeySet {
272
+ keys: JWK[]
273
+ }
@@ -0,0 +1,2 @@
1
+ import type { JWTPayload } from '../types';
2
+ export declare function decodeJwt(jwt: string): JWTPayload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jose",
3
- "version": "4.3.7",
3
+ "version": "4.5.0",
4
4
  "description": "'JSON Web Almost Everything' - JWA, JWS, JWE, JWT, JWK, JWKS with no dependencies using runtime's native crypto",
5
5
  "keywords": [
6
6
  "browser",