jose 4.5.3 → 4.6.2

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 (62) hide show
  1. package/dist/browser/jwe/general/encrypt.js +8 -1
  2. package/dist/browser/jwks/local.js +2 -1
  3. package/dist/browser/lib/buffer_utils.js +5 -11
  4. package/dist/browser/lib/crypto_key.js +1 -1
  5. package/dist/browser/lib/decrypt_key_management.js +1 -1
  6. package/dist/browser/lib/encrypt_key_management.js +1 -1
  7. package/dist/browser/lib/jwt_claims_set.js +2 -7
  8. package/dist/browser/runtime/base64url.js +6 -3
  9. package/dist/browser/runtime/ecdhes.js +2 -5
  10. package/dist/browser/runtime/pbes2kw.js +1 -1
  11. package/dist/node/cjs/jwe/general/encrypt.js +8 -1
  12. package/dist/node/cjs/jwks/local.js +2 -1
  13. package/dist/node/cjs/lib/buffer_utils.js +5 -11
  14. package/dist/node/cjs/lib/crypto_key.js +1 -1
  15. package/dist/node/cjs/lib/decrypt_key_management.js +1 -1
  16. package/dist/node/cjs/lib/encrypt_key_management.js +1 -1
  17. package/dist/node/cjs/lib/jwt_claims_set.js +2 -7
  18. package/dist/node/cjs/runtime/ecdhes.js +2 -2
  19. package/dist/node/cjs/runtime/generate.js +3 -2
  20. package/dist/node/cjs/runtime/pbes2kw.js +1 -1
  21. package/dist/node/esm/jwe/general/encrypt.js +8 -1
  22. package/dist/node/esm/jwks/local.js +2 -1
  23. package/dist/node/esm/lib/buffer_utils.js +5 -11
  24. package/dist/node/esm/lib/crypto_key.js +1 -1
  25. package/dist/node/esm/lib/decrypt_key_management.js +1 -1
  26. package/dist/node/esm/lib/encrypt_key_management.js +1 -1
  27. package/dist/node/esm/lib/jwt_claims_set.js +2 -7
  28. package/dist/node/esm/runtime/ecdhes.js +2 -2
  29. package/dist/node/esm/runtime/generate.js +3 -2
  30. package/dist/node/esm/runtime/pbes2kw.js +1 -1
  31. package/dist/types/jwe/compact/decrypt.d.ts +26 -0
  32. package/dist/types/jwe/compact/encrypt.d.ts +56 -0
  33. package/dist/types/jwe/flattened/decrypt.d.ts +39 -0
  34. package/dist/types/jwe/flattened/encrypt.d.ts +77 -0
  35. package/dist/types/jwe/general/decrypt.d.ts +43 -0
  36. package/dist/types/jwe/general/encrypt.d.ts +63 -0
  37. package/dist/types/jwk/embedded.d.ts +20 -0
  38. package/dist/types/jwk/thumbprint.d.ts +19 -0
  39. package/dist/types/jwks/local.d.ts +42 -0
  40. package/dist/types/jwks/remote.d.ts +44 -0
  41. package/dist/types/jws/compact/sign.d.ts +30 -0
  42. package/dist/types/jws/compact/verify.d.ts +29 -0
  43. package/dist/types/jws/flattened/sign.d.ts +35 -0
  44. package/dist/types/jws/flattened/verify.d.ts +34 -0
  45. package/dist/types/jws/general/sign.d.ts +50 -0
  46. package/dist/types/jws/general/verify.d.ts +37 -0
  47. package/dist/types/jwt/decrypt.d.ts +32 -0
  48. package/dist/types/jwt/encrypt.d.ts +68 -0
  49. package/dist/types/jwt/produce.d.ts +46 -0
  50. package/dist/types/jwt/sign.d.ts +28 -0
  51. package/dist/types/jwt/unsecured.d.ts +34 -0
  52. package/dist/types/jwt/verify.d.ts +35 -0
  53. package/dist/types/key/export.d.ts +38 -0
  54. package/dist/types/key/generate_key_pair.d.ts +38 -0
  55. package/dist/types/key/generate_secret.d.ts +20 -0
  56. package/dist/types/key/import.d.ts +96 -0
  57. package/dist/types/types.d.ts +499 -2
  58. package/dist/types/util/base64url.d.ts +10 -0
  59. package/dist/types/util/decode_jwt.d.ts +14 -0
  60. package/dist/types/util/decode_protected_header.d.ts +11 -0
  61. package/dist/types/util/errors.d.ts +65 -0
  62. package/package.json +1 -1
@@ -133,6 +133,12 @@ export class GeneralEncrypt {
133
133
  const recipient = this._recipients[i];
134
134
  const target = {};
135
135
  jwe.recipients.push(target);
136
+ const joseHeader = {
137
+ ...this._protectedHeader,
138
+ ...this._unprotectedHeader,
139
+ ...recipient.unprotectedHeader,
140
+ };
141
+ const p2c = joseHeader.alg.startsWith('PBES2') ? 2048 + i : undefined;
136
142
  if (i === 0) {
137
143
  const flattened = await new FlattenedEncrypt(this._plaintext)
138
144
  .setAdditionalAuthenticatedData(this._aad)
@@ -140,6 +146,7 @@ export class GeneralEncrypt {
140
146
  .setProtectedHeader(this._protectedHeader)
141
147
  .setSharedUnprotectedHeader(this._unprotectedHeader)
142
148
  .setUnprotectedHeader(recipient.unprotectedHeader)
149
+ .setKeyManagementParameters({ p2c })
143
150
  .encrypt(recipient.key, {
144
151
  ...recipient.options,
145
152
  ...options,
@@ -161,7 +168,7 @@ export class GeneralEncrypt {
161
168
  }
162
169
  const { encryptedKey, parameters } = await encryptKeyManagement(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
163
170
  ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
164
- ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
171
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek, { p2c });
165
172
  target.encrypted_key = base64url(encryptedKey);
166
173
  if (recipient.unprotectedHeader || parameters)
167
174
  target.header = { ...recipient.unprotectedHeader, ...parameters };
@@ -39,8 +39,9 @@ export class LocalJWKSet {
39
39
  }
40
40
  async getKey(protectedHeader, token) {
41
41
  const { alg, kid } = { ...protectedHeader, ...token.header };
42
+ const kty = getKtyFromAlg(alg);
42
43
  const candidates = this._jwks.keys.filter((jwk) => {
43
- let candidate = jwk.kty === getKtyFromAlg(alg);
44
+ let candidate = kty === jwk.kty;
44
45
  if (candidate && typeof kid === 'string') {
45
46
  candidate = kid === jwk.kid;
46
47
  }
@@ -39,19 +39,13 @@ export function lengthAndInput(input) {
39
39
  }
40
40
  export async function concatKdf(secret, bits, value) {
41
41
  const iterations = Math.ceil((bits >> 3) / 32);
42
- let res;
43
- for (let iter = 1; iter <= iterations; iter++) {
42
+ const res = new Uint8Array(iterations * 32);
43
+ for (let iter = 0; iter < iterations; iter++) {
44
44
  const buf = new Uint8Array(4 + secret.length + value.length);
45
- buf.set(uint32be(iter));
45
+ buf.set(uint32be(iter + 1));
46
46
  buf.set(secret, 4);
47
47
  buf.set(value, 4 + secret.length);
48
- if (!res) {
49
- res = await digest('sha256', buf);
50
- }
51
- else {
52
- res = concat(res, await digest('sha256', buf));
53
- }
48
+ res.set(await digest('sha256', buf), iter * 32);
54
49
  }
55
- res = res.slice(0, bits >> 3);
56
- return res;
50
+ return res.slice(0, bits >> 3);
57
51
  }
@@ -121,7 +121,7 @@ export function checkEncCryptoKey(key, alg, ...usages) {
121
121
  throw unusable(expected, 'algorithm.length');
122
122
  break;
123
123
  }
124
- case 'ECDH-ES':
124
+ case 'ECDH':
125
125
  if (!isAlgorithm(key.algorithm, 'ECDH'))
126
126
  throw unusable('ECDH');
127
127
  break;
@@ -26,7 +26,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
26
26
  if (!isObject(joseHeader.epk))
27
27
  throw new JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
28
28
  if (!ECDH.ecdhAllowed(key))
29
- throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
29
+ throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
30
30
  const epk = await importJWK(joseHeader.epk, alg);
31
31
  let partyUInfo;
32
32
  let partyVInfo;
@@ -23,7 +23,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
23
23
  case 'ECDH-ES+A192KW':
24
24
  case 'ECDH-ES+A256KW': {
25
25
  if (!ECDH.ecdhAllowed(key)) {
26
- throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
26
+ throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
27
27
  }
28
28
  const { apu, apv } = providedParameters;
29
29
  let { epk: ephemeralKey } = providedParameters;
@@ -58,13 +58,8 @@ export default (protectedHeader, encodedPayload, options = {}) => {
58
58
  }
59
59
  const { currentDate } = options;
60
60
  const now = epoch(currentDate || new Date());
61
- if (payload.iat !== undefined || options.maxTokenAge) {
62
- if (typeof payload.iat !== 'number') {
63
- throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
64
- }
65
- if (payload.exp === undefined && payload.iat > now + tolerance) {
66
- throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
67
- }
61
+ if ((payload.iat !== undefined || options.maxTokenAge) && typeof payload.iat !== 'number') {
62
+ throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
68
63
  }
69
64
  if (payload.nbf !== undefined) {
70
65
  if (typeof payload.nbf !== 'number') {
@@ -15,9 +15,12 @@ export const encode = (input) => {
15
15
  return encodeBase64(input).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
16
16
  };
17
17
  export const decodeBase64 = (encoded) => {
18
- return new Uint8Array(atob(encoded)
19
- .split('')
20
- .map((c) => c.charCodeAt(0)));
18
+ const binary = atob(encoded);
19
+ const bytes = new Uint8Array(binary.length);
20
+ for (let i = 0; i < binary.length; i++) {
21
+ bytes[i] = binary.charCodeAt(i);
22
+ }
23
+ return bytes;
21
24
  };
22
25
  export const decode = (input) => {
23
26
  let encoded = input;
@@ -7,15 +7,12 @@ export async function deriveKey(publicKey, privateKey, algorithm, keyLength, apu
7
7
  if (!isCryptoKey(publicKey)) {
8
8
  throw new TypeError(invalidKeyInput(publicKey, ...types));
9
9
  }
10
- checkEncCryptoKey(publicKey, 'ECDH-ES');
10
+ checkEncCryptoKey(publicKey, 'ECDH');
11
11
  if (!isCryptoKey(privateKey)) {
12
12
  throw new TypeError(invalidKeyInput(privateKey, ...types));
13
13
  }
14
- checkEncCryptoKey(privateKey, 'ECDH-ES', 'deriveBits', 'deriveKey');
14
+ checkEncCryptoKey(privateKey, 'ECDH', 'deriveBits');
15
15
  const value = concat(lengthAndInput(encoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength));
16
- if (!privateKey.usages.includes('deriveBits')) {
17
- throw new TypeError('ECDH-ES private key "usages" must include "deriveBits"');
18
- }
19
16
  const sharedSecret = new Uint8Array(await crypto.subtle.deriveBits({
20
17
  name: 'ECDH',
21
18
  public: publicKey,
@@ -40,7 +40,7 @@ async function deriveKey(p2s, alg, p2c, key) {
40
40
  }
41
41
  throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"');
42
42
  }
43
- export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
43
+ export const encrypt = async (alg, key, cek, p2c = 2048, p2s = random(new Uint8Array(16))) => {
44
44
  const derived = await deriveKey(p2s, alg, p2c, key);
45
45
  const encryptedKey = await wrap(alg.slice(-6), derived, cek);
46
46
  return { encryptedKey, p2c, p2s: base64url(p2s) };
@@ -136,6 +136,12 @@ class GeneralEncrypt {
136
136
  const recipient = this._recipients[i];
137
137
  const target = {};
138
138
  jwe.recipients.push(target);
139
+ const joseHeader = {
140
+ ...this._protectedHeader,
141
+ ...this._unprotectedHeader,
142
+ ...recipient.unprotectedHeader,
143
+ };
144
+ const p2c = joseHeader.alg.startsWith('PBES2') ? 2048 + i : undefined;
139
145
  if (i === 0) {
140
146
  const flattened = await new encrypt_js_1.FlattenedEncrypt(this._plaintext)
141
147
  .setAdditionalAuthenticatedData(this._aad)
@@ -143,6 +149,7 @@ class GeneralEncrypt {
143
149
  .setProtectedHeader(this._protectedHeader)
144
150
  .setSharedUnprotectedHeader(this._unprotectedHeader)
145
151
  .setUnprotectedHeader(recipient.unprotectedHeader)
152
+ .setKeyManagementParameters({ p2c })
146
153
  .encrypt(recipient.key, {
147
154
  ...recipient.options,
148
155
  ...options,
@@ -164,7 +171,7 @@ class GeneralEncrypt {
164
171
  }
165
172
  const { encryptedKey, parameters } = await (0, encrypt_key_management_js_1.default)(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
166
173
  ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
167
- ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
174
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek, { p2c });
168
175
  target.encrypted_key = (0, base64url_js_1.encode)(encryptedKey);
169
176
  if (recipient.unprotectedHeader || parameters)
170
177
  target.header = { ...recipient.unprotectedHeader, ...parameters };
@@ -43,8 +43,9 @@ class LocalJWKSet {
43
43
  }
44
44
  async getKey(protectedHeader, token) {
45
45
  const { alg, kid } = { ...protectedHeader, ...token.header };
46
+ const kty = getKtyFromAlg(alg);
46
47
  const candidates = this._jwks.keys.filter((jwk) => {
47
- let candidate = jwk.kty === getKtyFromAlg(alg);
48
+ let candidate = kty === jwk.kty;
48
49
  if (candidate && typeof kid === 'string') {
49
50
  candidate = kid === jwk.kid;
50
51
  }
@@ -47,20 +47,14 @@ function lengthAndInput(input) {
47
47
  exports.lengthAndInput = lengthAndInput;
48
48
  async function concatKdf(secret, bits, value) {
49
49
  const iterations = Math.ceil((bits >> 3) / 32);
50
- let res;
51
- for (let iter = 1; iter <= iterations; iter++) {
50
+ const res = new Uint8Array(iterations * 32);
51
+ for (let iter = 0; iter < iterations; iter++) {
52
52
  const buf = new Uint8Array(4 + secret.length + value.length);
53
- buf.set(uint32be(iter));
53
+ buf.set(uint32be(iter + 1));
54
54
  buf.set(secret, 4);
55
55
  buf.set(value, 4 + secret.length);
56
- if (!res) {
57
- res = await (0, digest_js_1.default)('sha256', buf);
58
- }
59
- else {
60
- res = concat(res, await (0, digest_js_1.default)('sha256', buf));
61
- }
56
+ res.set(await (0, digest_js_1.default)('sha256', buf), iter * 32);
62
57
  }
63
- res = res.slice(0, bits >> 3);
64
- return res;
58
+ return res.slice(0, bits >> 3);
65
59
  }
66
60
  exports.concatKdf = concatKdf;
@@ -125,7 +125,7 @@ function checkEncCryptoKey(key, alg, ...usages) {
125
125
  throw unusable(expected, 'algorithm.length');
126
126
  break;
127
127
  }
128
- case 'ECDH-ES':
128
+ case 'ECDH':
129
129
  if (!isAlgorithm(key.algorithm, 'ECDH'))
130
130
  throw unusable('ECDH');
131
131
  break;
@@ -28,7 +28,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
28
28
  if (!(0, is_object_js_1.default)(joseHeader.epk))
29
29
  throw new errors_js_1.JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
30
30
  if (!ECDH.ecdhAllowed(key))
31
- throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
31
+ throw new errors_js_1.JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
32
32
  const epk = await (0, import_js_1.importJWK)(joseHeader.epk, alg);
33
33
  let partyUInfo;
34
34
  let partyVInfo;
@@ -25,7 +25,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
25
25
  case 'ECDH-ES+A192KW':
26
26
  case 'ECDH-ES+A256KW': {
27
27
  if (!ECDH.ecdhAllowed(key)) {
28
- throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
28
+ throw new errors_js_1.JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
29
29
  }
30
30
  const { apu, apv } = providedParameters;
31
31
  let { epk: ephemeralKey } = providedParameters;
@@ -60,13 +60,8 @@ exports.default = (protectedHeader, encodedPayload, options = {}) => {
60
60
  }
61
61
  const { currentDate } = options;
62
62
  const now = (0, epoch_js_1.default)(currentDate || new Date());
63
- if (payload.iat !== undefined || options.maxTokenAge) {
64
- if (typeof payload.iat !== 'number') {
65
- throw new errors_js_1.JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
66
- }
67
- if (payload.exp === undefined && payload.iat > now + tolerance) {
68
- throw new errors_js_1.JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
69
- }
63
+ if ((payload.iat !== undefined || options.maxTokenAge) && typeof payload.iat !== 'number') {
64
+ throw new errors_js_1.JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
70
65
  }
71
66
  if (payload.nbf !== undefined) {
72
67
  if (typeof payload.nbf !== 'number') {
@@ -15,7 +15,7 @@ const generateKeyPair = (0, util_1.promisify)(crypto_1.generateKeyPair);
15
15
  async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
16
16
  let publicKey;
17
17
  if ((0, webcrypto_js_1.isCryptoKey)(publicKee)) {
18
- (0, crypto_key_js_1.checkEncCryptoKey)(publicKee, 'ECDH-ES');
18
+ (0, crypto_key_js_1.checkEncCryptoKey)(publicKee, 'ECDH');
19
19
  publicKey = crypto_1.KeyObject.from(publicKee);
20
20
  }
21
21
  else if ((0, is_key_object_js_1.default)(publicKee)) {
@@ -26,7 +26,7 @@ async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new
26
26
  }
27
27
  let privateKey;
28
28
  if ((0, webcrypto_js_1.isCryptoKey)(privateKee)) {
29
- (0, crypto_key_js_1.checkEncCryptoKey)(privateKee, 'ECDH-ES', 'deriveBits', 'deriveKey');
29
+ (0, crypto_key_js_1.checkEncCryptoKey)(privateKee, 'ECDH', 'deriveBits');
30
30
  privateKey = crypto_1.KeyObject.from(privateKee);
31
31
  }
32
32
  else if ((0, is_key_object_js_1.default)(privateKee)) {
@@ -84,12 +84,13 @@ async function generateKeyPair(alg, options) {
84
84
  case 'ECDH-ES+A128KW':
85
85
  case 'ECDH-ES+A192KW':
86
86
  case 'ECDH-ES+A256KW':
87
- switch (options === null || options === void 0 ? void 0 : options.crv) {
87
+ const crv = (_b = options === null || options === void 0 ? void 0 : options.crv) !== null && _b !== void 0 ? _b : 'P-256';
88
+ switch (crv) {
88
89
  case undefined:
89
90
  case 'P-256':
90
91
  case 'P-384':
91
92
  case 'P-521':
92
- return generate('ec', { namedCurve: (_b = options === null || options === void 0 ? void 0 : options.crv) !== null && _b !== void 0 ? _b : 'P-256' });
93
+ return generate('ec', { namedCurve: crv });
93
94
  case 'X25519':
94
95
  return generate('x25519');
95
96
  case 'X448':
@@ -27,7 +27,7 @@ function getPassword(key, alg) {
27
27
  }
28
28
  throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array'));
29
29
  }
30
- const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = (0, random_js_1.default)(new Uint8Array(16))) => {
30
+ const encrypt = async (alg, key, cek, p2c = 2048, p2s = (0, random_js_1.default)(new Uint8Array(16))) => {
31
31
  (0, check_p2s_js_1.default)(p2s);
32
32
  const salt = (0, buffer_utils_js_1.p2s)(alg, p2s);
33
33
  const keylen = parseInt(alg.slice(13, 16), 10) >> 3;
@@ -133,6 +133,12 @@ export class GeneralEncrypt {
133
133
  const recipient = this._recipients[i];
134
134
  const target = {};
135
135
  jwe.recipients.push(target);
136
+ const joseHeader = {
137
+ ...this._protectedHeader,
138
+ ...this._unprotectedHeader,
139
+ ...recipient.unprotectedHeader,
140
+ };
141
+ const p2c = joseHeader.alg.startsWith('PBES2') ? 2048 + i : undefined;
136
142
  if (i === 0) {
137
143
  const flattened = await new FlattenedEncrypt(this._plaintext)
138
144
  .setAdditionalAuthenticatedData(this._aad)
@@ -140,6 +146,7 @@ export class GeneralEncrypt {
140
146
  .setProtectedHeader(this._protectedHeader)
141
147
  .setSharedUnprotectedHeader(this._unprotectedHeader)
142
148
  .setUnprotectedHeader(recipient.unprotectedHeader)
149
+ .setKeyManagementParameters({ p2c })
143
150
  .encrypt(recipient.key, {
144
151
  ...recipient.options,
145
152
  ...options,
@@ -161,7 +168,7 @@ export class GeneralEncrypt {
161
168
  }
162
169
  const { encryptedKey, parameters } = await encryptKeyManagement(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
163
170
  ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
164
- ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
171
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek, { p2c });
165
172
  target.encrypted_key = base64url(encryptedKey);
166
173
  if (recipient.unprotectedHeader || parameters)
167
174
  target.header = { ...recipient.unprotectedHeader, ...parameters };
@@ -39,8 +39,9 @@ export class LocalJWKSet {
39
39
  }
40
40
  async getKey(protectedHeader, token) {
41
41
  const { alg, kid } = { ...protectedHeader, ...token.header };
42
+ const kty = getKtyFromAlg(alg);
42
43
  const candidates = this._jwks.keys.filter((jwk) => {
43
- let candidate = jwk.kty === getKtyFromAlg(alg);
44
+ let candidate = kty === jwk.kty;
44
45
  if (candidate && typeof kid === 'string') {
45
46
  candidate = kid === jwk.kid;
46
47
  }
@@ -39,19 +39,13 @@ export function lengthAndInput(input) {
39
39
  }
40
40
  export async function concatKdf(secret, bits, value) {
41
41
  const iterations = Math.ceil((bits >> 3) / 32);
42
- let res;
43
- for (let iter = 1; iter <= iterations; iter++) {
42
+ const res = new Uint8Array(iterations * 32);
43
+ for (let iter = 0; iter < iterations; iter++) {
44
44
  const buf = new Uint8Array(4 + secret.length + value.length);
45
- buf.set(uint32be(iter));
45
+ buf.set(uint32be(iter + 1));
46
46
  buf.set(secret, 4);
47
47
  buf.set(value, 4 + secret.length);
48
- if (!res) {
49
- res = await digest('sha256', buf);
50
- }
51
- else {
52
- res = concat(res, await digest('sha256', buf));
53
- }
48
+ res.set(await digest('sha256', buf), iter * 32);
54
49
  }
55
- res = res.slice(0, bits >> 3);
56
- return res;
50
+ return res.slice(0, bits >> 3);
57
51
  }
@@ -121,7 +121,7 @@ export function checkEncCryptoKey(key, alg, ...usages) {
121
121
  throw unusable(expected, 'algorithm.length');
122
122
  break;
123
123
  }
124
- case 'ECDH-ES':
124
+ case 'ECDH':
125
125
  if (!isAlgorithm(key.algorithm, 'ECDH'))
126
126
  throw unusable('ECDH');
127
127
  break;
@@ -26,7 +26,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
26
26
  if (!isObject(joseHeader.epk))
27
27
  throw new JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
28
28
  if (!ECDH.ecdhAllowed(key))
29
- throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
29
+ throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
30
30
  const epk = await importJWK(joseHeader.epk, alg);
31
31
  let partyUInfo;
32
32
  let partyVInfo;
@@ -23,7 +23,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
23
23
  case 'ECDH-ES+A192KW':
24
24
  case 'ECDH-ES+A256KW': {
25
25
  if (!ECDH.ecdhAllowed(key)) {
26
- throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
26
+ throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
27
27
  }
28
28
  const { apu, apv } = providedParameters;
29
29
  let { epk: ephemeralKey } = providedParameters;
@@ -58,13 +58,8 @@ export default (protectedHeader, encodedPayload, options = {}) => {
58
58
  }
59
59
  const { currentDate } = options;
60
60
  const now = epoch(currentDate || new Date());
61
- if (payload.iat !== undefined || options.maxTokenAge) {
62
- if (typeof payload.iat !== 'number') {
63
- throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
64
- }
65
- if (payload.exp === undefined && payload.iat > now + tolerance) {
66
- throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
67
- }
61
+ if ((payload.iat !== undefined || options.maxTokenAge) && typeof payload.iat !== 'number') {
62
+ throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
68
63
  }
69
64
  if (payload.nbf !== undefined) {
70
65
  if (typeof payload.nbf !== 'number') {
@@ -12,7 +12,7 @@ const generateKeyPair = promisify(generateKeyPairCb);
12
12
  export async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
13
13
  let publicKey;
14
14
  if (isCryptoKey(publicKee)) {
15
- checkEncCryptoKey(publicKee, 'ECDH-ES');
15
+ checkEncCryptoKey(publicKee, 'ECDH');
16
16
  publicKey = KeyObject.from(publicKee);
17
17
  }
18
18
  else if (isKeyObject(publicKee)) {
@@ -23,7 +23,7 @@ export async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu
23
23
  }
24
24
  let privateKey;
25
25
  if (isCryptoKey(privateKee)) {
26
- checkEncCryptoKey(privateKee, 'ECDH-ES', 'deriveBits', 'deriveKey');
26
+ checkEncCryptoKey(privateKee, 'ECDH', 'deriveBits');
27
27
  privateKey = KeyObject.from(privateKee);
28
28
  }
29
29
  else if (isKeyObject(privateKee)) {
@@ -80,12 +80,13 @@ export async function generateKeyPair(alg, options) {
80
80
  case 'ECDH-ES+A128KW':
81
81
  case 'ECDH-ES+A192KW':
82
82
  case 'ECDH-ES+A256KW':
83
- switch (options === null || options === void 0 ? void 0 : options.crv) {
83
+ const crv = (_b = options === null || options === void 0 ? void 0 : options.crv) !== null && _b !== void 0 ? _b : 'P-256';
84
+ switch (crv) {
84
85
  case undefined:
85
86
  case 'P-256':
86
87
  case 'P-384':
87
88
  case 'P-521':
88
- return generate('ec', { namedCurve: (_b = options === null || options === void 0 ? void 0 : options.crv) !== null && _b !== void 0 ? _b : 'P-256' });
89
+ return generate('ec', { namedCurve: crv });
89
90
  case 'X25519':
90
91
  return generate('x25519');
91
92
  case 'X448':
@@ -24,7 +24,7 @@ function getPassword(key, alg) {
24
24
  }
25
25
  throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
26
26
  }
27
- export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
27
+ export const encrypt = async (alg, key, cek, p2c = 2048, p2s = random(new Uint8Array(16))) => {
28
28
  checkP2s(p2s);
29
29
  const salt = concatSalt(alg, p2s);
30
30
  const keylen = parseInt(alg.slice(13, 16), 10) >> 3;
@@ -1,5 +1,31 @@
1
1
  import type { KeyLike, DecryptOptions, CompactJWEHeaderParameters, GetKeyFunction, FlattenedJWE, CompactDecryptResult, ResolvedKey } from '../../types';
2
+ /**
3
+ * Interface for Compact JWE Decryption dynamic key resolution.
4
+ * No token components have been verified at the time of this function call.
5
+ */
2
6
  export interface CompactDecryptGetKey extends GetKeyFunction<CompactJWEHeaderParameters, FlattenedJWE> {
3
7
  }
8
+ /**
9
+ * Decrypts a Compact JWE.
10
+ *
11
+ * @param jwe Compact JWE.
12
+ * @param key Private Key or Secret to decrypt the JWE with.
13
+ * @param options JWE Decryption options.
14
+ *
15
+ * @example Usage
16
+ * ```js
17
+ * const jwe = 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0.nyQ19eq9ogh9wA7fFtnI2oouzy5_8b5DeLkoRMfi2yijgfTs2zEnayCEofz_qhnL-nwszabd9qUeHv0-IwvhhJJS7GUJOU3ikiIe42qcIAFme1A_Fo9CTxw4XTOy-I5qanl8So91u6hwfyN1VxAqVLsSE7_23EC-gfGEg_5znew9PyXXsOIE-K_HH7IQowRrlZ1X_bM_Liu53RzDpLDvRz59mp3S8L56YqpM8FexFGTGpEaoTcEIst375qncYt3-79IVR7gZN1RWsWgjPatfvVbnh74PglQcATSf3UUhaW0OAKn6q7r3PDx6DIKQ35bgHQg5QopuN00eIfLQL2trGw.W3grIVj5HVuAb76X.6PcuDe5D6ttWFYyv0oqqdDXfI2R8wBg1F2Q80UUA_Gv8eEimNWfxIWdLxrjzgQGSvIhxmFKuLM0.a93_Ug3uZHuczj70Zavx8Q'
18
+ *
19
+ * const { plaintext, protectedHeader } = await jose.compactDecrypt(jwe, privateKey)
20
+ *
21
+ * console.log(protectedHeader)
22
+ * console.log(new TextDecoder().decode(plaintext))
23
+ * ```
24
+ */
4
25
  export declare function compactDecrypt(jwe: string | Uint8Array, key: KeyLike | Uint8Array, options?: DecryptOptions): Promise<CompactDecryptResult>;
26
+ /**
27
+ * @param jwe Compact JWE.
28
+ * @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
29
+ * @param options JWE Decryption options.
30
+ */
5
31
  export declare function compactDecrypt(jwe: string | Uint8Array, getKey: CompactDecryptGetKey, options?: DecryptOptions): Promise<CompactDecryptResult & ResolvedKey>;
@@ -1,10 +1,66 @@
1
1
  import type { KeyLike, JWEKeyManagementHeaderParameters, CompactJWEHeaderParameters, EncryptOptions } from '../../types';
2
+ /**
3
+ * The CompactEncrypt class is a utility for creating Compact JWE strings.
4
+ *
5
+ * @example Usage
6
+ * ```js
7
+ * const jwe = await new jose.CompactEncrypt(
8
+ * new TextEncoder().encode(
9
+ * 'It’s a dangerous business, Frodo, going out your door.'
10
+ * )
11
+ * )
12
+ * .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })
13
+ * .encrypt(publicKey)
14
+ *
15
+ * console.log(jwe)
16
+ * ```
17
+ */
2
18
  export declare class CompactEncrypt {
3
19
  private _flattened;
20
+ /**
21
+ * @param plaintext Binary representation of the plaintext to encrypt.
22
+ */
4
23
  constructor(plaintext: Uint8Array);
24
+ /**
25
+ * Sets a content encryption key to use, by default a random suitable one
26
+ * is generated for the JWE enc" (Encryption Algorithm) Header Parameter.
27
+ *
28
+ * @param cek JWE Content Encryption Key.
29
+ *
30
+ * @deprecated You should not use this method. It is only really intended
31
+ * for test and vector validation purposes.
32
+ */
5
33
  setContentEncryptionKey(cek: Uint8Array): this;
34
+ /**
35
+ * Sets the JWE Initialization Vector to use for content encryption, by default
36
+ * a random suitable one is generated for the JWE enc" (Encryption Algorithm)
37
+ * Header Parameter.
38
+ *
39
+ * @param iv JWE Initialization Vector.
40
+ *
41
+ * @deprecated You should not use this method. It is only really intended
42
+ * for test and vector validation purposes.
43
+ */
6
44
  setInitializationVector(iv: Uint8Array): this;
45
+ /**
46
+ * Sets the JWE Protected Header on the CompactEncrypt object.
47
+ *
48
+ * @param protectedHeader JWE Protected Header object.
49
+ */
7
50
  setProtectedHeader(protectedHeader: CompactJWEHeaderParameters): this;
51
+ /**
52
+ * Sets the JWE Key Management parameters to be used when encrypting the Content
53
+ * Encryption Key. You do not need to invoke this method, it is only really
54
+ * intended for test and vector validation purposes.
55
+ *
56
+ * @param parameters JWE Key Management parameters.
57
+ */
8
58
  setKeyManagementParameters(parameters: JWEKeyManagementHeaderParameters): this;
59
+ /**
60
+ * Encrypts and resolves the value of the Compact JWE string.
61
+ *
62
+ * @param key Public Key or Secret to encrypt the JWE with.
63
+ * @param options JWE Encryption options.
64
+ */
9
65
  encrypt(key: KeyLike | Uint8Array, options?: EncryptOptions): Promise<string>;
10
66
  }
@@ -1,5 +1,44 @@
1
1
  import type { FlattenedDecryptResult, KeyLike, FlattenedJWE, JWEHeaderParameters, DecryptOptions, GetKeyFunction, ResolvedKey } from '../../types';
2
+ /**
3
+ * Interface for Flattened JWE Decryption dynamic key resolution.
4
+ * No token components have been verified at the time of this function call.
5
+ */
2
6
  export interface FlattenedDecryptGetKey extends GetKeyFunction<JWEHeaderParameters | undefined, FlattenedJWE> {
3
7
  }
8
+ /**
9
+ * Decrypts a Flattened JWE.
10
+ *
11
+ * @param jwe Flattened JWE.
12
+ * @param key Private Key or Secret to decrypt the JWE with.
13
+ * @param options JWE Decryption options.
14
+ *
15
+ * @example Usage
16
+ * ```js
17
+ * const jwe = {
18
+ * ciphertext: '9EzjFISUyoG-ifC2mSihfP0DPC80yeyrxhTzKt1C_VJBkxeBG0MI4Te61Pk45RAGubUvBpU9jm4',
19
+ * iv: '8Fy7A_IuoX5VXG9s',
20
+ * tag: 'W76IYV6arGRuDSaSyWrQNg',
21
+ * encrypted_key: 'Z6eD4UK_yFb5ZoKvKkGAdqywEG_m0e4IYo0x8Vf30LAMJcsc-_zSgIeiF82teZyYi2YYduHKoqImk7MRnoPZOlEs0Q5BNK1OgBmSOhCE8DFyqh9Zh48TCTP6lmBQ52naqoUJFMtHzu-0LwZH26hxos0GP3Dt19O379MJB837TdKKa87skq0zHaVLAquRHOBF77GI54Bc7O49d8aOrSu1VEFGMThlW2caspPRiTSePDMDPq7_WGk50izRhB3Asl9wmP9wEeaTrkJKRnQj5ips1SAZ1hDBsqEQKKukxP1HtdcopHV5_qgwU8Hjm5EwSLMluMQuiE6hwlkXGOujZLVizA',
22
+ * aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',
23
+ * protected: 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0'
24
+ * }
25
+ *
26
+ * const {
27
+ * plaintext,
28
+ * protectedHeader,
29
+ * additionalAuthenticatedData
30
+ * } = await jose.flattenedDecrypt(jwe, privateKey)
31
+ *
32
+ * console.log(protectedHeader)
33
+ * const decoder = new TextDecoder()
34
+ * console.log(decoder.decode(plaintext))
35
+ * console.log(decoder.decode(additionalAuthenticatedData))
36
+ * ```
37
+ */
4
38
  export declare function flattenedDecrypt(jwe: FlattenedJWE, key: KeyLike | Uint8Array, options?: DecryptOptions): Promise<FlattenedDecryptResult>;
39
+ /**
40
+ * @param jwe Flattened JWE.
41
+ * @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
42
+ * @param options JWE Decryption options.
43
+ */
5
44
  export declare function flattenedDecrypt(jwe: FlattenedJWE, getKey: FlattenedDecryptGetKey, options?: DecryptOptions): Promise<FlattenedDecryptResult & ResolvedKey>;