@guarani/jose
Version:
Implementation of the RFCs of the JOSE Working Group.
111 lines (110 loc) • 5.91 kB
JavaScript
;
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;