From e6791ff52e5ea0ca3f824cda06ff1e64279ae1c3 Mon Sep 17 00:00:00 2001 From: tholenst <tholenst@google.com> Date: Wed, 28 Aug 2019 01:29:15 -0700 Subject: [PATCH] Migrate the HmacKeyManager to a KeyTypeManager. PiperOrigin-RevId: 265859469 --- .../crypto/tink/mac/HmacKeyManager.java | 118 +++++++++--------- .../com/google/crypto/tink/mac/MacConfig.java | 4 +- .../crypto/tink/mac/MacKeyTemplates.java | 2 +- .../com/google/crypto/tink/RegistryTest.java | 6 +- .../crypto/tink/mac/HmacKeyManagerTest.java | 25 ++-- .../crypto/tink/mac/MacKeyTemplatesTest.java | 10 +- 6 files changed, 87 insertions(+), 78 deletions(-) diff --git a/java/src/main/java/com/google/crypto/tink/mac/HmacKeyManager.java b/java/src/main/java/com/google/crypto/tink/mac/HmacKeyManager.java index 12629712c..a7863a0bd 100644 --- a/java/src/main/java/com/google/crypto/tink/mac/HmacKeyManager.java +++ b/java/src/main/java/com/google/crypto/tink/mac/HmacKeyManager.java @@ -16,7 +16,7 @@ package com.google.crypto.tink.mac; -import com.google.crypto.tink.KeyManagerBase; +import com.google.crypto.tink.KeyTypeManager; import com.google.crypto.tink.Mac; import com.google.crypto.tink.proto.HashType; import com.google.crypto.tink.proto.HmacKey; @@ -34,51 +34,42 @@ import javax.crypto.spec.SecretKeySpec; /** * This key manager generates new {@code HmacKey} keys and produces new instances of {@code MacJce}. */ -class HmacKeyManager extends KeyManagerBase<Mac, HmacKey, HmacKeyFormat> { +class HmacKeyManager extends KeyTypeManager<HmacKey> { public HmacKeyManager() { - super(Mac.class, HmacKey.class, HmacKeyFormat.class, TYPE_URL); + super( + HmacKey.class, + new PrimitiveFactory<Mac, HmacKey>(Mac.class) { + @Override + public Mac getPrimitive(HmacKey key) throws GeneralSecurityException { + HashType hash = key.getParams().getHash(); + byte[] keyValue = key.getKeyValue().toByteArray(); + SecretKeySpec keySpec = new SecretKeySpec(keyValue, "HMAC"); + int tagSize = key.getParams().getTagSize(); + switch (hash) { + case SHA1: + return new MacJce("HMACSHA1", keySpec, tagSize); + case SHA256: + return new MacJce("HMACSHA256", keySpec, tagSize); + case SHA512: + return new MacJce("HMACSHA512", keySpec, tagSize); + default: + throw new GeneralSecurityException("unknown hash"); + } + } + }); } - /** Type url that this manager does support. */ - public static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.HmacKey"; - /** Current version of this key manager. Keys with version equal or smaller are supported. */ - private static final int VERSION = 0; + private static final int VERSION = 0; + /** Minimum key size in bytes. */ private static final int MIN_KEY_SIZE_IN_BYTES = 16; /** Minimum tag size in bytes. This provides minimum 80-bit security strength. */ private static final int MIN_TAG_SIZE_IN_BYTES = 10; - /** @param serializedKey serialized {@code HmacKey} proto */ @Override - public Mac getPrimitiveFromKey(HmacKey keyProto) throws GeneralSecurityException { - HashType hash = keyProto.getParams().getHash(); - byte[] keyValue = keyProto.getKeyValue().toByteArray(); - SecretKeySpec keySpec = new SecretKeySpec(keyValue, "HMAC"); - int tagSize = keyProto.getParams().getTagSize(); - switch (hash) { - case SHA1: - return new MacJce("HMACSHA1", keySpec, tagSize); - case SHA256: - return new MacJce("HMACSHA256", keySpec, tagSize); - case SHA512: - return new MacJce("HMACSHA512", keySpec, tagSize); - default: - throw new GeneralSecurityException("unknown hash"); - } - } - - /** - * @param serializedKeyFormat serialized {@code HmacKeyFormat} proto - * @return new {@code HmacKey} proto - */ - @Override - public HmacKey newKeyFromFormat(HmacKeyFormat format) throws GeneralSecurityException { - return HmacKey.newBuilder() - .setVersion(VERSION) - .setParams(format.getParams()) - .setKeyValue(ByteString.copyFrom(Random.randBytes(format.getKeySize()))) - .build(); + public String getKeyType() { + return "type.googleapis.com/google.crypto.tink.HmacKey"; } @Override @@ -87,40 +78,25 @@ class HmacKeyManager extends KeyManagerBase<Mac, HmacKey, HmacKeyFormat> { } @Override - protected KeyMaterialType keyMaterialType() { + public KeyMaterialType keyMaterialType() { return KeyMaterialType.SYMMETRIC; } @Override - protected HmacKey parseKeyProto(ByteString byteString) - throws InvalidProtocolBufferException { - return HmacKey.parseFrom(byteString); - } - - @Override - protected HmacKeyFormat parseKeyFormatProto(ByteString byteString) - throws InvalidProtocolBufferException { - return HmacKeyFormat.parseFrom(byteString); - } - - @Override - protected void validateKey(HmacKey key) throws GeneralSecurityException { + public void validateKey(HmacKey key) throws GeneralSecurityException { Validators.validateVersion(key.getVersion(), VERSION); if (key.getKeyValue().size() < MIN_KEY_SIZE_IN_BYTES) { throw new GeneralSecurityException("key too short"); } - validate(key.getParams()); + validateParams(key.getParams()); } @Override - protected void validateKeyFormat(HmacKeyFormat format) throws GeneralSecurityException { - if (format.getKeySize() < MIN_KEY_SIZE_IN_BYTES) { - throw new GeneralSecurityException("key too short"); - } - validate(format.getParams()); + public HmacKey parseKey(ByteString byteString) throws InvalidProtocolBufferException { + return HmacKey.parseFrom(byteString); } - private void validate(HmacParams params) throws GeneralSecurityException { + private static void validateParams(HmacParams params) throws GeneralSecurityException { if (params.getTagSize() < MIN_TAG_SIZE_IN_BYTES) { throw new GeneralSecurityException("tag size too small"); } @@ -144,4 +120,32 @@ class HmacKeyManager extends KeyManagerBase<Mac, HmacKey, HmacKeyFormat> { throw new GeneralSecurityException("unknown hash type"); } } + + @Override + public KeyFactory<HmacKeyFormat, HmacKey> keyFactory() { + return new KeyFactory<HmacKeyFormat, HmacKey>(HmacKeyFormat.class) { + @Override + public void validateKeyFormat(HmacKeyFormat format) throws GeneralSecurityException { + if (format.getKeySize() < MIN_KEY_SIZE_IN_BYTES) { + throw new GeneralSecurityException("key too short"); + } + validateParams(format.getParams()); + } + + @Override + public HmacKeyFormat parseKeyFormat(ByteString byteString) + throws InvalidProtocolBufferException { + return HmacKeyFormat.parseFrom(byteString); + } + + @Override + public HmacKey createKey(HmacKeyFormat format) throws GeneralSecurityException { + return HmacKey.newBuilder() + .setVersion(VERSION) + .setParams(format.getParams()) + .setKeyValue(ByteString.copyFrom(Random.randBytes(format.getKeySize()))) + .build(); + } + }; + } } diff --git a/java/src/main/java/com/google/crypto/tink/mac/MacConfig.java b/java/src/main/java/com/google/crypto/tink/mac/MacConfig.java index e02de636a..29fd052eb 100644 --- a/java/src/main/java/com/google/crypto/tink/mac/MacConfig.java +++ b/java/src/main/java/com/google/crypto/tink/mac/MacConfig.java @@ -35,7 +35,7 @@ import java.security.GeneralSecurityException; * @since 1.0.0 */ public final class MacConfig { - public static final String HMAC_TYPE_URL = HmacKeyManager.TYPE_URL; + public static final String HMAC_TYPE_URL = new HmacKeyManager().getKeyType(); /** @deprecated */ @Deprecated @@ -83,7 +83,7 @@ public final class MacConfig { * @since 1.2.0 */ public static void register() throws GeneralSecurityException { - Registry.registerKeyManager(new HmacKeyManager()); + Registry.registerKeyManager(new HmacKeyManager(), true); Registry.registerKeyManager(new AesCmacKeyManager(), true); Registry.registerPrimitiveWrapper(new MacWrapper()); } diff --git a/java/src/main/java/com/google/crypto/tink/mac/MacKeyTemplates.java b/java/src/main/java/com/google/crypto/tink/mac/MacKeyTemplates.java index 8e28f5a13..7bfeceafa 100644 --- a/java/src/main/java/com/google/crypto/tink/mac/MacKeyTemplates.java +++ b/java/src/main/java/com/google/crypto/tink/mac/MacKeyTemplates.java @@ -132,7 +132,7 @@ public final class MacKeyTemplates { .build(); return KeyTemplate.newBuilder() .setValue(format.toByteString()) - .setTypeUrl(HmacKeyManager.TYPE_URL) + .setTypeUrl(new HmacKeyManager().getKeyType()) .setOutputPrefixType(OutputPrefixType.TINK) .build(); } diff --git a/java/src/test/java/com/google/crypto/tink/RegistryTest.java b/java/src/test/java/com/google/crypto/tink/RegistryTest.java index 985cb66dc..0c16ab7dc 100644 --- a/java/src/test/java/com/google/crypto/tink/RegistryTest.java +++ b/java/src/test/java/com/google/crypto/tink/RegistryTest.java @@ -126,7 +126,7 @@ public class RegistryTest { public void testGetKeyManager_legacy_shouldWork() throws Exception { testGetKeyManager_shouldWork(AeadConfig.AES_CTR_HMAC_AEAD_TYPE_URL, "AesCtrHmacAeadKeyManager"); testGetKeyManager_shouldWork(AeadConfig.AES_EAX_TYPE_URL, "AesEaxKeyManager"); - testGetKeyManager_shouldWork(MacConfig.HMAC_TYPE_URL, "HmacKeyManager"); + testGetKeyManager_shouldWork(MacConfig.HMAC_TYPE_URL, "KeyManagerImpl"); } @Test @@ -139,7 +139,7 @@ public class RegistryTest { @Test public void testGetKeyManager_shouldWorkHmac() throws Exception { assertThat(Registry.getKeyManager(MacConfig.HMAC_TYPE_URL, Mac.class).getClass().toString()) - .contains("HmacKeyManager"); + .contains("KeyManagerImpl"); } @Test @@ -196,7 +196,7 @@ public class RegistryTest { @Test public void testGetUntypedKeyManager_shouldWorkHmac() throws Exception { assertThat(Registry.getUntypedKeyManager(MacConfig.HMAC_TYPE_URL).getClass().toString()) - .contains("HmacKeyManager"); + .contains("KeyManagerImpl"); } @Test diff --git a/java/src/test/java/com/google/crypto/tink/mac/HmacKeyManagerTest.java b/java/src/test/java/com/google/crypto/tink/mac/HmacKeyManagerTest.java index 69c78871b..fb1d28205 100644 --- a/java/src/test/java/com/google/crypto/tink/mac/HmacKeyManagerTest.java +++ b/java/src/test/java/com/google/crypto/tink/mac/HmacKeyManagerTest.java @@ -19,6 +19,9 @@ package com.google.crypto.tink.mac; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import com.google.crypto.tink.KeyManager; +import com.google.crypto.tink.KeyManagerImpl; +import com.google.crypto.tink.Mac; import com.google.crypto.tink.TestUtil; import com.google.crypto.tink.proto.HashType; import com.google.crypto.tink.proto.HmacKey; @@ -38,16 +41,17 @@ import org.junit.runners.JUnit4; public class HmacKeyManagerTest { @Test public void testNewKeyMultipleTimes() throws Exception { - HmacKeyManager keyManager = new HmacKeyManager(); + KeyManager<Mac> keyManager = new KeyManagerImpl<>(new HmacKeyManager(), Mac.class); HmacKeyFormat hmacKeyFormat = HmacKeyFormat.newBuilder() .setParams(HmacParams.newBuilder().setHash(HashType.SHA256).setTagSize(16).build()) .setKeySize(32) .build(); ByteString serialized = ByteString.copyFrom(hmacKeyFormat.toByteArray()); - KeyTemplate keyTemplate = KeyTemplate.newBuilder() - .setTypeUrl(HmacKeyManager.TYPE_URL) - .setValue(serialized) - .build(); + KeyTemplate keyTemplate = + KeyTemplate.newBuilder() + .setTypeUrl(new HmacKeyManager().getKeyType()) + .setValue(serialized) + .build(); // Calls newKey multiple times and make sure that we get different HmacKey each time. Set<String> keys = new TreeSet<String>(); int numTests = 27; @@ -69,12 +73,13 @@ public class HmacKeyManagerTest { @Test public void testNewKeyCorruptedFormat() throws Exception { - HmacKeyManager keyManager = new HmacKeyManager(); + KeyManager<Mac> keyManager = new KeyManagerImpl<>(new HmacKeyManager(), Mac.class); ByteString serialized = ByteString.copyFrom(new byte[128]); - KeyTemplate keyTemplate = KeyTemplate.newBuilder() - .setTypeUrl(HmacKeyManager.TYPE_URL) - .setValue(serialized) - .build(); + KeyTemplate keyTemplate = + KeyTemplate.newBuilder() + .setTypeUrl(new HmacKeyManager().getKeyType()) + .setValue(serialized) + .build(); try { keyManager.newKey(serialized); fail("Corrupted format, should have thrown exception"); diff --git a/java/src/test/java/com/google/crypto/tink/mac/MacKeyTemplatesTest.java b/java/src/test/java/com/google/crypto/tink/mac/MacKeyTemplatesTest.java index 97c1d2647..be6976391 100644 --- a/java/src/test/java/com/google/crypto/tink/mac/MacKeyTemplatesTest.java +++ b/java/src/test/java/com/google/crypto/tink/mac/MacKeyTemplatesTest.java @@ -32,7 +32,7 @@ public class MacKeyTemplatesTest { @Test public void testHMAC_SHA256_128BITTAG() throws Exception { KeyTemplate template = MacKeyTemplates.HMAC_SHA256_128BITTAG; - assertEquals(HmacKeyManager.TYPE_URL, template.getTypeUrl()); + assertEquals(new HmacKeyManager().getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); HmacKeyFormat format = HmacKeyFormat.parseFrom(template.getValue()); @@ -44,7 +44,7 @@ public class MacKeyTemplatesTest { @Test public void testHMAC_SHA256_256BITTAG() throws Exception { KeyTemplate template = MacKeyTemplates.HMAC_SHA256_256BITTAG; - assertEquals(HmacKeyManager.TYPE_URL, template.getTypeUrl()); + assertEquals(new HmacKeyManager().getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); HmacKeyFormat format = HmacKeyFormat.parseFrom(template.getValue()); @@ -56,7 +56,7 @@ public class MacKeyTemplatesTest { @Test public void testHMAC_SHA512_256BITTAG() throws Exception { KeyTemplate template = MacKeyTemplates.HMAC_SHA512_256BITTAG; - assertEquals(HmacKeyManager.TYPE_URL, template.getTypeUrl()); + assertEquals(new HmacKeyManager().getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); HmacKeyFormat format = HmacKeyFormat.parseFrom(template.getValue()); @@ -68,7 +68,7 @@ public class MacKeyTemplatesTest { @Test public void testHMAC_SHA512_512BITTAG() throws Exception { KeyTemplate template = MacKeyTemplates.HMAC_SHA512_512BITTAG; - assertEquals(HmacKeyManager.TYPE_URL, template.getTypeUrl()); + assertEquals(new HmacKeyManager().getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); HmacKeyFormat format = HmacKeyFormat.parseFrom(template.getValue()); @@ -85,7 +85,7 @@ public class MacKeyTemplatesTest { int tagSize = 24; HashType hashType = HashType.SHA512; KeyTemplate template = MacKeyTemplates.createHmacKeyTemplate(keySize, tagSize, hashType); - assertEquals(HmacKeyManager.TYPE_URL, template.getTypeUrl()); + assertEquals(new HmacKeyManager().getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); HmacKeyFormat format = HmacKeyFormat.parseFrom(template.getValue()); -- GitLab