mirror of
https://github.com/google/nomulus.git
synced 2025-05-17 09:57:17 +02:00
Wrap Kms decrypt with Retrier
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=154861871
This commit is contained in:
parent
7f2821cd7e
commit
5e7834b00e
3 changed files with 37 additions and 15 deletions
|
@ -27,7 +27,9 @@ import com.google.api.services.cloudkms.v1beta1.model.KeyRing;
|
||||||
import com.google.api.services.cloudkms.v1beta1.model.UpdateCryptoKeyPrimaryVersionRequest;
|
import com.google.api.services.cloudkms.v1beta1.model.UpdateCryptoKeyPrimaryVersionRequest;
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.keyring.api.KeyringException;
|
import google.registry.keyring.api.KeyringException;
|
||||||
|
import google.registry.util.Retrier;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/** The {@link KmsConnection} which talks to Cloud KMS. */
|
/** The {@link KmsConnection} which talks to Cloud KMS. */
|
||||||
|
@ -41,14 +43,17 @@ class KmsConnectionImpl implements KmsConnection {
|
||||||
private final CloudKMS kms;
|
private final CloudKMS kms;
|
||||||
private final String kmsKeyRingName;
|
private final String kmsKeyRingName;
|
||||||
private final String projectId;
|
private final String projectId;
|
||||||
|
private final Retrier retrier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
KmsConnectionImpl(
|
KmsConnectionImpl(
|
||||||
@Config("cloudKmsProjectId") String projectId,
|
@Config("cloudKmsProjectId") String projectId,
|
||||||
@Config("cloudKmsKeyRing") String kmsKeyringName,
|
@Config("cloudKmsKeyRing") String kmsKeyringName,
|
||||||
|
Retrier retrier,
|
||||||
CloudKMS kms) {
|
CloudKMS kms) {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
this.kmsKeyRingName = kmsKeyringName;
|
this.kmsKeyRingName = kmsKeyringName;
|
||||||
|
this.retrier = retrier;
|
||||||
this.kms = kms;
|
this.kms = kms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,23 +134,34 @@ class KmsConnectionImpl implements KmsConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] decrypt(String cryptoKeyName, String encodedCiphertext) {
|
public byte[] decrypt(final String cryptoKeyName, final String encodedCiphertext) {
|
||||||
try {
|
try {
|
||||||
return kms.projects()
|
return retrier.callWithRetry(
|
||||||
.locations()
|
new Callable<byte[]>() {
|
||||||
.keyRings()
|
@Override
|
||||||
.cryptoKeys()
|
public byte[] call() throws IOException {
|
||||||
.decrypt(
|
return attemptDecrypt(cryptoKeyName, encodedCiphertext);
|
||||||
getCryptoKeyName(projectId, kmsKeyRingName, cryptoKeyName),
|
}
|
||||||
new DecryptRequest().setCiphertext(encodedCiphertext))
|
},
|
||||||
.execute()
|
IOException.class);
|
||||||
.decodePlaintext();
|
} catch (RuntimeException e) {
|
||||||
} catch (IOException e) {
|
|
||||||
throw new KeyringException(
|
throw new KeyringException(
|
||||||
String.format("CloudKMS decrypt operation failed for secret %s", cryptoKeyName), e);
|
String.format("CloudKMS decrypt operation failed for secret %s", cryptoKeyName), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] attemptDecrypt(String cryptoKeyName, String encodedCiphertext) throws IOException{
|
||||||
|
return kms.projects()
|
||||||
|
.locations()
|
||||||
|
.keyRings()
|
||||||
|
.cryptoKeys()
|
||||||
|
.decrypt(
|
||||||
|
getCryptoKeyName(projectId, kmsKeyRingName, cryptoKeyName),
|
||||||
|
new DecryptRequest().setCiphertext(encodedCiphertext))
|
||||||
|
.execute()
|
||||||
|
.decodePlaintext();
|
||||||
|
}
|
||||||
|
|
||||||
private static String getLocationName(String projectId) {
|
private static String getLocationName(String projectId) {
|
||||||
return String.format(KMS_LOCATION_FORMAT, projectId);
|
return String.format(KMS_LOCATION_FORMAT, projectId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ java_library(
|
||||||
"//java/google/registry/keyring/api",
|
"//java/google/registry/keyring/api",
|
||||||
"//java/google/registry/keyring/kms",
|
"//java/google/registry/keyring/kms",
|
||||||
"//java/google/registry/model",
|
"//java/google/registry/model",
|
||||||
|
"//java/google/registry/util",
|
||||||
"//javatests/google/registry/testing",
|
"//javatests/google/registry/testing",
|
||||||
"//third_party/java/objectify:objectify-v4_1",
|
"//third_party/java/objectify:objectify-v4_1",
|
||||||
"@com_google_api_client",
|
"@com_google_api_client",
|
||||||
|
|
|
@ -34,6 +34,9 @@ import com.google.api.services.cloudkms.v1beta1.model.EncryptRequest;
|
||||||
import com.google.api.services.cloudkms.v1beta1.model.EncryptResponse;
|
import com.google.api.services.cloudkms.v1beta1.model.EncryptResponse;
|
||||||
import com.google.api.services.cloudkms.v1beta1.model.KeyRing;
|
import com.google.api.services.cloudkms.v1beta1.model.KeyRing;
|
||||||
import com.google.api.services.cloudkms.v1beta1.model.UpdateCryptoKeyPrimaryVersionRequest;
|
import com.google.api.services.cloudkms.v1beta1.model.UpdateCryptoKeyPrimaryVersionRequest;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.testing.FakeSleeper;
|
||||||
|
import google.registry.util.Retrier;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -69,6 +72,8 @@ public class KmsConnectionImplTest {
|
||||||
@Mock private CloudKMS.Projects.Locations.KeyRings.CryptoKeys.Encrypt kmsCryptoKeysEncrypt;
|
@Mock private CloudKMS.Projects.Locations.KeyRings.CryptoKeys.Encrypt kmsCryptoKeysEncrypt;
|
||||||
@Mock private CloudKMS.Projects.Locations.KeyRings.CryptoKeys.Decrypt kmsCryptoKeysDecrypt;
|
@Mock private CloudKMS.Projects.Locations.KeyRings.CryptoKeys.Decrypt kmsCryptoKeysDecrypt;
|
||||||
|
|
||||||
|
private final Retrier retrier = new Retrier(new FakeSleeper(new FakeClock()), 3);
|
||||||
|
|
||||||
@Captor private ArgumentCaptor<KeyRing> keyRing;
|
@Captor private ArgumentCaptor<KeyRing> keyRing;
|
||||||
@Captor private ArgumentCaptor<CryptoKey> cryptoKey;
|
@Captor private ArgumentCaptor<CryptoKey> cryptoKey;
|
||||||
@Captor private ArgumentCaptor<CryptoKeyVersion> cryptoKeyVersion;
|
@Captor private ArgumentCaptor<CryptoKeyVersion> cryptoKeyVersion;
|
||||||
|
@ -116,7 +121,7 @@ public class KmsConnectionImplTest {
|
||||||
public void test_encrypt_createsKeyRingIfNotFound() throws Exception {
|
public void test_encrypt_createsKeyRingIfNotFound() throws Exception {
|
||||||
when(kmsKeyRingsGet.execute()).thenThrow(createNotFoundException());
|
when(kmsKeyRingsGet.execute()).thenThrow(createNotFoundException());
|
||||||
|
|
||||||
new KmsConnectionImpl("foo", "bar", kms).encrypt("key", "moo".getBytes(UTF_8));
|
new KmsConnectionImpl("foo", "bar", retrier, kms).encrypt("key", "moo".getBytes(UTF_8));
|
||||||
|
|
||||||
verify(kmsKeyRings).create(locationName.capture(), keyRing.capture());
|
verify(kmsKeyRings).create(locationName.capture(), keyRing.capture());
|
||||||
assertThat(locationName.getValue()).isEqualTo("projects/foo/locations/global");
|
assertThat(locationName.getValue()).isEqualTo("projects/foo/locations/global");
|
||||||
|
@ -135,7 +140,7 @@ public class KmsConnectionImplTest {
|
||||||
public void test_encrypt_newCryptoKey() throws Exception {
|
public void test_encrypt_newCryptoKey() throws Exception {
|
||||||
when(kmsCryptoKeysGet.execute()).thenThrow(createNotFoundException());
|
when(kmsCryptoKeysGet.execute()).thenThrow(createNotFoundException());
|
||||||
|
|
||||||
new KmsConnectionImpl("foo", "bar", kms).encrypt("key", "moo".getBytes(UTF_8));
|
new KmsConnectionImpl("foo", "bar", retrier, kms).encrypt("key", "moo".getBytes(UTF_8));
|
||||||
|
|
||||||
verify(kmsCryptoKeys).create(keyRingName.capture(), cryptoKey.capture());
|
verify(kmsCryptoKeys).create(keyRingName.capture(), cryptoKey.capture());
|
||||||
assertThat(keyRingName.getValue()).isEqualTo("projects/foo/locations/global/keyRings/bar");
|
assertThat(keyRingName.getValue()).isEqualTo("projects/foo/locations/global/keyRings/bar");
|
||||||
|
@ -154,7 +159,7 @@ public class KmsConnectionImplTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_encrypt() throws Exception {
|
public void test_encrypt() throws Exception {
|
||||||
new KmsConnectionImpl("foo", "bar", kms).encrypt("key", "moo".getBytes(UTF_8));
|
new KmsConnectionImpl("foo", "bar", retrier, kms).encrypt("key", "moo".getBytes(UTF_8));
|
||||||
|
|
||||||
|
|
||||||
verify(kmsCryptoKeyVersions).create(cryptoKeyName.capture(), cryptoKeyVersion.capture());
|
verify(kmsCryptoKeyVersions).create(cryptoKeyName.capture(), cryptoKeyVersion.capture());
|
||||||
|
@ -182,7 +187,7 @@ public class KmsConnectionImplTest {
|
||||||
when(kmsCryptoKeysDecrypt.execute())
|
when(kmsCryptoKeysDecrypt.execute())
|
||||||
.thenReturn(new DecryptResponse().encodePlaintext("moo".getBytes(UTF_8)));
|
.thenReturn(new DecryptResponse().encodePlaintext("moo".getBytes(UTF_8)));
|
||||||
|
|
||||||
byte[] plaintext = new KmsConnectionImpl("foo", "bar", kms).decrypt("key", "blah");
|
byte[] plaintext = new KmsConnectionImpl("foo", "bar", retrier, kms).decrypt("key", "blah");
|
||||||
|
|
||||||
verify(kmsCryptoKeys).decrypt(cryptoKeyName.capture(), decryptRequest.capture());
|
verify(kmsCryptoKeys).decrypt(cryptoKeyName.capture(), decryptRequest.capture());
|
||||||
assertThat(cryptoKeyName.getValue())
|
assertThat(cryptoKeyName.getValue())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue