UNPKG

@guarani/jose

Version:

Implementation of the RFCs of the JOSE Working Group.

106 lines (105 loc) 5.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonWebEncryption = void 0; const invalid_json_web_encryption_exception_1 = require("../exceptions/invalid-json-web-encryption.exception"); const jose_exception_1 = require("../exceptions/jose.exception"); const jsonwebencryption_keywrap_algorithms_registry_1 = require("./algorithms/alg/jsonwebencryption-keywrap-algorithms-registry"); const jsonwebencryption_contentencryption_algorithms_registry_1 = require("./algorithms/enc/jsonwebencryption-contentencryption-algorithms-registry"); const jsonwebencryption_compression_algorithms_registry_1 = require("./algorithms/zip/jsonwebencryption-compression-algorithms-registry"); const jsonwebencryption_header_1 = require("./jsonwebencryption.header"); /** * Implementation of {@link https://www.rfc-editor.org/rfc/rfc7516.html RFC 7516}. */ class JsonWebEncryption { /** * Instantiates a new JSON Web Encryption based on the provided JSON Web Encryption Header and Plaintext. * * @param header JSON Web Encryption Header. * @param plaintext Buffer to be used as the Plaintext. */ constructor(header, plaintext) { if (plaintext !== undefined && !Buffer.isBuffer(plaintext)) { throw new TypeError('Invalid JSON Web Encryption Plaintext.'); } this.header = new jsonwebencryption_header_1.JsonWebEncryptionHeader(header); this.plaintext = Buffer.isBuffer(plaintext) ? plaintext : Buffer.alloc(0); } /** * Decodes the provided JSON Web Encryption Token and returns its parsed Parameters. * * @param token JSON Web Encryption Token to be Decoded. * @returns Parsed Parameters of the JSON Web Encryption Token. */ static decodeCompact(token) { const splitToken = token.split('.'); if (splitToken.length !== 5) { throw new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException(); } const [b64Header, b64Ek, b64Iv, b64Ciphertext, b64Tag] = splitToken; const header = new jsonwebencryption_header_1.JsonWebEncryptionHeader(JSON.parse(Buffer.from(b64Header, 'base64url').toString('utf8'))); const ek = Buffer.from(b64Ek, 'base64url'); const iv = Buffer.from(b64Iv, 'base64url'); const ciphertext = Buffer.from(b64Ciphertext, 'base64url'); const tag = Buffer.from(b64Tag, 'base64url'); const aad = Buffer.from(b64Header, 'ascii'); return { aad, ciphertext, ek, header, iv, tag }; } /** * Deserializes a JSON Web Encryption Compact Token. * * @param token JSON Web Encryption Compact Token to be Deserialized. * @param key JSON Web Key used to Deserialize the JSON Web Encryption Compact Token. * @returns JSON Web Encryption containing the Deserialized JSON Web Encryption Header and Plaintext. */ static async deserializeCompact(token, key) { try { const { aad, ciphertext, ek, header, iv, tag } = this.decodeCompact(token); const alg = jsonwebencryption_keywrap_algorithms_registry_1.JSON_WEB_ENCRYPTION_KEY_WRAP_ALGORITHMS_REGISTRY[header.alg]; const enc = jsonwebencryption_contentencryption_algorithms_registry_1.JSON_WEB_ENCRYPTION_CONTENT_ENCRYPTION_ALGORITHMS_REGISTRY[header.enc]; const zip = header.zip !== undefined ? jsonwebencryption_compression_algorithms_registry_1.JSON_WEB_ENCRYPTION_COMPRESSION_ALGORITHMS_REGISTRY[header.zip] : null; const cek = await alg.unwrap(enc, key, ek, header); let plaintext = await enc.decrypt(ciphertext, aad, iv, tag, cek); if (zip !== null) { plaintext = await zip.decompress(plaintext); } return new JsonWebEncryption(header, plaintext); } catch (exc) { if (exc instanceof invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException) { throw exc; } throw exc instanceof jose_exception_1.JoseException ? new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException(exc) : new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException(null, exc); } } /** * Serializes the JSON Web Encryption into a Compact Token. * * @param key JSON Web Key used to Serialize the JSON Web Encryption. * @returns JSON Web Encryption Compact Token. */ async serializeCompact(key) { let { header, plaintext } = this; const alg = jsonwebencryption_keywrap_algorithms_registry_1.JSON_WEB_ENCRYPTION_KEY_WRAP_ALGORITHMS_REGISTRY[header.alg]; const enc = jsonwebencryption_contentencryption_algorithms_registry_1.JSON_WEB_ENCRYPTION_CONTENT_ENCRYPTION_ALGORITHMS_REGISTRY[header.enc]; const zip = header.zip !== undefined ? jsonwebencryption_compression_algorithms_registry_1.JSON_WEB_ENCRYPTION_COMPRESSION_ALGORITHMS_REGISTRY[header.zip] : null; const iv = await enc.generateInitializationVector(); const { cek, ek, additionalHeaderParams } = await alg.wrap(enc, key); if (additionalHeaderParams !== undefined) { Object.assign(header, additionalHeaderParams); } const b64Header = Buffer.from(JSON.stringify(header), 'utf8').toString('base64url'); const aad = Buffer.from(b64Header, 'ascii'); if (zip !== null) { plaintext = await zip.compress(plaintext); } const { ciphertext, tag } = await enc.encrypt(plaintext, aad, iv, cek); const b64Ek = ek.toString('base64url'); const b64Iv = iv.toString('base64url'); const b64Ciphertext = ciphertext.toString('base64url'); const b64Tag = tag.toString('base64url'); return `${b64Header}.${b64Ek}.${b64Iv}.${b64Ciphertext}.${b64Tag}`; } } exports.JsonWebEncryption = JsonWebEncryption;