diff options
author | lizatretyakova <lizatretyakova@google.com> | 2023-07-27 04:20:43 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-07-27 04:22:28 -0700 |
commit | 5619d180beb60770a8d1de5372d503959471d885 (patch) | |
tree | ab1e0d46f205959132bce5e8b8a5ad80c9a59688 /java_src/src/test/java | |
parent | 2df7af936e4eaa2a37c0af67599f5bec7473e74c (diff) | |
download | tink-5619d180beb60770a8d1de5372d503959471d885.tar.gz |
Introduce end-to-end testing of LegacyFullMac, and fix problems uncovered by the new tests.
PiperOrigin-RevId: 551486832
Diffstat (limited to 'java_src/src/test/java')
3 files changed, 256 insertions, 2 deletions
diff --git a/java_src/src/test/java/com/google/crypto/tink/mac/internal/BUILD.bazel b/java_src/src/test/java/com/google/crypto/tink/mac/internal/BUILD.bazel index 7731ee4bf..993a7f9e9 100644 --- a/java_src/src/test/java/com/google/crypto/tink/mac/internal/BUILD.bazel +++ b/java_src/src/test/java/com/google/crypto/tink/mac/internal/BUILD.bazel @@ -73,10 +73,15 @@ java_test( deps = [ "//src/main/java/com/google/crypto/tink:insecure_secret_key_access", "//src/main/java/com/google/crypto/tink:mac", + "//src/main/java/com/google/crypto/tink:primitive_set", + "//src/main/java/com/google/crypto/tink:primitive_wrapper", "//src/main/java/com/google/crypto/tink/internal:legacy_proto_key", + "//src/main/java/com/google/crypto/tink/internal:mutable_primitive_registry", "//src/main/java/com/google/crypto/tink/internal:mutable_serialization_registry", + "//src/main/java/com/google/crypto/tink/internal:primitive_constructor", "//src/main/java/com/google/crypto/tink/internal:proto_key_serialization", "//src/main/java/com/google/crypto/tink/mac:hmac_key", + "//src/main/java/com/google/crypto/tink/mac/internal:hmac_proto_serialization", "//src/main/java/com/google/crypto/tink/mac/internal:hmac_test_util", "//src/main/java/com/google/crypto/tink/mac/internal:legacy_full_mac", "//src/main/java/com/google/crypto/tink/mac/internal:legacy_hmac_test_key_manager", @@ -109,3 +114,32 @@ java_test( "@maven//:junit_junit", ], ) + +java_test( + name = "LegacyFullMacIntegrationTest", + size = "small", + srcs = ["LegacyFullMacIntegrationTest.java"], + deps = [ + "//proto:common_java_proto", + "//proto:hmac_java_proto", + "//proto:tink_java_proto", + "//src/main/java/com/google/crypto/tink:cleartext_keyset_handle", + "//src/main/java/com/google/crypto/tink:insecure_secret_key_access", + "//src/main/java/com/google/crypto/tink:mac", + "//src/main/java/com/google/crypto/tink:primitive_set", + "//src/main/java/com/google/crypto/tink:primitive_wrapper", + "//src/main/java/com/google/crypto/tink:registry_cluster", + "//src/main/java/com/google/crypto/tink/internal:enum_type_proto_converter", + "//src/main/java/com/google/crypto/tink/internal:legacy_proto_key", + "//src/main/java/com/google/crypto/tink/internal:mutable_primitive_registry", + "//src/main/java/com/google/crypto/tink/internal:primitive_constructor", + "//src/main/java/com/google/crypto/tink/mac:hmac_key", + "//src/main/java/com/google/crypto/tink/mac:hmac_parameters", + "//src/main/java/com/google/crypto/tink/mac/internal:hmac_test_util", + "//src/main/java/com/google/crypto/tink/mac/internal:legacy_full_mac", + "//src/main/java/com/google/crypto/tink/mac/internal:legacy_hmac_test_key_manager", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) diff --git a/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacIntegrationTest.java b/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacIntegrationTest.java new file mode 100644 index 000000000..5578e307f --- /dev/null +++ b/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacIntegrationTest.java @@ -0,0 +1,187 @@ +// Copyright 2023 Google LLC +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// + +package com.google.crypto.tink.mac.internal; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.crypto.tink.CleartextKeysetHandle; +import com.google.crypto.tink.InsecureSecretKeyAccess; +import com.google.crypto.tink.KeysetHandle; +import com.google.crypto.tink.Mac; +import com.google.crypto.tink.PrimitiveSet; +import com.google.crypto.tink.PrimitiveWrapper; +import com.google.crypto.tink.internal.EnumTypeProtoConverter; +import com.google.crypto.tink.internal.LegacyProtoKey; +import com.google.crypto.tink.internal.MutablePrimitiveRegistry; +import com.google.crypto.tink.internal.PrimitiveConstructor; +import com.google.crypto.tink.mac.HmacKey; +import com.google.crypto.tink.mac.HmacParameters; +import com.google.crypto.tink.mac.internal.HmacTestUtil.HmacTestVector; +import com.google.crypto.tink.proto.HashType; +import com.google.crypto.tink.proto.HmacParams; +import com.google.crypto.tink.proto.KeyData; +import com.google.crypto.tink.proto.KeyData.KeyMaterialType; +import com.google.crypto.tink.proto.KeyStatusType; +import com.google.crypto.tink.proto.Keyset; +import com.google.crypto.tink.proto.OutputPrefixType; +import com.google.protobuf.ByteString; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.FromDataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +/** Verifies that LegacyFullMac is correctly integrated with the Tink ecosystem. */ +@RunWith(Theories.class) +public class LegacyFullMacIntegrationTest { + private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.HmacKey"; + private static final EnumTypeProtoConverter<OutputPrefixType, HmacParameters.Variant> + OUTPUT_PREFIX_TYPE_CONVERTER = + EnumTypeProtoConverter.<OutputPrefixType, HmacParameters.Variant>builder() + .add(OutputPrefixType.RAW, HmacParameters.Variant.NO_PREFIX) + .add(OutputPrefixType.TINK, HmacParameters.Variant.TINK) + .add(OutputPrefixType.LEGACY, HmacParameters.Variant.LEGACY) + .add(OutputPrefixType.CRUNCHY, HmacParameters.Variant.CRUNCHY) + .build(); + private static final EnumTypeProtoConverter<HashType, HmacParameters.HashType> + HASH_TYPE_CONVERTER = + EnumTypeProtoConverter.<HashType, HmacParameters.HashType>builder() + .add(HashType.SHA1, HmacParameters.HashType.SHA1) + .add(HashType.SHA224, HmacParameters.HashType.SHA224) + .add(HashType.SHA256, HmacParameters.HashType.SHA256) + .add(HashType.SHA384, HmacParameters.HashType.SHA384) + .add(HashType.SHA512, HmacParameters.HashType.SHA512) + .build(); + + @BeforeClass + public static void setUp() throws Exception { + LegacyHmacTestKeyManager.register(); + + hmacImplementationTestVectors = + Arrays.copyOf( + HmacTestUtil.HMAC_TEST_VECTORS, + HmacTestUtil.HMAC_TEST_VECTORS.length + HmacTestUtil.PREFIXED_KEY_TYPES.length); + System.arraycopy( + HmacTestUtil.PREFIXED_KEY_TYPES, + 0, + hmacImplementationTestVectors, + HmacTestUtil.HMAC_TEST_VECTORS.length, + HmacTestUtil.PREFIXED_KEY_TYPES.length); + } + + @DataPoints("allHmacTestVectors") + public static HmacTestVector[] hmacImplementationTestVectors; + + @Theory + public void endToEnd_works(@FromDataPoints("allHmacTestVectors") HmacTestVector t) + throws Exception { + MutablePrimitiveRegistry.resetGlobalInstanceTestOnly(); + MutablePrimitiveRegistry.globalInstance() + .registerPrimitiveConstructor( + PrimitiveConstructor.create( + LegacyFullMac::create, LegacyProtoKey.class, LegacyFullMac.class)); + TestLegacyMacWrapper.register(); + + KeysetHandle keysetHandle = getKeysetHandleFromKeyNoSerialization(t.key); + Mac mac = keysetHandle.getPrimitive(Mac.class); + + assertThat(mac).isInstanceOf(LegacyFullMac.class); + mac.verifyMac(t.tag, t.message); + } + + @Test + public void legacyFullMacNotRegistered_fails() throws Exception { + MutablePrimitiveRegistry.resetGlobalInstanceTestOnly(); + TestLegacyMacWrapper.register(); + + KeysetHandle keysetHandle = + getKeysetHandleFromKeyNoSerialization(hmacImplementationTestVectors[0].key); + + assertThrows(GeneralSecurityException.class, () -> keysetHandle.getPrimitive(Mac.class)); + } + + private static KeysetHandle getKeysetHandleFromKeyNoSerialization(HmacKey key) + throws GeneralSecurityException { + KeyData rawKeyData = + KeyData.newBuilder() + .setValue( + com.google.crypto.tink.proto.HmacKey.newBuilder() + .setParams( + HmacParams.newBuilder() + .setHash( + HASH_TYPE_CONVERTER.toProtoEnum(key.getParameters().getHashType())) + .setTagSize(key.getParameters().getCryptographicTagSizeBytes()) + .build()) + .setKeyValue( + ByteString.copyFrom( + key.getKeyBytes().toByteArray(InsecureSecretKeyAccess.get()))) + .build() + .toByteString()) + .setTypeUrl(TYPE_URL) + .setKeyMaterialType(KeyMaterialType.SYMMETRIC) + .build(); + int id = key.getIdRequirementOrNull() == null ? 42 : key.getIdRequirementOrNull(); + Keyset.Key rawKeysetKey = + Keyset.Key.newBuilder() + .setKeyData(rawKeyData) + .setStatus(KeyStatusType.ENABLED) + .setKeyId(id) + .setOutputPrefixType( + OUTPUT_PREFIX_TYPE_CONVERTER.toProtoEnum(key.getParameters().getVariant())) + .build(); + /* Here, a to-be-removed API (CleartextKeysetHandle) is used due to the need to create the + * KeysetHandle from a Keyset (and security is of no concern since it's a test). + * + * The other way to do this would be through registering only the serialization part of + * HmacProtoSerialization (without parsing), and then creating the KeysetHandle from the + * Key object -- however, this seems unnecessarily complicated since this test covers legacy + * functionality anyway. + */ + return CleartextKeysetHandle.fromKeyset( + Keyset.newBuilder().addKey(rawKeysetKey).setPrimaryKeyId(id).build()); + } + + private static final class TestLegacyMacWrapper implements PrimitiveWrapper<LegacyFullMac, Mac> { + static final TestLegacyMacWrapper WRAPPER = new TestLegacyMacWrapper(); + + @Override + public LegacyFullMac wrap(PrimitiveSet<LegacyFullMac> primitiveSet) + throws GeneralSecurityException { + // This is a dummy test wrapper that act as a proxy to a single primitive object under test. + return primitiveSet.getPrimary().getFullPrimitive(); + } + + @Override + public Class<Mac> getPrimitiveClass() { + return Mac.class; + } + + @Override + public Class<LegacyFullMac> getInputPrimitiveClass() { + return LegacyFullMac.class; + } + + static void register() throws GeneralSecurityException { + MutablePrimitiveRegistry.globalInstance().registerPrimitiveWrapper(WRAPPER); + } + } +} diff --git a/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacTest.java b/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacTest.java index d6730ba7b..9366353f1 100644 --- a/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacTest.java +++ b/java_src/src/test/java/com/google/crypto/tink/mac/internal/LegacyFullMacTest.java @@ -21,8 +21,12 @@ import static org.junit.Assert.assertThrows; import com.google.crypto.tink.InsecureSecretKeyAccess; import com.google.crypto.tink.Mac; +import com.google.crypto.tink.PrimitiveSet; +import com.google.crypto.tink.PrimitiveWrapper; import com.google.crypto.tink.internal.LegacyProtoKey; +import com.google.crypto.tink.internal.MutablePrimitiveRegistry; import com.google.crypto.tink.internal.MutableSerializationRegistry; +import com.google.crypto.tink.internal.PrimitiveConstructor; import com.google.crypto.tink.internal.ProtoKeySerialization; import com.google.crypto.tink.mac.HmacKey; import com.google.crypto.tink.mac.internal.HmacTestUtil.HmacTestVector; @@ -37,9 +41,16 @@ import org.junit.runner.RunWith; @RunWith(Theories.class) public class LegacyFullMacTest { + @BeforeClass public static void setUp() throws Exception { LegacyHmacTestKeyManager.register(); + HmacProtoSerialization.register(); + MutablePrimitiveRegistry.globalInstance() + .registerPrimitiveConstructor( + PrimitiveConstructor.create( + LegacyFullMac::create, LegacyProtoKey.class, LegacyFullMac.class)); + TestLegacyMacWrapper.register(); hmacImplementationTestVectors = Arrays.copyOf( @@ -57,8 +68,6 @@ public class LegacyFullMacTest { public static final HmacTestVector[] HMAC_FAILING_TEST_VECTORS = HmacTestUtil.CREATE_VERIFICATION_FAILS_FAST; - public static final String TYPE_URL = "LegacyHmacTestKey"; - @DataPoints("allHmacTestVectors") public static HmacTestVector[] hmacImplementationTestVectors; @@ -95,4 +104,28 @@ public class LegacyFullMacTest { .serializeKey(hmacKey, ProtoKeySerialization.class, InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get()); } + + private static final class TestLegacyMacWrapper implements PrimitiveWrapper<LegacyFullMac, Mac> { + static final TestLegacyMacWrapper WRAPPER = new TestLegacyMacWrapper(); + + @Override + public LegacyFullMac wrap(PrimitiveSet<LegacyFullMac> primitiveSet) + throws GeneralSecurityException { + return primitiveSet.getPrimary().getFullPrimitive(); + } + + @Override + public Class<Mac> getPrimitiveClass() { + return Mac.class; + } + + @Override + public Class<LegacyFullMac> getInputPrimitiveClass() { + return LegacyFullMac.class; + } + + static void register() throws GeneralSecurityException { + MutablePrimitiveRegistry.globalInstance().registerPrimitiveWrapper(WRAPPER); + } + } } |