getEncryptionActionOverrides();
-
- /**
- * Returns an {@link EncryptionContext} to be used by the encryption client. Has information about the table
- * name, the names of the primary indices etc.
- * @return An {@link EncryptionContext} object.
- */
- EncryptionContext getEncryptionContext();
-
- /**
- * Default builder for an immutable implementation of {@link DynamoDbEncryptionConfiguration}.
- * @return A newly initialized {@link BasicDynamoDbEncryptionConfiguration.Builder}.
- */
- static BasicDynamoDbEncryptionConfiguration.Builder builder() {
- return new BasicDynamoDbEncryptionConfiguration.Builder();
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/EncryptionAction.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/EncryptionAction.java
deleted file mode 100644
index 9ee1c798..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/EncryptionAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2;
-
-/**
- * When configuring the {@link DynamoDbEncryptionClient} you may specify a default behavior for how attributes should
- * be treated when encrypting and decrypting, and also you may include overrides to change the behavior for specific
- * attributes. The following enumeration are the different valid behaviors for how a single attribute should be treated.
- */
-public enum EncryptionAction {
- /**
- * DO_NOTHING : This instructs the encryption client to completely ignore the attribute. The attribute will not be
- * encrypted and it will not be included in the signature calculation of the record.
- */
- DO_NOTHING,
-
- /**
- * SIGN_ONLY : This instructs the encryption client to include the attribute in the signature calculation of the
- * record, but not to encrypt its value.
- */
- SIGN_ONLY,
-
- /**
- * ENCRYPT_AND_SIGN : This instructs the encryption client to include the attribute in the signature calculation of
- * the record and to encrypt its value.
- */
- ENCRYPT_AND_SIGN
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DelegatedKey.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DelegatedKey.java
deleted file mode 100644
index 52e02f2e..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DelegatedKey.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-/**
- * Identifies keys which should not be used directly with {@link Cipher} but
- * instead contain their own cryptographic logic. This can be used to wrap more
- * complex logic, HSM integration, or service-calls.
- *
- *
- * Most delegated keys will only support a subset of these operations. (For
- * example, AES keys will generally not support {@link #sign(byte[], String)} or
- * {@link #verify(byte[], byte[], String)} and HMAC keys will generally not
- * support anything except sign
and verify
.)
- * {@link UnsupportedOperationException} should be thrown in these cases.
- *
- * @author Greg Rubin
- */
-public interface DelegatedKey extends SecretKey {
- /**
- * Encrypts the provided plaintext and returns a byte-array containing the ciphertext.
- *
- * @param plainText
- * @param additionalAssociatedData
- * Optional additional data which must then also be provided for successful
- * decryption. Both null
and arrays of length 0 are treated identically.
- * Not all keys will support this parameter.
- * @param algorithm
- * the transformation to be used when encrypting the data
- * @return ciphertext the ciphertext produced by this encryption operation
- * @throws UnsupportedOperationException
- * if encryption is not supported or if additionalAssociatedData
is
- * provided, but not supported.
- */
- byte[] encrypt(byte[] plainText, byte[] additionalAssociatedData, String algorithm)
- throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException,
- NoSuchPaddingException;
-
- /**
- * Decrypts the provided ciphertext and returns a byte-array containing the
- * plaintext.
- *
- * @param cipherText
- * @param additionalAssociatedData
- * Optional additional data which was provided during encryption.
- * Both null
and arrays of length 0 are treated
- * identically. Not all keys will support this parameter.
- * @param algorithm
- * the transformation to be used when decrypting the data
- * @return plaintext the result of decrypting the input ciphertext
- * @throws UnsupportedOperationException
- * if decryption is not supported or if
- * additionalAssociatedData
is provided, but not
- * supported.
- */
- byte[] decrypt(byte[] cipherText, byte[] additionalAssociatedData, String algorithm)
- throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException,
- NoSuchPaddingException, InvalidAlgorithmParameterException;
-
- /**
- * Wraps (encrypts) the provided key
to make it safe for
- * storage or transmission.
- *
- * @param key
- * @param additionalAssociatedData
- * Optional additional data which must then also be provided for
- * successful unwrapping. Both null
and arrays of
- * length 0 are treated identically. Not all keys will support
- * this parameter.
- * @param algorithm
- * the transformation to be used when wrapping the key
- * @return the wrapped key
- * @throws UnsupportedOperationException
- * if wrapping is not supported or if
- * additionalAssociatedData
is provided, but not
- * supported.
- */
- byte[] wrap(Key key, byte[] additionalAssociatedData, String algorithm) throws InvalidKeyException,
- NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException;
-
- /**
- * Unwraps (decrypts) the provided wrappedKey
to recover the
- * original key.
- *
- * @param wrappedKey
- * @param additionalAssociatedData
- * Optional additional data which was provided during wrapping.
- * Both null
and arrays of length 0 are treated
- * identically. Not all keys will support this parameter.
- * @param algorithm
- * the transformation to be used when unwrapping the key
- * @return the unwrapped key
- * @throws UnsupportedOperationException
- * if wrapping is not supported or if
- * additionalAssociatedData
is provided, but not
- * supported.
- */
- Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType,
- byte[] additionalAssociatedData, String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException,
- InvalidKeyException;
-
- /**
- * Calculates and returns a signature for dataToSign
.
- *
- * @param dataToSign
- * @param algorithm
- * @return the signature
- * @throws UnsupportedOperationException if signing is not supported
- */
- byte[] sign(byte[] dataToSign, String algorithm) throws GeneralSecurityException;
-
- /**
- * Checks the provided signature for correctness.
- *
- * @param dataToSign
- * @param signature
- * @param algorithm
- * @return true if and only if the signature
matches the dataToSign
.
- * @throws UnsupportedOperationException if signature validation is not supported
- */
- boolean verify(byte[] dataToSign, byte[] signature, String algorithm);
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbEncryptor.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbEncryptor.java
deleted file mode 100644
index 775fd12d..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbEncryptor.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.DynamoDbEncryptionClient;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.DynamoDbEncryptionConfiguration;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.EncryptionAction;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.exceptions.DynamoDbEncryptionException;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.EncryptionMaterialsProvider;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.AttributeValueMarshaller;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.ByteBufferInputStream;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Utils;
-
-/**
- * The low-level API for performing crypto operations on the record attributes.
- *
- * @author Greg Rubin
- */
-public class DynamoDbEncryptor implements DynamoDbEncryptionClient {
- private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withRSA";
- private static final String DEFAULT_METADATA_FIELD = "*amzn-ddb-map-desc*";
- private static final String DEFAULT_SIGNATURE_FIELD = "*amzn-ddb-map-sig*";
- private static final String DEFAULT_DESCRIPTION_BASE = "amzn-ddb-map-"; // Same as the Mapper
- private static final Charset UTF8 = Charset.forName("UTF-8");
- private static final String SYMMETRIC_ENCRYPTION_MODE = "/CBC/PKCS5Padding";
- private static final ConcurrentHashMap BLOCK_SIZE_CACHE = new ConcurrentHashMap<>();
- private static final Function BLOCK_SIZE_CALCULATOR = (transformation) -> {
- try {
- final Cipher c = Cipher.getInstance(transformation);
- return c.getBlockSize();
- } catch (final GeneralSecurityException ex) {
- throw new IllegalArgumentException("Algorithm does not exist", ex);
- }
- };
-
- private static final int CURRENT_VERSION = 0;
-
- // Static map used to convert an EncryptionAction into a corresponding set of EncryptionFlags
- private static final Map> ENCRYPTION_ACTION_TO_FLAGS_MAP;
- static {
- Map> encrytionActionToFlagsMap = new HashMap<>();
- encrytionActionToFlagsMap.put(EncryptionAction.DO_NOTHING, Collections.emptySet());
- encrytionActionToFlagsMap.put(EncryptionAction.SIGN_ONLY, Collections.singleton(EncryptionFlags.SIGN));
- encrytionActionToFlagsMap.put(EncryptionAction.ENCRYPT_AND_SIGN,
- Collections.unmodifiableSet(new HashSet<>(Arrays.asList(EncryptionFlags.SIGN, EncryptionFlags.ENCRYPT))));
- ENCRYPTION_ACTION_TO_FLAGS_MAP = Collections.unmodifiableMap(encrytionActionToFlagsMap);
- }
-
- private String signatureFieldName = DEFAULT_SIGNATURE_FIELD;
- private String materialDescriptionFieldName = DEFAULT_METADATA_FIELD;
-
- private EncryptionMaterialsProvider encryptionMaterialsProvider;
- private final String descriptionBase;
- private final String symmetricEncryptionModeHeader;
- private final String signingAlgorithmHeader;
-
- static final String DEFAULT_SIGNING_ALGORITHM_HEADER = DEFAULT_DESCRIPTION_BASE + "signingAlg";
-
- private Function encryptionContextOverrideOperator;
-
- protected DynamoDbEncryptor(EncryptionMaterialsProvider provider, String descriptionBase) {
- this.encryptionMaterialsProvider = provider;
- this.descriptionBase = descriptionBase;
- symmetricEncryptionModeHeader = this.descriptionBase + "sym-mode";
- signingAlgorithmHeader = this.descriptionBase + "signingAlg";
- }
-
- protected DynamoDbEncryptor(EncryptionMaterialsProvider provider) {
- this(provider, DEFAULT_DESCRIPTION_BASE);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EncryptionMaterialsProvider encryptionMaterialsProvider;
-
- public Builder encryptionMaterialsProvider(EncryptionMaterialsProvider encryptionMaterialsProvider) {
- this.encryptionMaterialsProvider = encryptionMaterialsProvider;
- return this;
- }
-
- public DynamoDbEncryptor build() {
- if (encryptionMaterialsProvider == null) {
- throw new IllegalArgumentException("A DynamoDbEncryptor cannot be built without an "
- + "EncryptionMaterialsProvider");
- }
-
- return new DynamoDbEncryptor(encryptionMaterialsProvider);
- }
- }
-
- @Override
- public Map encryptRecord(Map record,
- DynamoDbEncryptionConfiguration configuration) {
-
- validateParameters(record, configuration);
- return internalEncryptRecord(record,
- getEncryptionFlagsFromConfiguration(record, configuration),
- configuration.getEncryptionContext());
- }
-
- @Override
- public Map decryptRecord(Map record,
- DynamoDbEncryptionConfiguration configuration) {
-
- validateParameters(record, configuration);
- return internalDecryptRecord(record,
- getEncryptionFlagsFromConfiguration(record, configuration),
- configuration.getEncryptionContext());
- }
-
- private void validateParameters(Map record,
- DynamoDbEncryptionConfiguration configuration) {
- if (record == null) {
- throw new IllegalArgumentException("AttributeValues must not be null");
- }
- if (configuration == null) {
- throw new IllegalArgumentException("DynamoDbEncryptionConfiguration must not be null");
- }
- if (configuration.getEncryptionContext() == null) {
- throw new IllegalArgumentException("DynamoDbEncryptionConfiguration's EncryptionContext must not be null");
- }
- if (configuration.getDefaultEncryptionAction() == null) {
- throw new IllegalArgumentException("DynamoDbEncryptionConfiguration's DefaultEncryptionAction must not be"
- + " null");
- }
- }
-
-
- private Map> getEncryptionFlagsFromConfiguration(
- Map record,
- DynamoDbEncryptionConfiguration configuration) {
-
- return record.keySet()
- .stream()
- // Do not let attributes created by the encryption library participate in encrypting or signing
- .filter(key -> !key.equals(getMaterialDescriptionFieldName())
- && !key.equals(getSignatureFieldName()))
- .collect(Collectors.toMap(Function.identity(), key -> {
- EncryptionAction encryptionAction = configuration.getEncryptionActionOverrides().get(key);
-
- if (encryptionAction == null) {
- encryptionAction = configuration.getDefaultEncryptionAction();
- }
-
- return getEncryptionFlagsForAction(encryptionAction);
- }));
- }
-
- private Map internalDecryptRecord(
- Map itemAttributes,
- Map> attributeFlags,
- EncryptionContext context) {
- if (attributeFlags.isEmpty()) {
- return itemAttributes;
- }
- // Copy to avoid changing anyone elses objects
- itemAttributes = new HashMap<>(itemAttributes);
-
- Map materialDescription = Collections.emptyMap();
- DecryptionMaterials materials;
- SecretKey decryptionKey;
-
- DynamoDbSigner signer = DynamoDbSigner.getInstance(DEFAULT_SIGNATURE_ALGORITHM, Utils.getRng());
-
- if (itemAttributes.containsKey(materialDescriptionFieldName)) {
- materialDescription = unmarshallDescription(itemAttributes.get(materialDescriptionFieldName));
- }
- // Copy the material description and attribute values into the context
- context = context.toBuilder()
- .materialDescription(materialDescription)
- .attributeValues(itemAttributes)
- .build();
-
- Function encryptionContextOverrideOperator = getEncryptionContextOverrideOperator();
- if (encryptionContextOverrideOperator != null) {
- context = encryptionContextOverrideOperator.apply(context);
- }
-
- materials = encryptionMaterialsProvider.getDecryptionMaterials(context);
- decryptionKey = materials.getDecryptionKey();
- if (materialDescription.containsKey(signingAlgorithmHeader)) {
- String signingAlg = materialDescription.get(signingAlgorithmHeader);
- signer = DynamoDbSigner.getInstance(signingAlg, Utils.getRng());
- }
-
- ByteBuffer signature;
- if (!itemAttributes.containsKey(signatureFieldName) || itemAttributes.get(signatureFieldName).b() == null) {
- signature = ByteBuffer.allocate(0);
- } else {
- signature = itemAttributes.get(signatureFieldName).b().asByteBuffer();
- }
- itemAttributes.remove(signatureFieldName);
-
- String associatedData = "TABLE>" + context.getTableName() + " internalEncryptRecord(
- Map itemAttributes,
- Map> attributeFlags,
- EncryptionContext context) {
- if (attributeFlags.isEmpty()) {
- return itemAttributes;
- }
- // Copy to avoid changing anyone elses objects
- itemAttributes = new HashMap<>(itemAttributes);
-
- // Copy the attribute values into the context
- context = context.toBuilder()
- .attributeValues(itemAttributes)
- .build();
-
- Function encryptionContextOverrideOperator =
- getEncryptionContextOverrideOperator();
- if (encryptionContextOverrideOperator != null) {
- context = encryptionContextOverrideOperator.apply(context);
- }
-
- EncryptionMaterials materials = encryptionMaterialsProvider.getEncryptionMaterials(context);
- // We need to copy this because we modify it to record other encryption details
- Map materialDescription = new HashMap<>(
- materials.getMaterialDescription());
- SecretKey encryptionKey = materials.getEncryptionKey();
-
- try {
- actualEncryption(itemAttributes, attributeFlags, materialDescription, encryptionKey);
-
- // The description must be stored after encryption because its data
- // is necessary for proper decryption.
- final String signingAlgo = materialDescription.get(signingAlgorithmHeader);
- DynamoDbSigner signer;
- if (signingAlgo != null) {
- signer = DynamoDbSigner.getInstance(signingAlgo, Utils.getRng());
- } else {
- signer = DynamoDbSigner.getInstance(DEFAULT_SIGNATURE_ALGORITHM, Utils.getRng());
- }
-
- if (materials.getSigningKey() instanceof PrivateKey) {
- materialDescription.put(signingAlgorithmHeader, signer.getSigningAlgorithm());
- }
- if (! materialDescription.isEmpty()) {
- itemAttributes.put(materialDescriptionFieldName, marshallDescription(materialDescription));
- }
-
- String associatedData = "TABLE>" + context.getTableName() + " itemAttributes,
- Map> attributeFlags, SecretKey encryptionKey,
- Map materialDescription) throws GeneralSecurityException {
- final String encryptionMode = encryptionKey != null ? encryptionKey.getAlgorithm() +
- materialDescription.get(symmetricEncryptionModeHeader) : null;
- Cipher cipher = null;
- int blockSize = -1;
-
- for (Map.Entry entry: itemAttributes.entrySet()) {
- Set flags = attributeFlags.get(entry.getKey());
- if (flags != null && flags.contains(EncryptionFlags.ENCRYPT)) {
- if (!flags.contains(EncryptionFlags.SIGN)) {
- throw new IllegalArgumentException("All encrypted fields must be signed. Bad field: " + entry.getKey());
- }
- ByteBuffer plainText;
- ByteBuffer cipherText = entry.getValue().b().asByteBuffer();
- cipherText.rewind();
- if (encryptionKey instanceof DelegatedKey) {
- plainText = ByteBuffer.wrap(((DelegatedKey)encryptionKey).decrypt(toByteArray(cipherText), null, encryptionMode));
- } else {
- if (cipher == null) {
- blockSize = getBlockSize(encryptionMode);
- cipher = Cipher.getInstance(encryptionMode);
- }
- byte[] iv = new byte[blockSize];
- cipherText.get(iv);
- cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new IvParameterSpec(iv), Utils.getRng());
- plainText = ByteBuffer.allocate(cipher.getOutputSize(cipherText.remaining()));
- cipher.doFinal(cipherText, plainText);
- plainText.rewind();
- }
- entry.setValue(AttributeValueMarshaller.unmarshall(plainText));
- }
- }
- }
-
- private static int getBlockSize(final String encryptionMode) {
- return BLOCK_SIZE_CACHE.computeIfAbsent(encryptionMode, BLOCK_SIZE_CALCULATOR);
- }
-
- /**
- * This method has the side effect of replacing the plaintext
- * attribute-values of "itemAttributes" with ciphertext attribute-values
- * (which are always in the form of ByteBuffer) as per the corresponding
- * attribute flags.
- */
- private void actualEncryption(Map itemAttributes,
- Map> attributeFlags,
- Map materialDescription,
- SecretKey encryptionKey) throws GeneralSecurityException {
- String encryptionMode = null;
- if (encryptionKey != null) {
- materialDescription.put(this.symmetricEncryptionModeHeader,
- SYMMETRIC_ENCRYPTION_MODE);
- encryptionMode = encryptionKey.getAlgorithm() + SYMMETRIC_ENCRYPTION_MODE;
- }
- Cipher cipher = null;
- int blockSize = -1;
-
- for (Map.Entry entry: itemAttributes.entrySet()) {
- Set flags = attributeFlags.get(entry.getKey());
- if (flags != null && flags.contains(EncryptionFlags.ENCRYPT)) {
- if (!flags.contains(EncryptionFlags.SIGN)) {
- throw new IllegalArgumentException("All encrypted fields must be signed. Bad field: " + entry.getKey());
- }
- ByteBuffer plainText = AttributeValueMarshaller.marshall(entry.getValue());
- plainText.rewind();
- ByteBuffer cipherText;
- if (encryptionKey instanceof DelegatedKey) {
- DelegatedKey dk = (DelegatedKey) encryptionKey;
- cipherText = ByteBuffer.wrap(
- dk.encrypt(toByteArray(plainText), null, encryptionMode));
- } else {
- if (cipher == null) {
- blockSize = getBlockSize(encryptionMode);
- cipher = Cipher.getInstance(encryptionMode);
- }
- // Encryption format:
- // Note a unique iv is generated per attribute
- cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, Utils.getRng());
- cipherText = ByteBuffer.allocate(blockSize + cipher.getOutputSize(plainText.remaining()));
- cipherText.position(blockSize);
- cipher.doFinal(plainText, cipherText);
- cipherText.flip();
- final byte[] iv = cipher.getIV();
- if (iv.length != blockSize) {
- throw new IllegalStateException(String.format("Generated IV length (%d) not equal to block size (%d)",
- iv.length, blockSize));
- }
- cipherText.put(iv);
- cipherText.rewind();
- }
- // Replace the plaintext attribute value with the encrypted content
- entry.setValue(AttributeValue.builder().b(SdkBytes.fromByteBuffer(cipherText)).build());
- }
- }
- }
-
- /**
- * Get the name of the DynamoDB field used to store the signature.
- * Defaults to {@link #DEFAULT_SIGNATURE_FIELD}.
- *
- * @return the name of the DynamoDB field used to store the signature
- */
- String getSignatureFieldName() {
- return signatureFieldName;
- }
-
- /**
- * Set the name of the DynamoDB field used to store the signature.
- *
- * @param signatureFieldName
- */
- void setSignatureFieldName(final String signatureFieldName) {
- this.signatureFieldName = signatureFieldName;
- }
-
- /**
- * Get the name of the DynamoDB field used to store metadata used by the
- * DynamoDBEncryptedMapper. Defaults to {@link #DEFAULT_METADATA_FIELD}.
- *
- * @return the name of the DynamoDB field used to store metadata used by the
- * DynamoDBEncryptedMapper
- */
- String getMaterialDescriptionFieldName() {
- return materialDescriptionFieldName;
- }
-
- /**
- * Set the name of the DynamoDB field used to store metadata used by the
- * DynamoDBEncryptedMapper
- *
- * @param materialDescriptionFieldName
- */
- void setMaterialDescriptionFieldName(final String materialDescriptionFieldName) {
- this.materialDescriptionFieldName = materialDescriptionFieldName;
- }
-
- /**
- * Marshalls the description
into a ByteBuffer by outputting
- * each key (modified UTF-8) followed by its value (also in modified UTF-8).
- *
- * @param description
- * @return the description encoded as an AttributeValue with a ByteBuffer value
- * @see java.io.DataOutput#writeUTF(String)
- */
- private static AttributeValue marshallDescription(Map description) {
- try {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- DataOutputStream out = new DataOutputStream(bos);
- out.writeInt(CURRENT_VERSION);
- for (Map.Entry entry : description.entrySet()) {
- byte[] bytes = entry.getKey().getBytes(UTF8);
- out.writeInt(bytes.length);
- out.write(bytes);
- bytes = entry.getValue().getBytes(UTF8);
- out.writeInt(bytes.length);
- out.write(bytes);
- }
- out.close();
- return AttributeValue.builder().b(SdkBytes.fromByteArray(bos.toByteArray())).build();
- } catch (IOException ex) {
- // Due to the objects in use, an IOException is not possible.
- throw new RuntimeException("Unexpected exception", ex);
- }
- }
-
- /**
- * @see #marshallDescription(Map)
- */
- private static Map unmarshallDescription(AttributeValue attributeValue) {
- try (DataInputStream in = new DataInputStream(
- new ByteBufferInputStream(attributeValue.b().asByteBuffer())) ) {
- Map result = new HashMap<>();
- int version = in.readInt();
- if (version != CURRENT_VERSION) {
- throw new IllegalArgumentException("Unsupported description version");
- }
-
- String key, value;
- int keyLength, valueLength;
- try {
- while(in.available() > 0) {
- keyLength = in.readInt();
- byte[] bytes = new byte[keyLength];
- if (in.read(bytes) != keyLength) {
- throw new IllegalArgumentException("Malformed description");
- }
- key = new String(bytes, UTF8);
- valueLength = in.readInt();
- bytes = new byte[valueLength];
- if (in.read(bytes) != valueLength) {
- throw new IllegalArgumentException("Malformed description");
- }
- value = new String(bytes, UTF8);
- result.put(key, value);
- }
- } catch (EOFException eof) {
- throw new IllegalArgumentException("Malformed description", eof);
- }
- return result;
- } catch (IOException ex) {
- // Due to the objects in use, an IOException is not possible.
- throw new RuntimeException("Unexpected exception", ex);
- }
- }
-
- /**
- * @param encryptionContextOverrideOperator the nullable operator which will be used to override
- * the EncryptionContext.
- * @see EncryptionContextOperators
- */
- void setEncryptionContextOverrideOperator(
- Function encryptionContextOverrideOperator) {
- this.encryptionContextOverrideOperator = encryptionContextOverrideOperator;
- }
-
- /**
- * @return the operator used to override the EncryptionContext
- * @see #setEncryptionContextOverrideOperator(Function)
- */
- private Function getEncryptionContextOverrideOperator() {
- return encryptionContextOverrideOperator;
- }
-
- private static Set getEncryptionFlagsForAction(EncryptionAction encryptionAction) {
- Set encryptionFlags = ENCRYPTION_ACTION_TO_FLAGS_MAP.get(encryptionAction);
-
- if (encryptionFlags == null) {
- throw new RuntimeException("Unrecognized EncryptionAction : " + encryptionAction.name());
- }
-
- return encryptionFlags;
- }
-
- private static byte[] toByteArray(ByteBuffer buffer) {
- buffer = buffer.duplicate();
- // We can only return the array directly if:
- // 1. The ByteBuffer exposes an array
- // 2. The ByteBuffer starts at the beginning of the array
- // 3. The ByteBuffer uses the entire array
- if (buffer.hasArray() && buffer.arrayOffset() == 0) {
- byte[] result = buffer.array();
- if (buffer.remaining() == result.length) {
- return result;
- }
- }
-
- byte[] result = new byte[buffer.remaining()];
- buffer.get(result);
- return result;
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbSigner.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbSigner.java
deleted file mode 100644
index e27710c3..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/DynamoDbSigner.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.AttributeValueMarshaller;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Utils;
-
-import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
-
-/**
- * @author Greg Rubin
- */
-// NOTE: This class must remain thread-safe.
-class DynamoDbSigner {
- private static final ConcurrentHashMap cache =
- new ConcurrentHashMap<>();
-
- protected static final Charset UTF8 = Charset.forName("UTF-8");
- private final SecureRandom rnd;
- private final SecretKey hmacComparisonKey;
- private final String signingAlgorithm;
-
- /**
- * @param signingAlgorithm
- * is the algorithm used for asymmetric signing (ex:
- * SHA256withRSA). This is ignored for symmetric HMACs as that
- * algorithm is fully specified by the key.
- */
- static DynamoDbSigner getInstance(String signingAlgorithm, SecureRandom rnd) {
- DynamoDbSigner result = cache.get(signingAlgorithm);
- if (result == null) {
- result = new DynamoDbSigner(signingAlgorithm, rnd);
- cache.putIfAbsent(signingAlgorithm, result);
- }
- return result;
- }
-
- /**
- * @param signingAlgorithm
- * is the algorithm used for asymmetric signing (ex:
- * SHA256withRSA). This is ignored for symmetric HMACs as that
- * algorithm is fully specified by the key.
- */
- private DynamoDbSigner(String signingAlgorithm, SecureRandom rnd) {
- if (rnd == null) {
- rnd = Utils.getRng();
- }
- this.rnd = rnd;
- this.signingAlgorithm = signingAlgorithm;
- // Shorter than the output of SHA256 to avoid weak keys.
- // http://cs.nyu.edu/~dodis/ps/h-of-h.pdf
- // http://link.springer.com/chapter/10.1007%2F978-3-642-32009-5_21
- byte[] tmpKey = new byte[31];
- rnd.nextBytes(tmpKey);
- hmacComparisonKey = new SecretKeySpec(tmpKey, "HmacSHA256");
- }
-
- void verifySignature(Map itemAttributes, Map> attributeFlags,
- byte[] associatedData, Key verificationKey, ByteBuffer signature) throws GeneralSecurityException {
- if (verificationKey instanceof DelegatedKey) {
- DelegatedKey dKey = (DelegatedKey)verificationKey;
- byte[] stringToSign = calculateStringToSign(itemAttributes, attributeFlags, associatedData);
- if (!dKey.verify(stringToSign, toByteArray(signature), dKey.getAlgorithm())) {
- throw new SignatureException("Bad signature");
- }
- } else if (verificationKey instanceof SecretKey) {
- byte[] calculatedSig = calculateSignature(itemAttributes, attributeFlags, associatedData, (SecretKey)verificationKey);
- if (!safeEquals(signature, calculatedSig)) {
- throw new SignatureException("Bad signature");
- }
- } else if (verificationKey instanceof PublicKey) {
- PublicKey integrityKey = (PublicKey)verificationKey;
- byte[] stringToSign = calculateStringToSign(itemAttributes, attributeFlags, associatedData);
- Signature sig = Signature.getInstance(getSigningAlgorithm());
- sig.initVerify(integrityKey);
- sig.update(stringToSign);
- if (!sig.verify(toByteArray(signature))) {
- throw new SignatureException("Bad signature");
- }
- } else {
- throw new IllegalArgumentException("No integrity key provided");
- }
- }
-
- static byte[] calculateStringToSign(Map itemAttributes,
- Map> attributeFlags, byte[] associatedData)
- throws NoSuchAlgorithmException {
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- List attrNames = new ArrayList<>(itemAttributes.keySet());
- Collections.sort(attrNames);
- MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
- if (associatedData != null) {
- out.write(sha256.digest(associatedData));
- } else {
- out.write(sha256.digest());
- }
- sha256.reset();
-
- for (String name : attrNames) {
- Set set = attributeFlags.get(name);
- if(set != null && set.contains(EncryptionFlags.SIGN)) {
- AttributeValue tmp = itemAttributes.get(name);
- out.write(sha256.digest(name.getBytes(UTF8)));
- sha256.reset();
- if (set.contains(EncryptionFlags.ENCRYPT)) {
- sha256.update("ENCRYPTED".getBytes(UTF8));
- } else {
- sha256.update("PLAINTEXT".getBytes(UTF8));
- }
- out.write(sha256.digest());
-
- sha256.reset();
-
- sha256.update(AttributeValueMarshaller.marshall(tmp));
- out.write(sha256.digest());
- sha256.reset();
- }
- }
- return out.toByteArray();
- } catch (IOException ex) {
- // Due to the objects in use, an IOException is not possible.
- throw new RuntimeException("Unexpected exception", ex);
- }
- }
-
- /**
- * The itemAttributes have already been encrypted, if necessary, before the
- * signing.
- */
- byte[] calculateSignature(
- Map itemAttributes,
- Map> attributeFlags,
- byte[] associatedData, Key key) throws GeneralSecurityException {
- if (key instanceof DelegatedKey) {
- return calculateSignature(itemAttributes, attributeFlags, associatedData, (DelegatedKey) key);
- } else if (key instanceof SecretKey) {
- return calculateSignature(itemAttributes, attributeFlags, associatedData, (SecretKey) key);
- } else if (key instanceof PrivateKey) {
- return calculateSignature(itemAttributes, attributeFlags, associatedData, (PrivateKey) key);
- } else {
- throw new IllegalArgumentException("No integrity key provided");
- }
- }
-
- byte[] calculateSignature(Map itemAttributes,
- Map> attributeFlags, byte[] associatedData,
- DelegatedKey key) throws GeneralSecurityException {
- byte[] stringToSign = calculateStringToSign(itemAttributes, attributeFlags, associatedData);
- return key.sign(stringToSign, key.getAlgorithm());
- }
-
- byte[] calculateSignature(Map itemAttributes,
- Map> attributeFlags, byte[] associatedData,
- SecretKey key) throws GeneralSecurityException {
- if (key instanceof DelegatedKey) {
- return calculateSignature(itemAttributes, attributeFlags, associatedData, (DelegatedKey)key);
- }
- byte[] stringToSign = calculateStringToSign(itemAttributes, attributeFlags, associatedData);
- Mac hmac = Mac.getInstance(key.getAlgorithm());
- hmac.init(key);
- hmac.update(stringToSign);
- return hmac.doFinal();
- }
-
- byte[] calculateSignature(Map itemAttributes,
- Map> attributeFlags, byte[] associatedData,
- PrivateKey key) throws GeneralSecurityException {
- byte[] stringToSign = calculateStringToSign(itemAttributes, attributeFlags, associatedData);
- Signature sig = Signature.getInstance(signingAlgorithm);
- sig.initSign(key, rnd);
- sig.update(stringToSign);
- return sig.sign();
- }
-
- String getSigningAlgorithm() {
- return signingAlgorithm;
- }
-
- /**
- * Constant-time equality check.
- */
- private boolean safeEquals(ByteBuffer signature, byte[] calculatedSig) {
- try {
- signature.rewind();
- Mac hmac = Mac.getInstance(hmacComparisonKey.getAlgorithm());
- hmac.init(hmacComparisonKey);
- hmac.update(signature);
- byte[] signatureHash = hmac.doFinal();
-
- hmac.reset();
- hmac.update(calculatedSig);
- byte[] calculatedHash = hmac.doFinal();
-
- return MessageDigest.isEqual(signatureHash, calculatedHash);
- } catch (GeneralSecurityException ex) {
- // We've hardcoded these algorithms, so the error should not be possible.
- throw new RuntimeException("Unexpected exception", ex);
- }
- }
-
- private static byte[] toByteArray(ByteBuffer buffer) {
- if (buffer.hasArray()) {
- byte[] result = buffer.array();
- buffer.rewind();
- return result;
- } else {
- byte[] result = new byte[buffer.remaining()];
- buffer.get(result);
- buffer.rewind();
- return result;
- }
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContext.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContext.java
deleted file mode 100644
index 4651a8ea..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContext.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.EncryptionMaterialsProvider;
-
-import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
-
-/**
- * This class serves to provide additional useful data to
- * {@link EncryptionMaterialsProvider}s so they can more intelligently select
- * the proper {@link EncryptionMaterials} or {@link DecryptionMaterials} for
- * use. Any of the methods are permitted to return null.
- *
- * For the simplest cases, all a developer needs to provide in the context are:
- *
- * - TableName
- * - HashKeyName
- * - RangeKeyName (if present)
- *
- *
- * This class is immutable.
- *
- * @author Greg Rubin
- */
-public final class EncryptionContext {
- private final String tableName;
- private final Map attributeValues;
- private final Object developerContext;
- private final String hashKeyName;
- private final String rangeKeyName;
- private final Map materialDescription;
-
- /**
- * Return a new builder that can be used to construct an {@link EncryptionContext}
- * @return A newly initialized {@link EncryptionContext.Builder}.
- */
- public static Builder builder() {
- return new Builder();
- }
-
- private EncryptionContext(Builder builder) {
- tableName = builder.tableName;
- attributeValues = builder.attributeValues;
- developerContext = builder.developerContext;
- hashKeyName = builder.hashKeyName;
- rangeKeyName = builder.rangeKeyName;
- materialDescription = builder.materialDescription;
- }
-
- /**
- * Returns the name of the DynamoDB Table this record is associated with.
- */
- public String getTableName() {
- return tableName;
- }
-
- /**
- * Returns the DynamoDB record about to be encrypted/decrypted.
- */
- public Map getAttributeValues() {
- return attributeValues;
- }
-
- /**
- * This object has no meaning (and will not be set or examined) by any core libraries.
- * It exists to allow custom object mappers and data access layers to pass
- * data to {@link EncryptionMaterialsProvider}s through the {@link DynamoDbEncryptor}.
- */
- public Object getDeveloperContext() {
- return developerContext;
- }
-
- /**
- * Returns the name of the HashKey attribute for the record to be encrypted/decrypted.
- */
- public String getHashKeyName() {
- return hashKeyName;
- }
-
- /**
- * Returns the name of the RangeKey attribute for the record to be encrypted/decrypted.
- */
- public String getRangeKeyName() {
- return rangeKeyName;
- }
-
- public Map getMaterialDescription() {
- return materialDescription;
- }
-
- /**
- * Converts an existing {@link EncryptionContext} into a builder that can be used to mutate and make a new version.
- * @return A new {@link EncryptionContext.Builder} with all the fields filled out to match the current object.
- */
- public Builder toBuilder() {
- return new Builder(this);
- }
-
- /**
- * Builder class for {@link EncryptionContext}.
- * Mutable objects (other than developerContext
) will undergo
- * a defensive copy prior to being stored in the builder.
- *
- * This class is not thread-safe.
- */
- public static final class Builder {
- private String tableName = null;
- private Map attributeValues = null;
- private Object developerContext = null;
- private String hashKeyName = null;
- private String rangeKeyName = null;
- private Map materialDescription = null;
-
- private Builder() {
- }
-
- private Builder(EncryptionContext context) {
- tableName = context.getTableName();
- attributeValues = context.getAttributeValues();
- hashKeyName = context.getHashKeyName();
- rangeKeyName = context.getRangeKeyName();
- developerContext = context.getDeveloperContext();
- materialDescription = context.getMaterialDescription();
- }
-
- public EncryptionContext build() {
- return new EncryptionContext(this);
- }
-
- public Builder tableName(String tableName) {
- this.tableName = tableName;
- return this;
- }
-
- public Builder attributeValues(Map attributeValues) {
- this.attributeValues = Collections.unmodifiableMap(new HashMap<>(attributeValues));
- return this;
- }
-
- public Builder developerContext(Object developerContext) {
- this.developerContext = developerContext;
- return this;
- }
-
- public Builder hashKeyName(String hashKeyName) {
- this.hashKeyName = hashKeyName;
- return this;
- }
-
- public Builder rangeKeyName(String rangeKeyName) {
- this.rangeKeyName = rangeKeyName;
- return this;
- }
-
- public Builder materialDescription(Map materialDescription) {
- this.materialDescription = Collections.unmodifiableMap(new HashMap<>(materialDescription));
- return this;
- }
- }
-
- @Override
- public String toString() {
- return "EncryptionContext [tableName=" + tableName + ", attributeValues=" + attributeValues
- + ", developerContext=" + developerContext
- + ", hashKeyName=" + hashKeyName + ", rangeKeyName=" + rangeKeyName
- + ", materialDescription=" + materialDescription + "]";
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContextOperators.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContextOperators.java
deleted file mode 100644
index 2c880d39..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionContextOperators.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-import java.util.Map;
-import java.util.function.UnaryOperator;
-
-/**
- * Implementations of common operators for overriding the EncryptionContext
- */
-class EncryptionContextOperators {
-
- // Prevent instantiation
- private EncryptionContextOperators() {
- }
-
- /**
- * An operator for overriding EncryptionContext's table name for a specific DynamoDbEncryptor. If any table names or
- * the encryption context itself is null, then it returns the original EncryptionContext.
- *
- * @param originalTableName the name of the table that should be overridden in the Encryption Context
- * @param newTableName the table name that should be used in the Encryption Context
- * @return A UnaryOperator that produces a new EncryptionContext with the supplied table name
- */
- static UnaryOperator overrideEncryptionContextTableName(
- String originalTableName,
- String newTableName) {
- return encryptionContext -> {
- if (encryptionContext == null
- || encryptionContext.getTableName() == null
- || originalTableName == null
- || newTableName == null) {
- return encryptionContext;
- }
- if (originalTableName.equals(encryptionContext.getTableName())) {
- return encryptionContext.toBuilder().tableName(newTableName).build();
- } else {
- return encryptionContext;
- }
- };
- }
-
- /**
- * An operator for mapping multiple table names in the Encryption Context to a new table name. If the table name for
- * a given EncryptionContext is missing, then it returns the original EncryptionContext. Similarly, it returns the
- * original EncryptionContext if the value it is overridden to is null, or if the original table name is null.
- *
- * @param tableNameOverrideMap a map specifying the names of tables that should be overridden,
- * and the values to which they should be overridden. If the given table name
- * corresponds to null, or isn't in the map, then the table name won't be overridden.
- * @return A UnaryOperator that produces a new EncryptionContext with the supplied table name
- */
- static UnaryOperator overrideEncryptionContextTableNameUsingMap(
- Map tableNameOverrideMap) {
- return encryptionContext -> {
- if (tableNameOverrideMap == null || encryptionContext == null || encryptionContext.getTableName() == null) {
- return encryptionContext;
- }
- String newTableName = tableNameOverrideMap.get(encryptionContext.getTableName());
- if (newTableName != null) {
- return encryptionContext.toBuilder().tableName(newTableName).build();
- } else {
- return encryptionContext;
- }
- };
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionFlags.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionFlags.java
deleted file mode 100644
index ce3031da..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/EncryptionFlags.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption;
-
-/**
- * @author Greg Rubin
- */
-enum EncryptionFlags {
- ENCRYPT,
- SIGN
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/exceptions/DynamoDbEncryptionException.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/exceptions/DynamoDbEncryptionException.java
deleted file mode 100644
index f245d66e..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/exceptions/DynamoDbEncryptionException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.exceptions;
-
-/**
- * Generic exception thrown for any problem the DynamoDB encryption client has performing tasks
- */
-public class DynamoDbEncryptionException extends RuntimeException {
- private static final long serialVersionUID = - 7565904179772520868L;
-
- /**
- * Standard constructor
- * @param cause exception cause
- */
- public DynamoDbEncryptionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Standard constructor
- * @param message exception message
- */
- public DynamoDbEncryptionException(String message) {
- super(message);
- }
-
- /**
- * Standard constructor
- * @param message exception message
- * @param cause exception cause
- */
- public DynamoDbEncryptionException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AbstractRawMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AbstractRawMaterials.java
deleted file mode 100644
index 5dfbb197..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AbstractRawMaterials.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.Key;
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-/**
- * @author Greg Rubin
- */
-public abstract class AbstractRawMaterials implements DecryptionMaterials, EncryptionMaterials {
- private Map description;
- private final Key signingKey;
- private final Key verificationKey;
-
- @SuppressWarnings("unchecked")
- protected AbstractRawMaterials(KeyPair signingPair) {
- this(signingPair, Collections.EMPTY_MAP);
- }
-
- protected AbstractRawMaterials(KeyPair signingPair, Map description) {
- this.signingKey = signingPair.getPrivate();
- this.verificationKey = signingPair.getPublic();
- setMaterialDescription(description);
- }
-
- @SuppressWarnings("unchecked")
- protected AbstractRawMaterials(SecretKey macKey) {
- this(macKey, Collections.EMPTY_MAP);
- }
-
- protected AbstractRawMaterials(SecretKey macKey, Map description) {
- this.signingKey = macKey;
- this.verificationKey = macKey;
- this.description = Collections.unmodifiableMap(new HashMap<>(description));
- }
-
- @Override
- public Map getMaterialDescription() {
- return new HashMap<>(description);
- }
-
- public void setMaterialDescription(Map description) {
- this.description = Collections.unmodifiableMap(new HashMap<>(description));
- }
-
- @Override
- public Key getSigningKey() {
- return signingKey;
- }
-
- @Override
- public Key getVerificationKey() {
- return verificationKey;
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AsymmetricRawMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AsymmetricRawMaterials.java
deleted file mode 100644
index 003d0b60..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/AsymmetricRawMaterials.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-/**
- * @author Greg Rubin
- */
-public class AsymmetricRawMaterials extends WrappedRawMaterials {
- @SuppressWarnings("unchecked")
- public AsymmetricRawMaterials(KeyPair encryptionKey, KeyPair signingPair)
- throws GeneralSecurityException {
- this(encryptionKey, signingPair, Collections.EMPTY_MAP);
- }
-
- public AsymmetricRawMaterials(KeyPair encryptionKey, KeyPair signingPair, Map description)
- throws GeneralSecurityException {
- super(encryptionKey.getPublic(), encryptionKey.getPrivate(), signingPair, description);
- }
-
- @SuppressWarnings("unchecked")
- public AsymmetricRawMaterials(KeyPair encryptionKey, SecretKey macKey)
- throws GeneralSecurityException {
- this(encryptionKey, macKey, Collections.EMPTY_MAP);
- }
-
- public AsymmetricRawMaterials(KeyPair encryptionKey, SecretKey macKey, Map description)
- throws GeneralSecurityException {
- super(encryptionKey.getPublic(), encryptionKey.getPrivate(), macKey, description);
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/CryptographicMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/CryptographicMaterials.java
deleted file mode 100644
index 033d331f..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/CryptographicMaterials.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.util.Map;
-
-/**
- * @author Greg Rubin
- */
-public interface CryptographicMaterials {
- Map getMaterialDescription();
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/DecryptionMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/DecryptionMaterials.java
deleted file mode 100644
index 00f8548b..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/DecryptionMaterials.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.Key;
-
-import javax.crypto.SecretKey;
-
-/**
- * @author Greg Rubin
- */
-public interface DecryptionMaterials extends CryptographicMaterials {
- SecretKey getDecryptionKey();
- Key getVerificationKey();
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/EncryptionMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/EncryptionMaterials.java
deleted file mode 100644
index ecef9e9f..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/EncryptionMaterials.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.Key;
-
-import javax.crypto.SecretKey;
-
-/**
- * @author Greg Rubin
- */
-public interface EncryptionMaterials extends CryptographicMaterials {
- SecretKey getEncryptionKey();
- Key getSigningKey();
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/SymmetricRawMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/SymmetricRawMaterials.java
deleted file mode 100644
index b3daab44..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/SymmetricRawMaterials.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-/**
- * @author Greg Rubin
- */
-public class SymmetricRawMaterials extends AbstractRawMaterials {
- private final SecretKey cryptoKey;
-
- @SuppressWarnings("unchecked")
- public SymmetricRawMaterials(SecretKey encryptionKey, KeyPair signingPair) {
- this(encryptionKey, signingPair, Collections.EMPTY_MAP);
- }
-
- public SymmetricRawMaterials(SecretKey encryptionKey, KeyPair signingPair, Map description) {
- super(signingPair, description);
- this.cryptoKey = encryptionKey;
- }
-
- @SuppressWarnings("unchecked")
- public SymmetricRawMaterials(SecretKey encryptionKey, SecretKey macKey) {
- this(encryptionKey, macKey, Collections.EMPTY_MAP);
- }
-
- public SymmetricRawMaterials(SecretKey encryptionKey, SecretKey macKey, Map description) {
- super(macKey, description);
- this.cryptoKey = encryptionKey;
- }
-
- @Override
- public SecretKey getEncryptionKey() {
- return cryptoKey;
- }
-
- @Override
- public SecretKey getDecryptionKey() {
- return cryptoKey;
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/WrappedRawMaterials.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/WrappedRawMaterials.java
deleted file mode 100644
index 2941cf68..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/materials/WrappedRawMaterials.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.DelegatedKey;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Base64;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Utils;
-
-/**
- * Represents cryptographic materials used to manage unique record-level keys.
- * This class specifically implements Envelope Encryption where a unique content
- * key is randomly generated each time this class is constructed which is then
- * encrypted with the Wrapping Key and then persisted in the Description. If a
- * wrapped key is present in the Description, then that content key is unwrapped
- * and used to decrypt the actual data in the record.
- *
- * Other possibly implementations might use a Key-Derivation Function to derive
- * a unique key per record.
- *
- * @author Greg Rubin
- */
-
-public class WrappedRawMaterials extends AbstractRawMaterials {
- /**
- * The key-name in the Description which contains the algorithm use to wrap
- * content key. Example values are "AESWrap", or
- * "RSA/ECB/OAEPWithSHA-256AndMGF1Padding".
- */
- public static final String KEY_WRAPPING_ALGORITHM = "amzn-ddb-wrap-alg";
- /**
- * The key-name in the Description which contains the algorithm used by the
- * content key. Example values are "AES", or "Blowfish".
- */
- public static final String CONTENT_KEY_ALGORITHM = "amzn-ddb-env-alg";
- /**
- * The key-name in the Description which which contains the wrapped content
- * key.
- */
- public static final String ENVELOPE_KEY = "amzn-ddb-env-key";
- private static final String DEFAULT_ALGORITHM = "AES/256";
-
- protected final Key wrappingKey;
- protected final Key unwrappingKey;
- private final SecretKey envelopeKey;
-
- public WrappedRawMaterials(Key wrappingKey, Key unwrappingKey, KeyPair signingPair)
- throws GeneralSecurityException {
- this(wrappingKey, unwrappingKey, signingPair, Collections.emptyMap());
- }
-
- public WrappedRawMaterials(Key wrappingKey, Key unwrappingKey, KeyPair signingPair,
- Map description) throws GeneralSecurityException {
- super(signingPair, description);
- this.wrappingKey = wrappingKey;
- this.unwrappingKey = unwrappingKey;
- this.envelopeKey = initEnvelopeKey();
- }
-
- public WrappedRawMaterials(Key wrappingKey, Key unwrappingKey, SecretKey macKey)
- throws GeneralSecurityException {
- this(wrappingKey, unwrappingKey, macKey, Collections.emptyMap());
- }
-
- public WrappedRawMaterials(Key wrappingKey, Key unwrappingKey, SecretKey macKey,
- Map description) throws GeneralSecurityException {
- super(macKey, description);
- this.wrappingKey = wrappingKey;
- this.unwrappingKey = unwrappingKey;
- this.envelopeKey = initEnvelopeKey();
- }
-
- @Override
- public SecretKey getDecryptionKey() {
- return envelopeKey;
- }
-
- @Override
- public SecretKey getEncryptionKey() {
- return envelopeKey;
- }
-
- /**
- * Called by the constructors. If there is already a key associated with
- * this record (usually signified by a value stored in the description in
- * the key {@link #ENVELOPE_KEY}) it extracts it and returns it. Otherwise
- * it generates a new key, stores a wrapped version in the Description, and
- * returns the key to the caller.
- *
- * @return the content key (which is returned by both
- * {@link #getDecryptionKey()} and {@link #getEncryptionKey()}.
- * @throws GeneralSecurityException if there is a problem
- */
- protected SecretKey initEnvelopeKey() throws GeneralSecurityException {
- Map description = getMaterialDescription();
- if (description.containsKey(ENVELOPE_KEY)) {
- if (unwrappingKey == null) {
- throw new IllegalStateException("No private decryption key provided.");
- }
- byte[] encryptedKey = Base64.decode(description.get(ENVELOPE_KEY));
- String wrappingAlgorithm = unwrappingKey.getAlgorithm();
- if (description.containsKey(KEY_WRAPPING_ALGORITHM)) {
- wrappingAlgorithm = description.get(KEY_WRAPPING_ALGORITHM);
- }
- return unwrapKey(description, encryptedKey, wrappingAlgorithm);
- } else {
- SecretKey key = description.containsKey(CONTENT_KEY_ALGORITHM) ?
- generateContentKey(description.get(CONTENT_KEY_ALGORITHM)) :
- generateContentKey(DEFAULT_ALGORITHM);
-
- String wrappingAlg = description.containsKey(KEY_WRAPPING_ALGORITHM) ?
- description.get(KEY_WRAPPING_ALGORITHM) :
- getTransformation(wrappingKey.getAlgorithm());
- byte[] encryptedKey = wrapKey(key, wrappingAlg);
- description.put(ENVELOPE_KEY, Base64.encodeToString(encryptedKey));
- description.put(CONTENT_KEY_ALGORITHM, key.getAlgorithm());
- description.put(KEY_WRAPPING_ALGORITHM, wrappingAlg);
- setMaterialDescription(description);
- return key;
- }
- }
-
- public byte[] wrapKey(SecretKey key, String wrappingAlg) throws NoSuchAlgorithmException, NoSuchPaddingException,
- InvalidKeyException, IllegalBlockSizeException {
- if (wrappingKey instanceof DelegatedKey) {
- return ((DelegatedKey)wrappingKey).wrap(key, null, wrappingAlg);
- } else {
- Cipher cipher = Cipher.getInstance(wrappingAlg);
- cipher.init(Cipher.WRAP_MODE, wrappingKey, Utils.getRng());
- return cipher.wrap(key);
- }
- }
-
- protected SecretKey unwrapKey(Map description, byte[] encryptedKey, String wrappingAlgorithm)
- throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
- if (unwrappingKey instanceof DelegatedKey) {
- return (SecretKey)((DelegatedKey)unwrappingKey).unwrap(encryptedKey,
- description.get(CONTENT_KEY_ALGORITHM), Cipher.SECRET_KEY, null, wrappingAlgorithm);
- } else {
- Cipher cipher = Cipher.getInstance(wrappingAlgorithm);
- cipher.init(Cipher.UNWRAP_MODE, unwrappingKey, Utils.getRng());
- return (SecretKey) cipher.unwrap(encryptedKey,
- description.get(CONTENT_KEY_ALGORITHM), Cipher.SECRET_KEY);
- }
- }
-
- protected SecretKey generateContentKey(final String algorithm) throws NoSuchAlgorithmException {
- String[] pieces = algorithm.split("/", 2);
- KeyGenerator kg = KeyGenerator.getInstance(pieces[0]);
- int keyLen = 0;
- if (pieces.length == 2) {
- try {
- keyLen = Integer.parseInt(pieces[1]);
- } catch (NumberFormatException ignored) {
- }
- }
-
- if (keyLen > 0) {
- kg.init(keyLen, Utils.getRng());
- } else {
- kg.init(Utils.getRng());
- }
- return kg.generateKey();
- }
-
- private static String getTransformation(final String algorithm) {
- if (algorithm.equalsIgnoreCase("RSA")) {
- return "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
- } else if (algorithm.equalsIgnoreCase("AES")) {
- return "AESWrap";
- } else {
- return algorithm;
- }
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/AsymmetricStaticProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/AsymmetricStaticProvider.java
deleted file mode 100644
index b49e2b9a..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/AsymmetricStaticProvider.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-/**
- * This is a thin wrapper around the {@link WrappedMaterialsProvider}, using
- * the provided encryptionKey
for wrapping and unwrapping the
- * record key. Please see that class for detailed documentation.
- *
- * @author Greg Rubin
- */
-public class AsymmetricStaticProvider extends WrappedMaterialsProvider {
- public AsymmetricStaticProvider(KeyPair encryptionKey, KeyPair signingPair) {
- this(encryptionKey, signingPair, Collections.emptyMap());
- }
-
- public AsymmetricStaticProvider(KeyPair encryptionKey, SecretKey macKey) {
- this(encryptionKey, macKey, Collections.emptyMap());
- }
-
- public AsymmetricStaticProvider(KeyPair encryptionKey, KeyPair signingPair, Map description) {
- super(encryptionKey.getPublic(), encryptionKey.getPrivate(), signingPair, description);
- }
-
- public AsymmetricStaticProvider(KeyPair encryptionKey, SecretKey macKey, Map description) {
- super(encryptionKey.getPublic(), encryptionKey.getPrivate(), macKey, description);
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/DirectKmsMaterialsProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/DirectKmsMaterialsProvider.java
deleted file mode 100644
index ab402cbb..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/DirectKmsMaterialsProvider.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import static software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.WrappedRawMaterials.CONTENT_KEY_ALGORITHM;
-import static software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.WrappedRawMaterials.ENVELOPE_KEY;
-import static software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.WrappedRawMaterials.KEY_WRAPPING_ALGORITHM;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.exceptions.DynamoDbEncryptionException;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.SymmetricRawMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.WrappedRawMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Base64;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Hkdf;
-
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
-import software.amazon.awssdk.services.kms.KmsClient;
-import software.amazon.awssdk.services.kms.model.DecryptRequest;
-import software.amazon.awssdk.services.kms.model.DecryptResponse;
-import software.amazon.awssdk.services.kms.model.GenerateDataKeyRequest;
-import software.amazon.awssdk.services.kms.model.GenerateDataKeyResponse;
-
-/**
- * Generates a unique data key for each record in DynamoDB and protects that key
- * using {@link KmsClient}. Currently, the HashKey, RangeKey, and TableName will be
- * included in the KMS EncryptionContext for wrapping/unwrapping the key. This
- * means that records cannot be copied/moved between tables without re-encryption.
- *
- * @see KMS Encryption Context
- */
-public class DirectKmsMaterialsProvider implements EncryptionMaterialsProvider {
- private static final String COVERED_ATTR_CTX_KEY = "aws-kms-ec-attr";
- private static final String SIGNING_KEY_ALGORITHM = "amzn-ddb-sig-alg";
- private static final String TABLE_NAME_EC_KEY = "*aws-kms-table*";
-
- private static final String DEFAULT_ENC_ALG = "AES/256";
- private static final String DEFAULT_SIG_ALG = "HmacSHA256/256";
- private static final String KEY_COVERAGE = "*keys*";
- private static final String KDF_ALG = "HmacSHA256";
- private static final String KDF_SIG_INFO = "Signing";
- private static final String KDF_ENC_INFO = "Encryption";
-
- private final KmsClient kms;
- private final String encryptionKeyId;
- private final Map description;
- private final String dataKeyAlg;
- private final int dataKeyLength;
- private final String dataKeyDesc;
- private final String sigKeyAlg;
- private final int sigKeyLength;
- private final String sigKeyDesc;
-
- public DirectKmsMaterialsProvider(KmsClient kms) {
- this(kms, null);
- }
-
- public DirectKmsMaterialsProvider(KmsClient kms, String encryptionKeyId, Map materialDescription) {
- this.kms = kms;
- this.encryptionKeyId = encryptionKeyId;
- this.description = materialDescription != null ?
- Collections.unmodifiableMap(new HashMap<>(materialDescription)) :
- Collections.emptyMap();
-
- dataKeyDesc = description.getOrDefault(WrappedRawMaterials.CONTENT_KEY_ALGORITHM, DEFAULT_ENC_ALG);
-
- String[] parts = dataKeyDesc.split("/", 2);
- this.dataKeyAlg = parts[0];
- this.dataKeyLength = parts.length == 2 ? Integer.parseInt(parts[1]) : 256;
-
- sigKeyDesc = description.getOrDefault(SIGNING_KEY_ALGORITHM, DEFAULT_SIG_ALG);
-
- parts = sigKeyDesc.split("/", 2);
- this.sigKeyAlg = parts[0];
- this.sigKeyLength = parts.length == 2 ? Integer.parseInt(parts[1]) : 256;
- }
-
- public DirectKmsMaterialsProvider(KmsClient kms, String encryptionKeyId) {
- this(kms, encryptionKeyId, Collections.emptyMap());
- }
-
- @Override
- public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
- final Map materialDescription = context.getMaterialDescription();
-
- final Map ec = new HashMap<>();
- final String providedEncAlg = materialDescription.get(CONTENT_KEY_ALGORITHM);
- final String providedSigAlg = materialDescription.get(SIGNING_KEY_ALGORITHM);
-
- ec.put("*" + CONTENT_KEY_ALGORITHM + "*", providedEncAlg);
- ec.put("*" + SIGNING_KEY_ALGORITHM + "*", providedSigAlg);
-
- populateKmsEcFromEc(context, ec);
-
- DecryptRequest.Builder request = DecryptRequest.builder();
- request.ciphertextBlob(SdkBytes.fromByteArray(Base64.decode(materialDescription.get(ENVELOPE_KEY))));
- request.encryptionContext(ec);
- final DecryptResponse decryptResponse = decrypt(request.build(), context);
- validateEncryptionKeyId(decryptResponse.keyId(), context);
-
- final Hkdf kdf;
- try {
- kdf = Hkdf.getInstance(KDF_ALG);
- } catch (NoSuchAlgorithmException e) {
- throw new DynamoDbEncryptionException(e);
- }
- kdf.init(decryptResponse.plaintext().asByteArray());
-
- final String[] encAlgParts = providedEncAlg.split("/", 2);
- int encLength = encAlgParts.length == 2 ? Integer.parseInt(encAlgParts[1]) : 256;
- final String[] sigAlgParts = providedSigAlg.split("/", 2);
- int sigLength = sigAlgParts.length == 2 ? Integer.parseInt(sigAlgParts[1]) : 256;
-
- final SecretKey encryptionKey = new SecretKeySpec(kdf.deriveKey(KDF_ENC_INFO, encLength / 8), encAlgParts[0]);
- final SecretKey macKey = new SecretKeySpec(kdf.deriveKey(KDF_SIG_INFO, sigLength / 8), sigAlgParts[0]);
-
- return new SymmetricRawMaterials(encryptionKey, macKey, materialDescription);
- }
-
- @Override
- public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
- final Map ec = new HashMap<>();
- ec.put("*" + CONTENT_KEY_ALGORITHM + "*", dataKeyDesc);
- ec.put("*" + SIGNING_KEY_ALGORITHM + "*", sigKeyDesc);
- populateKmsEcFromEc(context, ec);
-
- final String keyId = selectEncryptionKeyId(context);
- if (keyId == null || keyId.isEmpty()) {
- throw new DynamoDbEncryptionException("Encryption key id is empty.");
- }
-
- final GenerateDataKeyRequest.Builder req = GenerateDataKeyRequest.builder();
- req.keyId(keyId);
- // NumberOfBytes parameter is used because we're not using this key as an AES-256 key,
- // we're using it as an HKDF-SHA256 key.
- req.numberOfBytes(256 / 8);
- req.encryptionContext(ec);
-
- final GenerateDataKeyResponse dataKeyResult = generateDataKey(req.build(), context);
-
- final Map materialDescription = new HashMap<>(description);
- materialDescription.put(COVERED_ATTR_CTX_KEY, KEY_COVERAGE);
- materialDescription.put(KEY_WRAPPING_ALGORITHM, "kms");
- materialDescription.put(CONTENT_KEY_ALGORITHM, dataKeyDesc);
- materialDescription.put(SIGNING_KEY_ALGORITHM, sigKeyDesc);
- materialDescription.put(ENVELOPE_KEY,
- Base64.encodeToString(dataKeyResult.ciphertextBlob().asByteArray()));
-
- final Hkdf kdf;
- try {
- kdf = Hkdf.getInstance(KDF_ALG);
- } catch (NoSuchAlgorithmException e) {
- throw new DynamoDbEncryptionException(e);
- }
-
- kdf.init(dataKeyResult.plaintext().asByteArray());
-
- final SecretKey encryptionKey = new SecretKeySpec(kdf.deriveKey(KDF_ENC_INFO, dataKeyLength / 8), dataKeyAlg);
- final SecretKey signatureKey = new SecretKeySpec(kdf.deriveKey(KDF_SIG_INFO, sigKeyLength / 8), sigKeyAlg);
- return new SymmetricRawMaterials(encryptionKey, signatureKey, materialDescription);
- }
-
- /**
- * Get encryption key id that is used to create the {@link EncryptionMaterials}.
- *
- * @return encryption key id.
- */
- protected String getEncryptionKeyId() {
- return this.encryptionKeyId;
- }
-
- /**
- * Select encryption key id to be used to generate data key. The default implementation of this method returns
- * {@link DirectKmsMaterialsProvider#encryptionKeyId}.
- *
- * @param context encryption context.
- * @return the encryptionKeyId.
- * @throws DynamoDbEncryptionException when we fails to select a valid encryption key id.
- */
- protected String selectEncryptionKeyId(EncryptionContext context) throws DynamoDbEncryptionException {
- return getEncryptionKeyId();
- }
-
- /**
- * Validate the encryption key id. The default implementation of this method does not validate
- * encryption key id.
- *
- * @param encryptionKeyId encryption key id from {@link DecryptResponse}.
- * @param context encryption context.
- * @throws DynamoDbEncryptionException when encryptionKeyId is invalid.
- */
- protected void validateEncryptionKeyId(String encryptionKeyId, EncryptionContext context)
- throws DynamoDbEncryptionException {
- // No action taken.
- }
-
- /**
- * Decrypts ciphertext. The default implementation calls KMS to decrypt the ciphertext using the parameters
- * provided in the {@link DecryptRequest}. Subclass can override the default implementation to provide
- * additional request parameters using attributes within the {@link EncryptionContext}.
- *
- * @param request request parameters to decrypt the given ciphertext.
- * @param context additional useful data to decrypt the ciphertext.
- * @return the decrypted plaintext for the given ciphertext.
- */
- protected DecryptResponse decrypt(final DecryptRequest request, final EncryptionContext context) {
- return kms.decrypt(request);
- }
-
- /**
- * Returns a data encryption key that you can use in your application to encrypt data locally. The default
- * implementation calls KMS to generate the data key using the parameters provided in the
- * {@link GenerateDataKeyRequest}. Subclass can override the default implementation to provide additional
- * request parameters using attributes within the {@link EncryptionContext}.
- *
- * @param request request parameters to generate the data key.
- * @param context additional useful data to generate the data key.
- * @return the newly generated data key which includes both the plaintext and ciphertext.
- */
- protected GenerateDataKeyResponse generateDataKey(final GenerateDataKeyRequest request,
- final EncryptionContext context) {
- return kms.generateDataKey(request);
- }
-
- /**
- * Extracts relevant information from {@code context} and uses it to populate fields in
- * {@code kmsEc}. Subclass can override the default implementation to provide an alternative
- * encryption context in calls to KMS. Currently, the default implementation includes these fields:
- *
- * - {@code HashKeyName}
- * - {@code HashKeyValue}
- * - {@code RangeKeyName}
- * - {@code RangeKeyValue}
- * - {@link #TABLE_NAME_EC_KEY}
- * - {@code TableName}
- */
- protected void populateKmsEcFromEc(EncryptionContext context, Map kmsEc) {
- final String hashKeyName = context.getHashKeyName();
- if (hashKeyName != null) {
- final AttributeValue hashKey = context.getAttributeValues().get(hashKeyName);
- if (hashKey.n() != null) {
- kmsEc.put(hashKeyName, hashKey.n());
- } else if (hashKey.s() != null) {
- kmsEc.put(hashKeyName, hashKey.s());
- } else if (hashKey.b() != null) {
- kmsEc.put(hashKeyName, Base64.encodeToString(hashKey.b().asByteArray()));
- } else {
- throw new UnsupportedOperationException("DirectKmsMaterialsProvider only supports String, Number, and Binary HashKeys");
- }
- }
- final String rangeKeyName = context.getRangeKeyName();
- if (rangeKeyName != null) {
- final AttributeValue rangeKey = context.getAttributeValues().get(rangeKeyName);
- if (rangeKey.n() != null) {
- kmsEc.put(rangeKeyName, rangeKey.n());
- } else if (rangeKey.s() != null) {
- kmsEc.put(rangeKeyName, rangeKey.s());
- } else if (rangeKey.b() != null) {
- kmsEc.put(rangeKeyName, Base64.encodeToString(rangeKey.b().asByteArray()));
- } else {
- throw new UnsupportedOperationException("DirectKmsMaterialsProvider only supports String, Number, and Binary RangeKeys");
- }
- }
-
- final String tableName = context.getTableName();
- if (tableName != null) {
- kmsEc.put(TABLE_NAME_EC_KEY, tableName);
- }
- }
-
- @Override
- public void refresh() {
- // No action needed
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/EncryptionMaterialsProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/EncryptionMaterialsProvider.java
deleted file mode 100644
index b60fee3e..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/EncryptionMaterialsProvider.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-
-/**
- * Interface for providing encryption materials.
- * Implementations are free to use any strategy for providing encryption
- * materials, such as simply providing static material that doesn't change,
- * or more complicated implementations, such as integrating with existing
- * key management systems.
- *
- * @author Greg Rubin
- */
-public interface EncryptionMaterialsProvider {
-
- /**
- * Retrieves encryption materials matching the specified description from some source.
- *
- * @param context
- * Information to assist in selecting a the proper return value. The implementation
- * is free to determine the minimum necessary for successful processing.
- *
- * @return
- * The encryption materials that match the description, or null if no matching encryption materials found.
- */
- DecryptionMaterials getDecryptionMaterials(EncryptionContext context);
-
- /**
- * Returns EncryptionMaterials which the caller can use for encryption.
- * Each implementation of EncryptionMaterialsProvider can choose its own
- * strategy for loading encryption material. For example, an
- * implementation might load encryption material from an existing key
- * management system, or load new encryption material when keys are
- * rotated.
- *
- * @param context
- * Information to assist in selecting a the proper return value. The implementation
- * is free to determine the minimum necessary for successful processing.
- *
- * @return EncryptionMaterials which the caller can use to encrypt or
- * decrypt data.
- */
- EncryptionMaterials getEncryptionMaterials(EncryptionContext context);
-
- /**
- * Forces this encryption materials provider to refresh its encryption
- * material. For many implementations of encryption materials provider,
- * this may simply be a no-op, such as any encryption materials provider
- * implementation that vends static/non-changing encryption material.
- * For other implementations that vend different encryption material
- * throughout their lifetime, this method should force the encryption
- * materials provider to refresh its encryption material.
- */
- void refresh();
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/KeyStoreMaterialsProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/KeyStoreMaterialsProvider.java
deleted file mode 100644
index 483b81b5..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/KeyStoreMaterialsProvider.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyStore;
-import java.security.KeyStore.Entry;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStore.ProtectionParameter;
-import java.security.KeyStore.SecretKeyEntry;
-import java.security.KeyStore.TrustedCertificateEntry;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.UnrecoverableEntryException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.exceptions.DynamoDbEncryptionException;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.AsymmetricRawMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.SymmetricRawMaterials;
-
-/**
- * @author Greg Rubin
- */
-public class KeyStoreMaterialsProvider implements EncryptionMaterialsProvider {
- private final Map description;
- private final String encryptionAlias;
- private final String signingAlias;
- private final ProtectionParameter encryptionProtection;
- private final ProtectionParameter signingProtection;
- private final KeyStore keyStore;
- private final AtomicReference currMaterials =
- new AtomicReference<>();
-
- public KeyStoreMaterialsProvider(KeyStore keyStore, String encryptionAlias, String signingAlias, Map description)
- throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
- this(keyStore, encryptionAlias, signingAlias, null, null, description);
- }
-
- public KeyStoreMaterialsProvider(KeyStore keyStore, String encryptionAlias, String signingAlias,
- ProtectionParameter encryptionProtection, ProtectionParameter signingProtection,
- Map description)
- throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
- super();
- this.keyStore = keyStore;
- this.encryptionAlias = encryptionAlias;
- this.signingAlias = signingAlias;
- this.encryptionProtection = encryptionProtection;
- this.signingProtection = signingProtection;
- this.description = Collections.unmodifiableMap(new HashMap<>(description));
-
- validateKeys();
- loadKeys();
- }
-
- @Override
- public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
- CurrentMaterials materials = currMaterials.get();
- if (context.getMaterialDescription().entrySet().containsAll(description.entrySet())) {
- if (materials.encryptionEntry instanceof SecretKeyEntry) {
- return materials.symRawMaterials;
- } else {
- try {
- return makeAsymMaterials(materials, context.getMaterialDescription());
- } catch (GeneralSecurityException ex) {
- throw new DynamoDbEncryptionException("Unable to decrypt envelope key", ex);
- }
- }
- } else {
- return null;
- }
- }
-
- @Override
- public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
- CurrentMaterials materials = currMaterials.get();
- if (materials.encryptionEntry instanceof SecretKeyEntry) {
- return materials.symRawMaterials;
- } else {
- try {
- return makeAsymMaterials(materials, description);
- } catch (GeneralSecurityException ex) {
- throw new DynamoDbEncryptionException("Unable to encrypt envelope key", ex);
- }
- }
- }
-
- private AsymmetricRawMaterials makeAsymMaterials(CurrentMaterials materials,
- Map description) throws GeneralSecurityException {
- KeyPair encryptionPair = entry2Pair(materials.encryptionEntry);
- if (materials.signingEntry instanceof SecretKeyEntry) {
- return new AsymmetricRawMaterials(encryptionPair,
- ((SecretKeyEntry) materials.signingEntry).getSecretKey(), description);
- } else {
- return new AsymmetricRawMaterials(encryptionPair, entry2Pair(materials.signingEntry),
- description);
- }
- }
-
- private static KeyPair entry2Pair(Entry entry) {
- PublicKey pub = null;
- PrivateKey priv = null;
-
- if (entry instanceof PrivateKeyEntry) {
- PrivateKeyEntry pk = (PrivateKeyEntry) entry;
- if (pk.getCertificate() != null) {
- pub = pk.getCertificate().getPublicKey();
- }
- priv = pk.getPrivateKey();
- } else if (entry instanceof TrustedCertificateEntry) {
- TrustedCertificateEntry tc = (TrustedCertificateEntry) entry;
- pub = tc.getTrustedCertificate().getPublicKey();
- } else {
- throw new IllegalArgumentException(
- "Only entry types PrivateKeyEntry and TrustedCertificateEntry are supported.");
- }
- return new KeyPair(pub, priv);
- }
-
- /**
- * Reloads the keys from the underlying keystore by calling
- * {@link KeyStore#getEntry(String, ProtectionParameter)} again for each of them.
- */
- @Override
- public void refresh() {
- try {
- loadKeys();
- } catch (GeneralSecurityException ex) {
- throw new DynamoDbEncryptionException("Unable to load keys from keystore", ex);
- }
- }
-
- private void validateKeys() throws KeyStoreException {
- if (!keyStore.containsAlias(encryptionAlias)) {
- throw new IllegalArgumentException("Keystore does not contain alias: "
- + encryptionAlias);
- }
- if (!keyStore.containsAlias(signingAlias)) {
- throw new IllegalArgumentException("Keystore does not contain alias: "
- + signingAlias);
- }
- }
-
- private void loadKeys() throws NoSuchAlgorithmException, UnrecoverableEntryException,
- KeyStoreException {
- Entry encryptionEntry = keyStore.getEntry(encryptionAlias, encryptionProtection);
- Entry signingEntry = keyStore.getEntry(signingAlias, signingProtection);
- CurrentMaterials newMaterials = new CurrentMaterials(encryptionEntry, signingEntry);
- currMaterials.set(newMaterials);
- }
-
- private class CurrentMaterials {
- public final Entry encryptionEntry;
- public final Entry signingEntry;
- public final SymmetricRawMaterials symRawMaterials;
-
- public CurrentMaterials(Entry encryptionEntry, Entry signingEntry) {
- super();
- this.encryptionEntry = encryptionEntry;
- this.signingEntry = signingEntry;
-
- if (encryptionEntry instanceof SecretKeyEntry) {
- if (signingEntry instanceof SecretKeyEntry) {
- this.symRawMaterials = new SymmetricRawMaterials(
- ((SecretKeyEntry) encryptionEntry).getSecretKey(),
- ((SecretKeyEntry) signingEntry).getSecretKey(),
- description);
- } else {
- this.symRawMaterials = new SymmetricRawMaterials(
- ((SecretKeyEntry) encryptionEntry).getSecretKey(),
- entry2Pair(signingEntry),
- description);
- }
- } else {
- this.symRawMaterials = null;
- }
- }
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/MostRecentProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/MostRecentProvider.java
deleted file mode 100644
index f0edc768..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/MostRecentProvider.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2016-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
- * in compliance with the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.ReentrantLock;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.store.ProviderStore;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.LRUCache;
-
-/**
- * This meta-Provider encrypts data with the most recent version of keying materials from a
- * {@link ProviderStore} and decrypts using whichever version is appropriate. It also caches the
- * results from the {@link ProviderStore} to avoid excessive load on the backing systems. The cache
- * is not currently configurable.
- */
-public class MostRecentProvider implements EncryptionMaterialsProvider {
- private static final long MILLI_TO_NANO = 1000000L;
- private static final long TTL_GRACE_IN_NANO = 500 * MILLI_TO_NANO;
- private final ProviderStore keystore;
- protected final String defaultMaterialName;
- private final long ttlInNanos;
- private final LRUCache cache;
- private final LRUCache currentVersions;
-
- /**
- * Creates a new {@link MostRecentProvider}.
- *
- * @param ttlInMillis
- * The length of time in milliseconds to cache the most recent provider
- */
- public MostRecentProvider(final ProviderStore keystore, final String materialName, final long ttlInMillis) {
- this.keystore = checkNotNull(keystore, "keystore must not be null");
- this.defaultMaterialName = materialName;
- this.ttlInNanos = ttlInMillis * MILLI_TO_NANO;
- this.cache = new LRUCache(1000);
- this.currentVersions = new LRUCache<>(1000);
- }
-
- @Override
- public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
- final String materialName = getMaterialName(context);
- final LockedState ls = getCurrentVersion(materialName);
-
- final State s = ls.getState();
- if (s.provider != null && System.nanoTime() - s.lastUpdated <= ttlInNanos) {
- return s.provider.getEncryptionMaterials(context);
- }
- if (s.provider == null || System.nanoTime() - s.lastUpdated > ttlInNanos + TTL_GRACE_IN_NANO) {
- // Either we don't have a provider at all, or we're more than 500 milliseconds past
- // our update time. Either way, grab the lock and force an update.
- ls.lock();
- } else if (!ls.tryLock()) {
- // If we can't get the lock immediately, just use the current provider
- return s.provider.getEncryptionMaterials(context);
- }
-
- try {
- final long newVersion = keystore.getMaxVersion(materialName);
- final long currentVersion;
- final EncryptionMaterialsProvider currentProvider;
- if (newVersion < 0) {
- // First version of the material, so we want to allow creation
- currentVersion = 0;
- currentProvider = keystore.getOrCreate(materialName, currentVersion);
- cache.add(buildCacheKey(materialName, currentVersion), currentProvider);
- } else if (newVersion != s.currentVersion) {
- // We're retrieving an existing version, so we avoid the creation
- // flow as it is slower
- currentVersion = newVersion;
- currentProvider = keystore.getProvider(materialName, currentVersion);
- cache.add(buildCacheKey(materialName, currentVersion), currentProvider);
- } else {
- // Our version hasn't changed, so we'll just re-use the existing
- // provider to avoid the overhead of retrieving and building a new one
- currentVersion = newVersion;
- currentProvider = s.provider;
- // There is no need to add this to the cache as it's already there
- }
-
- ls.update(currentProvider, currentVersion);
-
- return ls.getState().provider.getEncryptionMaterials(context);
- } finally {
- ls.unlock();
- }
- }
-
- public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
- final String materialName = getMaterialName(context);
- final long version = keystore.getVersionFromMaterialDescription(
- context.getMaterialDescription());
- EncryptionMaterialsProvider provider = cache.get(buildCacheKey(materialName, version));
- if (provider == null) {
- provider = keystore.getProvider(materialName, version);
- cache.add(buildCacheKey(materialName, version), provider);
- }
- return provider.getDecryptionMaterials(context);
- }
-
- /**
- * Completely empties the cache of both the current and old versions.
- */
- @Override
- public void refresh() {
- currentVersions.clear();
- cache.clear();
- }
-
- public String getMaterialName() {
- return defaultMaterialName;
- }
-
- public long getTtlInMills() {
- return ttlInNanos / MILLI_TO_NANO;
- }
-
- /**
- * The current version of the materials being used for encryption. Returns -1 if we do not
- * currently have a current version.
- */
- public long getCurrentVersion() {
- return getCurrentVersion(getMaterialName()).getState().currentVersion;
- }
-
- /**
- * The last time the current version was updated. Returns 0 if we do not currently have a
- * current version.
- */
- public long getLastUpdated() {
- return getCurrentVersion(getMaterialName()).getState().lastUpdated / MILLI_TO_NANO;
- }
-
- protected String getMaterialName(final EncryptionContext context) {
- return defaultMaterialName;
- }
-
- private LockedState getCurrentVersion(final String materialName) {
- final LockedState result = currentVersions.get(materialName);
- if (result == null) {
- currentVersions.add(materialName, new LockedState());
- return currentVersions.get(materialName);
- } else {
- return result;
- }
- }
-
- private static String buildCacheKey(final String materialName, final long version) {
- StringBuilder result = new StringBuilder(materialName);
- result.append('#');
- result.append(version);
- return result.toString();
- }
-
- private static V checkNotNull(final V ref, final String errMsg) {
- if (ref == null) {
- throw new NullPointerException(errMsg);
- } else {
- return ref;
- }
- }
-
- private static class LockedState {
- private final ReentrantLock lock = new ReentrantLock(true);
- private volatile AtomicReference state = new AtomicReference<>(new State());
-
- public State getState() {
- return state.get();
- }
-
- public void unlock() {
- lock.unlock();
- }
-
- public boolean tryLock() {
- return lock.tryLock();
- }
-
- public void lock() {
- lock.lock();
- }
-
- public void update(EncryptionMaterialsProvider provider, long currentVersion) {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalStateException("Lock not held by current thread");
- }
- state.set(new State(provider, currentVersion));
- }
- }
-
- private static class State {
- public final EncryptionMaterialsProvider provider;
- public final long currentVersion;
- public final long lastUpdated;
-
- public State() {
- this(null, -1);
- }
-
- public State(EncryptionMaterialsProvider provider, long currentVersion) {
- this.provider = provider;
- this.currentVersion = currentVersion;
- this.lastUpdated = currentVersion == -1 ? 0 : System.nanoTime();
- }
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/SymmetricStaticProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/SymmetricStaticProvider.java
deleted file mode 100644
index 8a63a032..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/SymmetricStaticProvider.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.CryptographicMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.SymmetricRawMaterials;
-
-/**
- * A provider which always returns the same provided symmetric
- * encryption/decryption key and the same signing/verification key(s).
- *
- * @author Greg Rubin
- */
-public class SymmetricStaticProvider implements EncryptionMaterialsProvider {
- private final SymmetricRawMaterials materials;
-
- /**
- * @param encryptionKey
- * the value to be returned by
- * {@link #getEncryptionMaterials(EncryptionContext)} and
- * {@link #getDecryptionMaterials(EncryptionContext)}
- * @param signingPair
- * the keypair used to sign/verify the data stored in Dynamo. If
- * only the public key is provided, then this provider may be
- * used for decryption, but not encryption.
- */
- public SymmetricStaticProvider(SecretKey encryptionKey, KeyPair signingPair) {
- this(encryptionKey, signingPair, Collections.emptyMap());
- }
-
- /**
- * @param encryptionKey
- * the value to be returned by
- * {@link #getEncryptionMaterials(EncryptionContext)} and
- * {@link #getDecryptionMaterials(EncryptionContext)}
- * @param signingPair
- * the keypair used to sign/verify the data stored in Dynamo. If
- * only the public key is provided, then this provider may be
- * used for decryption, but not encryption.
- * @param description
- * the value to be returned by
- * {@link CryptographicMaterials#getMaterialDescription()} for
- * any {@link CryptographicMaterials} returned by this object.
- */
- public SymmetricStaticProvider(SecretKey encryptionKey,
- KeyPair signingPair, Map description) {
- materials = new SymmetricRawMaterials(encryptionKey, signingPair,
- description);
- }
-
- /**
- * @param encryptionKey
- * the value to be returned by
- * {@link #getEncryptionMaterials(EncryptionContext)} and
- * {@link #getDecryptionMaterials(EncryptionContext)}
- * @param macKey
- * the key used to sign/verify the data stored in Dynamo.
- */
- public SymmetricStaticProvider(SecretKey encryptionKey, SecretKey macKey) {
- this(encryptionKey, macKey, Collections.emptyMap());
- }
-
- /**
- * @param encryptionKey
- * the value to be returned by
- * {@link #getEncryptionMaterials(EncryptionContext)} and
- * {@link #getDecryptionMaterials(EncryptionContext)}
- * @param macKey
- * the key used to sign/verify the data stored in Dynamo.
- * @param description
- * the value to be returned by
- * {@link CryptographicMaterials#getMaterialDescription()} for
- * any {@link CryptographicMaterials} returned by this object.
- */
- public SymmetricStaticProvider(SecretKey encryptionKey, SecretKey macKey, Map description) {
- materials = new SymmetricRawMaterials(encryptionKey, macKey, description);
- }
-
- /**
- * Returns the encryptionKey
provided to the constructor if and only if
- * materialDescription
is a super-set (may be equal) to the
- * description
provided to the constructor.
- */
- @Override
- public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
- if (context.getMaterialDescription().entrySet().containsAll(materials.getMaterialDescription().entrySet())) {
- return materials;
- }
- else {
- return null;
- }
- }
-
- /**
- * Returns the encryptionKey
provided to the constructor.
- */
- @Override
- public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
- return materials;
- }
-
- /**
- * Does nothing.
- */
- @Override
- public void refresh() {
- // Do Nothing
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/WrappedMaterialsProvider.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/WrappedMaterialsProvider.java
deleted file mode 100644
index 1c92fb3f..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/WrappedMaterialsProvider.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2014-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers;
-
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.KeyPair;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.exceptions.DynamoDbEncryptionException;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.CryptographicMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.DecryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.EncryptionMaterials;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.materials.WrappedRawMaterials;
-
-/**
- * This provider will use create a unique (random) symmetric key upon each call to
- * {@link #getEncryptionMaterials(EncryptionContext)}. Practically, this means each record in DynamoDB will be
- * encrypted under a unique record key. A wrapped/encrypted copy of this record key is stored in the
- * MaterialsDescription field of that record and is unwrapped/decrypted upon reading that record.
- *
- * This is generally a more secure way of encrypting data than with the
- * {@link SymmetricStaticProvider}.
- *
- * @see WrappedRawMaterials
- *
- * @author Greg Rubin
- */
-public class WrappedMaterialsProvider implements EncryptionMaterialsProvider {
- private final Key wrappingKey;
- private final Key unwrappingKey;
- private final KeyPair sigPair;
- private final SecretKey macKey;
- private final Map description;
-
- /**
- * @param wrappingKey
- * The key used to wrap/encrypt the symmetric record key. (May be the same as the
- * unwrappingKey
.)
- * @param unwrappingKey
- * The key used to unwrap/decrypt the symmetric record key. (May be the same as the
- * wrappingKey
.) If null, then this provider may only be used for
- * decryption, but not encryption.
- * @param signingPair
- * the keypair used to sign/verify the data stored in Dynamo. If only the public key
- * is provided, then this provider may only be used for decryption, but not
- * encryption.
- */
- public WrappedMaterialsProvider(Key wrappingKey, Key unwrappingKey, KeyPair signingPair) {
- this(wrappingKey, unwrappingKey, signingPair, Collections.emptyMap());
- }
-
- /**
- * @param wrappingKey
- * The key used to wrap/encrypt the symmetric record key. (May be the same as the
- * unwrappingKey
.)
- * @param unwrappingKey
- * The key used to unwrap/decrypt the symmetric record key. (May be the same as the
- * wrappingKey
.) If null, then this provider may only be used for
- * decryption, but not encryption.
- * @param signingPair
- * the keypair used to sign/verify the data stored in Dynamo. If only the public key
- * is provided, then this provider may only be used for decryption, but not
- * encryption.
- * @param description
- * description the value to be returned by
- * {@link CryptographicMaterials#getMaterialDescription()} for any
- * {@link CryptographicMaterials} returned by this object.
- */
- public WrappedMaterialsProvider(Key wrappingKey, Key unwrappingKey, KeyPair signingPair, Map description) {
- this.wrappingKey = wrappingKey;
- this.unwrappingKey = unwrappingKey;
- this.sigPair = signingPair;
- this.macKey = null;
- this.description = Collections.unmodifiableMap(new HashMap<>(description));
- }
-
- /**
- * @param wrappingKey
- * The key used to wrap/encrypt the symmetric record key. (May be the same as the
- * unwrappingKey
.)
- * @param unwrappingKey
- * The key used to unwrap/decrypt the symmetric record key. (May be the same as the
- * wrappingKey
.) If null, then this provider may only be used for
- * decryption, but not encryption.
- * @param macKey
- * the key used to sign/verify the data stored in Dynamo.
- */
- public WrappedMaterialsProvider(Key wrappingKey, Key unwrappingKey, SecretKey macKey) {
- this(wrappingKey, unwrappingKey, macKey, Collections.emptyMap());
- }
-
- /**
- * @param wrappingKey
- * The key used to wrap/encrypt the symmetric record key. (May be the same as the
- * unwrappingKey
.)
- * @param unwrappingKey
- * The key used to unwrap/decrypt the symmetric record key. (May be the same as the
- * wrappingKey
.) If null, then this provider may only be used for
- * decryption, but not encryption.
- * @param macKey
- * the key used to sign/verify the data stored in Dynamo.
- * @param description
- * description the value to be returned by
- * {@link CryptographicMaterials#getMaterialDescription()} for any
- * {@link CryptographicMaterials} returned by this object.
- */
- public WrappedMaterialsProvider(Key wrappingKey, Key unwrappingKey, SecretKey macKey, Map description) {
- this.wrappingKey = wrappingKey;
- this.unwrappingKey = unwrappingKey;
- this.sigPair = null;
- this.macKey = macKey;
- this.description = Collections.unmodifiableMap(new HashMap<>(description));
- }
-
- @Override
- public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
- try {
- if (macKey != null) {
- return new WrappedRawMaterials(wrappingKey, unwrappingKey, macKey, context.getMaterialDescription());
- } else {
- return new WrappedRawMaterials(wrappingKey, unwrappingKey, sigPair, context.getMaterialDescription());
- }
- } catch (GeneralSecurityException ex) {
- throw new DynamoDbEncryptionException("Unable to decrypt envelope key", ex);
- }
- }
-
- @Override
- public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
- try {
- if (macKey != null) {
- return new WrappedRawMaterials(wrappingKey, unwrappingKey, macKey, description);
- } else {
- return new WrappedRawMaterials(wrappingKey, unwrappingKey, sigPair, description);
- }
- } catch (GeneralSecurityException ex) {
- throw new DynamoDbEncryptionException("Unable to encrypt envelope key", ex);
- }
- }
-
- @Override
- public void refresh() {
- // Do nothing
- }
-}
diff --git a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/store/MetaStore.java b/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/store/MetaStore.java
deleted file mode 100644
index 9bc50036..00000000
--- a/sdk2/src/main/java/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/store/MetaStore.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright 2015-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
- * in compliance with the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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 software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.store;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
-import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
-import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
-import software.amazon.awssdk.services.dynamodb.model.ComparisonOperator;
-import software.amazon.awssdk.services.dynamodb.model.Condition;
-import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
-import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
-import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse;
-import software.amazon.awssdk.services.dynamodb.model.ExpectedAttributeValue;
-import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
-import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
-import software.amazon.awssdk.services.dynamodb.model.KeyType;
-import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
-import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
-import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
-import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.DynamoDbEncryptionConfiguration;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.EncryptionAction;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.DynamoDbEncryptor;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.EncryptionContext;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.EncryptionMaterialsProvider;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.encryption.providers.WrappedMaterialsProvider;
-import software.amazon.cryptools.dynamodbencryptionclientsdk2.internal.Utils;
-
-
-/**
- * Provides a simple collection of EncryptionMaterialProviders backed by an encrypted DynamoDB
- * table. This can be used to build key hierarchies or meta providers.
- *
- * Currently, this only supports AES-256 in AESWrap mode and HmacSHA256 for the providers persisted
- * in the table.
- *
- * @author rubin
- */
-public class MetaStore extends ProviderStore {
- private static final String INTEGRITY_ALGORITHM_FIELD = "intAlg";
- private static final String INTEGRITY_KEY_FIELD = "int";
- private static final String ENCRYPTION_ALGORITHM_FIELD = "encAlg";
- private static final String ENCRYPTION_KEY_FIELD = "enc";
- private static final Pattern COMBINED_PATTERN = Pattern.compile("([^#]+)#(\\d*)");
- private static final String DEFAULT_INTEGRITY = "HmacSHA256";
- private static final String DEFAULT_ENCRYPTION = "AES";
- private static final String MATERIAL_TYPE_VERSION = "t";
- private static final String META_ID = "amzn-ddb-meta-id";
-
- private static final String DEFAULT_HASH_KEY = "N";
- private static final String DEFAULT_RANGE_KEY = "V";
-
- /** Default no-op implementation of {@link ExtraDataSupplier}. */
- private static final EmptyExtraDataSupplier EMPTY_EXTRA_DATA_SUPPLIER
- = new EmptyExtraDataSupplier();
-
- /** DDB fields that must be encrypted. */
- private static final Set ENCRYPTED_FIELDS;
- static {
- final Set tempEncryptedFields = new HashSet<>();
- tempEncryptedFields.add(MATERIAL_TYPE_VERSION);
- tempEncryptedFields.add(ENCRYPTION_KEY_FIELD);
- tempEncryptedFields.add(ENCRYPTION_ALGORITHM_FIELD);
- tempEncryptedFields.add(INTEGRITY_KEY_FIELD);
- tempEncryptedFields.add(INTEGRITY_ALGORITHM_FIELD);
- ENCRYPTED_FIELDS = tempEncryptedFields;
- }
-
- private final Map doesNotExist;
- private final DynamoDbEncryptionConfiguration encryptionConfiguration;
- private final String tableName;
- private final DynamoDbClient ddb;
- private final DynamoDbEncryptor encryptor;
- private final ExtraDataSupplier extraDataSupplier;
-
- /**
- * Provides extra data that should be persisted along with the standard material data.
- */
- public interface ExtraDataSupplier {
-
- /**
- * Gets the extra data attributes for the specified material name.
- *
- * @param materialName material name.
- * @param version version number.
- * @return plain text of the extra data.
- */
- Map getAttributes(final String materialName, final long version);
-
- /**
- * Gets the extra data field names that should be signed only but not encrypted.
- *
- * @return signed only fields.
- */
- Set getSignedOnlyFieldNames();
- }
-
- /**
- * Create a new MetaStore with specified table name.
- *
- * @param ddb Interface for accessing DynamoDB.
- * @param tableName DynamoDB table name for this {@link MetaStore}.
- * @param encryptor used to perform crypto operations on the record attributes.
- */
- public MetaStore(final DynamoDbClient ddb, final String tableName,
- final DynamoDbEncryptor encryptor) {
- this(ddb, tableName, encryptor, EMPTY_EXTRA_DATA_SUPPLIER);
- }
-
- /**
- * Create a new MetaStore with specified table name and extra data supplier.
- *
- * @param ddb Interface for accessing DynamoDB.
- * @param tableName DynamoDB table name for this {@link MetaStore}.
- * @param encryptor used to perform crypto operations on the record attributes
- * @param extraDataSupplier provides extra data that should be stored along with the material.
- */
- public MetaStore(final DynamoDbClient ddb, final String tableName,
- final DynamoDbEncryptor encryptor, final ExtraDataSupplier extraDataSupplier) {
- this.ddb = checkNotNull(ddb, "ddb must not be null");
- this.tableName = checkNotNull(tableName, "tableName must not be null");
- this.encryptor = checkNotNull(encryptor, "encryptor must not be null");
- this.extraDataSupplier = checkNotNull(extraDataSupplier, "extraDataSupplier must not be null");
-
- final Map tmpExpected = new HashMap<>();
- tmpExpected.put(DEFAULT_HASH_KEY, ExpectedAttributeValue.builder().exists(false).build());
- tmpExpected.put(DEFAULT_RANGE_KEY, ExpectedAttributeValue.builder().exists(false).build());
- doesNotExist = Collections.unmodifiableMap(tmpExpected);
-
- this.encryptionConfiguration = DynamoDbEncryptionConfiguration.builder()
- .encryptionContext(EncryptionContext.builder()
- .tableName(this.tableName)
- .hashKeyName(DEFAULT_HASH_KEY)
- .rangeKeyName(DEFAULT_RANGE_KEY)
- .build())
- // All fields default to ENCRYPT_AND_SIGN with 'sign only' fields being explicitly overridden
- .defaultEncryptionAction(EncryptionAction.ENCRYPT_AND_SIGN)
- .addEncryptionActionOverrides(getSignedOnlyFields(extraDataSupplier).stream()
- .collect(Collectors.toMap(Function.identity(),
- ignored -> EncryptionAction.SIGN_ONLY)))
- .build();
- ;
- }
-
- @Override
- public EncryptionMaterialsProvider getProvider(final String materialName, final long version) {
- final Map item = getMaterialItem(materialName, version);
- return decryptProvider(item);
- }
-
- @Override
- public EncryptionMaterialsProvider getOrCreate(final String materialName, final long nextId) {
- final Map plaintext = createMaterialItem(materialName, nextId);
- final Map ciphertext = conditionalPut(getEncryptedText(plaintext));
- return decryptProvider(ciphertext);
- }
-
- @Override
- public long getMaxVersion(final String materialName) {
-
- final List