UNPKG

@guarani/jose

Version:

Implementation of the RFCs of the JOSE Working Group.

111 lines (110 loc) 5.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonWebSignature = void 0; const invalid_json_web_key_exception_1 = require("../exceptions/invalid-json-web-key.exception"); const invalid_json_web_signature_exception_1 = require("../exceptions/invalid-json-web-signature.exception"); const jose_exception_1 = require("../exceptions/jose.exception"); const jsonwebkey_1 = require("../jwk/jsonwebkey"); const jsonwebsignature_algorithms_registry_1 = require("./algorithms/jsonwebsignature-algorithms-registry"); const jsonwebsignature_header_1 = require("./jsonwebsignature.header"); /** * Implementation of {@link https://www.rfc-editor.org/rfc/rfc7515.html RFC 7515}. */ class JsonWebSignature { /** * Instantiates a new JSON Web Signature based on the provided JSON Web Signature Header and Payload. * * @param header JSON Web Signature Header. * @param payload Buffer to be used as the Payload. */ constructor(header, payload) { if (payload !== undefined && !Buffer.isBuffer(payload)) { throw new TypeError('Invalid JSON Web Signature Payload.'); } this.header = new jsonwebsignature_header_1.JsonWebSignatureHeader(header); this.payload = Buffer.isBuffer(payload) ? payload : Buffer.alloc(0); } /** * Decodes the Parameters of the provided JSON Web Signature Compact Token. * * ***note: this method does not validate the signature of the token.*** * * @param token JSON Web Signature Compact Token to be decoded. * @returns Decoded Parameters of the JSON Web Signature Compact Token. */ static decodeCompact(token) { if (typeof token !== 'string') { throw new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(); } const splitToken = token.split('.'); if (splitToken.length !== 3) { throw new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(); } try { const [b64Header, b64Payload, b64Signature] = splitToken; const header = new jsonwebsignature_header_1.JsonWebSignatureHeader(JSON.parse(Buffer.from(b64Header, 'base64url').toString('utf8'))); const payload = Buffer.from(b64Payload, 'base64url'); const signature = Buffer.from(b64Signature, 'base64url'); return { header, payload, signature }; } catch (exc) { if (exc instanceof invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException) { throw exc; } throw exc instanceof jose_exception_1.JoseException ? new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(exc) : new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(null, exc); } } /** * Deserializes a JSON Web Signature Compact Token. * * @param token JSON Web Signature Compact Token to be Deserialized. * @param keyOrKeyLoader JSON Web Key or function used to load the JSON Web Key used to verify * the Signature of the JSON Web Signature Compact Token. * @returns JSON Web Signature containing the Deserialized JSON Web Signature Header and Payload. */ static async deserializeCompact(token, keyOrKeyLoader, expectedAlgorithms) { if (keyOrKeyLoader !== null && !(keyOrKeyLoader instanceof jsonwebkey_1.JsonWebKey) && typeof keyOrKeyLoader !== 'function') { throw new invalid_json_web_key_exception_1.InvalidJsonWebKeyException(); } const { header, payload, signature } = this.decodeCompact(token); const key = typeof keyOrKeyLoader === 'function' ? await keyOrKeyLoader(header) : keyOrKeyLoader; if (Array.isArray(expectedAlgorithms) && expectedAlgorithms.every((alg) => alg !== header.alg)) { throw new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(`The Algorithm "${header.alg}" does not match the expected Algorithms.`); } const b64Header = Buffer.from(header.toString(), 'utf8').toString('base64url'); const b64Payload = payload.toString('base64url'); const message = Buffer.from(`${b64Header}.${b64Payload}`, 'utf8'); const algorithm = jsonwebsignature_algorithms_registry_1.JSON_WEB_SIGNATURE_ALGORITHMS_REGISTRY[header.alg]; await algorithm.verify(signature, message, key ?? undefined); return new JsonWebSignature(header, payload); } /** * Serializes the JSON Web Signature into a Compact Token. * * @param key JSON Web Key used to Sign the JSON Web Signature Token. * @returns JSON Web Signature Compact Token. */ async serializeCompact(key) { const { header, payload } = this; try { const b64Header = Buffer.from(JSON.stringify(header), 'utf8').toString('base64url'); const b64Payload = payload.toString('base64url'); const message = Buffer.from(`${b64Header}.${b64Payload}`, 'utf8'); const algorithm = jsonwebsignature_algorithms_registry_1.JSON_WEB_SIGNATURE_ALGORITHMS_REGISTRY[header.alg]; const signature = await algorithm.sign(message, key); const b64Signature = signature.toString('base64url'); return `${message}.${b64Signature}`; } catch (exc) { if (exc instanceof invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException) { throw exc; } throw exc instanceof jose_exception_1.JoseException ? new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(exc) : new invalid_json_web_signature_exception_1.InvalidJsonWebSignatureException(null, exc); } } } exports.JsonWebSignature = JsonWebSignature;