diff options
author | tholenst <tholenst@google.com> | 2023-06-08 07:31:12 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-06-08 07:32:28 -0700 |
commit | 38c7e3866ea86fede15c2d721af91e218ab7ef3d (patch) | |
tree | 027bb9525e43ff45875ead25dd33fa96aa129df5 /tools | |
parent | f30e9cf3d7700d4f4be09580a95c21504827e32f (diff) | |
download | tink-38c7e3866ea86fede15c2d721af91e218ab7ef3d.tar.gz |
Add a TinkeyTestKmsClient and use it in the AddKeyCommandTest.
PiperOrigin-RevId: 538779637
Diffstat (limited to 'tools')
5 files changed, 252 insertions, 25 deletions
diff --git a/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/BUILD.bazel b/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/BUILD.bazel index 9d18f6e2d..bcb68f667 100644 --- a/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/BUILD.bazel +++ b/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/BUILD.bazel @@ -308,3 +308,27 @@ java_library( srcs = ["HelpCommand.java"], deps = [":command"], ) + +java_library( + name = "tinkey_test_kms_client", + testonly = 1, + srcs = ["TinkeyTestKmsClient.java"], + plugins = [":auto_service_plugin"], + deps = [ + "@maven//:com_google_auto_service_auto_service_annotations", + "@tink_java//src/main/java/com/google/crypto/tink:aead", + "@tink_java//src/main/java/com/google/crypto/tink:insecure_secret_key_access", + "@tink_java//src/main/java/com/google/crypto/tink:kms_client", + "@tink_java//src/main/java/com/google/crypto/tink:registry_cluster", + "@tink_java//src/main/java/com/google/crypto/tink:tink_json_proto_keyset_format", + ], +) + +java_plugin( + name = "auto_service_plugin", + processor_class = "com.google.auto.service.processor.AutoServiceProcessor", + deps = [ + "@maven//:com_google_auto_auto_common", + "@maven//:com_google_auto_service_auto_service", + ], +) diff --git a/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClient.java b/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClient.java new file mode 100644 index 000000000..63f215b9d --- /dev/null +++ b/tools/tinkey/src/main/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClient.java @@ -0,0 +1,100 @@ +// 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.tinkey; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.auto.service.AutoService; +import com.google.crypto.tink.Aead; +import com.google.crypto.tink.InsecureSecretKeyAccess; +import com.google.crypto.tink.KeysetHandle; +import com.google.crypto.tink.KmsClient; +import com.google.crypto.tink.TinkJsonProtoKeysetFormat; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.util.Arrays; + +/** + * A client for testing. + * + * <p>The client supports all key uris which start with "tinkey-test-kms-client://" followed by a + * JSON-encoded AEAD keyset. It will use this Aead when "getAead" is called. As credentials, it must + * be given a file which starts whose contents are "VALID CREDENTIALS". + */ +@AutoService(KmsClient.class) +public final class TinkeyTestKmsClient implements KmsClient { + + public TinkeyTestKmsClient() {} + + private static final String PREFIX = "tinkey-test-kms-client://"; + private static final String CREDENTIALS_FILE_CONTENTS = "VALID CREDENTIALS"; + + static String createKeyUri(KeysetHandle handle) throws GeneralSecurityException { + return PREFIX + + TinkJsonProtoKeysetFormat.serializeKeyset(handle, InsecureSecretKeyAccess.get()); + } + + static void createCredentialFile(Path path) throws IOException { + Files.write(path, CREDENTIALS_FILE_CONTENTS.getBytes(UTF_8)); + } + + private static String stripPrefix(String str) throws GeneralSecurityException { + if (!str.startsWith(PREFIX)) { + throw new GeneralSecurityException("Invalid key uri: " + str); + } + return str.substring(PREFIX.length()); + } + + @Override + public boolean doesSupport(String keyUri) { + return keyUri.startsWith(PREFIX); + } + + byte[] credentialFileContents = new byte[] {}; + + @Override + public KmsClient withCredentials(String credentials) throws GeneralSecurityException { + try { + credentialFileContents = Files.readAllBytes(Paths.get(credentials)); + return this; + } catch (IOException e) { + throw new GeneralSecurityException(e); + } + } + + @Override + public KmsClient withDefaultCredentials() throws GeneralSecurityException { + throw new GeneralSecurityException("TinkeyTestKmsClient has no default credentials"); + } + + private void checkCredentials() throws GeneralSecurityException { + if (!Arrays.equals(credentialFileContents, CREDENTIALS_FILE_CONTENTS.getBytes(UTF_8))) { + throw new GeneralSecurityException( + "Invalid credentials: " + Arrays.toString(credentialFileContents)); + } + } + + @Override + public Aead getAead(String keyUri) throws GeneralSecurityException { + checkCredentials(); + String keyset = stripPrefix(keyUri); + return TinkJsonProtoKeysetFormat.parseKeyset(keyset, InsecureSecretKeyAccess.get()) + .getPrimitive(Aead.class); + } +} diff --git a/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/AddKeyCommandTest.java b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/AddKeyCommandTest.java index e15bdcc0c..c4c07a845 100644 --- a/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/AddKeyCommandTest.java +++ b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/AddKeyCommandTest.java @@ -23,12 +23,12 @@ import static org.junit.Assert.assertThrows; import com.google.crypto.tink.Aead; import com.google.crypto.tink.InsecureSecretKeyAccess; import com.google.crypto.tink.KeysetHandle; -import com.google.crypto.tink.KmsClients; import com.google.crypto.tink.TinkJsonProtoKeysetFormat; import com.google.crypto.tink.TinkProtoKeysetFormat; +import com.google.crypto.tink.aead.AeadConfig; +import com.google.crypto.tink.aead.PredefinedAeadParameters; import com.google.crypto.tink.mac.MacConfig; import com.google.crypto.tink.mac.PredefinedMacParameters; -import com.google.crypto.tink.testing.TestUtil; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -42,6 +42,7 @@ import org.junit.runners.JUnit4; public class AddKeyCommandTest { @BeforeClass public static void setUp() throws Exception { + AeadConfig.register(); MacConfig.register(); } @@ -124,11 +125,13 @@ public class AddKeyCommandTest { Path path = Files.createTempDirectory(/* prefix= */ ""); Path inputFile = Paths.get(path.toString(), "input"); Path outputFile = Paths.get(path.toString(), "output"); + Path credentialFile = Paths.get(path.toString(), "credentials"); + TinkeyTestKmsClient.createCredentialFile(credentialFile); - Aead masterKeyAead = - KmsClients.getAutoLoaded(TestUtil.GCP_KMS_TEST_KEY_URI) - .withCredentials(TestUtil.SERVICE_ACCOUNT_FILE) - .getAead(TestUtil.GCP_KMS_TEST_KEY_URI); + KeysetHandle masterKeyAeadKeyset = + KeysetHandle.generateNew(PredefinedAeadParameters.AES128_GCM); + Aead masterKeyAead = masterKeyAeadKeyset.getPrimitive(Aead.class); + String masterKeyUri = TinkeyTestKmsClient.createKeyUri(masterKeyAeadKeyset); KeysetHandle inputKeyset = KeysetHandle.generateNew(PredefinedMacParameters.HMAC_SHA256_128BITTAG); @@ -150,9 +153,9 @@ public class AddKeyCommandTest { "--key-template", "HMAC_SHA256_256BITTAG", "--master-key-uri", - TestUtil.GCP_KMS_TEST_KEY_URI, + masterKeyUri, "--credential", - TestUtil.SERVICE_ACCOUNT_FILE + credentialFile.toString() }); KeysetHandle handle = @@ -172,11 +175,13 @@ public class AddKeyCommandTest { Path path = Files.createTempDirectory(/* prefix= */ ""); Path inputFile = Paths.get(path.toString(), "input"); Path outputFile = Paths.get(path.toString(), "output"); + Path credentialFile = Paths.get(path.toString(), "credentials"); + TinkeyTestKmsClient.createCredentialFile(credentialFile); - Aead masterKeyAead = - KmsClients.getAutoLoaded(TestUtil.GCP_KMS_TEST_KEY_URI) - .withCredentials(TestUtil.SERVICE_ACCOUNT_FILE) - .getAead(TestUtil.GCP_KMS_TEST_KEY_URI); + KeysetHandle masterKeyAeadKeyset = + KeysetHandle.generateNew(PredefinedAeadParameters.AES128_GCM); + Aead masterKeyAead = masterKeyAeadKeyset.getPrimitive(Aead.class); + String masterKeyUri = TinkeyTestKmsClient.createKeyUri(masterKeyAeadKeyset); KeysetHandle inputKeyset = KeysetHandle.generateNew(PredefinedMacParameters.HMAC_SHA256_128BITTAG); @@ -199,9 +204,9 @@ public class AddKeyCommandTest { "--key-template", "HMAC_SHA256_256BITTAG", "--master-key-uri", - TestUtil.GCP_KMS_TEST_KEY_URI, + masterKeyUri, "--credential", - TestUtil.SERVICE_ACCOUNT_FILE + credentialFile.toString() }); KeysetHandle handle = @@ -239,10 +244,6 @@ public class AddKeyCommandTest { "binary", "--key-template", "HMAC_SHA256_256BITTAG", - "--master-key-uri", - TestUtil.GCP_KMS_TEST_KEY_URI, - "--credential", - TestUtil.SERVICE_ACCOUNT_FILE })); } } diff --git a/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/BUILD.bazel b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/BUILD.bazel index 6eb2971ac..4b481ff4f 100644 --- a/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/BUILD.bazel +++ b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/BUILD.bazel @@ -61,25 +61,23 @@ java_test( name = "AddKeyCommandTest", size = "small", srcs = ["AddKeyCommandTest.java"], - data = ["//testdata/gcp:credentials"], - tags = [ - "manual", - "no_rbe", - "requires-network", + runtime_deps = [ + "//tinkey/src/main/java/com/google/crypto/tink/tinkey:tinkey_test_kms_client", ], deps = [ "//tinkey/src/main/java/com/google/crypto/tink/tinkey", + "//tinkey/src/main/java/com/google/crypto/tink/tinkey:tinkey_test_kms_client", "@maven//:com_google_truth_truth", "@maven//:junit_junit", "@tink_java//src/main/java/com/google/crypto/tink:aead", "@tink_java//src/main/java/com/google/crypto/tink:insecure_secret_key_access", - "@tink_java//src/main/java/com/google/crypto/tink:kms_clients", "@tink_java//src/main/java/com/google/crypto/tink:registry_cluster", "@tink_java//src/main/java/com/google/crypto/tink:tink_json_proto_keyset_format", "@tink_java//src/main/java/com/google/crypto/tink:tink_proto_keyset_format", + "@tink_java//src/main/java/com/google/crypto/tink/aead:aead_config", + "@tink_java//src/main/java/com/google/crypto/tink/aead:predefined_aead_parameters", "@tink_java//src/main/java/com/google/crypto/tink/mac:mac_config", "@tink_java//src/main/java/com/google/crypto/tink/mac:predefined_mac_parameters", - "@tink_java//src/main/java/com/google/crypto/tink/testing:test_util", ], ) @@ -108,3 +106,23 @@ java_test( "@tink_java//src/main/java/com/google/crypto/tink/testing:test_util", ], ) + +java_test( + name = "TinkeyTestKmsClientTest", + size = "small", + srcs = ["TinkeyTestKmsClientTest.java"], + runtime_deps = [ + "//tinkey/src/main/java/com/google/crypto/tink/tinkey:tinkey_test_kms_client", + ], + deps = [ + "//tinkey/src/main/java/com/google/crypto/tink/tinkey:tinkey_test_kms_client", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + "@tink_java//src/main/java/com/google/crypto/tink:aead", + "@tink_java//src/main/java/com/google/crypto/tink:kms_client", + "@tink_java//src/main/java/com/google/crypto/tink:kms_clients", + "@tink_java//src/main/java/com/google/crypto/tink:registry_cluster", + "@tink_java//src/main/java/com/google/crypto/tink/aead:aead_config", + "@tink_java//src/main/java/com/google/crypto/tink/aead:predefined_aead_parameters", + ], +) diff --git a/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClientTest.java b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClientTest.java new file mode 100644 index 000000000..cde78affb --- /dev/null +++ b/tools/tinkey/src/test/java/com/google/crypto/tink/tinkey/TinkeyTestKmsClientTest.java @@ -0,0 +1,84 @@ +// 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.tinkey; + +import static com.google.common.truth.Truth.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertThrows; + +import com.google.crypto.tink.Aead; +import com.google.crypto.tink.KeysetHandle; +import com.google.crypto.tink.KmsClient; +import com.google.crypto.tink.KmsClients; +import com.google.crypto.tink.aead.AeadConfig; +import com.google.crypto.tink.aead.PredefinedAeadParameters; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class TinkeyTestKmsClientTest { + @BeforeClass + public static void setUp() throws Exception { + AeadConfig.register(); + } + + @Test + public void test_clientCanBeLoadedWithCredential_works() throws Exception { + Path directory = Files.createTempDirectory(/* prefix= */ ""); + Path credentialPath = Paths.get(directory.toString(), "credentials"); + Files.write(credentialPath, "VALID CREDENTIALS".getBytes(UTF_8)); + + KeysetHandle handle = KeysetHandle.generateNew(PredefinedAeadParameters.AES128_GCM); + String masterKeyUri = TinkeyTestKmsClient.createKeyUri(handle); + Aead masterKey = + KmsClients.getAutoLoaded(masterKeyUri) + .withCredentials(credentialPath.toString()) + .getAead(masterKeyUri); + Aead manualMasterKey = handle.getPrimitive(Aead.class); + + byte[] ciphertext = manualMasterKey.encrypt(new byte[] {}, new byte[] {}); + assertThat(masterKey.decrypt(ciphertext, new byte[] {})).isEqualTo(new byte[] {}); + } + + @Test + public void test_clientCannotBeUsedWithWrongCredentials_throws() throws Exception { + Path directory = Files.createTempDirectory(/* prefix= */ ""); + Path credentialPath = Paths.get(directory.toString(), "credentials"); + Files.write(credentialPath, "these are not valid credentials".getBytes(UTF_8)); + + KeysetHandle handle = KeysetHandle.generateNew(PredefinedAeadParameters.AES128_GCM); + String masterKeyUri = TinkeyTestKmsClient.createKeyUri(handle); + KmsClient client = + KmsClients.getAutoLoaded(masterKeyUri).withCredentials(credentialPath.toString()); + assertThrows(GeneralSecurityException.class, () -> client.getAead(masterKeyUri)); + } + + @Test + public void test_clientCannotBeUsedWithoutCallingWithCredential_throws() throws Exception { + KeysetHandle handle = KeysetHandle.generateNew(PredefinedAeadParameters.AES128_GCM); + String masterKeyUri = TinkeyTestKmsClient.createKeyUri(handle); + KmsClient client = KmsClients.getAutoLoaded(masterKeyUri); + + assertThrows(GeneralSecurityException.class, () -> client.getAead(masterKeyUri)); + } +} |