UNPKG

pooja-docucomb-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.

101 lines (92 loc) 3.4 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import {SecurityException} from '../exception/security_exception'; import {CryptoFormat} from '../internal/crypto_format'; import * as PrimitiveSet from '../internal/primitive_set'; import {PrimitiveWrapper} from '../internal/primitive_wrapper'; import {PbKeyStatusType} from '../internal/proto'; import {HybridDecrypt} from './internal/hybrid_decrypt'; /** * @final */ class WrappedHybridDecrypt extends HybridDecrypt { // The constructor should be @private, but it is not supported by Closure // (see https://github.com/google/closure-compiler/issues/2761). constructor(private readonly hybridDecryptPrimitiveSet: PrimitiveSet.PrimitiveSet<HybridDecrypt>) { super(); } static newHybridDecrypt(hybridDecryptPrimitiveSet: PrimitiveSet.PrimitiveSet<HybridDecrypt>): HybridDecrypt { if (!hybridDecryptPrimitiveSet) { throw new SecurityException('Primitive set has to be non-null.'); } return new WrappedHybridDecrypt(hybridDecryptPrimitiveSet); } async decrypt(ciphertext: Uint8Array, opt_contextInfo?: Uint8Array) { if (!ciphertext) { throw new SecurityException('Ciphertext has to be non-null.'); } if (ciphertext.length > CryptoFormat.NON_RAW_PREFIX_SIZE) { const keyId = ciphertext.subarray(0, CryptoFormat.NON_RAW_PREFIX_SIZE); const primitives = await this.hybridDecryptPrimitiveSet.getPrimitives(keyId); const rawCiphertext = ciphertext.subarray( CryptoFormat.NON_RAW_PREFIX_SIZE, ciphertext.length); let decryptedText: Uint8Array|undefined; try { decryptedText = await this.tryDecryption( primitives, rawCiphertext, opt_contextInfo); } catch (e) { } if (decryptedText) { return decryptedText; } } const primitives = await this.hybridDecryptPrimitiveSet.getRawPrimitives(); return this.tryDecryption(primitives, ciphertext, opt_contextInfo); } /** * Tries to decrypt the ciphertext using each entry in primitives and * returns the ciphertext decrypted by first primitive which succeed. It * throws an exception if no entry succeeds. * * */ private async tryDecryption( primitives: Array<PrimitiveSet.Entry<HybridDecrypt>>, ciphertext: Uint8Array, opt_contextInfo?: Uint8Array|null): Promise<Uint8Array> { const primitivesLength = primitives.length; for (let i = 0; i < primitivesLength; i++) { if (primitives[i].getKeyStatus() != PbKeyStatusType.ENABLED) { continue; } const primitive = primitives[i].getPrimitive(); let decryptionResult; try { decryptionResult = await primitive.decrypt(ciphertext, opt_contextInfo); } catch (e) { continue; } return decryptionResult; } throw new SecurityException('Decryption failed for the given ciphertext.'); } } export class HybridDecryptWrapper implements PrimitiveWrapper<HybridDecrypt> { /** */ wrap(primitiveSet: PrimitiveSet.PrimitiveSet<HybridDecrypt>) { return WrappedHybridDecrypt.newHybridDecrypt(primitiveSet); } /** */ getPrimitiveType() { return HybridDecrypt; } }