diff --git a/DynamoDbEncryption/runtimes/net/DynamoDbEncryption.sln b/DynamoDbEncryption/runtimes/net/DynamoDbEncryption.sln
deleted file mode 100644
index bc8ce2d2e..000000000
--- a/DynamoDbEncryption/runtimes/net/DynamoDbEncryption.sln
+++ /dev/null
@@ -1,16 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamoDbEncryption", "DynamoDbEncryption.csproj", "{597FCA8F-7BA1-49FA-95CC-F682654B22E8}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {597FCA8F-7BA1-49FA-95CC-F682654B22E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {597FCA8F-7BA1-49FA-95CC-F682654B22E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {597FCA8F-7BA1-49FA-95CC-F682654B22E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {597FCA8F-7BA1-49FA-95CC-F682654B22E8}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
diff --git a/Examples/runtimes/java/DynamoDbEncryption/README.md b/Examples/runtimes/java/DynamoDbEncryption/README.md
index 8346b9c1c..7c7d8cdba 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/README.md
+++ b/Examples/runtimes/java/DynamoDbEncryption/README.md
@@ -9,10 +9,9 @@ Overview:
├── src
│ ├── main/java/software/amazon/cryptography/examples: Examples source
│ │ ├── BasicPutGetExample: Example using AWS DB ESDK to Put and Get an encrypted item from DynamoDB
-│ │ ├── CreateKeyStoreTableExample: Example creating a Keystore DynamoDB table for use with a hierarchical keyring
-│ │ ├── CreateKeyStoreKeyExample: Example creating a branch key in a Keystore DynamoDB table
│ │ ├── clientsupplier: Examples using a custom KMS ClientSupplier
│ │ ├── enhanced: Examples using the DynamoDbEnhancedClient
+│ │ ├── hierarchy: Examples using the Hierarchy Keyring and Key Store to reduce calls to KMS
│ │ ├── itemencryptor: Examples using the DynamoDbItemEncryptor
│ │ ├── keyring: Examples creating and using different keyrings
│ │ └── searchableencryption: Examples demonstrating searchable encryption configuration and usage
diff --git a/Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts b/Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts
index bcf62436d..992571ce5 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts
+++ b/Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts
@@ -77,9 +77,17 @@ dependencies {
implementation("software.amazon.awssdk:dynamodb-enhanced")
implementation("software.amazon.awssdk:kms")
implementation("software.amazon.awssdk:sts")
-
+ implementation("software.amazon.awssdk:apache-client:2.19.0")
implementation("org.bouncycastle:bcprov-jdk18on:1.72")
+ // https://mvnrepository.com/artifact/org.projectlombok/lombok
+ implementation("org.projectlombok:lombok:1.18.30")
+ annotationProcessor("org.projectlombok:lombok:1.18.30")
+ // https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305
+ implementation("com.google.code.findbugs:jsr305:3.0.2")
+ // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
+ implementation("org.apache.commons:commons-lang3:3.14.0")
+
// https://mvnrepository.com/artifact/org.testng/testng
testImplementation("org.testng:testng:7.5")
}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreKeyExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreKeyExample.java
deleted file mode 100644
index 9b7087026..000000000
--- a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreKeyExample.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package software.amazon.cryptography.examples;
-
-import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
-import software.amazon.awssdk.services.kms.KmsClient;
-import software.amazon.cryptography.keystore.KeyStore;
-import software.amazon.cryptography.keystore.model.CreateKeyInput;
-import software.amazon.cryptography.keystore.model.KMSConfiguration;
-import software.amazon.cryptography.keystore.model.KeyStoreConfig;
-
-/*
- The Hierarchical Keyring Example and Searchable Encryption Examples
- rely on the existence of a DDB-backed key store with pre-existing
- branch key material or beacon key material.
-
- See the "Create KeyStore Table Example" for how to first set up
- the DDB Table that will back this KeyStore.
-
- This example demonstrates configuring a KeyStore and then
- using a helper method to create a branch key and beacon key
- that share the same Id, then return that Id.
- We will always create a new beacon key alongside a new branch key,
- even if you are not using searchable encryption.
-
- This key creation should occur within your control plane.
- */
-public class CreateKeyStoreKeyExample {
-
- public static String KeyStoreCreateKey(
- String keyStoreTableName,
- String logicalKeyStoreName,
- String kmsKeyArn
- ) {
- // 1. Configure your KeyStore resource.
- // This SHOULD be the same configuration that was used to create the DDB table
- // in the "Create KeyStore Table Example".
- final KeyStore keystore = KeyStore
- .builder()
- .KeyStoreConfig(
- KeyStoreConfig
- .builder()
- .ddbClient(DynamoDbClient.create())
- .ddbTableName(keyStoreTableName)
- .logicalKeyStoreName(logicalKeyStoreName)
- .kmsClient(KmsClient.create())
- .kmsConfiguration(
- KMSConfiguration.builder().kmsKeyArn(kmsKeyArn).build()
- )
- .build()
- )
- .build();
-
- // 2. Create a new branch key and beacon key in our KeyStore.
- // Both the branch key and the beacon key will share an Id.
- // This creation is eventually consistent.
-
- final String branchKeyId = keystore
- .CreateKey(CreateKeyInput.builder().build())
- .branchKeyIdentifier();
-
- return branchKeyId;
- }
-
- public static void main(final String[] args) {
- if (args.length <= 1) {
- throw new IllegalArgumentException(
- "To run this example, include the keyStoreTableName, logicalKeyStoreName, and kmsKeyArn in args"
- );
- }
- final String keyStoreTableName = args[0];
- final String logicalKeyStoreName = args[1];
- final String kmsKeyArn = args[2];
- KeyStoreCreateKey(keyStoreTableName, logicalKeyStoreName, kmsKeyArn);
- }
-}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CredentialUtils.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CredentialUtils.java
new file mode 100644
index 000000000..88f6aa6ab
--- /dev/null
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CredentialUtils.java
@@ -0,0 +1,47 @@
+package software.amazon.cryptography.examples;
+
+import javax.annotation.Nonnull;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.sts.StsClient;
+import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider;
+import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
+
+public class CredentialUtils {
+
+ public static StsAssumeRoleCredentialsProvider credsForRole(
+ @Nonnull String roleArn,
+ @Nonnull String roleSessionName,
+ @Nonnull Region region,
+ @Nonnull SdkHttpClient httpClient,
+ @Nonnull AwsCredentialsProvider creds
+ ) {
+ StsAssumeRoleCredentialsProvider provider = StsAssumeRoleCredentialsProvider
+ .builder()
+ .stsClient(
+ StsClient
+ .builder()
+ .httpClient(httpClient)
+ .region(region)
+ .credentialsProvider(creds)
+ .build()
+ )
+ .refreshRequest(
+ AssumeRoleRequest
+ .builder()
+ .roleArn(roleArn)
+ .roleSessionName(roleSessionName)
+ .durationSeconds(900) // 15 minutes by 60 seconds
+ .build()
+ )
+ .build();
+ // Force credential resolution.
+ // If the host does not have permission to use these credentials,
+ // we want to fail early.
+ // This may not be appropriate in a production environment,
+ // as it is "greedy initialization".
+ provider.resolveCredentials();
+ return provider;
+ }
+}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/EnvUtils.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/EnvUtils.java
new file mode 100644
index 000000000..0cc362f09
--- /dev/null
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/EnvUtils.java
@@ -0,0 +1,31 @@
+package software.amazon.cryptography.examples;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang3.StringUtils;
+
+public class EnvUtils {
+
+ @Nonnull
+ public static String envOrDefault(
+ @Nonnull String key,
+ @Nonnull String _default
+ ) {
+ @Nullable
+ String maybe = System.getenv(key);
+ if (StringUtils.isEmpty(maybe)) {
+ return _default;
+ }
+ return maybe;
+ }
+
+ @Nonnull
+ public static String envOrFail(@Nonnull String key) {
+ @Nullable
+ String maybe = System.getenv(key);
+ if (StringUtils.isEmpty(maybe)) {
+ throw new RuntimeException(String.format("Env had no key: %s", key));
+ }
+ return maybe;
+ }
+}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/CreateBranchKeyExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/CreateBranchKeyExample.java
new file mode 100644
index 000000000..465f24a48
--- /dev/null
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/CreateBranchKeyExample.java
@@ -0,0 +1,94 @@
+package software.amazon.cryptography.examples.hierarchy.controlPlane;
+
+import java.time.Duration;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.http.apache.ApacheHttpClient;
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+import software.amazon.cryptography.keystore.KeyStore;
+import software.amazon.cryptography.keystore.model.CreateKeyInput;
+
+/*
+ The Hierarchical Keyring Example and Searchable Encryption Examples
+ rely on the existence of a DDB-backed key store with pre-existing
+ branch key material or beacon key material.
+
+ See the "Create KeyStore Table Example" for how to first set up
+ the DDB Table that will back this KeyStore.
+
+ This example demonstrates configuring a KeyStore and then
+ using a helper method to create a branch key and beacon key
+ that share the same Id, then return that Id.
+ We will always create a new beacon key alongside a new branch key,
+ even if you are not using searchable encryption.
+
+ This key creation should occur within your control plane.
+ */
+@SuppressWarnings("UnnecessaryLocalVariable")
+public class CreateBranchKeyExample {
+
+ public static String KeyStoreCreateKey(
+ String keyStoreTableName,
+ String logicalKeyStoreName,
+ String kmsKeyArn,
+ DynamoDbClient keystoreAdminDDBClient,
+ SdkHttpClient kmsHTTPClient,
+ AwsCredentialsProvider kmsCredentials
+ ) {
+ final StrictKeyStoreFactory factory = new StrictKeyStoreFactory(
+ kmsHTTPClient,
+ keystoreAdminDDBClient,
+ keyStoreTableName,
+ logicalKeyStoreName
+ );
+ // 1. Configure your KeyStore resource.
+ // See StrictKeyStoreFactory.
+ // Only Strict KeyStores can Create or Version Branch Keys
+ final KeyStore keystore = factory.getKeyStore(kmsKeyArn, kmsCredentials);
+
+ // 2. Create a new branch key and beacon key in our KeyStore.
+ // Both the branch key and the beacon key will share an Id.
+ // This creation is eventually consistent.
+ // This MUST be done before data can be encrypted or decrypted with this Branch Key.
+ // Ideally, for the Multi-Tenant use case,
+ // Branch Key Creation is executed when a tenant
+ // onboards to the service or application.
+ final String branchKeyId = keystore
+ .CreateKey(CreateKeyInput.builder().build())
+ .branchKeyIdentifier();
+
+ return branchKeyId;
+ }
+
+ public static void main(final String[] args) {
+ if (args.length <= 1) {
+ throw new IllegalArgumentException(
+ "To run this example, include the keyStoreTableName, logicalKeyStoreName, and kmsKeyArn in args"
+ );
+ }
+ final String keyStoreTableName = args[0];
+ final String logicalKeyStoreName = args[1];
+ final String kmsKeyArn = args[2];
+ // It is more efficient to re-use these than create unique ones for DDB & KMS.
+ final AwsCredentialsProvider defaultCreds =
+ DefaultCredentialsProvider.create();
+ final SdkHttpClient httpClient = ApacheHttpClient
+ .builder()
+ .connectionTimeToLive(Duration.ofSeconds(5))
+ .build();
+ final DynamoDbClient keystoreAdminDDBClient = DynamoDbClient
+ .builder()
+ .httpClient(httpClient)
+ .credentialsProvider(defaultCreds)
+ .build();
+ KeyStoreCreateKey(
+ keyStoreTableName,
+ logicalKeyStoreName,
+ kmsKeyArn,
+ keystoreAdminDDBClient,
+ httpClient,
+ defaultCreds
+ );
+ }
+}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/StrictKeyStoreFactory.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/StrictKeyStoreFactory.java
new file mode 100644
index 000000000..30956dbf2
--- /dev/null
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/controlPlane/StrictKeyStoreFactory.java
@@ -0,0 +1,167 @@
+package software.amazon.cryptography.examples.hierarchy.controlPlane;
+
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.cryptography.keystore.KeyStore;
+import software.amazon.cryptography.keystore.model.KMSConfiguration;
+import software.amazon.cryptography.keystore.model.KeyStoreConfig;
+
+/**
+ * This factory class demonstrates various ways to provide
+ * a "Strict" Key Store instance.
+ * That is a Key Store that only works with a particular KMS Key ARN.
+ * Such Key Stores can be used to Create or Version Branch Keys,
+ * and thus are REQUIRED for Key Store Administration.
+ *
+ * These Key Stores are also appropriate for Applications that
+ * protect all their tenants with one KMS Key.
+ *
+ * Or for Searchable Encryption configurations that only use one KMS Key.
+ *
+ * If an Application needs to use different KMS Keys per Tenant,
+ * then the Discovery Configurations are more helpful.
+ * See the DiscoveryKeyStoreFactory.
+ *
+ * However, even these Multi-KMS-Key applications will need to use
+ * the Strict KeyStore configurations to Administrate their "conceptual Key Store"
+ * (that is, Create or Version Branch Keys).
+ *
+ * By "conceptual Key Store", we mean all the Branch Keys persisted
+ * with the same Logical Table Name
+ * in the same backing Table.
+ *
+ * There are two "strict" configurations:
+ *
+ * - {@code kmsKeyArn} : Only use this KMS Key
+ * - {@code kmsMRKeyArn} : Only use this Replication of a KMS Multi-Region Key
+ *
+ * Both configurations accept Single Region or Multi-Region KMS Keys.
+ *
+ * Key Stores with a KMS Configuration of {@code kmsKeyArn} reject any Branch Keys
+ * encountered that are protected by a different KMS Key.
+ *
+ * Key Stores with a KMS Configuration of {@code kmsMRKeyArn} reject any Branch Keys
+ * encountered that are not protected by any replication of this KMS Multi-Region Key;
+ * unless the KMS ARN passed is NOT a KMS Multi-Region Key.
+ * If the KMS ARN passed is not a KMS Multi-Region Key,
+ * {@code kmsMRKeyArn} behaves as {@code kmsKeyArn}.
+ *
+ * Note: Neither configuration accepts KMS Aliases.
+ */
+@ThreadSafe
+public class StrictKeyStoreFactory {
+
+ private final SdkHttpClient httpClient;
+ private final DynamoDbClient dynamoDbClient;
+ private final String backingTableName;
+ private final String logicalName;
+ // Loading the Default Credentials takes time.
+ // If you can do it once, and provide them to future clients,
+ // that saves on effort.
+ private final AwsCredentialsProvider defaultCreds =
+ DefaultCredentialsProvider.create();
+
+ public StrictKeyStoreFactory(
+ @Nonnull SdkHttpClient httpClient,
+ @Nonnull DynamoDbClient dynamoDbClient,
+ @Nonnull String backingTableName,
+ @Nonnull String logicalKeyStoreName
+ ) {
+ // Some Applications may need to use specific credentials,
+ // like Grant Tokens, for a KMS Key.
+ // By re-using an HTTP Client across KMS Clients,
+ // we can customize the credentials without re-doing
+ // the TLS handshake.
+ this.httpClient = httpClient;
+ this.dynamoDbClient = dynamoDbClient;
+ this.backingTableName = backingTableName;
+ this.logicalName = logicalKeyStoreName;
+ }
+
+ public KeyStore getKeyStore(@Nonnull String kmsKeyArn) {
+ return this.getKeyStore(kmsKeyArn, this.defaultCreds, null);
+ }
+
+ public KeyStore getKeyStore(
+ @Nonnull String kmsKeyArn,
+ @Nonnull AwsCredentialsProvider kmsCredentials
+ ) {
+ return this.getKeyStore(kmsKeyArn, kmsCredentials, null);
+ }
+
+ public KeyStore getKeyStore(
+ @Nonnull String kmsKeyArn,
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nullable List grantTokens
+ ) {
+ KmsClient kmsClient = KmsClient
+ .builder()
+ .httpClient(this.httpClient)
+ .credentialsProvider(kmsCredentials)
+ .build();
+ KeyStoreConfig.Builder config = commonBuilder(grantTokens, kmsClient);
+ config.kmsConfiguration(
+ KMSConfiguration.builder().kmsKeyArn(kmsKeyArn).build()
+ );
+ return KeyStore.builder().KeyStoreConfig(config.build()).build();
+ }
+
+ public KeyStore getMRKeyStore(
+ @Nonnull String kmsKeyArn,
+ @Nonnull Region region
+ ) {
+ return this.getMRKeyStore(kmsKeyArn, this.defaultCreds, region, null);
+ }
+
+ public KeyStore getMRKeyStore(
+ @Nonnull String kmsKeyArn,
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nonnull Region region
+ ) {
+ return this.getMRKeyStore(kmsKeyArn, kmsCredentials, region, null);
+ }
+
+ public KeyStore getMRKeyStore(
+ @Nonnull String kmsKeyArn,
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nonnull Region region,
+ @Nullable List grantTokens
+ ) {
+ KmsClient kmsClient = KmsClient
+ .builder()
+ .httpClient(this.httpClient)
+ .credentialsProvider(kmsCredentials)
+ .region(region)
+ .build();
+ KeyStoreConfig.Builder config = commonBuilder(grantTokens, kmsClient);
+ config.kmsConfiguration(
+ KMSConfiguration.builder().kmsMRKeyArn(kmsKeyArn).build()
+ );
+ return KeyStore.builder().KeyStoreConfig(config.build()).build();
+ }
+
+ private KeyStoreConfig.Builder commonBuilder(
+ List grantTokens,
+ KmsClient kmsClient
+ ) {
+ KeyStoreConfig.Builder config = KeyStoreConfig
+ .builder()
+ .ddbClient(this.dynamoDbClient)
+ .kmsClient(kmsClient)
+ .logicalKeyStoreName(this.logicalName)
+ .ddbTableName(this.backingTableName);
+ if (Objects.nonNull(grantTokens) && grantTokens.size() > 0) {
+ config.grantTokens(grantTokens);
+ }
+ return config;
+ }
+}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/dataPlane/DiscoveryKeyStoreFactory.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/dataPlane/DiscoveryKeyStoreFactory.java
new file mode 100644
index 000000000..e699e3f56
--- /dev/null
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/dataPlane/DiscoveryKeyStoreFactory.java
@@ -0,0 +1,152 @@
+package software.amazon.cryptography.examples.hierarchy.dataPlane;
+
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.cryptography.keystore.KeyStore;
+import software.amazon.cryptography.keystore.model.Discovery;
+import software.amazon.cryptography.keystore.model.KMSConfiguration;
+import software.amazon.cryptography.keystore.model.KeyStoreConfig;
+import software.amazon.cryptography.keystore.model.MRDiscovery;
+
+/**
+ * This factory class demonstrates various ways to provide
+ * a "Discovery" Key Store instance.
+ * That is a Key Store that MAY use the KMS Key ARNs already persisted to
+ * the backing table,
+ * provided they are in records created with an identical Logical Key Store name
+ * (i.e: in the same "conceptual Key Store").
+ * Such Key Stores can NOT be used to Create or Version Branch Keys.
+ *
+ * These Key Stores are also appropriate for applications that
+ * protect different tenants with different KMS Keys.
+ *
+ * However, even these Multi-KMS-Key applications will need to use
+ * the Strict KeyStore configurations to Administrate their "conceptual Key Store"
+ * (that is, Create or Version Branch Keys).
+ *
+ * By "conceptual Key Store", we mean all the Branch Keys persisted
+ * with the same Logical Table Name in the same backing Table.
+ *
+ * There are two "Discovery" configurations:
+ *
+ * - {@code discovery} : Use the KMS Key recorded in the requested Branch Key's record as is.
+ * - {@code mrDiscovery} : If the KMS Key recorded in the requested Branch Key's record is a KMS Multi-Region Key, replace the region with this region.
+ *
+ * Both configurations work with Single Region or Multi-Region KMS Keys.
+ *
+ * Key Stores with a KMS Configuration of {@code mrDiscovery} enable Multi-Region applications
+ * to use a local replication of the KMS Multi-Region Key.
+ *
+ * Note: Neither configuration works with KMS Aliases.
+ */
+@ThreadSafe
+public class DiscoveryKeyStoreFactory {
+
+ private final SdkHttpClient httpClient;
+ private final DynamoDbClient dynamoDbClient;
+ private final String backingTableName;
+ private final String logicalName;
+ // Loading the Default Credentials takes time.
+ // If you can do it once, and provide them to future clients,
+ // that saves on effort.
+ private final AwsCredentialsProvider defaultCreds =
+ DefaultCredentialsProvider.create();
+
+ public DiscoveryKeyStoreFactory(
+ @Nonnull SdkHttpClient httpClient,
+ @Nonnull DynamoDbClient dynamoDbClient,
+ @Nonnull String backingTableName,
+ @Nonnull String logicalKeyStoreName
+ ) {
+ // Some Applications may need to use specific credentials,
+ // like Grant Tokens, for a KMS Key.
+ // By re-using an HTTP Client across KMS Clients,
+ // we can customize the credentials without re-doing
+ // the TLS handshake.
+ this.httpClient = httpClient;
+ this.dynamoDbClient = dynamoDbClient;
+ this.backingTableName = backingTableName;
+ this.logicalName = logicalKeyStoreName;
+ }
+
+ public KeyStore getKeyStore() {
+ return this.getKeyStore(this.defaultCreds, null);
+ }
+
+ public KeyStore getKeyStore(@Nonnull AwsCredentialsProvider kmsCredentials) {
+ return this.getKeyStore(kmsCredentials, null);
+ }
+
+ public KeyStore getKeyStore(
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nullable List grantTokens
+ ) {
+ KmsClient kmsClient = KmsClient
+ .builder()
+ .httpClient(this.httpClient)
+ .credentialsProvider(kmsCredentials)
+ .build();
+ KeyStoreConfig.Builder config = commonBuilder(grantTokens, kmsClient);
+ config.kmsConfiguration(
+ KMSConfiguration.builder().discovery(Discovery.builder().build()).build()
+ );
+ return KeyStore.builder().KeyStoreConfig(config.build()).build();
+ }
+
+ public KeyStore getMRKeyStore(@Nonnull Region region) {
+ return this.getMRKeyStore(this.defaultCreds, region, null);
+ }
+
+ public KeyStore getMRKeyStore(
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nonnull Region region
+ ) {
+ return this.getMRKeyStore(kmsCredentials, region, null);
+ }
+
+ public KeyStore getMRKeyStore(
+ @Nonnull AwsCredentialsProvider kmsCredentials,
+ @Nonnull Region region,
+ @Nullable List grantTokens
+ ) {
+ KmsClient kmsClient = KmsClient
+ .builder()
+ .httpClient(this.httpClient)
+ .credentialsProvider(kmsCredentials)
+ .region(region)
+ .build();
+ KeyStoreConfig.Builder config = commonBuilder(grantTokens, kmsClient);
+ config.kmsConfiguration(
+ KMSConfiguration
+ .builder()
+ .mrDiscovery(MRDiscovery.builder().region(region.toString()).build())
+ .build()
+ );
+ return KeyStore.builder().KeyStoreConfig(config.build()).build();
+ }
+
+ private KeyStoreConfig.Builder commonBuilder(
+ List grantTokens,
+ KmsClient kmsClient
+ ) {
+ KeyStoreConfig.Builder config = KeyStoreConfig
+ .builder()
+ .ddbClient(this.dynamoDbClient)
+ .kmsClient(kmsClient)
+ .logicalKeyStoreName(this.logicalName)
+ .ddbTableName(this.backingTableName);
+ if (Objects.nonNull(grantTokens) && grantTokens.size() > 0) {
+ config.grantTokens(grantTokens);
+ }
+ return config;
+ }
+}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreTableExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/regionBuild/CreateKeyStoreTableExample.java
similarity index 93%
rename from Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreTableExample.java
rename to Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/regionBuild/CreateKeyStoreTableExample.java
index 8aaa5c516..99f706404 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreTableExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/hierarchy/regionBuild/CreateKeyStoreTableExample.java
@@ -1,4 +1,4 @@
-package software.amazon.cryptography.examples;
+package software.amazon.cryptography.examples.hierarchy.regionBuild;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.kms.KmsClient;
@@ -16,7 +16,7 @@
using a helper method to create the DDB table that will be
used to persist branch keys and beacons keys for this KeyStore.
- This table creation should occur within your control plane. This
+ This table creation should occur during your region build. This
only needs to occur once. While not demonstrated in this example,
you should additionally use the `VersionKey` API on the KeyStore
to periodically rotate your branch key material.
@@ -56,7 +56,7 @@ public static void KeyStoreCreateTable(
// it will create one. If a table exists, it will verify
// the table's configuration and will error if the configuration is incorrect.
keystore.CreateKeyStore(CreateKeyStoreInput.builder().build());
- // It may take a couple minutes for the table to become ACTIVE,
+ // It may take a couple of minutes for the table to become ACTIVE,
// at which point it is ready to store branch and beacon keys.
// See the Create KeyStore Key Example for how to populate
// this table.
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreKeyExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreKeyExample.java
index 854c0833c..6b6baaeb5 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreKeyExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreKeyExample.java
@@ -3,17 +3,21 @@
import static org.testng.Assert.assertNotNull;
import org.testng.annotations.Test;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestCreateKeyStoreKeyExample {
@Test
public void TestCreateKeyStoreKeyExample() {
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId = CreateBranchKeyExample.KeyStoreCreateKey(
TestUtils.TEST_KEYSTORE_NAME,
TestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- TestUtils.TEST_KEYSTORE_KMS_KEY_ID
+ TestUtils.TEST_KEYSTORE_KMS_KEY_ID,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
- assertNotNull(keyId);
+ assertNotNull(branchKeyId);
}
}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreTableExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreTableExample.java
index 5c7714936..eee747c04 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreTableExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestCreateKeyStoreTableExample.java
@@ -1,6 +1,7 @@
package software.amazon.cryptography.examples;
import org.testng.annotations.Test;
+import software.amazon.cryptography.examples.hierarchy.regionBuild.CreateKeyStoreTableExample;
public class TestCreateKeyStoreTableExample {
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestUtils.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestUtils.java
index 76fe7cbb8..cfa59b9a0 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestUtils.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestUtils.java
@@ -1,27 +1,96 @@
package software.amazon.cryptography.examples;
+import java.time.Duration;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.http.apache.ApacheHttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+
public class TestUtils {
- public static final String TEST_KEYSTORE_NAME = "KeyStoreDdbTable";
- public static final String TEST_LOGICAL_KEYSTORE_NAME = "KeyStoreDdbTable";
- public static final String TEST_KEYSTORE_KMS_KEY_ID =
- "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126";
+ public static final String SESSION_NAME =
+ EnvUtils.envOrFail("USER") + "-DB-ESDK-Java";
+ public static final String TEST_KEYSTORE_NAME = EnvUtils.envOrDefault(
+ "KEYSTORE_TABLE",
+ "KeyStoreDdbTable"
+ );
+ public static final String TEST_LOGICAL_KEYSTORE_NAME = EnvUtils.envOrDefault(
+ "KEYSTORE_TABLE",
+ "KeyStoreDdbTable"
+ );
+ public static final String TEST_KEYSTORE_KMS_KEY_ID = EnvUtils.envOrDefault(
+ "TEST_KEYSTORE_KMS_KEY_ID",
+ "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126"
+ );
- public static final String TEST_AWS_ACCOUNT_ID = "658956600833";
- public static final String TEST_AWS_REGION = "us-west-2";
+ public static final String TEST_AWS_ACCOUNT_ID = EnvUtils.envOrDefault(
+ "TEST_AWS_ACCOUNT_ID",
+ "658956600833"
+ );
+ public static final String TEST_AWS_REGION = EnvUtils.envOrDefault(
+ "TEST_AWS_REGION",
+ "us-west-2"
+ );
// These are public KMS Keys that MUST only be used for testing, and MUST NOT be used for any production data
- public static final String TEST_KMS_KEY_ID =
- "arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f";
- public static final String TEST_MRK_KEY_ID =
- "arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
- public static final String TEST_KMS_RSA_KEY_ID =
- "arn:aws:kms:us-west-2:658956600833:key/8b432da4-dde4-4bc3-a794-c7d68cbab5a6";
+ public static final String TEST_KMS_KEY_ID = EnvUtils.envOrDefault(
+ "TEST_KMS_KEY_ID",
+ "arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f"
+ );
+ public static final String TEST_MRK_KEY_ID = EnvUtils.envOrDefault(
+ "TEST_MRK_KEY_ID",
+ "arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7"
+ );
+ public static final String TEST_KMS_RSA_KEY_ID = EnvUtils.envOrDefault(
+ "TEST_KMS_RSA_KEY_ID",
+ "arn:aws:kms:us-west-2:658956600833:key/8b432da4-dde4-4bc3-a794-c7d68cbab5a6"
+ );
public static final String TEST_MRK_REPLICA_KEY_ID_US_EAST_1 =
- "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
+ EnvUtils.envOrDefault(
+ "TEST_MRK_REPLICA_KEY_ID_US_EAST_1",
+ "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7"
+ );
public static final String TEST_MRK_REPLICA_KEY_ID_EU_WEST_1 =
- "arn:aws:kms:eu-west-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
+ EnvUtils.envOrDefault(
+ "TEST_MRK_REPLICA_KEY_ID_EU_WEST_1",
+ "arn:aws:kms:eu-west-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7"
+ );
// Our tests require access to DDB Table with this name
- public static final String TEST_DDB_TABLE_NAME =
- "DynamoDbEncryptionInterceptorTestTable";
+ public static final String TEST_DDB_TABLE_NAME = EnvUtils.envOrDefault(
+ "TEST_DDB_TABLE_NAME",
+ "DynamoDbEncryptionInterceptorTestTable"
+ );
+
+ public static final String KEYSTORE_USER_ROLE_ARN = EnvUtils.envOrDefault(
+ "KEYSTORE_USER_ROLE_ARN",
+ "arn:aws:iam::658956600833:role/CryptographyExample-KeyStoreUser-us-west-2"
+ );
+ public static final String KEYSTORE_ADMIN_ROLE_ARN = EnvUtils.envOrDefault(
+ "KEYSTORE_ADMIN_ROLE_ARN",
+ "arn:aws:iam::658956600833:role/CryptographyExample-KeyStoreAdmin-us-west-2"
+ );
+
+ public static final AwsCredentialsProvider defaultCreds =
+ DefaultCredentialsProvider.create();
+ public static final SdkHttpClient kmsHttpClient = ApacheHttpClient
+ .builder()
+ .connectionTimeToLive(Duration.ofSeconds(5))
+ .build();
+ public static final SdkHttpClient httpClient = ApacheHttpClient.create();
+ public static final DynamoDbClient keystoreAdminDDBClient = DynamoDbClient
+ .builder()
+ .httpClient(httpClient)
+ .credentialsProvider(
+ CredentialUtils.credsForRole(
+ KEYSTORE_ADMIN_ROLE_ARN,
+ SESSION_NAME,
+ Region.of(TEST_AWS_REGION),
+ httpClient,
+ TestUtils.defaultCreds
+ )
+ )
+ .region(Region.of(TEST_AWS_REGION))
+ .build();
}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/keyring/TestHierarchicalKeyringExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/keyring/TestHierarchicalKeyringExample.java
index 92f0d7f62..f8a3b00ef 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/keyring/TestHierarchicalKeyringExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/keyring/TestHierarchicalKeyringExample.java
@@ -1,23 +1,29 @@
package software.amazon.cryptography.examples.keyring;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestHierarchicalKeyringExample {
@Test
public void TestHierarchicalKeyringExample() throws InterruptedException {
// Create new branch keys for test
- String keyId1 = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId1 = CreateBranchKeyExample.KeyStoreCreateKey(
TestUtils.TEST_KEYSTORE_NAME,
TestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- TestUtils.TEST_KEYSTORE_KMS_KEY_ID
+ TestUtils.TEST_KEYSTORE_KMS_KEY_ID,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
- String keyId2 = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId2 = CreateBranchKeyExample.KeyStoreCreateKey(
TestUtils.TEST_KEYSTORE_NAME,
TestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- TestUtils.TEST_KEYSTORE_KMS_KEY_ID
+ TestUtils.TEST_KEYSTORE_KMS_KEY_ID,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
@@ -26,8 +32,8 @@ public void TestHierarchicalKeyringExample() throws InterruptedException {
HierarchicalKeyringExample.HierarchicalKeyringGetItemPutItem(
TestUtils.TEST_DDB_TABLE_NAME,
- keyId1,
- keyId2,
+ branchKeyId1,
+ branchKeyId2,
TestUtils.TEST_KEYSTORE_NAME,
TestUtils.TEST_LOGICAL_KEYSTORE_NAME,
TestUtils.TEST_KEYSTORE_KMS_KEY_ID
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/SearchableEncryptionTestUtils.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/SearchableEncryptionTestUtils.java
index a0083a655..1c649ca3b 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/SearchableEncryptionTestUtils.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/SearchableEncryptionTestUtils.java
@@ -1,5 +1,7 @@
package software.amazon.cryptography.examples.searchableencryption;
+import software.amazon.cryptography.examples.TestUtils;
+
public class SearchableEncryptionTestUtils {
// Our tests require access to DDB Tables with these name
@@ -16,6 +18,7 @@ public class SearchableEncryptionTestUtils {
// Our tests require access to DDB Table with this name configured as a branch keystore
public static final String TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME =
- "KeyStoreDdbTable";
- public static final String TEST_LOGICAL_KEYSTORE_NAME = "KeyStoreDdbTable";
+ TestUtils.TEST_DDB_TABLE_NAME;
+ public static final String TEST_LOGICAL_KEYSTORE_NAME =
+ TestUtils.TEST_LOGICAL_KEYSTORE_NAME;
}
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBasicSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBasicSearchableEncryptionExample.java
index 57539f58d..20e5afd5f 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBasicSearchableEncryptionExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBasicSearchableEncryptionExample.java
@@ -1,17 +1,21 @@
package software.amazon.cryptography.examples.searchableencryption;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
+import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestBasicSearchableEncryptionExample {
@Test
public void TestBasicExample() throws InterruptedException {
// Create new branch key for test
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId = CreateBranchKeyExample.KeyStoreCreateKey(
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME,
SearchableEncryptionTestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN
+ SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
@@ -20,7 +24,7 @@ public void TestBasicExample() throws InterruptedException {
BasicSearchableEncryptionExample.PutItemQueryItemWithBeacon(
SearchableEncryptionTestUtils.UNIT_INSPECTION_TEST_DDB_TABLE_NAME,
- keyId,
+ branchKeyId,
SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME
);
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBeaconStylesSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBeaconStylesSearchableEncryptionExample.java
index 82f7be340..a850b98ab 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBeaconStylesSearchableEncryptionExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestBeaconStylesSearchableEncryptionExample.java
@@ -1,17 +1,21 @@
package software.amazon.cryptography.examples.searchableencryption;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
+import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestBeaconStylesSearchableEncryptionExample {
@Test
public void TestCompoundItemEncryptDecrypt() throws InterruptedException {
// Create new branch key for test
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String keyId = CreateBranchKeyExample.KeyStoreCreateKey(
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME,
SearchableEncryptionTestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN
+ SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestCompoundBeaconSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestCompoundBeaconSearchableEncryptionExample.java
index 9661c1f8f..46e8b5ad8 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestCompoundBeaconSearchableEncryptionExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestCompoundBeaconSearchableEncryptionExample.java
@@ -1,17 +1,21 @@
package software.amazon.cryptography.examples.searchableencryption;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
+import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestCompoundBeaconSearchableEncryptionExample {
@Test
public void TestCompoundItemEncryptDecrypt() throws InterruptedException {
// Create new branch key for test
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId1 = CreateBranchKeyExample.KeyStoreCreateKey(
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME,
SearchableEncryptionTestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN
+ SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
@@ -20,7 +24,7 @@ public void TestCompoundItemEncryptDecrypt() throws InterruptedException {
CompoundBeaconSearchableEncryptionExample.PutItemQueryItemWithCompoundBeacon(
SearchableEncryptionTestUtils.UNIT_INSPECTION_TEST_DDB_TABLE_NAME,
- keyId,
+ branchKeyId1,
SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME
);
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestVirtualBeaconSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestVirtualBeaconSearchableEncryptionExample.java
index 0ba858780..c61cf36cd 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestVirtualBeaconSearchableEncryptionExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/TestVirtualBeaconSearchableEncryptionExample.java
@@ -1,17 +1,21 @@
package software.amazon.cryptography.examples.searchableencryption;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
+import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
public class TestVirtualBeaconSearchableEncryptionExample {
@Test
public void TestVirtualBeaconExample() throws InterruptedException {
// Create new branch key for test
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String branchKeyId = CreateBranchKeyExample.KeyStoreCreateKey(
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME,
SearchableEncryptionTestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN
+ SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
@@ -20,7 +24,7 @@ public void TestVirtualBeaconExample() throws InterruptedException {
VirtualBeaconSearchableEncryptionExample.PutItemQueryItemWithVirtualBeacon(
SearchableEncryptionTestUtils.SIMPLE_BEACON_TEST_DDB_TABLE_NAME,
- keyId,
+ branchKeyId,
SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME
);
diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/complexexample/TestComplexSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/complexexample/TestComplexSearchableEncryptionExample.java
index 06174d0bb..02b87af81 100644
--- a/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/complexexample/TestComplexSearchableEncryptionExample.java
+++ b/Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/searchableencryption/complexexample/TestComplexSearchableEncryptionExample.java
@@ -1,7 +1,8 @@
package software.amazon.cryptography.examples.searchableencryption.complexexample;
import org.testng.annotations.Test;
-import software.amazon.cryptography.examples.CreateKeyStoreKeyExample;
+import software.amazon.cryptography.examples.TestUtils;
+import software.amazon.cryptography.examples.hierarchy.controlPlane.CreateBranchKeyExample;
import software.amazon.cryptography.examples.searchableencryption.SearchableEncryptionTestUtils;
public class TestComplexSearchableEncryptionExample {
@@ -9,10 +10,13 @@ public class TestComplexSearchableEncryptionExample {
@Test
public void TestComplexExample() throws InterruptedException {
// Create new branch key for test
- String keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey(
+ String keyId = CreateBranchKeyExample.KeyStoreCreateKey(
SearchableEncryptionTestUtils.TEST_BRANCH_KEYSTORE_DDB_TABLE_NAME,
SearchableEncryptionTestUtils.TEST_LOGICAL_KEYSTORE_NAME,
- SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN
+ SearchableEncryptionTestUtils.TEST_BRANCH_KEY_WRAPPING_KMS_KEY_ARN,
+ TestUtils.keystoreAdminDDBClient,
+ TestUtils.kmsHttpClient,
+ TestUtils.defaultCreds
);
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
diff --git a/submodules/MaterialProviders b/submodules/MaterialProviders
index b6d28dcd6..1f98bd316 160000
--- a/submodules/MaterialProviders
+++ b/submodules/MaterialProviders
@@ -1 +1 @@
-Subproject commit b6d28dcd6968b00fa200fc0d51a1c83f437191ab
+Subproject commit 1f98bd31636a3acb3d12de48a3e48d37a1c799a7