jose 4.3.7 → 4.3.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.
Files changed (53) hide show
  1. package/dist/browser/jwks/remote.js +1 -1
  2. package/dist/browser/lib/aesgcmkw.js +2 -2
  3. package/dist/browser/lib/crypto_key.js +7 -7
  4. package/dist/browser/lib/decrypt_key_management.js +2 -2
  5. package/dist/browser/lib/encrypt_key_management.js +3 -3
  6. package/dist/browser/runtime/aeskw.js +1 -1
  7. package/dist/browser/runtime/asn1.js +21 -20
  8. package/dist/browser/runtime/decrypt.js +3 -3
  9. package/dist/browser/runtime/digest.js +1 -1
  10. package/dist/browser/runtime/ecdhes.js +8 -9
  11. package/dist/browser/runtime/encrypt.js +3 -3
  12. package/dist/browser/runtime/generate.js +7 -7
  13. package/dist/browser/runtime/get_sign_verify_key.js +1 -1
  14. package/dist/browser/runtime/jwk_to_key.js +4 -4
  15. package/dist/browser/runtime/pbes2kw.js +4 -4
  16. package/dist/browser/runtime/sign.js +1 -1
  17. package/dist/browser/runtime/subtle_dsa.js +7 -6
  18. package/dist/browser/runtime/verify.js +1 -1
  19. package/dist/node/cjs/jwks/remote.js +1 -1
  20. package/dist/node/cjs/lib/aesgcmkw.js +2 -2
  21. package/dist/node/cjs/lib/crypto_key.js +7 -7
  22. package/dist/node/cjs/lib/decrypt_key_management.js +2 -2
  23. package/dist/node/cjs/lib/encrypt_key_management.js +3 -3
  24. package/dist/node/cjs/runtime/aeskw.js +3 -3
  25. package/dist/node/cjs/runtime/check_cek_length.js +2 -2
  26. package/dist/node/cjs/runtime/decrypt.js +3 -3
  27. package/dist/node/cjs/runtime/ecdhes.js +7 -7
  28. package/dist/node/cjs/runtime/encrypt.js +3 -3
  29. package/dist/node/cjs/runtime/generate.js +2 -2
  30. package/dist/node/cjs/runtime/get_named_curve.js +2 -2
  31. package/dist/node/cjs/runtime/jwk_to_key.js +1 -1
  32. package/dist/node/cjs/runtime/key_to_jwk.js +1 -1
  33. package/dist/node/cjs/runtime/node_key.js +2 -2
  34. package/dist/node/cjs/runtime/pbes2kw.js +6 -6
  35. package/dist/node/cjs/runtime/verify.js +1 -1
  36. package/dist/node/esm/jwks/remote.js +1 -1
  37. package/dist/node/esm/lib/aesgcmkw.js +2 -2
  38. package/dist/node/esm/lib/crypto_key.js +7 -7
  39. package/dist/node/esm/lib/decrypt_key_management.js +2 -2
  40. package/dist/node/esm/lib/encrypt_key_management.js +3 -3
  41. package/dist/node/esm/runtime/aeskw.js +3 -3
  42. package/dist/node/esm/runtime/check_cek_length.js +2 -2
  43. package/dist/node/esm/runtime/decrypt.js +3 -3
  44. package/dist/node/esm/runtime/ecdhes.js +7 -7
  45. package/dist/node/esm/runtime/encrypt.js +3 -3
  46. package/dist/node/esm/runtime/generate.js +2 -2
  47. package/dist/node/esm/runtime/get_named_curve.js +2 -2
  48. package/dist/node/esm/runtime/jwk_to_key.js +1 -1
  49. package/dist/node/esm/runtime/key_to_jwk.js +1 -1
  50. package/dist/node/esm/runtime/node_key.js +2 -2
  51. package/dist/node/esm/runtime/pbes2kw.js +6 -6
  52. package/dist/node/esm/runtime/verify.js +1 -1
  53. package/package.json +1 -1
@@ -3,7 +3,7 @@ import { importJWK } from '../key/import.js';
3
3
  import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
4
4
  import isObject from '../lib/is_object.js';
5
5
  function getKtyFromAlg(alg) {
6
- switch (typeof alg === 'string' && alg.substr(0, 2)) {
6
+ switch (typeof alg === 'string' && alg.slice(0, 2)) {
7
7
  case 'RS':
8
8
  case 'PS':
9
9
  return 'RSA';
@@ -3,12 +3,12 @@ import decrypt from '../runtime/decrypt.js';
3
3
  import generateIv from './iv.js';
4
4
  import { encode as base64url } from '../runtime/base64url.js';
5
5
  export async function wrap(alg, key, cek, iv) {
6
- const jweAlgorithm = alg.substr(0, 7);
6
+ const jweAlgorithm = alg.slice(0, 7);
7
7
  iv || (iv = generateIv(jweAlgorithm));
8
8
  const { ciphertext: encryptedKey, tag } = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array(0));
9
9
  return { encryptedKey, iv: base64url(iv), tag: base64url(tag) };
10
10
  }
11
11
  export async function unwrap(alg, key, encryptedKey, iv, tag) {
12
- const jweAlgorithm = alg.substr(0, 7);
12
+ const jweAlgorithm = alg.slice(0, 7);
13
13
  return decrypt(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
14
14
  }
@@ -6,7 +6,7 @@ function isAlgorithm(algorithm, name) {
6
6
  return algorithm.name === name;
7
7
  }
8
8
  function getHashLength(hash) {
9
- return parseInt(hash.name.substr(4), 10);
9
+ return parseInt(hash.name.slice(4), 10);
10
10
  }
11
11
  function getNamedCurve(alg) {
12
12
  switch (alg) {
@@ -43,7 +43,7 @@ export function checkSigCryptoKey(key, alg, ...usages) {
43
43
  case 'HS512': {
44
44
  if (!isAlgorithm(key.algorithm, 'HMAC'))
45
45
  throw unusable('HMAC');
46
- const expected = parseInt(alg.substr(2), 10);
46
+ const expected = parseInt(alg.slice(2), 10);
47
47
  const actual = getHashLength(key.algorithm.hash);
48
48
  if (actual !== expected)
49
49
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -54,7 +54,7 @@ export function checkSigCryptoKey(key, alg, ...usages) {
54
54
  case 'RS512': {
55
55
  if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
56
56
  throw unusable('RSASSA-PKCS1-v1_5');
57
- const expected = parseInt(alg.substr(2), 10);
57
+ const expected = parseInt(alg.slice(2), 10);
58
58
  const actual = getHashLength(key.algorithm.hash);
59
59
  if (actual !== expected)
60
60
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -65,7 +65,7 @@ export function checkSigCryptoKey(key, alg, ...usages) {
65
65
  case 'PS512': {
66
66
  if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
67
67
  throw unusable('RSA-PSS');
68
- const expected = parseInt(alg.substr(2), 10);
68
+ const expected = parseInt(alg.slice(2), 10);
69
69
  const actual = getHashLength(key.algorithm.hash);
70
70
  if (actual !== expected)
71
71
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -104,7 +104,7 @@ export function checkEncCryptoKey(key, alg, ...usages) {
104
104
  case 'A256GCM': {
105
105
  if (!isAlgorithm(key.algorithm, 'AES-GCM'))
106
106
  throw unusable('AES-GCM');
107
- const expected = parseInt(alg.substr(1, 3), 10);
107
+ const expected = parseInt(alg.slice(1, 4), 10);
108
108
  const actual = key.algorithm.length;
109
109
  if (actual !== expected)
110
110
  throw unusable(expected, 'algorithm.length');
@@ -115,7 +115,7 @@ export function checkEncCryptoKey(key, alg, ...usages) {
115
115
  case 'A256KW': {
116
116
  if (!isAlgorithm(key.algorithm, 'AES-KW'))
117
117
  throw unusable('AES-KW');
118
- const expected = parseInt(alg.substr(1, 3), 10);
118
+ const expected = parseInt(alg.slice(1, 4), 10);
119
119
  const actual = key.algorithm.length;
120
120
  if (actual !== expected)
121
121
  throw unusable(expected, 'algorithm.length');
@@ -137,7 +137,7 @@ export function checkEncCryptoKey(key, alg, ...usages) {
137
137
  case 'RSA-OAEP-512': {
138
138
  if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
139
139
  throw unusable('RSA-OAEP');
140
- const expected = parseInt(alg.substr(9), 10) || 1;
140
+ const expected = parseInt(alg.slice(9), 10) || 1;
141
141
  const actual = getHashLength(key.algorithm.hash);
142
142
  if (actual !== expected)
143
143
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -40,12 +40,12 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
40
40
  throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
41
41
  partyVInfo = base64url(joseHeader.apv);
42
42
  }
43
- const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? cekLength(joseHeader.enc) : parseInt(alg.substr(-5, 3), 10), partyUInfo, partyVInfo);
43
+ const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? cekLength(joseHeader.enc) : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
44
44
  if (alg === 'ECDH-ES')
45
45
  return sharedSecret;
46
46
  if (encryptedKey === undefined)
47
47
  throw new JWEInvalid('JWE Encrypted Key missing');
48
- return aesKw(alg.substr(-6), sharedSecret, encryptedKey);
48
+ return aesKw(alg.slice(-6), sharedSecret, encryptedKey);
49
49
  }
50
50
  case 'RSA1_5':
51
51
  case 'RSA-OAEP':
@@ -27,9 +27,9 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
27
27
  }
28
28
  const { apu, apv } = providedParameters;
29
29
  let { epk: ephemeralKey } = providedParameters;
30
- ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
30
+ ephemeralKey || (ephemeralKey = (await ECDH.generateEpk(key)).privateKey);
31
31
  const { x, y, crv, kty } = await exportJWK(ephemeralKey);
32
- const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? cekLength(enc) : parseInt(alg.substr(-5, 3), 10), apu, apv);
32
+ const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? cekLength(enc) : parseInt(alg.slice(-5, -2), 10), apu, apv);
33
33
  parameters = { epk: { x, y, crv, kty } };
34
34
  if (apu)
35
35
  parameters.apu = base64url(apu);
@@ -40,7 +40,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
40
40
  break;
41
41
  }
42
42
  cek = providedCek || generateCek(enc);
43
- const kwAlg = alg.substr(-6);
43
+ const kwAlg = alg.slice(-6);
44
44
  encryptedKey = await aesKw(kwAlg, sharedSecret, cek);
45
45
  break;
46
46
  }
@@ -4,7 +4,7 @@ import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
4
  import invalidKeyInput from '../lib/invalid_key_input.js';
5
5
  import { types } from './is_key_like.js';
6
6
  function checkKeySize(key, alg) {
7
- if (key.algorithm.length !== parseInt(alg.substr(1, 3), 10)) {
7
+ if (key.algorithm.length !== parseInt(alg.slice(1, 4), 10)) {
8
8
  throw new TypeError(`Invalid key size for alg: ${alg}`);
9
9
  }
10
10
  }
@@ -23,29 +23,30 @@ export const toSPKI = (key) => {
23
23
  export const toPKCS8 = (key) => {
24
24
  return genericExport('private', 'pkcs8', key);
25
25
  };
26
+ const findOid = (keyData, oid, from = 0) => {
27
+ if (from === 0) {
28
+ oid.unshift(oid.length);
29
+ oid.unshift(0x06);
30
+ }
31
+ let i = keyData.indexOf(oid[0], from);
32
+ if (i === -1)
33
+ return false;
34
+ const sub = keyData.subarray(i, i + oid.length);
35
+ if (sub.length !== oid.length)
36
+ return false;
37
+ return sub.every((value, index) => value === oid[index]) || findOid(keyData, oid, i + 1);
38
+ };
26
39
  const getNamedCurve = (keyData) => {
27
- const keyDataStr = keyData.toString();
28
40
  switch (true) {
29
- case keyDataStr.includes(new Uint8Array([
30
- 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
31
- 0x3d, 0x03, 0x01, 0x07,
32
- ]).toString()):
41
+ case findOid(keyData, [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]):
33
42
  return 'P-256';
34
- case keyDataStr.includes(new Uint8Array([
35
- 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
36
- 0x22,
37
- ]).toString()):
43
+ case findOid(keyData, [0x2b, 0x81, 0x04, 0x00, 0x22]):
38
44
  return 'P-384';
39
- case keyDataStr.includes(new Uint8Array([
40
- 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
41
- 0x23,
42
- ]).toString()):
45
+ case findOid(keyData, [0x2b, 0x81, 0x04, 0x00, 0x23]):
43
46
  return 'P-521';
44
- case (isCloudflareWorkers() || isNodeJs()) &&
45
- keyDataStr.includes(new Uint8Array([0x06, 0x03, 0x2b, 0x65, 0x70]).toString()):
47
+ case (isCloudflareWorkers() || isNodeJs()) && findOid(keyData, [0x2b, 0x65, 0x70]):
46
48
  return 'Ed25519';
47
- case isNodeJs() &&
48
- keyDataStr.includes(new Uint8Array([0x06, 0x03, 0x2b, 0x65, 0x71]).toString()):
49
+ case isNodeJs() && findOid(keyData, [0x2b, 0x65, 0x71]):
49
50
  return 'Ed448';
50
51
  default:
51
52
  throw new JOSENotSupported('Invalid or unsupported EC Key Curve or OKP Key Sub Type');
@@ -63,13 +64,13 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
63
64
  case 'PS256':
64
65
  case 'PS384':
65
66
  case 'PS512':
66
- algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.substr(-3)}` };
67
+ algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };
67
68
  keyUsages = isPublic ? ['verify'] : ['sign'];
68
69
  break;
69
70
  case 'RS256':
70
71
  case 'RS384':
71
72
  case 'RS512':
72
- algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.substr(-3)}` };
73
+ algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };
73
74
  keyUsages = isPublic ? ['verify'] : ['sign'];
74
75
  break;
75
76
  case 'RSA-OAEP':
@@ -78,7 +79,7 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
78
79
  case 'RSA-OAEP-512':
79
80
  algorithm = {
80
81
  name: 'RSA-OAEP',
81
- hash: `SHA-${parseInt(alg.substr(-3), 10) || 1}`,
82
+ hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
82
83
  };
83
84
  keyUsages = isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];
84
85
  break;
@@ -11,7 +11,7 @@ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
11
11
  if (!(cek instanceof Uint8Array)) {
12
12
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
13
13
  }
14
- const keySize = parseInt(enc.substr(1, 3), 10);
14
+ const keySize = parseInt(enc.slice(1, 4), 10);
15
15
  const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['decrypt']);
16
16
  const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
17
17
  hash: `SHA-${keySize << 1}`,
@@ -70,13 +70,13 @@ const decrypt = async (enc, cek, ciphertext, iv, tag, aad) => {
70
70
  case 'A192CBC-HS384':
71
71
  case 'A256CBC-HS512':
72
72
  if (cek instanceof Uint8Array)
73
- checkCekLength(cek, parseInt(enc.substr(-3), 10));
73
+ checkCekLength(cek, parseInt(enc.slice(-3), 10));
74
74
  return cbcDecrypt(enc, cek, ciphertext, iv, tag, aad);
75
75
  case 'A128GCM':
76
76
  case 'A192GCM':
77
77
  case 'A256GCM':
78
78
  if (cek instanceof Uint8Array)
79
- checkCekLength(cek, parseInt(enc.substr(1, 3), 10));
79
+ checkCekLength(cek, parseInt(enc.slice(1, 4), 10));
80
80
  return gcmDecrypt(enc, cek, ciphertext, iv, tag, aad);
81
81
  default:
82
82
  throw new JOSENotSupported('Unsupported JWE Content Encryption Algorithm');
@@ -1,6 +1,6 @@
1
1
  import crypto from './webcrypto.js';
2
2
  const digest = async (algorithm, data) => {
3
- const subtleDigest = `SHA-${algorithm.substr(-3)}`;
3
+ const subtleDigest = `SHA-${algorithm.slice(-3)}`;
4
4
  return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
5
5
  };
6
6
  export default digest;
@@ -4,7 +4,7 @@ import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
4
  import digest from './digest.js';
5
5
  import invalidKeyInput from '../lib/invalid_key_input.js';
6
6
  import { types } from './is_key_like.js';
7
- export const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) => {
7
+ export async function deriveKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
8
8
  if (!isCryptoKey(publicKey)) {
9
9
  throw new TypeError(invalidKeyInput(publicKey, ...types));
10
10
  }
@@ -20,19 +20,18 @@ export const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu
20
20
  const sharedSecret = new Uint8Array(await crypto.subtle.deriveBits({
21
21
  name: 'ECDH',
22
22
  public: publicKey,
23
- }, privateKey, Math.ceil(parseInt(privateKey.algorithm.namedCurve.substr(-3), 10) / 8) <<
24
- 3));
23
+ }, privateKey, Math.ceil(parseInt(privateKey.algorithm.namedCurve.slice(-3), 10) / 8) << 3));
25
24
  return concatKdf(digest, sharedSecret, keyLength, value);
26
- };
27
- export const generateEpk = async (key) => {
25
+ }
26
+ export async function generateEpk(key) {
28
27
  if (!isCryptoKey(key)) {
29
28
  throw new TypeError(invalidKeyInput(key, ...types));
30
29
  }
31
- return (await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: key.algorithm.namedCurve }, true, ['deriveBits'])).privateKey;
32
- };
33
- export const ecdhAllowed = (key) => {
30
+ return crypto.subtle.generateKey(key.algorithm, true, ['deriveBits']);
31
+ }
32
+ export function ecdhAllowed(key) {
34
33
  if (!isCryptoKey(key)) {
35
34
  throw new TypeError(invalidKeyInput(key, ...types));
36
35
  }
37
36
  return ['P-256', 'P-384', 'P-521'].includes(key.algorithm.namedCurve);
38
- };
37
+ }
@@ -10,7 +10,7 @@ async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
10
10
  if (!(cek instanceof Uint8Array)) {
11
11
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
12
12
  }
13
- const keySize = parseInt(enc.substr(1, 3), 10);
13
+ const keySize = parseInt(enc.slice(1, 4), 10);
14
14
  const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt']);
15
15
  const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
16
16
  hash: `SHA-${keySize << 1}`,
@@ -53,13 +53,13 @@ const encrypt = async (enc, plaintext, cek, iv, aad) => {
53
53
  case 'A192CBC-HS384':
54
54
  case 'A256CBC-HS512':
55
55
  if (cek instanceof Uint8Array)
56
- checkCekLength(cek, parseInt(enc.substr(-3), 10));
56
+ checkCekLength(cek, parseInt(enc.slice(-3), 10));
57
57
  return cbcEncrypt(enc, plaintext, cek, iv, aad);
58
58
  case 'A128GCM':
59
59
  case 'A192GCM':
60
60
  case 'A256GCM':
61
61
  if (cek instanceof Uint8Array)
62
- checkCekLength(cek, parseInt(enc.substr(1, 3), 10));
62
+ checkCekLength(cek, parseInt(enc.slice(1, 4), 10));
63
63
  return gcmEncrypt(enc, plaintext, cek, iv, aad);
64
64
  default:
65
65
  throw new JOSENotSupported('Unsupported JWE Content Encryption Algorithm');
@@ -11,19 +11,19 @@ export async function generateSecret(alg, options) {
11
11
  case 'HS256':
12
12
  case 'HS384':
13
13
  case 'HS512':
14
- length = parseInt(alg.substr(-3), 10);
14
+ length = parseInt(alg.slice(-3), 10);
15
15
  algorithm = { name: 'HMAC', hash: `SHA-${length}`, length };
16
16
  keyUsages = ['sign', 'verify'];
17
17
  break;
18
18
  case 'A128CBC-HS256':
19
19
  case 'A192CBC-HS384':
20
20
  case 'A256CBC-HS512':
21
- length = parseInt(alg.substr(-3), 10);
21
+ length = parseInt(alg.slice(-3), 10);
22
22
  return random(new Uint8Array(length >> 3));
23
23
  case 'A128KW':
24
24
  case 'A192KW':
25
25
  case 'A256KW':
26
- length = parseInt(alg.substring(1, 4), 10);
26
+ length = parseInt(alg.slice(1, 4), 10);
27
27
  algorithm = { name: 'AES-KW', length };
28
28
  keyUsages = ['wrapKey', 'unwrapKey'];
29
29
  break;
@@ -33,7 +33,7 @@ export async function generateSecret(alg, options) {
33
33
  case 'A128GCM':
34
34
  case 'A192GCM':
35
35
  case 'A256GCM':
36
- length = parseInt(alg.substring(1, 4), 10);
36
+ length = parseInt(alg.slice(1, 4), 10);
37
37
  algorithm = { name: 'AES-GCM', length };
38
38
  keyUsages = ['encrypt', 'decrypt'];
39
39
  break;
@@ -60,7 +60,7 @@ export async function generateKeyPair(alg, options) {
60
60
  case 'PS512':
61
61
  algorithm = {
62
62
  name: 'RSA-PSS',
63
- hash: `SHA-${alg.substr(-3)}`,
63
+ hash: `SHA-${alg.slice(-3)}`,
64
64
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
65
65
  modulusLength: getModulusLengthOption(options),
66
66
  };
@@ -71,7 +71,7 @@ export async function generateKeyPair(alg, options) {
71
71
  case 'RS512':
72
72
  algorithm = {
73
73
  name: 'RSASSA-PKCS1-v1_5',
74
- hash: `SHA-${alg.substr(-3)}`,
74
+ hash: `SHA-${alg.slice(-3)}`,
75
75
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
76
76
  modulusLength: getModulusLengthOption(options),
77
77
  };
@@ -83,7 +83,7 @@ export async function generateKeyPair(alg, options) {
83
83
  case 'RSA-OAEP-512':
84
84
  algorithm = {
85
85
  name: 'RSA-OAEP',
86
- hash: `SHA-${parseInt(alg.substr(-3), 10) || 1}`,
86
+ hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
87
87
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
88
88
  modulusLength: getModulusLengthOption(options),
89
89
  };
@@ -11,7 +11,7 @@ export default function getCryptoKey(alg, key, usage) {
11
11
  if (!alg.startsWith('HS')) {
12
12
  throw new TypeError(invalidKeyInput(key, ...types));
13
13
  }
14
- return crypto.subtle.importKey('raw', key, { hash: `SHA-${alg.substr(-3)}`, name: 'HMAC' }, false, [usage]);
14
+ return crypto.subtle.importKey('raw', key, { hash: `SHA-${alg.slice(-3)}`, name: 'HMAC' }, false, [usage]);
15
15
  }
16
16
  throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
17
17
  }
@@ -11,7 +11,7 @@ function subtleMapping(jwk) {
11
11
  case 'HS256':
12
12
  case 'HS384':
13
13
  case 'HS512':
14
- algorithm = { name: 'HMAC', hash: `SHA-${jwk.alg.substr(-3)}` };
14
+ algorithm = { name: 'HMAC', hash: `SHA-${jwk.alg.slice(-3)}` };
15
15
  keyUsages = ['sign', 'verify'];
16
16
  break;
17
17
  case 'A128CBC-HS256':
@@ -49,13 +49,13 @@ function subtleMapping(jwk) {
49
49
  case 'PS256':
50
50
  case 'PS384':
51
51
  case 'PS512':
52
- algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.substr(-3)}` };
52
+ algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.slice(-3)}` };
53
53
  keyUsages = jwk.d ? ['sign'] : ['verify'];
54
54
  break;
55
55
  case 'RS256':
56
56
  case 'RS384':
57
57
  case 'RS512':
58
- algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.substr(-3)}` };
58
+ algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.slice(-3)}` };
59
59
  keyUsages = jwk.d ? ['sign'] : ['verify'];
60
60
  break;
61
61
  case 'RSA-OAEP':
@@ -64,7 +64,7 @@ function subtleMapping(jwk) {
64
64
  case 'RSA-OAEP-512':
65
65
  algorithm = {
66
66
  name: 'RSA-OAEP',
67
- hash: `SHA-${parseInt(jwk.alg.substr(-3), 10) || 1}`,
67
+ hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`,
68
68
  };
69
69
  keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey'];
70
70
  break;
@@ -20,9 +20,9 @@ function getCryptoKey(key, alg) {
20
20
  async function deriveKey(p2s, alg, p2c, key) {
21
21
  checkP2s(p2s);
22
22
  const salt = concatSalt(alg, p2s);
23
- const keylen = parseInt(alg.substr(13, 3), 10);
23
+ const keylen = parseInt(alg.slice(13, 16), 10);
24
24
  const subtleAlg = {
25
- hash: `SHA-${alg.substr(8, 3)}`,
25
+ hash: `SHA-${alg.slice(8, 11)}`,
26
26
  iterations: p2c,
27
27
  name: 'PBKDF2',
28
28
  salt,
@@ -42,10 +42,10 @@ async function deriveKey(p2s, alg, p2c, key) {
42
42
  }
43
43
  export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
44
44
  const derived = await deriveKey(p2s, alg, p2c, key);
45
- const encryptedKey = await wrap(alg.substr(-6), derived, cek);
45
+ const encryptedKey = await wrap(alg.slice(-6), derived, cek);
46
46
  return { encryptedKey, p2c, p2s: base64url(p2s) };
47
47
  };
48
48
  export const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
49
49
  const derived = await deriveKey(p2s, alg, p2c, key);
50
- return unwrap(alg.substr(-6), derived, encryptedKey);
50
+ return unwrap(alg.slice(-6), derived, encryptedKey);
51
51
  };
@@ -5,7 +5,7 @@ import getSignKey from './get_sign_verify_key.js';
5
5
  const sign = async (alg, key, data) => {
6
6
  const cryptoKey = await getSignKey(alg, key, 'sign');
7
7
  checkKeyLength(alg, cryptoKey);
8
- const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm.namedCurve), cryptoKey, data);
8
+ const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
9
9
  return new Uint8Array(signature);
10
10
  };
11
11
  export default sign;
@@ -1,25 +1,26 @@
1
1
  import { isCloudflareWorkers, isNodeJs } from './env.js';
2
2
  import { JOSENotSupported } from '../util/errors.js';
3
- export default function subtleDsa(alg, namedCurve) {
4
- const length = parseInt(alg.substr(-3), 10);
3
+ export default function subtleDsa(alg, algorithm) {
4
+ const hash = `SHA-${alg.slice(-3)}`;
5
5
  switch (alg) {
6
6
  case 'HS256':
7
7
  case 'HS384':
8
8
  case 'HS512':
9
- return { hash: `SHA-${length}`, name: 'HMAC' };
9
+ return { hash, name: 'HMAC' };
10
10
  case 'PS256':
11
11
  case 'PS384':
12
12
  case 'PS512':
13
- return { hash: `SHA-${length}`, name: 'RSA-PSS', saltLength: length >> 3 };
13
+ return { hash, name: 'RSA-PSS', saltLength: alg.slice(-3) >> 3 };
14
14
  case 'RS256':
15
15
  case 'RS384':
16
16
  case 'RS512':
17
- return { hash: `SHA-${length}`, name: 'RSASSA-PKCS1-v1_5' };
17
+ return { hash, name: 'RSASSA-PKCS1-v1_5' };
18
18
  case 'ES256':
19
19
  case 'ES384':
20
20
  case 'ES512':
21
- return { hash: `SHA-${length}`, name: 'ECDSA', namedCurve };
21
+ return { hash, name: 'ECDSA', namedCurve: algorithm.namedCurve };
22
22
  case (isCloudflareWorkers() || isNodeJs()) && 'EdDSA':
23
+ const { namedCurve } = algorithm;
23
24
  return { name: namedCurve, namedCurve };
24
25
  default:
25
26
  throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
@@ -5,7 +5,7 @@ import getVerifyKey from './get_sign_verify_key.js';
5
5
  const verify = async (alg, key, signature, data) => {
6
6
  const cryptoKey = await getVerifyKey(alg, key, 'verify');
7
7
  checkKeyLength(alg, cryptoKey);
8
- const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm.namedCurve);
8
+ const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
9
9
  try {
10
10
  return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
11
11
  }
@@ -6,7 +6,7 @@ const import_js_1 = require("../key/import.js");
6
6
  const errors_js_1 = require("../util/errors.js");
7
7
  const is_object_js_1 = require("../lib/is_object.js");
8
8
  function getKtyFromAlg(alg) {
9
- switch (typeof alg === 'string' && alg.substr(0, 2)) {
9
+ switch (typeof alg === 'string' && alg.slice(0, 2)) {
10
10
  case 'RS':
11
11
  case 'PS':
12
12
  return 'RSA';
@@ -6,14 +6,14 @@ const decrypt_js_1 = require("../runtime/decrypt.js");
6
6
  const iv_js_1 = require("./iv.js");
7
7
  const base64url_js_1 = require("../runtime/base64url.js");
8
8
  async function wrap(alg, key, cek, iv) {
9
- const jweAlgorithm = alg.substr(0, 7);
9
+ const jweAlgorithm = alg.slice(0, 7);
10
10
  iv || (iv = (0, iv_js_1.default)(jweAlgorithm));
11
11
  const { ciphertext: encryptedKey, tag } = await (0, encrypt_js_1.default)(jweAlgorithm, cek, key, iv, new Uint8Array(0));
12
12
  return { encryptedKey, iv: (0, base64url_js_1.encode)(iv), tag: (0, base64url_js_1.encode)(tag) };
13
13
  }
14
14
  exports.wrap = wrap;
15
15
  async function unwrap(alg, key, encryptedKey, iv, tag) {
16
- const jweAlgorithm = alg.substr(0, 7);
16
+ const jweAlgorithm = alg.slice(0, 7);
17
17
  return (0, decrypt_js_1.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
18
18
  }
19
19
  exports.unwrap = unwrap;
@@ -9,7 +9,7 @@ function isAlgorithm(algorithm, name) {
9
9
  return algorithm.name === name;
10
10
  }
11
11
  function getHashLength(hash) {
12
- return parseInt(hash.name.substr(4), 10);
12
+ return parseInt(hash.name.slice(4), 10);
13
13
  }
14
14
  function getNamedCurve(alg) {
15
15
  switch (alg) {
@@ -46,7 +46,7 @@ function checkSigCryptoKey(key, alg, ...usages) {
46
46
  case 'HS512': {
47
47
  if (!isAlgorithm(key.algorithm, 'HMAC'))
48
48
  throw unusable('HMAC');
49
- const expected = parseInt(alg.substr(2), 10);
49
+ const expected = parseInt(alg.slice(2), 10);
50
50
  const actual = getHashLength(key.algorithm.hash);
51
51
  if (actual !== expected)
52
52
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -57,7 +57,7 @@ function checkSigCryptoKey(key, alg, ...usages) {
57
57
  case 'RS512': {
58
58
  if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
59
59
  throw unusable('RSASSA-PKCS1-v1_5');
60
- const expected = parseInt(alg.substr(2), 10);
60
+ const expected = parseInt(alg.slice(2), 10);
61
61
  const actual = getHashLength(key.algorithm.hash);
62
62
  if (actual !== expected)
63
63
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -68,7 +68,7 @@ function checkSigCryptoKey(key, alg, ...usages) {
68
68
  case 'PS512': {
69
69
  if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
70
70
  throw unusable('RSA-PSS');
71
- const expected = parseInt(alg.substr(2), 10);
71
+ const expected = parseInt(alg.slice(2), 10);
72
72
  const actual = getHashLength(key.algorithm.hash);
73
73
  if (actual !== expected)
74
74
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -108,7 +108,7 @@ function checkEncCryptoKey(key, alg, ...usages) {
108
108
  case 'A256GCM': {
109
109
  if (!isAlgorithm(key.algorithm, 'AES-GCM'))
110
110
  throw unusable('AES-GCM');
111
- const expected = parseInt(alg.substr(1, 3), 10);
111
+ const expected = parseInt(alg.slice(1, 4), 10);
112
112
  const actual = key.algorithm.length;
113
113
  if (actual !== expected)
114
114
  throw unusable(expected, 'algorithm.length');
@@ -119,7 +119,7 @@ function checkEncCryptoKey(key, alg, ...usages) {
119
119
  case 'A256KW': {
120
120
  if (!isAlgorithm(key.algorithm, 'AES-KW'))
121
121
  throw unusable('AES-KW');
122
- const expected = parseInt(alg.substr(1, 3), 10);
122
+ const expected = parseInt(alg.slice(1, 4), 10);
123
123
  const actual = key.algorithm.length;
124
124
  if (actual !== expected)
125
125
  throw unusable(expected, 'algorithm.length');
@@ -141,7 +141,7 @@ function checkEncCryptoKey(key, alg, ...usages) {
141
141
  case 'RSA-OAEP-512': {
142
142
  if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
143
143
  throw unusable('RSA-OAEP');
144
- const expected = parseInt(alg.substr(9), 10) || 1;
144
+ const expected = parseInt(alg.slice(9), 10) || 1;
145
145
  const actual = getHashLength(key.algorithm.hash);
146
146
  if (actual !== expected)
147
147
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
@@ -42,12 +42,12 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
42
42
  throw new errors_js_1.JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
43
43
  partyVInfo = (0, base64url_js_1.decode)(joseHeader.apv);
44
44
  }
45
- const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1.bitLength)(joseHeader.enc) : parseInt(alg.substr(-5, 3), 10), partyUInfo, partyVInfo);
45
+ const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1.bitLength)(joseHeader.enc) : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
46
46
  if (alg === 'ECDH-ES')
47
47
  return sharedSecret;
48
48
  if (encryptedKey === undefined)
49
49
  throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
50
- return (0, aeskw_js_1.unwrap)(alg.substr(-6), sharedSecret, encryptedKey);
50
+ return (0, aeskw_js_1.unwrap)(alg.slice(-6), sharedSecret, encryptedKey);
51
51
  }
52
52
  case 'RSA1_5':
53
53
  case 'RSA-OAEP':
@@ -29,9 +29,9 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
29
29
  }
30
30
  const { apu, apv } = providedParameters;
31
31
  let { epk: ephemeralKey } = providedParameters;
32
- ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
32
+ ephemeralKey || (ephemeralKey = (await ECDH.generateEpk(key)).privateKey);
33
33
  const { x, y, crv, kty } = await (0, export_js_1.exportJWK)(ephemeralKey);
34
- const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1.bitLength)(enc) : parseInt(alg.substr(-5, 3), 10), apu, apv);
34
+ const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1.bitLength)(enc) : parseInt(alg.slice(-5, -2), 10), apu, apv);
35
35
  parameters = { epk: { x, y, crv, kty } };
36
36
  if (apu)
37
37
  parameters.apu = (0, base64url_js_1.encode)(apu);
@@ -42,7 +42,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
42
42
  break;
43
43
  }
44
44
  cek = providedCek || (0, cek_js_1.default)(enc);
45
- const kwAlg = alg.substr(-6);
45
+ const kwAlg = alg.slice(-6);
46
46
  encryptedKey = await (0, aeskw_js_1.wrap)(kwAlg, sharedSecret, cek);
47
47
  break;
48
48
  }