decrypt_key_management.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { unwrap as aesKw } from '../runtime/aeskw.js';
  2. import * as ECDH from '../runtime/ecdhes.js';
  3. import { decrypt as pbes2Kw } from '../runtime/pbes2kw.js';
  4. import { decrypt as rsaEs } from '../runtime/rsaes.js';
  5. import { decode as base64url } from '../runtime/base64url.js';
  6. import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
  7. import { bitLength as cekLength } from '../lib/cek.js';
  8. import { importJWK } from '../key/import.js';
  9. import checkKeyType from './check_key_type.js';
  10. import isObject from './is_object.js';
  11. import { unwrap as aesGcmKw } from './aesgcmkw.js';
  12. async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options) {
  13. checkKeyType(alg, key, 'decrypt');
  14. switch (alg) {
  15. case 'dir': {
  16. if (encryptedKey !== undefined)
  17. throw new JWEInvalid('Encountered unexpected JWE Encrypted Key');
  18. return key;
  19. }
  20. case 'ECDH-ES':
  21. if (encryptedKey !== undefined)
  22. throw new JWEInvalid('Encountered unexpected JWE Encrypted Key');
  23. case 'ECDH-ES+A128KW':
  24. case 'ECDH-ES+A192KW':
  25. case 'ECDH-ES+A256KW': {
  26. if (!isObject(joseHeader.epk))
  27. throw new JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
  28. if (!ECDH.ecdhAllowed(key))
  29. throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
  30. const epk = await importJWK(joseHeader.epk, alg);
  31. let partyUInfo;
  32. let partyVInfo;
  33. if (joseHeader.apu !== undefined) {
  34. if (typeof joseHeader.apu !== 'string')
  35. throw new JWEInvalid(`JOSE Header "apu" (Agreement PartyUInfo) invalid`);
  36. try {
  37. partyUInfo = base64url(joseHeader.apu);
  38. }
  39. catch (_a) {
  40. throw new JWEInvalid('Failed to base64url decode the apu');
  41. }
  42. }
  43. if (joseHeader.apv !== undefined) {
  44. if (typeof joseHeader.apv !== 'string')
  45. throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
  46. try {
  47. partyVInfo = base64url(joseHeader.apv);
  48. }
  49. catch (_b) {
  50. throw new JWEInvalid('Failed to base64url decode the apv');
  51. }
  52. }
  53. 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);
  54. if (alg === 'ECDH-ES')
  55. return sharedSecret;
  56. if (encryptedKey === undefined)
  57. throw new JWEInvalid('JWE Encrypted Key missing');
  58. return aesKw(alg.slice(-6), sharedSecret, encryptedKey);
  59. }
  60. case 'RSA1_5':
  61. case 'RSA-OAEP':
  62. case 'RSA-OAEP-256':
  63. case 'RSA-OAEP-384':
  64. case 'RSA-OAEP-512': {
  65. if (encryptedKey === undefined)
  66. throw new JWEInvalid('JWE Encrypted Key missing');
  67. return rsaEs(alg, key, encryptedKey);
  68. }
  69. case 'PBES2-HS256+A128KW':
  70. case 'PBES2-HS384+A192KW':
  71. case 'PBES2-HS512+A256KW': {
  72. if (encryptedKey === undefined)
  73. throw new JWEInvalid('JWE Encrypted Key missing');
  74. if (typeof joseHeader.p2c !== 'number')
  75. throw new JWEInvalid(`JOSE Header "p2c" (PBES2 Count) missing or invalid`);
  76. const p2cLimit = (options === null || options === void 0 ? void 0 : options.maxPBES2Count) || 10000;
  77. if (joseHeader.p2c > p2cLimit)
  78. throw new JWEInvalid(`JOSE Header "p2c" (PBES2 Count) out is of acceptable bounds`);
  79. if (typeof joseHeader.p2s !== 'string')
  80. throw new JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`);
  81. let p2s;
  82. try {
  83. p2s = base64url(joseHeader.p2s);
  84. }
  85. catch (_c) {
  86. throw new JWEInvalid('Failed to base64url decode the p2s');
  87. }
  88. return pbes2Kw(alg, key, encryptedKey, joseHeader.p2c, p2s);
  89. }
  90. case 'A128KW':
  91. case 'A192KW':
  92. case 'A256KW': {
  93. if (encryptedKey === undefined)
  94. throw new JWEInvalid('JWE Encrypted Key missing');
  95. return aesKw(alg, key, encryptedKey);
  96. }
  97. case 'A128GCMKW':
  98. case 'A192GCMKW':
  99. case 'A256GCMKW': {
  100. if (encryptedKey === undefined)
  101. throw new JWEInvalid('JWE Encrypted Key missing');
  102. if (typeof joseHeader.iv !== 'string')
  103. throw new JWEInvalid(`JOSE Header "iv" (Initialization Vector) missing or invalid`);
  104. if (typeof joseHeader.tag !== 'string')
  105. throw new JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`);
  106. let iv;
  107. try {
  108. iv = base64url(joseHeader.iv);
  109. }
  110. catch (_d) {
  111. throw new JWEInvalid('Failed to base64url decode the iv');
  112. }
  113. let tag;
  114. try {
  115. tag = base64url(joseHeader.tag);
  116. }
  117. catch (_e) {
  118. throw new JWEInvalid('Failed to base64url decode the tag');
  119. }
  120. return aesGcmKw(alg, key, encryptedKey, iv, tag);
  121. }
  122. default: {
  123. throw new JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value');
  124. }
  125. }
  126. }
  127. export default decryptKeyManagement;