verify.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.flattenedVerify = void 0;
  4. const base64url_js_1 = require("../../runtime/base64url.js");
  5. const verify_js_1 = require("../../runtime/verify.js");
  6. const errors_js_1 = require("../../util/errors.js");
  7. const buffer_utils_js_1 = require("../../lib/buffer_utils.js");
  8. const is_disjoint_js_1 = require("../../lib/is_disjoint.js");
  9. const is_object_js_1 = require("../../lib/is_object.js");
  10. const check_key_type_js_1 = require("../../lib/check_key_type.js");
  11. const validate_crit_js_1 = require("../../lib/validate_crit.js");
  12. const validate_algorithms_js_1 = require("../../lib/validate_algorithms.js");
  13. async function flattenedVerify(jws, key, options) {
  14. var _a;
  15. if (!(0, is_object_js_1.default)(jws)) {
  16. throw new errors_js_1.JWSInvalid('Flattened JWS must be an object');
  17. }
  18. if (jws.protected === undefined && jws.header === undefined) {
  19. throw new errors_js_1.JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
  20. }
  21. if (jws.protected !== undefined && typeof jws.protected !== 'string') {
  22. throw new errors_js_1.JWSInvalid('JWS Protected Header incorrect type');
  23. }
  24. if (jws.payload === undefined) {
  25. throw new errors_js_1.JWSInvalid('JWS Payload missing');
  26. }
  27. if (typeof jws.signature !== 'string') {
  28. throw new errors_js_1.JWSInvalid('JWS Signature missing or incorrect type');
  29. }
  30. if (jws.header !== undefined && !(0, is_object_js_1.default)(jws.header)) {
  31. throw new errors_js_1.JWSInvalid('JWS Unprotected Header incorrect type');
  32. }
  33. let parsedProt = {};
  34. if (jws.protected) {
  35. try {
  36. const protectedHeader = (0, base64url_js_1.decode)(jws.protected);
  37. parsedProt = JSON.parse(buffer_utils_js_1.decoder.decode(protectedHeader));
  38. }
  39. catch {
  40. throw new errors_js_1.JWSInvalid('JWS Protected Header is invalid');
  41. }
  42. }
  43. if (!(0, is_disjoint_js_1.default)(parsedProt, jws.header)) {
  44. throw new errors_js_1.JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
  45. }
  46. const joseHeader = {
  47. ...parsedProt,
  48. ...jws.header,
  49. };
  50. const extensions = (0, validate_crit_js_1.default)(errors_js_1.JWSInvalid, new Map([['b64', true]]), options === null || options === void 0 ? void 0 : options.crit, parsedProt, joseHeader);
  51. let b64 = true;
  52. if (extensions.has('b64')) {
  53. b64 = parsedProt.b64;
  54. if (typeof b64 !== 'boolean') {
  55. throw new errors_js_1.JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
  56. }
  57. }
  58. const { alg } = joseHeader;
  59. if (typeof alg !== 'string' || !alg) {
  60. throw new errors_js_1.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
  61. }
  62. const algorithms = options && (0, validate_algorithms_js_1.default)('algorithms', options.algorithms);
  63. if (algorithms && !algorithms.has(alg)) {
  64. throw new errors_js_1.JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed');
  65. }
  66. if (b64) {
  67. if (typeof jws.payload !== 'string') {
  68. throw new errors_js_1.JWSInvalid('JWS Payload must be a string');
  69. }
  70. }
  71. else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {
  72. throw new errors_js_1.JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
  73. }
  74. let resolvedKey = false;
  75. if (typeof key === 'function') {
  76. key = await key(parsedProt, jws);
  77. resolvedKey = true;
  78. }
  79. (0, check_key_type_js_1.default)(alg, key, 'verify');
  80. const data = (0, buffer_utils_js_1.concat)(buffer_utils_js_1.encoder.encode((_a = jws.protected) !== null && _a !== void 0 ? _a : ''), buffer_utils_js_1.encoder.encode('.'), typeof jws.payload === 'string' ? buffer_utils_js_1.encoder.encode(jws.payload) : jws.payload);
  81. let signature;
  82. try {
  83. signature = (0, base64url_js_1.decode)(jws.signature);
  84. }
  85. catch {
  86. throw new errors_js_1.JWSInvalid('Failed to base64url decode the signature');
  87. }
  88. const verified = await (0, verify_js_1.default)(alg, key, signature, data);
  89. if (!verified) {
  90. throw new errors_js_1.JWSSignatureVerificationFailed();
  91. }
  92. let payload;
  93. if (b64) {
  94. try {
  95. payload = (0, base64url_js_1.decode)(jws.payload);
  96. }
  97. catch {
  98. throw new errors_js_1.JWSInvalid('Failed to base64url decode the payload');
  99. }
  100. }
  101. else if (typeof jws.payload === 'string') {
  102. payload = buffer_utils_js_1.encoder.encode(jws.payload);
  103. }
  104. else {
  105. payload = jws.payload;
  106. }
  107. const result = { payload };
  108. if (jws.protected !== undefined) {
  109. result.protectedHeader = parsedProt;
  110. }
  111. if (jws.header !== undefined) {
  112. result.unprotectedHeader = jws.header;
  113. }
  114. if (resolvedKey) {
  115. return { ...result, key };
  116. }
  117. return result;
  118. }
  119. exports.flattenedVerify = flattenedVerify;