| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| goog.module('tink.RegistryTest'); |
| goog.setTestOnly('tink.RegistryTest'); |
| |
| const Aead = goog.require('tink.Aead'); |
| const AeadConfig = goog.require('tink.aead.AeadConfig'); |
| const AeadKeyTemplates = goog.require('tink.aead.AeadKeyTemplates'); |
| const AesCtrHmacAeadKeyManager = goog.require('tink.aead.AesCtrHmacAeadKeyManager'); |
| const EncryptThenAuthenticate = goog.require('tink.subtle.EncryptThenAuthenticate'); |
| const HybridConfig = goog.require('tink.hybrid.HybridConfig'); |
| const HybridKeyTemplates = goog.require('tink.hybrid.HybridKeyTemplates'); |
| const KeyManager = goog.require('tink.KeyManager'); |
| const Mac = goog.require('tink.Mac'); |
| const PbAesCtrHmacAeadKey = goog.require('proto.google.crypto.tink.AesCtrHmacAeadKey'); |
| const PbAesCtrHmacAeadKeyFormat = goog.require('proto.google.crypto.tink.AesCtrHmacAeadKeyFormat'); |
| const PbAesCtrKey = goog.require('proto.google.crypto.tink.AesCtrKey'); |
| const PbAesCtrKeyFormat = goog.require('proto.google.crypto.tink.AesCtrKeyFormat'); |
| const PbAesCtrParams = goog.require('proto.google.crypto.tink.AesCtrParams'); |
| const PbEciesAeadHkdfPrivateKey = goog.require('proto.google.crypto.tink.EciesAeadHkdfPrivateKey'); |
| const PbEciesAeadHkdfPublicKey = goog.require('proto.google.crypto.tink.EciesAeadHkdfPublicKey'); |
| const PbHashType = goog.require('proto.google.crypto.tink.HashType'); |
| const PbHmacKeyFormat = goog.require('proto.google.crypto.tink.HmacKeyFormat'); |
| const PbHmacParams = goog.require('proto.google.crypto.tink.HmacParams'); |
| const PbKeyData = goog.require('proto.google.crypto.tink.KeyData'); |
| const PbKeyTemplate = goog.require('proto.google.crypto.tink.KeyTemplate'); |
| const PbMessage = goog.require('jspb.Message'); |
| const PrimitiveSet = goog.require('tink.PrimitiveSet'); |
| const Registry = goog.require('tink.Registry'); |
| const SecurityException = goog.require('tink.exception.SecurityException'); |
| const testSuite = goog.require('goog.testing.testSuite'); |
| const userAgent = goog.require('goog.userAgent'); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // tests |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| testSuite({ |
| async tearDown() { |
| Registry.reset(); |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for registerPrimitiveWrapper method |
| testRegisterPrimitiveWrapper_emptyManager() { |
| try { |
| Registry.registerPrimitiveWrapper(null); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| 'CustomError: primitive wrapper cannot be null', e.toString()); |
| } |
| }, |
| |
| testRegisterPrimitiveWrapper_overwritingWithSameClass() { |
| const primitive = 'somePrimitive'; |
| const primitiveType = 'somePrimitiveType'; |
| Registry.registerPrimitiveWrapper( |
| new DummyPrimitiveWrapper1(primitive, primitiveType)); |
| Registry.registerPrimitiveWrapper( |
| new DummyPrimitiveWrapper1(primitive, primitiveType)); |
| }, |
| |
| testRegisterPrimitiveWrapper_overwritingWithDifferentClass() { |
| const primitive = 'somePrimitive'; |
| const primitiveType = 'somePrimitiveType'; |
| Registry.registerPrimitiveWrapper( |
| new DummyPrimitiveWrapper1(primitive, primitiveType)); |
| try { |
| Registry.registerPrimitiveWrapper( |
| new DummyPrimitiveWrapper2(primitive, primitiveType)); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| 'CustomError: primitive wrapper for type ' + primitiveType + |
| ' has already been registered and cannot be overwritten', |
| e.toString()); |
| } |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for wrap method |
| testWrap_shouldWork() { |
| const primitive = 'somePrimitive'; |
| const primitiveType = 'somePrimitiveType'; |
| const numberOfKeyManagers = 10; |
| |
| for (let i = 0; i < numberOfKeyManagers; i++) { |
| Registry.registerPrimitiveWrapper(new DummyPrimitiveWrapper1( |
| primitive + i.toString(), primitiveType + i.toString())); |
| } |
| |
| let result; |
| for (let i = 0; i < numberOfKeyManagers; i++) { |
| result = Registry.wrap( |
| new PrimitiveSet.PrimitiveSet(primitiveType + i.toString())); |
| assertObjectEquals(primitive + i.toString(), result); |
| } |
| }, |
| |
| testWrap_notRegisteredPrimitiveType() { |
| const primitiveType = 'does not exist'; |
| |
| try { |
| Registry.wrap(new PrimitiveSet.PrimitiveSet(primitiveType)); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| 'CustomError: no primitive wrapper found for type ' + primitiveType, |
| e.toString()); |
| } |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for registerKeyManager method |
| testRegisterKeyManager_emptyManager() { |
| try { |
| Registry.registerKeyManager(null); |
| } catch (e) { |
| assertEquals(ExceptionText.nullKeyManager(), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| testRegisterKeyManager_overwritingAttempt() { |
| const keyType = 'someKeyType'; |
| |
| try { |
| Registry.registerKeyManager(new DummyKeyManager1(keyType)); |
| Registry.registerKeyManager(new DummyKeyManager2(keyType)); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.keyManagerOverwrittingAttempt(keyType), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| // Testing newKeyAllowed behavior -- should hold the most restrictive setting. |
| async testRegisterKeyManager_moreRestrictiveNewKeyAllowed() { |
| const keyType = 'someTypeUrl'; |
| const keyManager1 = new DummyKeyManager1(keyType); |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyType); |
| |
| //Register the key manager with new_key_allowed and test that it is possible |
| //to create a new key data. |
| Registry.registerKeyManager(keyManager1); |
| await Registry.newKeyData(keyTemplate); |
| |
| //Restrict the key manager and test that new key data cannot be created. |
| Registry.registerKeyManager(keyManager1, false); |
| try { |
| await Registry.newKeyData(keyTemplate); |
| } catch (e) { |
| assertEquals(ExceptionText.newKeyForbidden(keyType), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| async testRegisterKeyManager_lessRestrictiveNewKeyAllowed() { |
| const keyType = 'someTypeUrl'; |
| const keyManager1 = new DummyKeyManager1(keyType); |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyType); |
| |
| Registry.registerKeyManager(keyManager1, false); |
| |
| // Re-registering key manager with less restrictive setting should not be |
| // possible and the restriction has to be still true (i.e. new key data |
| // cannot be created). |
| try { |
| Registry.registerKeyManager(keyManager1); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.prohibitedChangeToLessRestricted( |
| keyManager1.getKeyType()), |
| e.toString()); |
| } |
| try { |
| await Registry.newKeyData(keyTemplate); |
| } catch (e) { |
| assertEquals(ExceptionText.newKeyForbidden(keyType), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for getKeyManager method |
| testGetKeyManager_shouldWork() { |
| const numberOfKeyManagers = 10; |
| let keyManagers1 = []; |
| let keyManagers2 = []; |
| |
| for (let i = 0; i < numberOfKeyManagers; i++) { |
| keyManagers1.push(new DummyKeyManager1('someKeyType' + i.toString())); |
| keyManagers2.push(new DummyKeyManager2('otherKeyType' + i.toString())); |
| |
| Registry.registerKeyManager(keyManagers1[i]); |
| Registry.registerKeyManager(keyManagers2[i]); |
| } |
| |
| let result; |
| for (let i = 0; i < numberOfKeyManagers; i++) { |
| result = Registry.getKeyManager(keyManagers1[i].getKeyType()); |
| assertObjectEquals(keyManagers1[i], result); |
| |
| result = Registry.getKeyManager(keyManagers2[i].getKeyType()); |
| assertObjectEquals(keyManagers2[i], result); |
| } |
| }, |
| |
| testGetKeyManager_notRegisteredKeyType() { |
| const keyType = 'some_key_type'; |
| |
| try { |
| Registry.getKeyManager(keyType); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.notRegisteredKeyType(keyType), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for newKeyData method |
| async testNewKeyData_noManagerForGivenKeyType() { |
| const keyManager1 = new DummyKeyManager1('someKeyType'); |
| const differentKeyType = 'otherKeyType'; |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(differentKeyType); |
| |
| Registry.registerKeyManager(keyManager1); |
| try { |
| await Registry.newKeyData(keyTemplate); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.notRegisteredKeyType(differentKeyType), |
| e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| async testNewKeyData_newKeyDisallowed() { |
| const keyManager1 = new DummyKeyManager1('someKeyType'); |
| const keyTemplate = |
| new PbKeyTemplate().setTypeUrl(keyManager1.getKeyType()); |
| |
| Registry.registerKeyManager(keyManager1, false); |
| try { |
| await Registry.newKeyData(keyTemplate); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.newKeyForbidden(keyManager1.getKeyType()), |
| e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| async testNewKeyData_newKeyAllowed() { |
| const /** Array<string> */ keyTypes = []; |
| for (let i = 0; i < 10; i++) { |
| keyTypes.push('someKeyType' + i.toString()); |
| } |
| |
| const keyTypesLength = keyTypes.length; |
| for (let i = 0; i < keyTypesLength; i++) { |
| Registry.registerKeyManager(new DummyKeyManager1(keyTypes[i]), true); |
| } |
| |
| for (let i = 0; i < keyTypesLength; i++) { |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyTypes[i]); |
| const result = await Registry.newKeyData(keyTemplate); |
| assertEquals(keyTypes[i], result.getTypeUrl()); |
| } |
| }, |
| |
| async testNewKeyData_newKeyIsAllowedAutomatically() { |
| const /** Array<string> */ keyTypes = []; |
| for (let i = 0; i < 10; i++) { |
| keyTypes.push('someKeyType' + i.toString()); |
| } |
| |
| const keyTypesLength = keyTypes.length; |
| for (let i = 0; i < keyTypesLength; i++) { |
| Registry.registerKeyManager(new DummyKeyManager1(keyTypes[i])); |
| } |
| |
| for (let i = 0; i < keyTypesLength; i++) { |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyTypes[i]); |
| const result = await Registry.newKeyData(keyTemplate); |
| assertEquals(keyTypes[i], result.getTypeUrl()); |
| } |
| }, |
| |
| async testNewKeyData_withAesCtrHmacAeadKey() { |
| const manager = new AesCtrHmacAeadKeyManager(); |
| Registry.registerKeyManager(manager); |
| const keyTemplate = createAesCtrHmacAeadTestKeyTemplate(); |
| const keyData = await Registry.newKeyData(keyTemplate); |
| |
| // Checks that correct AES CTR HMAC AEAD key was returned. |
| const keyFormat = |
| PbAesCtrHmacAeadKeyFormat.deserializeBinary(keyTemplate.getValue()); |
| const key = PbAesCtrHmacAeadKey.deserializeBinary(keyData.getValue()); |
| // Check AES CTR key. |
| assertEquals( |
| key.getAesCtrKey().getKeyValue().length, |
| keyFormat.getAesCtrKeyFormat().getKeySize()); |
| assertObjectEquals( |
| key.getAesCtrKey().getParams(), |
| keyFormat.getAesCtrKeyFormat().getParams()); |
| // Check HMAC key. |
| assertEquals( |
| key.getHmacKey().getKeyValue().length, |
| keyFormat.getHmacKeyFormat().getKeySize()); |
| assertObjectEquals( |
| key.getHmacKey().getParams(), keyFormat.getHmacKeyFormat().getParams()); |
| }, |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for newKey method |
| async testNewKey_noManagerForGivenKeyType() { |
| const notRegisteredKeyType = 'not_registered_key_type'; |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(notRegisteredKeyType); |
| |
| try { |
| await Registry.newKey(keyTemplate); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.notRegisteredKeyType(notRegisteredKeyType), |
| e.toString()); |
| } |
| }, |
| |
| async testNewKey_newKeyDisallowed() { |
| const keyManager = new DummyKeyManagerForNewKeyTests('someKeyType'); |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyManager.getKeyType()); |
| Registry.registerKeyManager(keyManager, /* opt_newKeyAllowed = */ false); |
| |
| try { |
| await Registry.newKey(keyTemplate); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.newKeyForbidden(keyManager.getKeyType()), e.toString()); |
| } |
| }, |
| |
| async testNewKey_shouldWork() { |
| const /** Array<string> */ keyTypes = []; |
| const /** Array<Uint8Array> */ newKeyMethodResult = []; |
| const keyTypesLength = 10; |
| |
| // Add some keys to Registry. |
| for (let i = 0; i < keyTypesLength; i++) { |
| keyTypes.push('someKeyType' + i.toString()); |
| newKeyMethodResult.push(new Uint8Array([i + 1])); |
| |
| Registry.registerKeyManager( |
| new DummyKeyManagerForNewKeyTests(keyTypes[i], newKeyMethodResult[i]), |
| /* newKeyAllowed = */ true); |
| } |
| |
| // For every keyType verify that it calls new key method of the |
| // corresponding KeyManager (KeyFactory). |
| for (let i = 0; i < keyTypesLength; i++) { |
| const keyTemplate = new PbKeyTemplate().setTypeUrl(keyTypes[i]); |
| |
| const key = |
| /** @type {!PbAesCtrKey} */ (await Registry.newKey(keyTemplate)); |
| |
| // The new key method of DummyKeyFactory returns an AesCtrKey which |
| // KeyValue is set to corresponding value in newKeyMethodResult. |
| assertEquals(newKeyMethodResult[i], key.getKeyValue()); |
| } |
| }, |
| |
| async testNewKey_withAesCtrHmacAeadKey() { |
| const manager = new AesCtrHmacAeadKeyManager(); |
| Registry.registerKeyManager(manager); |
| const keyTemplate = AeadKeyTemplates.aes256CtrHmacSha256(); |
| |
| const key = |
| /** @type{!PbAesCtrHmacAeadKey} */ (await Registry.newKey(keyTemplate)); |
| |
| // Checks that correct AES CTR HMAC AEAD key was returned. |
| const keyFormat = |
| PbAesCtrHmacAeadKeyFormat.deserializeBinary(keyTemplate.getValue()); |
| // Check AES CTR key. |
| assertEquals( |
| key.getAesCtrKey().getKeyValue().length, |
| keyFormat.getAesCtrKeyFormat().getKeySize()); |
| assertObjectEquals( |
| key.getAesCtrKey().getParams(), |
| keyFormat.getAesCtrKeyFormat().getParams()); |
| // Check HMAC key. |
| assertEquals( |
| key.getHmacKey().getKeyValue().length, |
| keyFormat.getHmacKeyFormat().getKeySize()); |
| assertObjectEquals( |
| key.getHmacKey().getParams(), keyFormat.getHmacKeyFormat().getParams()); |
| }, |
| |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // tests for getPrimitive method |
| async testGetPrimitive_differentKeyTypes() { |
| const keyDataType = 'key_data_key_type_url'; |
| const anotherType = 'another_key_type_url'; |
| const keyData = new PbKeyData().setTypeUrl(keyDataType); |
| |
| try { |
| await Registry.getPrimitive(null, keyData, anotherType); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.keyTypesAreNotMatching(keyDataType, anotherType), |
| e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| async testGetPrimitive_withoutDefiningKeyType() { |
| // Get primitive from key proto without key type. |
| try { |
| await Registry.getPrimitive(null, new PbMessage); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals(ExceptionText.keyTypeNotDefined(), e.toString()); |
| } |
| }, |
| |
| async testGetPrimitive_missingKeyManager() { |
| const keyDataType = 'key_data_key_type_url'; |
| const keyData = new PbKeyData().setTypeUrl(keyDataType); |
| |
| try { |
| await Registry.getPrimitive(null, keyData); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.notRegisteredKeyType(keyDataType), e.toString()); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| async testGetPrimitive_fromAesCtrHmacAeadKeyData() { |
| const manager = new AesCtrHmacAeadKeyManager(); |
| Registry.registerKeyManager(manager); |
| let keyTemplate = createAesCtrHmacAeadTestKeyTemplate(); |
| const keyData = await Registry.newKeyData(keyTemplate); |
| |
| const primitive = |
| await Registry.getPrimitive(manager.getPrimitiveType(), keyData); |
| assertTrue(primitive instanceof EncryptThenAuthenticate); |
| }, |
| |
| async testGetPrimitive_fromAesCtrHmacAeadKey() { |
| const manager = new AesCtrHmacAeadKeyManager(); |
| Registry.registerKeyManager(manager); |
| let keyTemplate = createAesCtrHmacAeadTestKeyTemplate(); |
| const keyData = await Registry.newKeyData(keyTemplate); |
| const key = PbAesCtrHmacAeadKey.deserializeBinary(keyData.getValue()); |
| |
| const primitive = await Registry.getPrimitive( |
| manager.getPrimitiveType(), key, keyData.getTypeUrl()); |
| assertTrue(primitive instanceof EncryptThenAuthenticate); |
| }, |
| |
| async testGetPrimitive_macFromAesCtrHmacAeadKey() { |
| const manager = new AesCtrHmacAeadKeyManager(); |
| Registry.registerKeyManager(manager); |
| let keyTemplate = createAesCtrHmacAeadTestKeyTemplate(); |
| const keyData = await Registry.newKeyData(keyTemplate); |
| const key = PbAesCtrHmacAeadKey.deserializeBinary(keyData.getValue()); |
| |
| try { |
| await Registry.getPrimitive(Mac, key, keyData.getTypeUrl()); |
| } catch (e) { |
| assertTrue( |
| e.toString().includes(ExceptionText.getPrimitiveBadPrimitive())); |
| return; |
| } |
| fail('An exception should be thrown.'); |
| }, |
| |
| testGetPublicKeyData: { |
| shouldRunTests() { |
| return !userAgent.EDGE; // b/120286783 |
| }, |
| |
| testNotPrivateKeyFactory() { |
| AeadConfig.register(); |
| const notPrivateTypeUrl = AeadConfig.AES_GCM_TYPE_URL; |
| try { |
| Registry.getPublicKeyData(notPrivateTypeUrl, new Uint8Array(8)); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals( |
| ExceptionText.notPrivateKeyFactory(notPrivateTypeUrl), |
| e.toString()); |
| } |
| }, |
| |
| testInvalidPrivateKeyProtoSerialization() { |
| HybridConfig.register(); |
| const typeUrl = HybridConfig.ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE; |
| try { |
| Registry.getPublicKeyData(typeUrl, new Uint8Array(10)); |
| fail('An exception should be thrown.'); |
| } catch (e) { |
| assertEquals(ExceptionText.couldNotParse(typeUrl), e.toString()); |
| } |
| }, |
| |
| async testShouldWork() { |
| HybridConfig.register(); |
| const privateKeyData = await Registry.newKeyData( |
| HybridKeyTemplates.eciesP256HkdfHmacSha256Aes128Gcm()); |
| const privateKey = PbEciesAeadHkdfPrivateKey.deserializeBinary( |
| privateKeyData.getValue()); |
| |
| const publicKeyData = Registry.getPublicKeyData( |
| privateKeyData.getTypeUrl(), privateKeyData.getValue_asU8()); |
| assertEquals( |
| publicKeyData.getTypeUrl(), |
| HybridConfig.ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE); |
| assertEquals( |
| publicKeyData.getKeyMaterialType(), |
| PbKeyData.KeyMaterialType.ASYMMETRIC_PUBLIC); |
| |
| const expectedPublicKey = privateKey.getPublicKey(); |
| const publicKey = PbEciesAeadHkdfPublicKey.deserializeBinary( |
| publicKeyData.getValue_asU8()); |
| assertObjectEquals(expectedPublicKey, publicKey); |
| }, |
| }, |
| }); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // helper functions and classes for tests |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Class which holds texts for each type of exception. |
| * @final |
| */ |
| class ExceptionText { |
| /** @return {string} */ |
| static notImplemented() { |
| return 'CustomError: Not implemented yet.'; |
| } |
| |
| /** |
| * @param {string} keyType |
| * |
| * @return {string} |
| */ |
| static newKeyForbidden(keyType) { |
| return 'CustomError: New key operation is forbidden for key type: ' + |
| keyType + '.'; |
| } |
| |
| /** |
| * @param {string} keyType |
| * |
| * @return {string} |
| */ |
| static notRegisteredKeyType(keyType) { |
| return 'CustomError: Key manager for key type ' + keyType + |
| ' has not been registered.'; |
| } |
| |
| /** |
| * @return {string} |
| */ |
| static nullKeyManager() { |
| return 'CustomError: Key manager cannot be null.'; |
| } |
| |
| /** |
| * @return {string} |
| */ |
| static undefinedKeyType() { |
| return 'CustomError: Key type has to be defined.'; |
| } |
| |
| /** |
| * @param {string} keyType |
| * |
| * @return {string} |
| */ |
| static keyManagerOverwrittingAttempt(keyType) { |
| return 'CustomError: Key manager for key type ' + keyType + |
| ' has already been registered and cannot be overwritten.'; |
| } |
| |
| /** |
| * @param {string} givenKeyType |
| * |
| * @return {string} |
| */ |
| static notSupportedKey(givenKeyType) { |
| return 'CustomError: The provided key manager does not support ' |
| + 'key type ' + givenKeyType + '.'; |
| } |
| |
| /** |
| * @param {string} keyType |
| * |
| * @return {string} |
| */ |
| static prohibitedChangeToLessRestricted(keyType) { |
| return 'CustomError: Key manager for key type ' + keyType + |
| ' has already been registered with forbidden new key operation.'; |
| } |
| |
| /** |
| * @param {string} keyTypeFromKeyData |
| * @param {string} keyTypeParam |
| * |
| * @return {string} |
| */ |
| static keyTypesAreNotMatching(keyTypeFromKeyData, keyTypeParam) { |
| return 'CustomError: Key type is ' + keyTypeParam + |
| ', but it is expected to be ' + keyTypeFromKeyData + ' or undefined.'; |
| } |
| |
| /** @return {string} */ |
| static keyTypeNotDefined() { |
| return 'CustomError: Key type has to be specified.'; |
| } |
| |
| /** @return {string} */ |
| static nullKeysetHandle() { |
| return 'CustomError: Keyset handle has to be non-null.'; |
| } |
| |
| /** |
| * @return {string} |
| */ |
| static getPrimitiveBadPrimitive() { |
| return 'Requested primitive type which is not supported by this ' + |
| 'key manager.'; |
| } |
| |
| /** |
| * @param {string} typeUrl |
| * @return {string} |
| */ |
| static notPrivateKeyFactory(typeUrl) { |
| return 'CustomError: Key manager for key type ' + typeUrl + |
| ' does not have a private key factory.'; |
| } |
| |
| /** |
| * @param {string} typeUrl |
| * @return {string} |
| */ |
| static couldNotParse(typeUrl) { |
| return 'CustomError: Input cannot be parsed as ' + typeUrl + ' key-proto.'; |
| } |
| } |
| |
| /** |
| * Creates AES CTR HMAC AEAD key format which can be used in tests |
| * |
| * @return {!PbKeyTemplate} |
| */ |
| const createAesCtrHmacAeadTestKeyTemplate = function() { |
| const KEY_SIZE = 16; |
| const IV_SIZE = 12; |
| const TAG_SIZE = 16; |
| |
| let keyFormat = new PbAesCtrHmacAeadKeyFormat().setAesCtrKeyFormat( |
| new PbAesCtrKeyFormat()); |
| keyFormat.getAesCtrKeyFormat().setKeySize(KEY_SIZE); |
| keyFormat.getAesCtrKeyFormat().setParams(new PbAesCtrParams()); |
| keyFormat.getAesCtrKeyFormat().getParams().setIvSize(IV_SIZE); |
| |
| // set HMAC key |
| keyFormat.setHmacKeyFormat(new PbHmacKeyFormat()); |
| keyFormat.getHmacKeyFormat().setKeySize(KEY_SIZE); |
| keyFormat.getHmacKeyFormat().setParams(new PbHmacParams()); |
| keyFormat.getHmacKeyFormat().getParams().setHash(PbHashType.SHA1); |
| keyFormat.getHmacKeyFormat().getParams().setTagSize(TAG_SIZE); |
| |
| let keyTemplate = |
| new PbKeyTemplate() |
| .setTypeUrl( |
| 'type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey') |
| .setValue(keyFormat.serializeBinary()); |
| return keyTemplate; |
| }; |
| |
| // Key factory and key manager classes used in tests |
| /** |
| * @final |
| * @implements {KeyManager.KeyFactory} |
| */ |
| class DummyKeyFactory { |
| /** |
| * @param {string} keyType |
| * @param {?Uint8Array=} opt_newKeyMethodResult |
| */ |
| constructor(keyType, opt_newKeyMethodResult) { |
| /** |
| * @const @private {string} |
| */ |
| this.KEY_TYPE_ = keyType; |
| |
| if (!opt_newKeyMethodResult) { |
| opt_newKeyMethodResult = new Uint8Array(10); |
| } |
| |
| /** |
| * @const @private {!Uint8Array} |
| */ |
| this.NEW_KEY_METHOD_RESULT_ = opt_newKeyMethodResult; |
| } |
| |
| /** |
| * @override |
| */ |
| newKey(keyFormat) { |
| const key = new PbAesCtrKey().setKeyValue(this.NEW_KEY_METHOD_RESULT_); |
| |
| return key; |
| } |
| |
| /** |
| * @override |
| */ |
| newKeyData(serializedKeyFormat) { |
| let keyData = |
| new PbKeyData() |
| .setTypeUrl(this.KEY_TYPE_) |
| .setValue(this.NEW_KEY_METHOD_RESULT_) |
| .setKeyMaterialType(PbKeyData.KeyMaterialType.UNKNOWN_KEYMATERIAL); |
| |
| return keyData; |
| } |
| } |
| |
| const DEFAULT_PRIMITIVE_TYPE = Aead; |
| |
| /** |
| * @final |
| * @implements {KeyManager.KeyManager<string>} |
| */ |
| class DummyKeyManager1 { |
| /** |
| * @param {string} keyType |
| * @param {?string=} opt_primitive |
| * @param {?Object=} opt_primitiveType |
| */ |
| constructor(keyType, opt_primitive, opt_primitiveType) { |
| /** |
| * @private @const {string} |
| */ |
| this.KEY_TYPE_ = keyType; |
| |
| if (!opt_primitive) { |
| opt_primitive = keyType; |
| } |
| /** |
| * @private @const {string} |
| */ |
| this.PRIMITIVE_ = opt_primitive; |
| /** |
| * @private @const {!KeyManager.KeyFactory} |
| */ |
| this.KEY_FACTORY_ = new DummyKeyFactory(keyType); |
| |
| if (!opt_primitiveType) { |
| opt_primitiveType = DEFAULT_PRIMITIVE_TYPE; |
| } |
| /** |
| * @private @const {!Object} |
| */ |
| this.PRIMITIVE_TYPE_ = opt_primitiveType; |
| } |
| |
| /** @override */ |
| async getPrimitive(primitiveType, key) { |
| if (primitiveType !== this.PRIMITIVE_TYPE_) { |
| throw new SecurityException( |
| 'Requested primitive type which is not ' + |
| 'supported by this key manager.'); |
| } |
| return this.PRIMITIVE_; |
| } |
| |
| /** @override */ |
| doesSupport(keyType) { |
| return keyType === this.getKeyType(); |
| } |
| |
| /** @override */ |
| getKeyType() { |
| return this.KEY_TYPE_; |
| } |
| |
| /** @override */ |
| getPrimitiveType() { |
| return this.PRIMITIVE_TYPE_; |
| } |
| |
| /** @override */ |
| getVersion() { |
| throw new SecurityException('Not implemented, only for testing purposes.'); |
| } |
| |
| /** @override */ |
| getKeyFactory() { |
| return this.KEY_FACTORY_; |
| } |
| } |
| |
| /** |
| * @final |
| * @implements {KeyManager.KeyManager<string>} |
| */ |
| class DummyKeyManager2 { |
| /** |
| * @param {string} keyType |
| * @param {string=} opt_primitive |
| * @param {?Object=} opt_primitiveType |
| */ |
| constructor(keyType, opt_primitive, opt_primitiveType) { |
| /** |
| * @private @const {string} |
| */ |
| this.KEY_TYPE_ = keyType; |
| |
| if (!opt_primitive) { |
| opt_primitive = keyType; |
| } |
| /** |
| * @private @const {string} |
| */ |
| this.PRIMITIVE_ = opt_primitive; |
| /** |
| * @private @const {!KeyManager.KeyFactory} |
| */ |
| this.KEY_FACTORY_ = new DummyKeyFactory(keyType); |
| |
| if (!opt_primitiveType) { |
| opt_primitiveType = DEFAULT_PRIMITIVE_TYPE; |
| } |
| /** |
| * @private @const {!Object} |
| */ |
| this.PRIMITIVE_TYPE_ = opt_primitiveType; |
| } |
| |
| /** @override */ |
| async getPrimitive(primitiveType, key) { |
| if (primitiveType !== this.PRIMITIVE_TYPE_) { |
| throw new SecurityException( |
| 'Requested primitive type which is not ' + |
| 'supported by this key manager.'); |
| } |
| return this.PRIMITIVE_; |
| } |
| |
| /** @override */ |
| doesSupport(keyType) { |
| return keyType === this.getKeyType(); |
| } |
| |
| /** @override */ |
| getKeyType() { |
| return this.KEY_TYPE_; |
| } |
| |
| /** @override */ |
| getPrimitiveType() { |
| return this.PRIMITIVE_TYPE_; |
| } |
| |
| /** @override */ |
| getVersion() { |
| throw new SecurityException('Not implemented, only for testing purposes.'); |
| } |
| |
| /** @override */ |
| getKeyFactory() { |
| return this.KEY_FACTORY_; |
| } |
| } |
| |
| /** |
| * @final |
| * @implements {KeyManager.KeyManager<string>} |
| */ |
| class DummyKeyManagerForNewKeyTests { |
| /** |
| * @param {string} keyType |
| * @param {?Uint8Array=} opt_newKeyMethodResult |
| */ |
| constructor(keyType, opt_newKeyMethodResult) { |
| /** |
| * @private @const {string} |
| */ |
| this.KEY_TYPE_ = keyType; |
| |
| /** |
| * @private @const {!KeyManager.KeyFactory} |
| */ |
| this.KEY_FACTORY_ = new DummyKeyFactory(keyType, opt_newKeyMethodResult); |
| } |
| |
| /** @override */ |
| async getPrimitive(primitiveType, key) { |
| throw new SecurityException('Not implemented, function is not needed.'); |
| } |
| |
| /** @override */ |
| doesSupport(keyType) { |
| return keyType === this.getKeyType(); |
| } |
| |
| /** @override */ |
| getKeyType() { |
| return this.KEY_TYPE_; |
| } |
| |
| /** @override */ |
| getPrimitiveType() { |
| throw new SecurityException('Not implemented, function is not needed.'); |
| } |
| |
| /** @override */ |
| getVersion() { |
| throw new SecurityException('Not implemented, function is not needed.'); |
| } |
| |
| /** @override */ |
| getKeyFactory() { |
| return this.KEY_FACTORY_; |
| } |
| } |
| |
| // PrimitiveWrapper classes for testing purposes |
| /** |
| * @final |
| * @implements {PrimitiveWrapper<string>} |
| */ |
| class DummyPrimitiveWrapper1 { |
| /** |
| * @param {string} primitive |
| * @param {!Object} primitiveType |
| */ |
| constructor(primitive, primitiveType) { |
| /** |
| * @private @const {string} |
| */ |
| this.PRIMITIVE_ = primitive; |
| |
| /** |
| * @private @const {!Object} |
| */ |
| this.PRIMITIVE_TYPE_ = primitiveType; |
| } |
| |
| /** |
| * @override |
| */ |
| wrap(primitiveSet) { |
| return this.PRIMITIVE_; |
| } |
| |
| /** |
| * @override |
| */ |
| getPrimitiveType() { |
| return this.PRIMITIVE_TYPE_; |
| } |
| } |
| |
| // PrimitiveWrapper classes for testing purposes |
| /** |
| * @final |
| * @implements {PrimitiveWrapper<string>} |
| */ |
| class DummyPrimitiveWrapper2 { |
| /** |
| * @param {string} primitive |
| * @param {!Object} primitiveType |
| */ |
| constructor(primitive, primitiveType) { |
| /** |
| * @private @const {string} |
| */ |
| this.PRIMITIVE_ = primitive; |
| |
| /** |
| * @private @const {!Object} |
| */ |
| this.PRIMITIVE_TYPE_ = primitiveType; |
| } |
| |
| /** |
| * @override |
| */ |
| wrap(primitiveSet) { |
| return this.PRIMITIVE_; |
| } |
| |
| /** |
| * @override |
| */ |
| getPrimitiveType() { |
| return this.PRIMITIVE_TYPE_; |
| } |
| } |