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.

149 lines (139 loc) 5.4 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import {Aead} from '../aead'; import {AeadConfig} from '../aead/aead_config'; import {SecurityException} from '../exception/security_exception'; import {PbAesCtrHmacAeadKey, PbAesCtrHmacAeadKeyFormat, PbAesGcmKey, PbAesGcmKeyFormat, PbKeyTemplate} from '../internal/proto'; import * as Registry from '../internal/registry'; import {EciesAeadHkdfDemHelper} from '../subtle/ecies_aead_hkdf_dem_helper'; /** * @final */ export class RegistryEciesAeadHkdfDemHelper implements EciesAeadHkdfDemHelper { private readonly key: PbAesCtrHmacAeadKey|PbAesGcmKey; private readonly demKeyTypeUrl: string; private readonly demKeySize: number; private readonly aesCtrKeySize?: number; constructor(keyTemplate: PbKeyTemplate) { let demKeySize: number; let aesCtrKeySize: number|undefined; let keyFormat: PbAesCtrHmacAeadKeyFormat|PbAesGcmKeyFormat; const keyTypeUrl = keyTemplate.getTypeUrl(); switch (keyTypeUrl) { case AeadConfig.AES_CTR_HMAC_AEAD_TYPE_URL: keyFormat = RegistryEciesAeadHkdfDemHelper.getAesCtrHmacKeyFormat(keyTemplate); const aesCtrKeyFormat = keyFormat.getAesCtrKeyFormat(); if (!aesCtrKeyFormat) { throw new SecurityException('AES-CTR key format not set'); } aesCtrKeySize = aesCtrKeyFormat.getKeySize(); const hmacKeyFormat = keyFormat.getHmacKeyFormat(); if (!hmacKeyFormat) { throw new SecurityException('HMAC key format not set'); } const hmacKeySize = hmacKeyFormat.getKeySize(); demKeySize = aesCtrKeySize + hmacKeySize; break; case AeadConfig.AES_GCM_TYPE_URL: keyFormat = RegistryEciesAeadHkdfDemHelper.getAesGcmKeyFormat(keyTemplate); demKeySize = keyFormat.getKeySize(); break; default: throw new SecurityException( 'Key type URL ' + keyTypeUrl + ' is not supported.'); } const keyFactory = Registry.getKeyManager(keyTypeUrl).getKeyFactory(); this.key = (keyFactory.newKey(keyFormat) as PbAesCtrHmacAeadKey | PbAesGcmKey); this.demKeyTypeUrl = keyTypeUrl; this.demKeySize = demKeySize; this.aesCtrKeySize = aesCtrKeySize; } /** */ getDemKeySizeInBytes() { return this.demKeySize; } /** */ async getAead(demKey: Uint8Array): Promise<Aead> { if (demKey.length !== this.demKeySize) { throw new SecurityException( `Key is not of the correct length, expected length: ${ this.demKeySize}, but got key of length: ${demKey.length}.`); } let key: PbAesCtrHmacAeadKey|PbAesGcmKey; if (this.demKeyTypeUrl === AeadConfig.AES_CTR_HMAC_AEAD_TYPE_URL) { key = this.replaceAesCtrHmacKeyValue(demKey); } else { key = this.replaceAesGcmKeyValue(demKey); } return Registry.getPrimitive<Aead>(Aead, key, this.demKeyTypeUrl); } private static getAesGcmKeyFormat(keyTemplate: PbKeyTemplate): PbAesGcmKeyFormat { let keyFormat: PbAesGcmKeyFormat; try { keyFormat = PbAesGcmKeyFormat.deserializeBinary(keyTemplate.getValue()); } catch (e) { throw new SecurityException( 'Could not parse the given Uint8Array as a serialized proto of ' + AeadConfig.AES_GCM_TYPE_URL + '.'); } if (!keyFormat.getKeySize()) { throw new SecurityException( 'Could not parse the given Uint8Array as a serialized proto of ' + AeadConfig.AES_GCM_TYPE_URL + '.'); } return keyFormat; } private static getAesCtrHmacKeyFormat(keyTemplate: PbKeyTemplate): PbAesCtrHmacAeadKeyFormat { let keyFormat: PbAesCtrHmacAeadKeyFormat; try { keyFormat = PbAesCtrHmacAeadKeyFormat.deserializeBinary(keyTemplate.getValue()); } catch (e) { throw new SecurityException( 'Could not parse the given Uint8Array ' + 'as a serialized proto of ' + AeadConfig.AES_CTR_HMAC_AEAD_TYPE_URL + '.'); } if (!keyFormat.getAesCtrKeyFormat() || !keyFormat.getHmacKeyFormat()) { throw new SecurityException( 'Could not parse the given Uint8Array as a serialized proto of ' + AeadConfig.AES_CTR_HMAC_AEAD_TYPE_URL + '.'); } return keyFormat; } private replaceAesGcmKeyValue(symmetricKey: Uint8Array): PbAesGcmKey { if (!(this.key instanceof PbAesGcmKey)) { throw new SecurityException('Key is not an AES-CTR key'); } const key = this.key.setKeyValue(symmetricKey); return key; } private replaceAesCtrHmacKeyValue(symmetricKey: Uint8Array): PbAesCtrHmacAeadKey { const key = (this.key as PbAesCtrHmacAeadKey); const aesCtrKey = key.getAesCtrKey(); if (!aesCtrKey) { throw new SecurityException('AES-CTR key not set'); } const aesCtrKeyValue = symmetricKey.slice(0, this.aesCtrKeySize); aesCtrKey.setKeyValue(aesCtrKeyValue); const hmacKey = key.getHmacKey(); if (!hmacKey) { throw new SecurityException('HMAC key not set'); } const hmacKeyValue = symmetricKey.slice(this.aesCtrKeySize, this.demKeySize); hmacKey.setKeyValue(hmacKeyValue); return key; } }