UNPKG

tink-crypto

Version:

A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

107 lines 15.2 kB
/** * @license * Copyright 2023 Google LLC * SPDX-License-Identifier: Apache-2.0 */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { InvalidArgumentsException } from '../../../exception/invalid_arguments_exception'; import { SecurityException } from '../../../exception/security_exception'; import { PbHpkeKem } from '../../../internal/proto'; import { bytesAsU8 } from '../../../internal/proto_shims'; import { HybridDecrypt } from '../hybrid_decrypt'; import * as hpkeContext from './hpke_context'; import { HpkeKemKeyFactory } from './hpke_kem_key_factory'; import { HpkePrimitiveFactory } from './hpke_primitive_factory'; /** * Hybrid Public Key Encryption (HPKE) decryption. * * @final */ export class HpkeDecrypt extends HybridDecrypt { constructor(recipientPrivateKey, kem, kdf, aead, encapsulatedKeyLength) { super(); if (!recipientPrivateKey) { throw new InvalidArgumentsException('Recipient private key must be non-null.'); } if (!kem) { throw new InvalidArgumentsException('KEM algorithm must be non-null.'); } if (!kdf) { throw new InvalidArgumentsException('KDF algorithm must be non-null.'); } if (!aead) { throw new InvalidArgumentsException('AEAD algorithm must be non-null.'); } this.recipientPrivateKey = recipientPrivateKey; this.kem = kem; this.kdf = kdf; this.aead = aead; this.encapsulatedKeyLength = encapsulatedKeyLength; } /** * Returns the encapsulated key length (in bytes) for the specified * `kemProtoEnum`. This value corresponds to the 'Nenc' column in the following * table. * * <p>https://www.rfc-editor.org/rfc/rfc9180.html#name-key-encapsulation-mechanism. */ static encodingSizeInBytes(kemProtoEnum) { switch (kemProtoEnum) { case PbHpkeKem.DHKEM_P256_HKDF_SHA256: return 65; case PbHpkeKem.DHKEM_P521_HKDF_SHA512: return 133; default: throw new InvalidArgumentsException('Unable to determine KEM-encoding length'); } } /** * Returns an HPKE decryption primitive created from a given * recipientPrivateKey. */ static createHpkeDecrypt(recipientPrivateKey) { return __awaiter(this, void 0, void 0, function* () { if (bytesAsU8(recipientPrivateKey.getPrivateKey()).length === 0) { throw new InvalidArgumentsException('Recipient private key is empty.'); } const publicKey = recipientPrivateKey.getPublicKey(); if (!publicKey) { throw new InvalidArgumentsException('Recipient private key is missing public key field.'); } const params = publicKey.getParams(); if (!params) { throw new InvalidArgumentsException('Public key is missing params field.'); } const kem = HpkePrimitiveFactory.createKemFromParams(params); const kdf = HpkePrimitiveFactory.createKdfFromParams(params); const aead = HpkePrimitiveFactory.createAeadFromParams(params); const encapsulatedKeyLength = HpkeDecrypt.encodingSizeInBytes(params.getKem()); const recipientKemPrivateKey = yield HpkeKemKeyFactory.createPrivate(recipientPrivateKey); return new HpkeDecrypt(recipientKemPrivateKey, kem, kdf, aead, encapsulatedKeyLength); }); } decrypt(ciphertext, contextInfo) { return __awaiter(this, void 0, void 0, function* () { if (ciphertext.length <= this.encapsulatedKeyLength) { throw new SecurityException('Ciphertext is too short.'); } if (!contextInfo) { contextInfo = new Uint8Array(0); } const encapsulatedKey = ciphertext.slice(0, this.encapsulatedKeyLength); const aeadCiphertext = ciphertext.slice(this.encapsulatedKeyLength, ciphertext.length); const context = yield hpkeContext.createRecipientContext(encapsulatedKey, this.recipientPrivateKey, this.kem, this.kdf, this.aead, contextInfo); return context.open(aeadCiphertext, HpkeDecrypt.EMPTY_ASSOCIATED_DATA); }); } } HpkeDecrypt.EMPTY_ASSOCIATED_DATA = new Uint8Array(0); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHBrZV9kZWNyeXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vaHlicmlkL2ludGVybmFsL2hwa2UvaHBrZV9kZWNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7Ozs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUMseUJBQXlCLEVBQUMsTUFBTSxnREFBZ0QsQ0FBQztBQUN6RixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RSxPQUFPLEVBQUMsU0FBUyxFQUFrRCxNQUFNLHlCQUF5QixDQUFDO0FBQ25HLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUN4RCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFHaEQsT0FBTyxLQUFLLFdBQVcsTUFBTSxnQkFBZ0IsQ0FBQztBQUc5QyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUU5RDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFdBQVksU0FBUSxhQUFhO0lBUzVDLFlBQ0ksbUJBQXNDLEVBQUUsR0FBWSxFQUFFLEdBQVksRUFDbEUsSUFBYyxFQUFFLHFCQUE2QjtRQUMvQyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtZQUN4QixNQUFNLElBQUkseUJBQXlCLENBQy9CLHlDQUF5QyxDQUFDLENBQUM7U0FDaEQ7UUFDRCxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ1IsTUFBTSxJQUFJLHlCQUF5QixDQUFDLGlDQUFpQyxDQUFDLENBQUM7U0FDeEU7UUFDRCxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ1IsTUFBTSxJQUFJLHlCQUF5QixDQUFDLGlDQUFpQyxDQUFDLENBQUM7U0FDeEU7UUFDRCxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1Qs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RUFBRSxJQUFJLENBQUMsR0FBRyxFQUM3RCxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQzVCLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDekUsQ0FBQztLQUFBOztBQW5HdUIsaUNBQXFCLEdBQUcsSUFBSSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7SW52YWxpZEFyZ3VtZW50c0V4Y2VwdGlvbn0gZnJvbSAnLi4vLi4vLi4vZXhjZXB0aW9uL2ludmFsaWRfYXJndW1lbnRzX2V4Y2VwdGlvbic7XG5pbXBvcnQge1NlY3VyaXR5RXhjZXB0aW9ufSBmcm9tICcuLi8uLi8uLi9leGNlcHRpb24vc2VjdXJpdHlfZXhjZXB0aW9uJztcbmltcG9ydCB7UGJIcGtlS2VtLCBQYkhwa2VQYXJhbXMsIFBiSHBrZVByaXZhdGVLZXksIFBiSHBrZVB1YmxpY0tleX0gZnJvbSAnLi4vLi4vLi4vaW50ZXJuYWwvcHJvdG8nO1xuaW1wb3J0IHtieXRlc0FzVTh9IGZyb20gJy4uLy4uLy4uL2ludGVybmFsL3Byb3RvX3NoaW1zJztcbmltcG9ydCB7SHlicmlkRGVjcnlwdH0gZnJvbSAnLi4vaHlicmlkX2RlY3J5cHQnO1xuXG5pbXBvcnQge0hwa2VBZWFkfSBmcm9tICcuL2hwa2VfYWVhZCc7XG5pbXBvcnQgKiBhcyBocGtlQ29udGV4dCBmcm9tICcuL2hwa2VfY29udGV4dCc7XG5pbXBvcnQge0hwa2VLZGZ9IGZyb20gJy4vaHBrZV9rZGYnO1xuaW1wb3J0IHtIcGtlS2VtfSBmcm9tICcuL2hwa2Vfa2VtJztcbmltcG9ydCB7SHBrZUtlbUtleUZhY3Rvcnl9IGZyb20gJy4vaHBrZV9rZW1fa2V5X2ZhY3RvcnknO1xuaW1wb3J0IHtIcGtlS2VtUHJpdmF0ZUtleX0gZnJvbSAnLi9ocGtlX2tlbV9wcml2YXRlX2tleSc7XG5pbXBvcnQge0hwa2VQcmltaXRpdmVGYWN0b3J5fSBmcm9tICcuL2hwa2VfcHJpbWl0aXZlX2ZhY3RvcnknO1xuXG4vKipcbiAqIEh5YnJpZCBQdWJsaWMgS2V5IEVuY3J5cHRpb24gKEhQS0UpIGRlY3J5cHRpb24uXG4gKlxuICogQGZpbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBIcGtlRGVjcnlwdCBleHRlbmRzIEh5YnJpZERlY3J5cHQge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBFTVBUWV9BU1NPQ0lBVEVEX0RBVEEgPSBuZXcgVWludDhBcnJheSgwKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHJlY2lwaWVudFByaXZhdGVLZXk6IEhwa2VLZW1Qcml2YXRlS2V5O1xuICBwcml2YXRlIHJlYWRvbmx5IGtlbTogSHBrZUtlbTtcbiAgcHJpdmF0ZSByZWFkb25seSBrZGY6IEhwa2VLZGY7XG4gIHByaXZhdGUgcmVhZG9ubHkgYWVhZDogSHBrZUFlYWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5jYXBzdWxhdGVkS2V5TGVuZ3RoOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICByZWNpcGllbnRQcml2YXRlS2V5OiBIcGtlS2VtUHJpdmF0ZUtleSwga2VtOiBIcGtlS2VtLCBrZGY6IEhwa2VLZGYsXG4gICAgICBhZWFkOiBIcGtlQWVhZCwgZW5jYXBzdWxhdGVkS2V5TGVuZ3RoOiBudW1iZXIpIHtcbiAgICBzdXBlcigpO1xuICAgIGlmICghcmVjaXBpZW50UHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudHNFeGNlcHRpb24oXG4gICAgICAgICAgJ1JlY2lwaWVudCBwcml2YXRlIGtleSBtdXN0IGJlIG5vbi1udWxsLicpO1xuICAgIH1cbiAgICBpZiAoIWtlbSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudHNFeGNlcHRpb24oJ0tFTSBhbGdvcml0aG0gbXVzdCBiZSBub24tbnVsbC4nKTtcbiAgICB9XG4gICAgaWYgKCFrZGYpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRzRXhjZXB0aW9uKCdLREYgYWxnb3JpdGhtIG11c3QgYmUgbm9uLW51bGwuJyk7XG4gICAgfVxuICAgIGlmICghYWVhZCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudHNFeGNlcHRpb24oJ0FFQUQgYWxnb3JpdGhtIG11c3QgYmUgbm9uLW51bGwuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNpcGllbnRQcml2YXRlS2V5ID0gcmVjaXBpZW50UHJpdmF0ZUtleTtcbiAgICB0aGlzLmtlbSA9IGtlbTtcbiAgICB0aGlzLmtkZiA9IGtkZjtcbiAgICB0aGlzLmFlYWQgPSBhZWFkO1xuICAgIHRoaXMuZW5jYXBzdWxhdGVkS2V5TGVuZ3RoID0gZW5jYXBzdWxhdGVkS2V5TGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVuY2Fwc3VsYXRlZCBrZXkgbGVuZ3RoIChpbiBieXRlcykgZm9yIHRoZSBzcGVjaWZpZWRcbiAgICogYGtlbVByb3RvRW51bWAuIFRoaXMgdmFsdWUgY29ycmVzcG9uZHMgdG8gdGhlICdOZW5jJyBjb2x1bW4gaW4gdGhlIGZvbGxvd2luZ1xuICAgKiB0YWJsZS5cbiAgICpcbiAgICogPHA+aHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzkxODAuaHRtbCNuYW1lLWtleS1lbmNhcHN1bGF0aW9uLW1lY2hhbmlzbS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGVuY29kaW5nU2l6ZUluQnl0ZXMoa2VtUHJvdG9FbnVtOiBQYkhwa2VLZW0pIHtcbiAgICBzd2l0Y2ggKGtlbVByb3RvRW51bSkge1xuICAgICAgY2FzZSBQYkhwa2VLZW0uREhLRU1fUDI1Nl9IS0RGX1NIQTI1NjpcbiAgICAgICAgcmV0dXJuIDY1O1xuICAgICAgY2FzZSBQYkhwa2VLZW0uREhLRU1fUDUyMV9IS0RGX1NIQTUxMjpcbiAgICAgICAgcmV0dXJuIDEzMztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRzRXhjZXB0aW9uKFxuICAgICAgICAgICAgJ1VuYWJsZSB0byBkZXRlcm1pbmUgS0VNLWVuY29kaW5nIGxlbmd0aCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIEhQS0UgZGVjcnlwdGlvbiBwcmltaXRpdmUgY3JlYXRlZCBmcm9tIGEgZ2l2ZW5cbiAgICogcmVjaXBpZW50UHJpdmF0ZUtleS5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBjcmVhdGVIcGtlRGVjcnlwdChyZWNpcGllbnRQcml2YXRlS2V5OiBQYkhwa2VQcml2YXRlS2V5KSB7XG4gICAgaWYgKGJ5dGVzQXNVOChyZWNpcGllbnRQcml2YXRlS2V5LmdldFByaXZhdGVLZXkoKSkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50c0V4Y2VwdGlvbignUmVjaXBpZW50IHByaXZhdGUga2V5IGlzIGVtcHR5LicpO1xuICAgIH1cbiAgICBjb25zdCBwdWJsaWNLZXk6IFBiSHBrZVB1YmxpY0tleXx1bmRlZmluZWQgPVxuICAgICAgICByZWNpcGllbnRQcml2YXRlS2V5LmdldFB1YmxpY0tleSgpO1xuICAgIGlmICghcHVibGljS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50c0V4Y2VwdGlvbihcbiAgICAgICAgICAnUmVjaXBpZW50IHByaXZhdGUga2V5IGlzIG1pc3NpbmcgcHVibGljIGtleSBmaWVsZC4nKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zOiBQYkhwa2VQYXJhbXN8dW5kZWZpbmVkID0gcHVibGljS2V5LmdldFBhcmFtcygpO1xuICAgIGlmICghcGFyYW1zKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50c0V4Y2VwdGlvbihcbiAgICAgICAgICAnUHVibGljIGtleSBpcyBtaXNzaW5nIHBhcmFtcyBmaWVsZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZW06IEhwa2VLZW0gPSBIcGtlUHJpbWl0aXZlRmFjdG9yeS5jcmVhdGVLZW1Gcm9tUGFyYW1zKHBhcmFtcyk7XG4gICAgY29uc3Qga2RmOiBIcGtlS2RmID0gSHBrZVByaW1pdGl2ZUZhY3RvcnkuY3JlYXRlS2RmRnJvbVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IGFlYWQ6IEhwa2VBZWFkID0gSHBrZVByaW1pdGl2ZUZhY3RvcnkuY3JlYXRlQWVhZEZyb21QYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCBlbmNhcHN1bGF0ZWRLZXlMZW5ndGggPVxuICAgICAgICBIcGtlRGVjcnlwdC5lbmNvZGluZ1NpemVJbkJ5dGVzKHBhcmFtcy5nZXRLZW0oKSk7XG4gICAgY29uc3QgcmVjaXBpZW50S2VtUHJpdmF0ZUtleSA6IEhwa2VLZW1Qcml2YXRlS2V5ID1cbiAgICAgICAgYXdhaXQgSHBrZUtlbUtleUZhY3RvcnkuY3JlYXRlUHJpdmF0ZShyZWNpcGllbnRQcml2YXRlS2V5KTtcbiAgICByZXR1cm4gbmV3IEhwa2VEZWNyeXB0KFxuICAgICAgICByZWNpcGllbnRLZW1Qcml2YXRlS2V5LCBrZW0sIGtkZiwgYWVhZCwgZW5jYXBzdWxhdGVkS2V5TGVuZ3RoKTtcbiAgfVxuXG4gIGFzeW5jIGRlY3J5cHQoY2lwaGVydGV4dDogVWludDhBcnJheSwgY29udGV4dEluZm8/OiBVaW50OEFycmF5KSB7XG4gICAgaWYgKGNpcGhlcnRleHQubGVuZ3RoIDw9IHRoaXMuZW5jYXBzdWxhdGVkS2V5TGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ0NpcGhlcnRleHQgaXMgdG9vIHNob3J0LicpO1xuICAgIH1cblxuICAgIGlmICghY29udGV4dEluZm8pIHtcbiAgICAgIGNvbnRleHRJbmZvID0gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5jYXBzdWxhdGVkS2V5ID0gY2lwaGVydGV4dC5zbGljZSgwLCB0aGlzLmVuY2Fwc3VsYXRlZEtleUxlbmd0aCk7XG4gICAgY29uc3QgYWVhZENpcGhlcnRleHQgPVxuICAgICAgICBjaXBoZXJ0ZXh0LnNsaWNlKHRoaXMuZW5jYXBzdWxhdGVkS2V5TGVuZ3RoLCBjaXBoZXJ0ZXh0Lmxlbmd0aCk7XG4gICAgY29uc3QgY29udGV4dCA9IGF3YWl0IGhwa2VDb250ZXh0LmNyZWF0ZVJlY2lwaWVudENvbnRleHQoXG4gICAgICAgIGVuY2Fwc3VsYXRlZEtleSwgdGhpcy5yZWNpcGllbnRQcml2YXRlS2V5LCB0aGlzLmtlbSwgdGhpcy5rZGYsXG4gICAgICAgIHRoaXMuYWVhZCwgY29udGV4dEluZm8pO1xuICAgIHJldHVybiBjb250ZXh0Lm9wZW4oYWVhZENpcGhlcnRleHQsIEhwa2VEZWNyeXB0LkVNUFRZX0FTU09DSUFURURfREFUQSk7XG4gIH1cbn1cbiJdfQ==