From 0d20979c7def0d37058bf65996f742937bacf08d Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Fri, 17 Jan 2020 20:01:23 -0800 Subject: [PATCH 1/2] Using original Materials classes instead of new Keyring classes Since the CryptoMaterialsManager interface uses the original EncryptionMaterials and DecryptionMaterials, we would force customers to update their code once we deprecate those materials in favor of the new Keyring versions. To avoid this, Keyrings will now use modified versions of the original Materials classes, with certain methods deprecated. In addition, this commit removed the MasterKeyProviderKeyring, which was found to not be feasible for the Java ESDK since MasterKeys are provided in the result object, which would force MasterKeys to be incorporated into Keyrings. --- .../keyrings/DecryptionMaterials.java | 227 ------------ .../keyrings/EncryptionMaterials.java | 270 -------------- .../encryptionsdk/keyrings/Keyring.java | 2 + .../encryptionsdk/keyrings/KmsKeyring.java | 23 +- .../keyrings/MasterKeyProviderKeyring.java | 137 -------- .../encryptionsdk/keyrings/MultiKeyring.java | 12 +- .../encryptionsdk/keyrings/RawKeyring.java | 22 +- .../keyrings/StandardKeyrings.java | 12 - .../model/DecryptionMaterials.java | 143 +++++++- .../model/EncryptionMaterials.java | 96 ++++- .../keyrings/KmsKeyringTest.java | 134 ++++--- .../MasterKeyProviderKeyringTest.java | 332 ------------------ .../keyrings/MultiKeyringTest.java | 22 +- .../keyrings/RawAesKeyringTest.java | 40 ++- .../keyrings/RawKeyringTest.java | 82 +++-- .../keyrings/RawRsaKeyringTest.java | 40 ++- .../DecryptionMaterialsTest.java | 101 +++--- .../EncryptionMaterialsTest.java | 112 +++--- 18 files changed, 540 insertions(+), 1267 deletions(-) delete mode 100644 src/main/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterials.java delete mode 100644 src/main/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterials.java delete mode 100644 src/main/java/com/amazonaws/encryptionsdk/keyrings/MasterKeyProviderKeyring.java delete mode 100644 src/test/java/com/amazonaws/encryptionsdk/keyrings/MasterKeyProviderKeyringTest.java rename src/test/java/com/amazonaws/encryptionsdk/{keyrings => model}/DecryptionMaterialsTest.java (60%) rename src/test/java/com/amazonaws/encryptionsdk/{keyrings => model}/EncryptionMaterialsTest.java (63%) diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterials.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterials.java deleted file mode 100644 index 1cf84058e..000000000 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterials.java +++ /dev/null @@ -1,227 +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 com.amazonaws.encryptionsdk.keyrings; - -import com.amazonaws.encryptionsdk.CryptoAlgorithm; - -import javax.crypto.SecretKey; -import java.security.PublicKey; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import static java.util.Objects.requireNonNull; -import static org.apache.commons.lang3.Validate.isTrue; - -/** - * Contains the cryptographic materials needed for a decryption operation with Keyrings. - */ -public final class DecryptionMaterials { - private final CryptoAlgorithm algorithmSuite; - private SecretKey plaintextDataKey; - private final PublicKey verificationKey; - private final Map encryptionContext; - private final KeyringTrace keyringTrace; - - private DecryptionMaterials(Builder b) { - requireNonNull(b.algorithmSuite, "algorithmSuite is required"); - requireNonNull(b.keyringTrace, "keyringTrace is required"); - requireNonNull(b.encryptionContext, "encryptionContext is required"); - validatePlaintextDataKey(b.algorithmSuite, b.plaintextDataKey); - validateVerificationKey(b.algorithmSuite, b.verificationKey); - - algorithmSuite = b.algorithmSuite; - plaintextDataKey = b.plaintextDataKey; - verificationKey = b.verificationKey; - encryptionContext = b.encryptionContext; - keyringTrace = b.keyringTrace; - } - - /** - * The algorithm suite to use for this decryption operation. - */ - public CryptoAlgorithm getAlgorithmSuite() { - return algorithmSuite; - } - - /** - * Returns true if a plaintext data key has been populated. - * - * @return True if plaintext data key is populated, false otherwise. - */ - public boolean hasPlaintextDataKey() { - return this.plaintextDataKey != null; - } - - /** - * A data key to be used as input for encryption. - * - * @return The plaintext data key. - * @throws IllegalStateException if plaintext data key has not been populated. - */ - public SecretKey getPlaintextDataKey() throws IllegalStateException { - if (!hasPlaintextDataKey()) { - throw new IllegalStateException("plaintextDataKey has not been populated"); - } - return plaintextDataKey; - } - - /** - * Sets the plaintext data key. The plaintext data key must not already be populated. - * - * @param plaintextDataKey The plaintext data key. - * @param keyringTraceEntry The keyring trace entry recording this action. - */ - public void setPlaintextDataKey(SecretKey plaintextDataKey, KeyringTraceEntry keyringTraceEntry) { - if (hasPlaintextDataKey()) { - throw new IllegalStateException("plaintextDataKey was already populated"); - } - requireNonNull(plaintextDataKey, "plaintextDataKey is required"); - requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); - validatePlaintextDataKey(algorithmSuite, plaintextDataKey); - this.plaintextDataKey = plaintextDataKey; - keyringTrace.add(keyringTraceEntry); - } - - /** - * Returns true if verification key has been populated. - * - * @return True if verification key is populated, false otherwise. - */ - public boolean hasVerificationKey() { - return verificationKey != null; - } - - /** - * The verification key used for signature verification. - * - * @return The verification key. - * @throws IllegalStateException if a verification key has not been populated. - */ - public PublicKey getVerificationKey() throws IllegalStateException { - if (!hasVerificationKey()) { - throw new IllegalStateException(String.format( - "Signature verification is not supported by AlgorithmSuite %s", algorithmSuite.name())); - } - return verificationKey; - } - - public Map getEncryptionContext() { - return encryptionContext; - } - - public KeyringTrace getKeyringTrace() { - return keyringTrace; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DecryptionMaterials that = (DecryptionMaterials) o; - return algorithmSuite == that.algorithmSuite && - Objects.equals(plaintextDataKey, that.plaintextDataKey) && - Objects.equals(verificationKey, that.verificationKey) && - Objects.equals(encryptionContext, that.encryptionContext) && - Objects.equals(keyringTrace, that.keyringTrace); - } - - @Override - public int hashCode() { - return Objects.hash(algorithmSuite, plaintextDataKey, verificationKey, encryptionContext, keyringTrace); - } - - public static Builder newBuilder(CryptoAlgorithm algorithm) { - return new Builder(algorithm); - } - - public Builder toBuilder() { - return new Builder(this); - } - - private void validatePlaintextDataKey(CryptoAlgorithm algorithmSuite, SecretKey plaintextDataKey) throws IllegalArgumentException { - if (plaintextDataKey != null) { - isTrue(algorithmSuite.getDataKeyLength() == plaintextDataKey.getEncoded().length, - String.format("Incorrect key length. Expected %s but got %s", - algorithmSuite.getDataKeyLength(), plaintextDataKey.getEncoded().length)); - isTrue(algorithmSuite.getDataKeyAlgo().equalsIgnoreCase(plaintextDataKey.getAlgorithm()), - String.format("Incorrect key algorithm. Expected %s but got %s", - algorithmSuite.getDataKeyAlgo(), plaintextDataKey.getAlgorithm())); - } - } - - /** - * Validates that a verification key is specified if and only if - * the given algorithm suite supports signature verification. - */ - private void validateVerificationKey(CryptoAlgorithm algorithmSuite, PublicKey verificationKey) throws IllegalArgumentException { - if (algorithmSuite.getTrailingSignatureAlgo() == null && verificationKey != null) { - throw new IllegalArgumentException( - String.format("Algorithm Suite %s does not support signature verification", algorithmSuite.name())); - } else if (algorithmSuite.getTrailingSignatureAlgo() != null && verificationKey == null) { - throw new IllegalArgumentException( - String.format("Algorithm %s requires a verification key for signature verification", algorithmSuite.name())); - } - } - - public static final class Builder { - private CryptoAlgorithm algorithmSuite; - private SecretKey plaintextDataKey; - private PublicKey verificationKey; - private Map encryptionContext = Collections.emptyMap(); - private KeyringTrace keyringTrace = new KeyringTrace(); - - private Builder(CryptoAlgorithm algorithmSuite) { - this.algorithmSuite = algorithmSuite; - } - - private Builder(DecryptionMaterials result) { - this.algorithmSuite = result.algorithmSuite; - this.plaintextDataKey = result.plaintextDataKey; - this.verificationKey = result.verificationKey; - this.encryptionContext = result.encryptionContext; - this.keyringTrace = result.keyringTrace; - } - - public Builder algorithmSuite(CryptoAlgorithm algorithmSuite) { - this.algorithmSuite = algorithmSuite; - return this; - } - - public Builder plaintextDataKey(SecretKey plaintextDataKey) { - this.plaintextDataKey = plaintextDataKey; - return this; - } - - public Builder verificationKey(PublicKey verificationKey) { - this.verificationKey = verificationKey; - return this; - } - - public Builder encryptionContext(Map encryptionContext) { - this.encryptionContext = Collections.unmodifiableMap(new HashMap<>(encryptionContext)); - return this; - } - - public Builder keyringTrace(KeyringTrace keyringTrace) { - this.keyringTrace = keyringTrace; - return this; - } - - public DecryptionMaterials build() { - return new DecryptionMaterials(this); - } - } -} diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterials.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterials.java deleted file mode 100644 index d52f5d355..000000000 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterials.java +++ /dev/null @@ -1,270 +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 com.amazonaws.encryptionsdk.keyrings; - -import com.amazonaws.encryptionsdk.CryptoAlgorithm; -import com.amazonaws.encryptionsdk.EncryptedDataKey; - -import javax.crypto.SecretKey; -import java.security.PrivateKey; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static java.util.Objects.requireNonNull; -import static org.apache.commons.lang3.Validate.isTrue; - -/** - * Contains the cryptographic materials needed for an encryption operation with Keyrings. - */ -public final class EncryptionMaterials { - private final CryptoAlgorithm algorithmSuite; - private final Map encryptionContext; - private final List encryptedDataKeys; - private SecretKey plaintextDataKey; - private final PrivateKey signingKey; - private final KeyringTrace keyringTrace; - - private EncryptionMaterials(Builder b) { - requireNonNull(b.algorithmSuite, "algorithmSuite is required"); - requireNonNull(b.keyringTrace, "keyringTrace is required"); - requireNonNull(b.encryptionContext, "encryptionContext is required"); - validatePlaintextDataKey(b.algorithmSuite, b.plaintextDataKey); - validateSigningKey(b.algorithmSuite, b.signingKey); - this.algorithmSuite = b.algorithmSuite; - this.encryptionContext = b.encryptionContext; - this.encryptedDataKeys = b.encryptedDataKeys; - this.plaintextDataKey = b.plaintextDataKey; - this.signingKey = b.signingKey; - this.keyringTrace = b.keyringTrace; - } - - public Builder toBuilder() { - return new Builder(this); - } - - public static Builder newBuilder(CryptoAlgorithm algorithmSuite) { - return new Builder(algorithmSuite); - } - - /** - * The algorithm suite to be used for encryption. - */ - public CryptoAlgorithm getAlgorithmSuite() { - return algorithmSuite; - } - - /** - * The encryption context associated with this encryption. - */ - public Map getEncryptionContext() { - return encryptionContext; - } - - /** - * An unmodifiable list of the encrypted data keys that correspond to the plaintext data key. - */ - public List getEncryptedDataKeys() { - return Collections.unmodifiableList(encryptedDataKeys); - } - - /** - * Add an encrypted data key to the list of encrypted data keys. - * - * @param encryptedDataKey The encrypted data key to add. - * @param keyringTraceEntry The keyring trace entry recording this action. - */ - public void addEncryptedDataKey(EncryptedDataKey encryptedDataKey, KeyringTraceEntry keyringTraceEntry) { - requireNonNull(encryptedDataKey, "encryptedDataKey is required"); - requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); - encryptedDataKeys.add(encryptedDataKey); - keyringTrace.add(keyringTraceEntry); - } - - /** - * Returns true if a plaintext data key has been populated. - * - * @return True if plaintext data key is populated, false otherwise. - */ - public boolean hasPlaintextDataKey() { - return this.plaintextDataKey != null; - } - - /** - * A data key to be used as input for encryption. - * - * @return The plaintext data key. - * @throws IllegalStateException if plain text data key has not been populated. - */ - public SecretKey getPlaintextDataKey() throws IllegalStateException { - if (!hasPlaintextDataKey()) { - throw new IllegalStateException("plaintextDataKey has not been populated"); - } - return plaintextDataKey; - } - - /** - * Sets the plaintext data key. The plaintext data key must not already be populated. - * - * @param plaintextDataKey The plaintext data key. - * @param keyringTraceEntry The keyring trace entry recording this action. - */ - public void setPlaintextDataKey(SecretKey plaintextDataKey, KeyringTraceEntry keyringTraceEntry) { - if (hasPlaintextDataKey()) { - throw new IllegalStateException("plaintextDataKey was already populated"); - } - requireNonNull(plaintextDataKey, "plaintextDataKey is required"); - requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); - validatePlaintextDataKey(algorithmSuite, plaintextDataKey); - this.plaintextDataKey = plaintextDataKey; - keyringTrace.add(keyringTraceEntry); - } - - /** - * Returns true if a signing key has been populated. - * - * @return True if signing key is populated, false otherwise. - */ - public boolean hasSigningKey() { - return this.signingKey != null; - } - - - /** - * The key to be used as the signing key for signature verification during encryption. - * - * @return The signing key. - * @throws IllegalStateException if signing key has not been populated. - */ - public PrivateKey getSigningKey() throws IllegalStateException { - if (!hasSigningKey()) { - throw new IllegalStateException(String.format( - "Signing is not supported by AlgorithmSuite %s", algorithmSuite.name())); - } - return signingKey; - } - - /** - * A keyring trace containing all of the actions that keyrings have taken on this set of encryption materials. - */ - public KeyringTrace getKeyringTrace() { - return keyringTrace; - } - - /** - * Validates that the given plaintext data key fits the specification - * for the data key algorithm specified in the given algorithm suite. - */ - private void validatePlaintextDataKey(CryptoAlgorithm algorithmSuite, SecretKey plaintextDataKey) throws IllegalArgumentException { - if (plaintextDataKey != null) { - isTrue(algorithmSuite.getDataKeyLength() == plaintextDataKey.getEncoded().length, - String.format("Incorrect data key length. Expected %s but got %s", - algorithmSuite.getDataKeyLength(), plaintextDataKey.getEncoded().length)); - isTrue(algorithmSuite.getDataKeyAlgo().equalsIgnoreCase(plaintextDataKey.getAlgorithm()), - String.format("Incorrect data key algorithm. Expected %s but got %s", - algorithmSuite.getDataKeyAlgo(), plaintextDataKey.getAlgorithm())); - } - } - - /** - * Validates that a signing key is specified only if and only if - * the given algorithm suite supports signature verification. - */ - private void validateSigningKey(CryptoAlgorithm algorithmSuite, PrivateKey signingKey) throws IllegalArgumentException { - if (algorithmSuite.getTrailingSignatureAlgo() == null && signingKey != null) { - throw new IllegalArgumentException( - String.format("Algorithm Suite %s does not support signing", algorithmSuite.name())); - } else if (algorithmSuite.getTrailingSignatureAlgo() != null && signingKey == null) { - throw new IllegalArgumentException( - String.format("Algorithm Suite %s requires a signing key for signing", algorithmSuite.name())); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EncryptionMaterials that = (EncryptionMaterials) o; - return algorithmSuite == that.algorithmSuite && - Objects.equals(encryptionContext, that.encryptionContext) && - Objects.equals(encryptedDataKeys, that.encryptedDataKeys) && - Objects.equals(plaintextDataKey, that.plaintextDataKey) && - Objects.equals(signingKey, that.signingKey) && - Objects.equals(keyringTrace, that.keyringTrace); - } - - @Override - public int hashCode() { - return Objects.hash(algorithmSuite, encryptionContext, encryptedDataKeys, plaintextDataKey, signingKey, keyringTrace); - } - - public static class Builder { - private CryptoAlgorithm algorithmSuite; - private Map encryptionContext = Collections.emptyMap(); - private List encryptedDataKeys = new ArrayList<>(); - private SecretKey plaintextDataKey; - private PrivateKey signingKey; - private KeyringTrace keyringTrace = new KeyringTrace(); - - private Builder(CryptoAlgorithm algorithmSuite) { - this.algorithmSuite = algorithmSuite; - } - - private Builder(EncryptionMaterials r) { - algorithmSuite = r.algorithmSuite; - encryptionContext = r.encryptionContext; - encryptedDataKeys = r.encryptedDataKeys; - plaintextDataKey = r.plaintextDataKey; - signingKey = r.signingKey; - keyringTrace = r.keyringTrace; - } - - public EncryptionMaterials build() { - return new EncryptionMaterials(this); - } - - public Builder algorithmSuite(CryptoAlgorithm algorithmSuite) { - this.algorithmSuite = algorithmSuite; - return this; - } - - public Builder encryptionContext(Map encryptionContext) { - this.encryptionContext = Collections.unmodifiableMap(new HashMap<>(encryptionContext)); - return this; - } - - public Builder encryptedDataKeys(List encryptedDataKeys) { - this.encryptedDataKeys = new ArrayList<>(encryptedDataKeys); - return this; - } - - public Builder plaintextDataKey(SecretKey plaintextDataKey) { - this.plaintextDataKey = plaintextDataKey; - return this; - } - - public Builder signingKey(PrivateKey signingKey) { - this.signingKey = signingKey; - return this; - } - - public Builder keyringTrace(KeyringTrace keyringTrace) { - this.keyringTrace = keyringTrace; - return this; - } - } -} diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/Keyring.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/Keyring.java index 20f4c69f5..93002270d 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/Keyring.java +++ b/src/main/java/com/amazonaws/encryptionsdk/keyrings/Keyring.java @@ -14,6 +14,8 @@ package com.amazonaws.encryptionsdk.keyrings; import com.amazonaws.encryptionsdk.EncryptedDataKey; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import java.util.List; diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java index 4b3974501..d0450ec29 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java +++ b/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java @@ -21,6 +21,9 @@ import com.amazonaws.encryptionsdk.kms.DataKeyEncryptionDao.DecryptDataKeyResult; import com.amazonaws.encryptionsdk.kms.DataKeyEncryptionDao.GenerateDataKeyResult; import com.amazonaws.encryptionsdk.kms.KmsUtils; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; +import com.amazonaws.encryptionsdk.model.KeyBlob; import java.util.ArrayList; import java.util.HashSet; @@ -77,7 +80,7 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { // If the input encryption materials do not contain a plaintext data key and this keyring does not // have a generator defined, OnEncrypt MUST not modify the encryption materials and MUST fail. - if (!encryptionMaterials.hasPlaintextDataKey() && generatorKeyId == null) { + if (encryptionMaterials.getCleartextDataKey() == null && generatorKeyId == null) { throw new AwsCryptoException("Encryption materials must contain either a plaintext data key or a generator"); } @@ -85,7 +88,7 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { // If the input encryption materials do not contain a plaintext data key and a generator is defined onEncrypt // MUST attempt to generate a new plaintext data key and encrypt that data key by calling KMS GenerateDataKey. - if (!encryptionMaterials.hasPlaintextDataKey()) { + if (encryptionMaterials.getCleartextDataKey() == null) { generateDataKey(encryptionMaterials); } else if (generatorKeyId != null) { // If this keyring's generator is defined and was not used to generate a data key, OnEncrypt @@ -102,19 +105,19 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { private void generateDataKey(final EncryptionMaterials encryptionMaterials) { final GenerateDataKeyResult result = dataKeyEncryptionDao.generateDataKey(generatorKeyId, - encryptionMaterials.getAlgorithmSuite(), encryptionMaterials.getEncryptionContext()); + encryptionMaterials.getAlgorithm(), encryptionMaterials.getEncryptionContext()); - encryptionMaterials.setPlaintextDataKey(result.getPlaintextDataKey(), + encryptionMaterials.setCleartextDataKey(result.getPlaintextDataKey(), new KeyringTraceEntry(KMS_PROVIDER_ID, generatorKeyId, KeyringTraceFlag.GENERATED_DATA_KEY)); - encryptionMaterials.addEncryptedDataKey(result.getEncryptedDataKey(), + encryptionMaterials.addEncryptedDataKey(new KeyBlob(result.getEncryptedDataKey()), new KeyringTraceEntry(KMS_PROVIDER_ID, generatorKeyId, KeyringTraceFlag.ENCRYPTED_DATA_KEY, KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT)); } private void encryptDataKey(final String keyId, final EncryptionMaterials encryptionMaterials) { final EncryptedDataKey encryptedDataKey = dataKeyEncryptionDao.encryptDataKey(keyId, - encryptionMaterials.getPlaintextDataKey(), encryptionMaterials.getEncryptionContext()); + encryptionMaterials.getCleartextDataKey(), encryptionMaterials.getEncryptionContext()); - encryptionMaterials.addEncryptedDataKey(encryptedDataKey, + encryptionMaterials.addEncryptedDataKey(new KeyBlob(encryptedDataKey), new KeyringTraceEntry(KMS_PROVIDER_ID, keyId, KeyringTraceFlag.ENCRYPTED_DATA_KEY, KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT)); } @@ -123,7 +126,7 @@ public void onDecrypt(DecryptionMaterials decryptionMaterials, List> implements Keyring { - - private final MasterKeyProvider masterKeyProvider; - - MasterKeyProviderKeyring(MasterKeyProvider masterKeyProvider) { - requireNonNull(masterKeyProvider, "masterKeyProvider is required"); - - this.masterKeyProvider = masterKeyProvider; - } - - @Override - public void onEncrypt(EncryptionMaterials encryptionMaterials) { - requireNonNull(encryptionMaterials, "encryptionMaterials are required"); - - final List masterKeys = masterKeyProvider.getMasterKeysForEncryption(MasterKeyRequest.newBuilder() - .setEncryptionContext(encryptionMaterials.getEncryptionContext()).build()); - - if (masterKeys == null || masterKeys.isEmpty()) { - throw new AwsCryptoException("No master keys available from the master key provider."); - } - - final K primaryMasterKey = masterKeys.get(0); - final List masterKeysToEncryptWith = new ArrayList<>(masterKeys); - - if (!encryptionMaterials.hasPlaintextDataKey()) { - final DataKey dataKey = primaryMasterKey.generateDataKey( - encryptionMaterials.getAlgorithmSuite(), encryptionMaterials.getEncryptionContext()); - encryptionMaterials.setPlaintextDataKey(dataKey.getKey(), new KeyringTraceEntry( - primaryMasterKey.getProviderId(), primaryMasterKey.getKeyId(), KeyringTraceFlag.GENERATED_DATA_KEY)); - encryptionMaterials.addEncryptedDataKey(dataKey, encryptTraceEntry(primaryMasterKey)); - // The primary master key has already been used for encryption, so remove it from the list to encrypt with - masterKeysToEncryptWith.remove(primaryMasterKey); - } - - final DataKey dataKey = new DataKey<>(encryptionMaterials.getPlaintextDataKey(), EMPTY_BYTE_ARRAY, - EMPTY_BYTE_ARRAY, primaryMasterKey); - - for (K masterKey : masterKeysToEncryptWith) { - final EncryptedDataKey encryptedDataKey = masterKey.encryptDataKey(encryptionMaterials.getAlgorithmSuite(), - encryptionMaterials.getEncryptionContext(), dataKey); - encryptionMaterials.addEncryptedDataKey(encryptedDataKey, encryptTraceEntry(masterKey)); - } - } - - @Override - public void onDecrypt(DecryptionMaterials decryptionMaterials, List encryptedDataKeys) { - requireNonNull(decryptionMaterials, "decryptionMaterials are required"); - requireNonNull(encryptedDataKeys, "encryptedDataKeys are required"); - - if (decryptionMaterials.hasPlaintextDataKey()) { - return; - } - - final DataKey dataKey; - try { - dataKey = masterKeyProvider.decryptDataKey(decryptionMaterials.getAlgorithmSuite(), encryptedDataKeys, - decryptionMaterials.getEncryptionContext()); - } catch (CannotUnwrapDataKeyException e) { - return; - } - - decryptionMaterials.setPlaintextDataKey(dataKey.getKey(), decryptTraceEntry(dataKey.getMasterKey())); - } - - private boolean signedEncryptionContext(MasterKey masterKey) { - if (masterKey instanceof KmsMasterKey) { - return true; - } - - if (masterKey instanceof JceMasterKey) { - return ((JceMasterKey) masterKey).isEncryptionContextSigned(); - } - - return false; - } - - private KeyringTraceEntry encryptTraceEntry(MasterKey masterKey) { - final List flags = new ArrayList<>(); - flags.add(ENCRYPTED_DATA_KEY); - - if (signedEncryptionContext(masterKey)) { - flags.add(SIGNED_ENCRYPTION_CONTEXT); - } - - return new KeyringTraceEntry(masterKey.getProviderId(), masterKey.getKeyId(), flags.toArray(new KeyringTraceFlag[]{})); - } - - private KeyringTraceEntry decryptTraceEntry(MasterKey masterKey) { - final List flags = new ArrayList<>(); - flags.add(DECRYPTED_DATA_KEY); - - if (signedEncryptionContext(masterKey)) { - flags.add(VERIFIED_ENCRYPTION_CONTEXT); - } - - return new KeyringTraceEntry(masterKey.getProviderId(), masterKey.getKeyId(), flags.toArray(new KeyringTraceFlag[]{})); - } -} diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyring.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyring.java index 7d957b281..b78dbf0c7 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyring.java +++ b/src/main/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyring.java @@ -16,6 +16,8 @@ import com.amazonaws.encryptionsdk.EncryptedDataKey; import com.amazonaws.encryptionsdk.exception.AwsCryptoException; import com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import java.util.ArrayList; import java.util.List; @@ -50,9 +52,9 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { generatorKeyring.onEncrypt(encryptionMaterials); } - if (!encryptionMaterials.hasPlaintextDataKey()) { - throw new AwsCryptoException("Either a generator keyring must be supplied that produces a plaintext " + - "data key or a plaintext data key must already be present in the encryption materials."); + if (encryptionMaterials.getCleartextDataKey() == null) { + throw new AwsCryptoException("Either a generator keyring must be supplied that produces a cleartext " + + "data key or a cleartext data key must already be present in the encryption materials."); } for (Keyring keyring : childrenKeyrings) { @@ -65,7 +67,7 @@ public void onDecrypt(DecryptionMaterials decryptionMaterials, List masterKeyProvider) { - return new MasterKeyProviderKeyring<>(masterKeyProvider); - } /** * Constructs a {@code Keyring} which interacts with AWS Key Management Service (KMS) to create, diff --git a/src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterials.java b/src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterials.java index 94423b884..149d67396 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterials.java +++ b/src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterials.java @@ -1,26 +1,87 @@ package com.amazonaws.encryptionsdk.model; +import com.amazonaws.encryptionsdk.CryptoAlgorithm; +import com.amazonaws.encryptionsdk.DataKey; +import com.amazonaws.encryptionsdk.keyrings.KeyringTrace; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceEntry; + +import javax.crypto.SecretKey; import java.security.PublicKey; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; -import com.amazonaws.encryptionsdk.DataKey; +import static java.util.Objects.requireNonNull; +import static org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY; +import static org.apache.commons.lang3.Validate.isTrue; public final class DecryptionMaterials { - private final DataKey dataKey; + private final CryptoAlgorithm algorithm; + private final Map encryptionContext; + private DataKey dataKey; private final PublicKey trailingSignatureKey; + private final KeyringTrace keyringTrace; private DecryptionMaterials(Builder b) { + algorithm = b.algorithm; + encryptionContext = b.encryptionContext; dataKey = b.getDataKey(); trailingSignatureKey = b.getTrailingSignatureKey(); + keyringTrace = b.keyringTrace; + } + + /** + * The algorithm suite to use for this decryption operation. + */ + public CryptoAlgorithm getAlgorithm() { + return algorithm; } + /** + * The encryption context + */ + public Map getEncryptionContext() { + return encryptionContext; + } + + /** + * @deprecated Replaced by {@link #getCleartextDataKey()} + */ + @Deprecated public DataKey getDataKey() { return dataKey; } + /** + * Sets the cleartext data key. The cleartext data key must not already be populated. + * + * @param cleartextDataKey The cleartext data key. + * @param keyringTraceEntry The keyring trace entry recording this action. + */ + public void setCleartextDataKey(SecretKey cleartextDataKey, KeyringTraceEntry keyringTraceEntry) { + if (this.dataKey != null) { + throw new IllegalStateException("cleartextDataKey was already populated"); + } + requireNonNull(cleartextDataKey, "cleartextDataKey is required"); + requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); + validateCleartextDataKey(algorithm, cleartextDataKey); + this.dataKey = new DataKey<>(cleartextDataKey, EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY, null); + keyringTrace.add(keyringTraceEntry); + } + + public SecretKey getCleartextDataKey() { + return dataKey == null ? null : dataKey.getKey(); + } + public PublicKey getTrailingSignatureKey() { return trailingSignatureKey; } + public KeyringTrace getKeyringTrace() { + return keyringTrace; + } + public static Builder newBuilder() { return new Builder(); } @@ -29,26 +90,94 @@ public Builder toBuilder() { return new Builder(this); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DecryptionMaterials that = (DecryptionMaterials) o; + + return algorithm == that.algorithm && + Objects.equals(getCleartextDataKey(), that.getCleartextDataKey()) && + Objects.equals(trailingSignatureKey, that.trailingSignatureKey) && + Objects.equals(encryptionContext, that.encryptionContext) && + Objects.equals(keyringTrace, that.keyringTrace); + } + + @Override + public int hashCode() { + return Objects.hash(algorithm, getCleartextDataKey(), trailingSignatureKey, encryptionContext, keyringTrace); + } + + private void validateCleartextDataKey(CryptoAlgorithm algorithm, SecretKey cleartextDataKey) throws IllegalArgumentException { + if (algorithm != null && cleartextDataKey != null) { + isTrue(algorithm.getDataKeyLength() == cleartextDataKey.getEncoded().length, + String.format("Incorrect key length. Expected %s but got %s", + algorithm.getDataKeyLength(), cleartextDataKey.getEncoded().length)); + isTrue(algorithm.getDataKeyAlgo().equalsIgnoreCase(cleartextDataKey.getAlgorithm()), + String.format("Incorrect key algorithm. Expected %s but got %s", + algorithm.getDataKeyAlgo(), cleartextDataKey.getAlgorithm())); + } + } + public static final class Builder { + private CryptoAlgorithm algorithm; + private Map encryptionContext = Collections.emptyMap(); private DataKey dataKey; private PublicKey trailingSignatureKey; + private KeyringTrace keyringTrace = new KeyringTrace(); private Builder(DecryptionMaterials result) { + this.algorithm = result.getAlgorithm(); + this.encryptionContext = result.getEncryptionContext(); this.dataKey = result.getDataKey(); this.trailingSignatureKey = result.getTrailingSignatureKey(); + this.keyringTrace = result.keyringTrace; } private Builder() {} + public CryptoAlgorithm getAlgorithm() { + return algorithm; + } + + public Builder setAlgorithm(CryptoAlgorithm algorithm) { + requireNonNull(algorithm, "algorithm is required"); + this.algorithm = algorithm; + return this; + } + + public Map getEncryptionContext() { + return encryptionContext; + } + + public Builder setEncryptionContext(Map encryptionContext) { + requireNonNull(encryptionContext, "encryptionContext is required"); + this.encryptionContext = Collections.unmodifiableMap(new HashMap<>(encryptionContext)); + return this; + } + + @Deprecated public DataKey getDataKey() { return dataKey; } + @Deprecated public Builder setDataKey(DataKey dataKey) { this.dataKey = dataKey; return this; } + /** + * Sets the cleartext data key. + * + * @param cleartextDataKey The cleartext data key. + */ + public Builder setCleartextDataKey(SecretKey cleartextDataKey) { + requireNonNull(cleartextDataKey, "cleartextDataKey is required"); + this.dataKey = new DataKey<>(cleartextDataKey, EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY, null); + return this; + } + public PublicKey getTrailingSignatureKey() { return trailingSignatureKey; } @@ -58,6 +187,16 @@ public Builder setTrailingSignatureKey(PublicKey trailingSignatureKey) { return this; } + public KeyringTrace getKeyringTrace() { + return keyringTrace; + } + + public Builder setKeyringTrace(KeyringTrace keyringTrace) { + requireNonNull(keyringTrace, "keyringTrace is required"); + this.keyringTrace = keyringTrace; + return this; + } + public DecryptionMaterials build() { return new DecryptionMaterials(this); } diff --git a/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java b/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java index 1a40d7c36..776eee722 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java +++ b/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java @@ -1,5 +1,11 @@ package com.amazonaws.encryptionsdk.model; +import com.amazonaws.encryptionsdk.CryptoAlgorithm; +import com.amazonaws.encryptionsdk.MasterKey; +import com.amazonaws.encryptionsdk.keyrings.Keyring; +import com.amazonaws.encryptionsdk.keyrings.KeyringTrace; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceEntry; + import javax.crypto.SecretKey; import java.security.PrivateKey; import java.util.ArrayList; @@ -9,8 +15,9 @@ import java.util.Map; import java.util.Objects; -import com.amazonaws.encryptionsdk.CryptoAlgorithm; -import com.amazonaws.encryptionsdk.MasterKey; +import static java.util.Collections.unmodifiableList; +import static java.util.Objects.requireNonNull; +import static org.apache.commons.lang3.Validate.isTrue; /** * Contains the cryptographic materials needed for an encryption operation. @@ -21,9 +28,10 @@ public final class EncryptionMaterials { private final CryptoAlgorithm algorithm; private final Map encryptionContext; private final List encryptedDataKeys; - private final SecretKey cleartextDataKey; + private SecretKey cleartextDataKey; private final PrivateKey trailingSignatureKey; private final List masterKeys; + private final KeyringTrace keyringTrace; private EncryptionMaterials(Builder b) { this.algorithm = b.algorithm; @@ -32,6 +40,7 @@ private EncryptionMaterials(Builder b) { this.cleartextDataKey = b.cleartextDataKey; this.trailingSignatureKey = b.trailingSignatureKey; this.masterKeys = b.getMasterKeys(); + this.keyringTrace = b.keyringTrace; } public Builder toBuilder() { @@ -61,7 +70,20 @@ public Map getEncryptionContext() { * The KeyBlobs to serialize (in cleartext) into the encrypted message. */ public List getEncryptedDataKeys() { - return encryptedDataKeys; + return unmodifiableList(encryptedDataKeys); + } + + /** + * Add an encrypted data key to the list of encrypted data keys. + * + * @param encryptedDataKey The encrypted data key to add. + * @param keyringTraceEntry The keyring trace entry recording this action. + */ + public void addEncryptedDataKey(KeyBlob encryptedDataKey, KeyringTraceEntry keyringTraceEntry) { + requireNonNull(encryptedDataKey, "encryptedDataKey is required"); + requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); + encryptedDataKeys.add(encryptedDataKey); + keyringTrace.add(keyringTraceEntry); } /** @@ -72,6 +94,23 @@ public SecretKey getCleartextDataKey() { return cleartextDataKey; } + /** + * Sets the cleartext data key. The cleartext data key must not already be populated. + * + * @param cleartextDataKey The cleartext data key. + * @param keyringTraceEntry The keyring trace entry recording this action. + */ + public void setCleartextDataKey(SecretKey cleartextDataKey, KeyringTraceEntry keyringTraceEntry) { + if (this.cleartextDataKey != null) { + throw new IllegalStateException("cleartextDataKey was already populated"); + } + requireNonNull(cleartextDataKey, "cleartextDataKey is required"); + requireNonNull(keyringTraceEntry, "keyringTraceEntry is required"); + validateCleartextDataKey(algorithm, cleartextDataKey); + this.cleartextDataKey = cleartextDataKey; + keyringTrace.add(keyringTraceEntry); + } + /** * The private key to be used to sign the message trailer. Must be present if any only if required by the * crypto algorithm, and the key type must likewise match the algorithm in use. @@ -86,11 +125,36 @@ public PrivateKey getTrailingSignatureKey() { /** * Contains a list of all MasterKeys that could decrypt this message. + * + * @deprecated {@link MasterKey}s have been replaced by {@link Keyring}s */ + @Deprecated public List getMasterKeys() { return masterKeys; } + /** + * A keyring trace containing all of the actions that keyrings have taken on this set of encryption materials. + */ + public KeyringTrace getKeyringTrace() { + return keyringTrace; + } + + /** + * Validates that the given plaintext data key fits the specification + * for the data key algorithm specified in the given algorithm suite. + */ + private void validateCleartextDataKey(CryptoAlgorithm algorithmSuite, SecretKey cleartextDataKey) throws IllegalArgumentException { + if (algorithmSuite != null && cleartextDataKey != null) { + isTrue(algorithmSuite.getDataKeyLength() == cleartextDataKey.getEncoded().length, + String.format("Incorrect data key length. Expected %s but got %s", + algorithmSuite.getDataKeyLength(), cleartextDataKey.getEncoded().length)); + isTrue(algorithmSuite.getDataKeyAlgo().equalsIgnoreCase(cleartextDataKey.getAlgorithm()), + String.format("Incorrect data key algorithm. Expected %s but got %s", + algorithmSuite.getDataKeyAlgo(), cleartextDataKey.getAlgorithm())); + } + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; @@ -100,21 +164,23 @@ public List getMasterKeys() { Objects.equals(encryptedDataKeys, that.encryptedDataKeys) && Objects.equals(cleartextDataKey, that.cleartextDataKey) && Objects.equals(trailingSignatureKey, that.trailingSignatureKey) && - Objects.equals(masterKeys, that.masterKeys); + Objects.equals(masterKeys, that.masterKeys) && + Objects.equals(keyringTrace, that.keyringTrace); } @Override public int hashCode() { return Objects.hash(algorithm, encryptionContext, encryptedDataKeys, cleartextDataKey, trailingSignatureKey, - masterKeys); + masterKeys, keyringTrace); } public static class Builder { private CryptoAlgorithm algorithm; private Map encryptionContext = Collections.emptyMap(); - private List encryptedDataKeys = null; + private List encryptedDataKeys = new ArrayList<>(); private SecretKey cleartextDataKey; private PrivateKey trailingSignatureKey; private List masterKeys = Collections.emptyList(); + private KeyringTrace keyringTrace = new KeyringTrace(); private Builder() {} @@ -125,6 +191,7 @@ private Builder(EncryptionMaterials r) { cleartextDataKey = r.cleartextDataKey; trailingSignatureKey = r.trailingSignatureKey; setMasterKeys(r.masterKeys); + keyringTrace = r.keyringTrace; } public EncryptionMaterials build() { @@ -154,7 +221,7 @@ public List getEncryptedDataKeys() { } public Builder setEncryptedDataKeys(List encryptedDataKeys) { - this.encryptedDataKeys = Collections.unmodifiableList(new ArrayList<>(encryptedDataKeys)); + this.encryptedDataKeys = new ArrayList<>(encryptedDataKeys); return this; } @@ -176,12 +243,23 @@ public Builder setTrailingSignatureKey(PrivateKey trailingSignatureKey) { return this; } + @Deprecated public List getMasterKeys() { return masterKeys; } + @Deprecated public Builder setMasterKeys(List masterKeys) { - this.masterKeys = Collections.unmodifiableList(new ArrayList<>(masterKeys)); + this.masterKeys = unmodifiableList(new ArrayList<>(masterKeys)); + return this; + } + + public KeyringTrace getKeyringTrace() { + return keyringTrace; + } + + public Builder setKeyringTrace(KeyringTrace keyringTrace) { + this.keyringTrace = keyringTrace; return this; } } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java index 6ed3629ff..ef820f7e9 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java @@ -21,6 +21,8 @@ import com.amazonaws.encryptionsdk.exception.MismatchedDataKeyException; import com.amazonaws.encryptionsdk.kms.DataKeyEncryptionDao; import com.amazonaws.encryptionsdk.kms.DataKeyEncryptionDao.DecryptDataKeyResult; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import com.amazonaws.encryptionsdk.model.KeyBlob; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -41,8 +43,9 @@ import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.GENERATED_DATA_KEY; import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT; import static com.amazonaws.encryptionsdk.kms.KmsUtils.KMS_PROVIDER_ID; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; @@ -97,9 +100,10 @@ void testMalformedArns() { assertThrows(MalformedArnException.class, () -> new KmsKeyring(dataKeyEncryptionDao, null, "badArn")); assertThrows(MalformedArnException.class, () -> new KmsKeyring(dataKeyEncryptionDao, Collections.singletonList("badArn"), GENERATOR_KEY_ID)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); List encryptedDataKeys = new ArrayList<>(); @@ -107,7 +111,7 @@ void testMalformedArns() { encryptedDataKeys.add(ENCRYPTED_KEY_1); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); // Malformed Arn for a non KMS provider shouldn't fail encryptedDataKeys.clear(); @@ -122,26 +126,28 @@ void testGeneratorKeyInKeyIds() { @Test void testEncryptDecryptExistingDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); assertEquals(3, encryptionMaterials.getEncryptedDataKeys().size()); - assertTrue(encryptionMaterials.getEncryptedDataKeys().contains(ENCRYPTED_GENERATOR_KEY)); - assertTrue(encryptionMaterials.getEncryptedDataKeys().contains(ENCRYPTED_KEY_1)); - assertTrue(encryptionMaterials.getEncryptedDataKeys().contains(ENCRYPTED_KEY_2)); + assertEncryptedDataKeyEquals(ENCRYPTED_KEY_1, encryptionMaterials.getEncryptedDataKeys().get(0)); + assertEncryptedDataKeyEquals(ENCRYPTED_KEY_2, encryptionMaterials.getEncryptedDataKeys().get(1)); + assertEncryptedDataKeyEquals(ENCRYPTED_GENERATOR_KEY, encryptionMaterials.getEncryptedDataKeys().get(2)); assertEquals(3, encryptionMaterials.getKeyringTrace().getEntries().size()); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_GENERATOR_KEY_TRACE)); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_KEY_1_TRACE)); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_KEY_2_TRACE)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); List encryptedDataKeys = new ArrayList<>(); @@ -150,7 +156,7 @@ void testEncryptDecryptExistingDataKey() { encryptedDataKeys.add(ENCRYPTED_KEY_2); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); KeyringTraceEntry expectedKeyringTraceEntry = new KeyringTraceEntry(KMS_PROVIDER_ID, GENERATOR_KEY_ID, KeyringTraceFlag.DECRYPTED_DATA_KEY, KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT); assertEquals(expectedKeyringTraceEntry, decryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -158,15 +164,16 @@ void testEncryptDecryptExistingDataKey() { @Test void testEncryptNullDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); when(dataKeyEncryptionDao.generateDataKey(GENERATOR_KEY_ID, ALGORITHM_SUITE, ENCRYPTION_CONTEXT)).thenReturn(new DataKeyEncryptionDao.GenerateDataKeyResult(PLAINTEXT_DATA_KEY, ENCRYPTED_GENERATOR_KEY)); keyring.onEncrypt(encryptionMaterials); - assertEquals(PLAINTEXT_DATA_KEY, encryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, encryptionMaterials.getCleartextDataKey()); assertEquals(4, encryptionMaterials.getKeyringTrace().getEntries().size()); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(GENERATED_DATA_KEY_TRACE)); @@ -174,9 +181,10 @@ void testEncryptNullDataKey() { assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_KEY_1_TRACE)); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_KEY_2_TRACE)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); List encryptedDataKeys = new ArrayList<>(); @@ -185,7 +193,7 @@ void testEncryptNullDataKey() { encryptedDataKeys.add(ENCRYPTED_KEY_2); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); KeyringTraceEntry expectedKeyringTraceEntry = new KeyringTraceEntry(KMS_PROVIDER_ID, GENERATOR_KEY_ID, KeyringTraceFlag.DECRYPTED_DATA_KEY, KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT); assertEquals(expectedKeyringTraceEntry, decryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -193,10 +201,11 @@ void testEncryptNullDataKey() { @Test void testEncryptNullGenerator() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .keyringTrace(new KeyringTrace()) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setKeyringTrace(new KeyringTrace()) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); Keyring keyring = new KmsKeyring(dataKeyEncryptionDao, Collections.singletonList(KEY_ID_1), null); @@ -204,9 +213,9 @@ void testEncryptNullGenerator() { keyring.onEncrypt(encryptionMaterials); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); - assertTrue(encryptionMaterials.getEncryptedDataKeys().contains(ENCRYPTED_KEY_1)); + assertEncryptedDataKeyEquals(ENCRYPTED_KEY_1, encryptionMaterials.getEncryptedDataKeys().get(0)); - assertEquals(PLAINTEXT_DATA_KEY, encryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, encryptionMaterials.getCleartextDataKey()); assertEquals(1, encryptionMaterials.getKeyringTrace().getEntries().size()); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().contains(ENCRYPTED_KEY_1_TRACE)); @@ -216,30 +225,32 @@ void testEncryptNullGenerator() { void testDiscoveryEncrypt() { keyring = new KmsKeyring(dataKeyEncryptionDao, null, null); - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); - assertFalse(encryptionMaterials.hasPlaintextDataKey()); + assertNull(encryptionMaterials.getCleartextDataKey()); assertEquals(0, encryptionMaterials.getKeyringTrace().getEntries().size()); } @Test - void testEncryptNoGeneratorOrPlaintextDataKey() { + void testEncryptNoGeneratorOrCleartextDataKey() { List keyIds = new ArrayList<>(); keyIds.add(KEY_ID_1); keyring = new KmsKeyring(dataKeyEncryptionDao, keyIds, null); - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE).build(); + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder().setAlgorithm(ALGORITHM_SUITE).build(); assertThrows(AwsCryptoException.class, () -> keyring.onEncrypt(encryptionMaterials)); } @Test void testDecryptFirstKeyFails() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); when(dataKeyEncryptionDao.decryptDataKey(ENCRYPTED_KEY_1, ALGORITHM_SUITE, ENCRYPTION_CONTEXT)).thenThrow(new CannotUnwrapDataKeyException()); @@ -249,7 +260,7 @@ void testDecryptFirstKeyFails() { encryptedDataKeys.add(ENCRYPTED_KEY_2); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); KeyringTraceEntry expectedKeyringTraceEntry = new KeyringTraceEntry(KMS_PROVIDER_ID, KEY_ID_2, KeyringTraceFlag.DECRYPTED_DATA_KEY, KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT); assertEquals(expectedKeyringTraceEntry, decryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -257,8 +268,9 @@ void testDecryptFirstKeyFails() { @Test void testDecryptMismatchedDataKeyException() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); when(dataKeyEncryptionDao.decryptDataKey(ENCRYPTED_KEY_1, ALGORITHM_SUITE, ENCRYPTION_CONTEXT)).thenThrow(new MismatchedDataKeyException()); @@ -268,9 +280,10 @@ void testDecryptMismatchedDataKeyException() { @Test void testDecryptFirstKeyWrongProvider() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); EncryptedDataKey wrongProviderKey = new KeyBlob("OtherProvider", KEY_ID_1.getBytes(PROVIDER_ENCODING), new byte[]{}); @@ -280,7 +293,7 @@ void testDecryptFirstKeyWrongProvider() { encryptedDataKeys.add(ENCRYPTED_KEY_2); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); KeyringTraceEntry expectedKeyringTraceEntry = new KeyringTraceEntry(KMS_PROVIDER_ID, KEY_ID_2, KeyringTraceFlag.DECRYPTED_DATA_KEY, KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT); assertEquals(expectedKeyringTraceEntry, decryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -290,9 +303,10 @@ void testDecryptFirstKeyWrongProvider() { void testDiscoveryDecrypt() { keyring = new KmsKeyring(dataKeyEncryptionDao, null, null); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); List encryptedDataKeys = new ArrayList<>(); @@ -300,7 +314,7 @@ void testDiscoveryDecrypt() { encryptedDataKeys.add(ENCRYPTED_KEY_2); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); KeyringTraceEntry expectedKeyringTraceEntry = new KeyringTraceEntry(KMS_PROVIDER_ID, KEY_ID_1, KeyringTraceFlag.DECRYPTED_DATA_KEY, KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT); assertEquals(expectedKeyringTraceEntry, decryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -308,27 +322,35 @@ void testDiscoveryDecrypt() { @Test void testDecryptAlreadyDecryptedDataKey() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .encryptionContext(ENCRYPTION_CONTEXT) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onDecrypt(decryptionMaterials, Collections.singletonList(ENCRYPTED_GENERATOR_KEY)); - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } @Test void testDecryptNoDataKey() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, Collections.emptyList()); - assertFalse(decryptionMaterials.hasPlaintextDataKey()); + assertNull(decryptionMaterials.getCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } + + private void assertEncryptedDataKeyEquals(EncryptedDataKey expected, EncryptedDataKey actual) { + assertEquals(expected.getProviderId(), actual.getProviderId()); + assertArrayEquals(expected.getProviderInformation(), actual.getProviderInformation()); + assertArrayEquals(expected.getEncryptedDataKey(), actual.getEncryptedDataKey()); + } } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MasterKeyProviderKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/MasterKeyProviderKeyringTest.java deleted file mode 100644 index 64b8b26dd..000000000 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MasterKeyProviderKeyringTest.java +++ /dev/null @@ -1,332 +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 com.amazonaws.encryptionsdk.keyrings; - -import com.amazonaws.encryptionsdk.CryptoAlgorithm; -import com.amazonaws.encryptionsdk.DataKey; -import com.amazonaws.encryptionsdk.EncryptedDataKey; -import com.amazonaws.encryptionsdk.MasterKey; -import com.amazonaws.encryptionsdk.MasterKeyProvider; -import com.amazonaws.encryptionsdk.MasterKeyRequest; -import com.amazonaws.encryptionsdk.exception.AwsCryptoException; -import com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException; -import com.amazonaws.encryptionsdk.jce.JceMasterKey; -import com.amazonaws.encryptionsdk.kms.KmsMasterKey; -import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; -import com.amazonaws.encryptionsdk.model.KeyBlob; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static com.amazonaws.encryptionsdk.EncryptedDataKey.PROVIDER_ENCODING; -import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; -import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.DECRYPTED_DATA_KEY; -import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.ENCRYPTED_DATA_KEY; -import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.GENERATED_DATA_KEY; -import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT; -import static com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class MasterKeyProviderKeyringTest { - - private static final CryptoAlgorithm ALGORITHM_SUITE = CryptoAlgorithm.ALG_AES_256_GCM_IV12_TAG16_HKDF_SHA256; - private static final SecretKey PLAINTEXT_DATA_KEY = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength()), ALGORITHM_SUITE.getDataKeyAlgo()); - private static final Map ENCRYPTION_CONTEXT = Collections.singletonMap("myKey", "myValue"); - - @Test - void testOnEncryptWithoutPlaintextDataKey() { - - MasterKeyProvider masterKeyProvider = mock(JceMasterKey.class); - - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - - JceMasterKey masterKey1 = mock(JceMasterKey.class); - JceMasterKey masterKey2 = mock(JceMasterKey.class); - - List masterKeys = new ArrayList<>(); - masterKeys.add(masterKey1); - masterKeys.add(masterKey2); - - ArgumentCaptor masterKeyRequestCaptor = ArgumentCaptor.forClass(MasterKeyRequest.class); - ArgumentCaptor dataKeyCaptor = ArgumentCaptor.forClass(DataKey.class); - - final String KEY_ID_1 = "KeyId1"; - final String KEY_ID_2 = "KeyId2"; - final String PROVIDER_1 = "Provider1"; - final String PROVIDER_2 = "Provider2"; - - DataKey dataKey1 = new DataKey<>(PLAINTEXT_DATA_KEY, generate(100), KEY_ID_1.getBytes(PROVIDER_ENCODING), masterKey1); - DataKey dataKey2 = new DataKey<>(PLAINTEXT_DATA_KEY, generate(100), KEY_ID_2.getBytes(PROVIDER_ENCODING), masterKey2); - - when(masterKeyProvider.getMasterKeysForEncryption(masterKeyRequestCaptor.capture())).thenReturn(masterKeys); - when(masterKey1.generateDataKey(ALGORITHM_SUITE, ENCRYPTION_CONTEXT)).thenReturn(dataKey1); - when(masterKey2.encryptDataKey(eq(ALGORITHM_SUITE), eq(ENCRYPTION_CONTEXT), dataKeyCaptor.capture())) - .thenReturn(dataKey2); - when(masterKey1.getProviderId()).thenReturn(PROVIDER_1); - when(masterKey1.getKeyId()).thenReturn(KEY_ID_1); - when(masterKey2.getProviderId()).thenReturn(PROVIDER_2); - when(masterKey2.getKeyId()).thenReturn(KEY_ID_2); - when(masterKey1.isEncryptionContextSigned()).thenReturn(true); - when(masterKey2.isEncryptionContextSigned()).thenReturn(false); - - keyring.onEncrypt(encryptionMaterials); - - assertEquals(ENCRYPTION_CONTEXT, masterKeyRequestCaptor.getValue().getEncryptionContext()); - assertEquals(PLAINTEXT_DATA_KEY, dataKeyCaptor.getValue().getKey()); - assertEncryptedDataKeyEquals(dataKey1, encryptionMaterials.getEncryptedDataKeys().get(0)); - assertEncryptedDataKeyEquals(dataKey2, encryptionMaterials.getEncryptedDataKeys().get(1)); - assertEquals(new KeyringTraceEntry(PROVIDER_1, KEY_ID_1, GENERATED_DATA_KEY), - encryptionMaterials.getKeyringTrace().getEntries().get(0)); - assertEquals(new KeyringTraceEntry(PROVIDER_1, KEY_ID_1, ENCRYPTED_DATA_KEY, SIGNED_ENCRYPTION_CONTEXT), - encryptionMaterials.getKeyringTrace().getEntries().get(1)); - assertEquals(new KeyringTraceEntry(PROVIDER_2, KEY_ID_2, ENCRYPTED_DATA_KEY), - encryptionMaterials.getKeyringTrace().getEntries().get(2)); - } - - @Test - void testOnEncryptWithPlaintextDataKey() { - - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .build(); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - - KmsMasterKey masterKey1 = mock(KmsMasterKey.class); - KmsMasterKey masterKey2 = mock(KmsMasterKey.class); - - List masterKeys = new ArrayList<>(); - masterKeys.add(masterKey1); - masterKeys.add(masterKey2); - - ArgumentCaptor masterKeyRequestCaptor = ArgumentCaptor.forClass(MasterKeyRequest.class); - ArgumentCaptor dataKeyCaptor = ArgumentCaptor.forClass(DataKey.class); - - final String KEY_ID_1 = "KeyId1"; - final String KEY_ID_2 = "KeyId2"; - final String PROVIDER_1 = "Provider1"; - final String PROVIDER_2 = "Provider2"; - - DataKey dataKey1 = new DataKey<>(PLAINTEXT_DATA_KEY, generate(100), KEY_ID_1.getBytes(PROVIDER_ENCODING), masterKey1); - DataKey dataKey2 = new DataKey<>(PLAINTEXT_DATA_KEY, generate(100), KEY_ID_2.getBytes(PROVIDER_ENCODING), masterKey2); - - when(masterKeyProvider.getMasterKeysForEncryption(masterKeyRequestCaptor.capture())).thenReturn(masterKeys); - when(masterKey1.encryptDataKey(eq(ALGORITHM_SUITE), eq(ENCRYPTION_CONTEXT), dataKeyCaptor.capture())) - .thenReturn(dataKey1); - when(masterKey2.encryptDataKey(eq(ALGORITHM_SUITE), eq(ENCRYPTION_CONTEXT), dataKeyCaptor.capture())) - .thenReturn(dataKey2); - when(masterKey1.getProviderId()).thenReturn(PROVIDER_1); - when(masterKey1.getKeyId()).thenReturn(KEY_ID_1); - when(masterKey2.getProviderId()).thenReturn(PROVIDER_2); - when(masterKey2.getKeyId()).thenReturn(KEY_ID_2); - - keyring.onEncrypt(encryptionMaterials); - - assertEquals(ENCRYPTION_CONTEXT, masterKeyRequestCaptor.getValue().getEncryptionContext()); - assertEquals(PLAINTEXT_DATA_KEY, dataKeyCaptor.getAllValues().get(0).getKey()); - assertEquals(PLAINTEXT_DATA_KEY, dataKeyCaptor.getAllValues().get(1).getKey()); - assertEncryptedDataKeyEquals(dataKey1, encryptionMaterials.getEncryptedDataKeys().get(0)); - assertEncryptedDataKeyEquals(dataKey2, encryptionMaterials.getEncryptedDataKeys().get(1)); - assertEquals(new KeyringTraceEntry(PROVIDER_1, KEY_ID_1, ENCRYPTED_DATA_KEY, SIGNED_ENCRYPTION_CONTEXT), - encryptionMaterials.getKeyringTrace().getEntries().get(0)); - assertEquals(new KeyringTraceEntry(PROVIDER_2, KEY_ID_2, ENCRYPTED_DATA_KEY, SIGNED_ENCRYPTION_CONTEXT), - encryptionMaterials.getKeyringTrace().getEntries().get(1)); - } - - @SuppressWarnings("unchecked") - @Test - void testOnEncryptWithNonKmsOrJceMasterKeyProvider() { - - MasterKeyProvider masterKeyProvider = mock(MasterKeyProvider.class); - - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .build(); - - Keyring keyring = new MasterKeyProviderKeyring(masterKeyProvider); - - MasterKey masterKey = mock(MasterKey.class); - - final String KEY_ID = "KeyId1"; - final String PROVIDER = "Provider1"; - - DataKey dataKey = new DataKey(PLAINTEXT_DATA_KEY, generate(100), KEY_ID.getBytes(PROVIDER_ENCODING), masterKey); - - when(masterKeyProvider.getMasterKeysForEncryption(isA(MasterKeyRequest.class))).thenReturn(singletonList(masterKey)); - when(masterKey.encryptDataKey(eq(ALGORITHM_SUITE), eq(ENCRYPTION_CONTEXT), isA(DataKey.class))) - .thenReturn(dataKey); - when(masterKey.getProviderId()).thenReturn(PROVIDER); - when(masterKey.getKeyId()).thenReturn(KEY_ID); - - keyring.onEncrypt(encryptionMaterials); - - assertEncryptedDataKeyEquals(dataKey, encryptionMaterials.getEncryptedDataKeys().get(0)); - assertEquals(new KeyringTraceEntry(PROVIDER, KEY_ID, ENCRYPTED_DATA_KEY), - encryptionMaterials.getKeyringTrace().getEntries().get(0)); - } - - @Test - void testOnEncryptWithNoMasterKeys() { - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - - when(masterKeyProvider.getMasterKeysForEncryption(isA(MasterKeyRequest.class))).thenReturn(emptyList()); - - assertThrows(AwsCryptoException.class, () -> keyring.onEncrypt(encryptionMaterials)); - } - - @Test - void testOnDecryptWithPlaintextDataKey() { - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .build(); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - keyring.onDecrypt(decryptionMaterials, emptyList()); - - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); - } - - @Test - void testOnDecrypt() { - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - KmsMasterKey masterKey = mock(KmsMasterKey.class); - - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - final String KEY_ID = "KeyId1"; - final String PROVIDER = "Provider1"; - - EncryptedDataKey encryptedDataKey = new KeyBlob(PROVIDER, - KEY_ID.getBytes(PROVIDER_ENCODING), generate(ALGORITHM_SUITE.getDataKeyLength())); - - when(masterKeyProvider.decryptDataKey(ALGORITHM_SUITE, singletonList(encryptedDataKey), ENCRYPTION_CONTEXT)) - .thenReturn(new DataKey<>(PLAINTEXT_DATA_KEY, encryptedDataKey.getEncryptedDataKey(), - encryptedDataKey.getProviderInformation(), masterKey)); - when(masterKey.getProviderId()).thenReturn(PROVIDER); - when(masterKey.getKeyId()).thenReturn(KEY_ID); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - keyring.onDecrypt(decryptionMaterials, singletonList(encryptedDataKey)); - - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); - assertEquals(new KeyringTraceEntry(PROVIDER, KEY_ID, DECRYPTED_DATA_KEY, VERIFIED_ENCRYPTION_CONTEXT), - decryptionMaterials.getKeyringTrace().getEntries().get(0)); - } - - @Test - void testOnDecryptMasterKeyCannotUnwrapDataKeyException() { - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - EncryptedDataKey encryptedDataKey = mock(EncryptedDataKey.class); - - when(masterKeyProvider.decryptDataKey(ALGORITHM_SUITE, singletonList(encryptedDataKey), ENCRYPTION_CONTEXT)) - .thenThrow(new CannotUnwrapDataKeyException()); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - keyring.onDecrypt(decryptionMaterials, singletonList(encryptedDataKey)); - - assertFalse(decryptionMaterials.hasPlaintextDataKey()); - } - - @Test - void testOnDecryptMasterKeyOtherException() { - MasterKeyProvider masterKeyProvider = mock(KmsMasterKeyProvider.class); - - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - EncryptedDataKey encryptedDataKey = mock(EncryptedDataKey.class); - - when(masterKeyProvider.decryptDataKey(ALGORITHM_SUITE, singletonList(encryptedDataKey), ENCRYPTION_CONTEXT)) - .thenThrow(new AwsCryptoException()); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - assertThrows(AwsCryptoException.class, () -> keyring.onDecrypt(decryptionMaterials, singletonList(encryptedDataKey))); - } - - @Test - void testOnDecryptNonVerifiedEncryptionContext() { - MasterKeyProvider masterKeyProvider = mock(JceMasterKey.class); - JceMasterKey masterKey = mock(JceMasterKey.class); - - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .build(); - - final String KEY_ID = "KeyId1"; - final String PROVIDER = "Provider1"; - - EncryptedDataKey encryptedDataKey = new KeyBlob(PROVIDER, - KEY_ID.getBytes(PROVIDER_ENCODING), generate(ALGORITHM_SUITE.getDataKeyLength())); - - when(masterKeyProvider.decryptDataKey(ALGORITHM_SUITE, singletonList(encryptedDataKey), ENCRYPTION_CONTEXT)) - .thenReturn(new DataKey<>(PLAINTEXT_DATA_KEY, encryptedDataKey.getEncryptedDataKey(), - encryptedDataKey.getProviderInformation(), masterKey)); - when(masterKey.getProviderId()).thenReturn(PROVIDER); - when(masterKey.getKeyId()).thenReturn(KEY_ID); - when(masterKey.isEncryptionContextSigned()).thenReturn(false); - - Keyring keyring = StandardKeyrings.masterKeyProvider(masterKeyProvider); - keyring.onDecrypt(decryptionMaterials, singletonList(encryptedDataKey)); - - assertEquals(PLAINTEXT_DATA_KEY, decryptionMaterials.getPlaintextDataKey()); - assertEquals(new KeyringTraceEntry(PROVIDER, KEY_ID, DECRYPTED_DATA_KEY), - decryptionMaterials.getKeyringTrace().getEntries().get(0)); - } - - private static void assertEncryptedDataKeyEquals(EncryptedDataKey expected, EncryptedDataKey actual) { - assertEquals(expected.getProviderId(), actual.getProviderId()); - assertArrayEquals(expected.getProviderInformation(), actual.getProviderInformation()); - assertArrayEquals(expected.getEncryptedDataKey(), actual.getEncryptedDataKey()); - } -} diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java index 75e43a676..ba5f97d92 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java @@ -15,6 +15,8 @@ import com.amazonaws.encryptionsdk.EncryptedDataKey; import com.amazonaws.encryptionsdk.exception.AwsCryptoException; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -22,6 +24,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import javax.crypto.SecretKey; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -44,6 +47,7 @@ class MultiKeyringTest { @Mock EncryptionMaterials encryptionMaterials; @Mock DecryptionMaterials decryptionMaterials; @Mock List encryptedDataKeys; + @Mock SecretKey cleartextDataKey; final List childrenKeyrings = new ArrayList<>(); @BeforeEach @@ -63,7 +67,7 @@ void testConstructor() { @Test void testOnEncryptWithGenerator() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(encryptionMaterials.hasPlaintextDataKey()).thenReturn(true); + when(encryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); keyring.onEncrypt(encryptionMaterials); @@ -75,7 +79,7 @@ void testOnEncryptWithGenerator() { @Test void testOnEncryptWithoutGenerator() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(encryptionMaterials.hasPlaintextDataKey()).thenReturn(true); + when(encryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); keyring.onEncrypt(encryptionMaterials); @@ -87,7 +91,7 @@ void testOnEncryptWithoutGenerator() { @Test void testOnEncryptNoPlaintextDataKey() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(encryptionMaterials.hasPlaintextDataKey()).thenReturn(false); + when(encryptionMaterials.getCleartextDataKey()).thenReturn(null); assertThrows(AwsCryptoException.class, () -> keyring.onEncrypt(encryptionMaterials)); } @@ -96,7 +100,7 @@ void testOnEncryptNoPlaintextDataKey() { void testOnDecryptWithPlaintextDataKey() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(true); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); verifyNoInteractions(generatorKeyring, keyring1, keyring2); @@ -106,7 +110,7 @@ void testOnDecryptWithPlaintextDataKey() { void testOnDecryptWithGenerator() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(false).thenReturn(false).thenReturn(true); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(null).thenReturn(cleartextDataKey); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(generatorKeyring, keyring1); @@ -119,7 +123,7 @@ void testOnDecryptWithGenerator() { void testOnDecryptWithoutGenerator() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(false).thenReturn(false).thenReturn(true); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(null).thenReturn(cleartextDataKey); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(keyring1, keyring2); @@ -132,7 +136,7 @@ void testOnDecryptWithoutGenerator() { void testOnDecryptFailureThenSuccess() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(false).thenReturn(true); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(cleartextDataKey); doThrow(new IllegalStateException()).when(generatorKeyring).onDecrypt(decryptionMaterials, encryptedDataKeys); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); @@ -147,7 +151,7 @@ void testOnDecryptFailureThenSuccess() { void testOnDecryptFailure() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(false); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(null); doThrow(new AwsCryptoException()).when(generatorKeyring).onDecrypt(decryptionMaterials, encryptedDataKeys); doThrow(new IllegalStateException()).when(keyring1).onDecrypt(decryptionMaterials, encryptedDataKeys); doThrow(new IllegalArgumentException()).when(keyring2).onDecrypt(decryptionMaterials, encryptedDataKeys); @@ -172,7 +176,7 @@ void testOnDecryptFailure() { void testOnDecryptNoFailuresNoPlaintextDataKeys() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.hasPlaintextDataKey()).thenReturn(false, false, false, false); + when(decryptionMaterials.getCleartextDataKey()).thenReturn(null, null, null, null); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(generatorKeyring, keyring1, keyring2); diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawAesKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawAesKeyringTest.java index 4183e9a06..556e63132 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawAesKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawAesKeyringTest.java @@ -15,6 +15,8 @@ import com.amazonaws.encryptionsdk.EncryptedDataKey; import com.amazonaws.encryptionsdk.internal.Utils; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import com.amazonaws.encryptionsdk.model.KeyBlob; import org.apache.commons.lang3.ArrayUtils; import org.junit.jupiter.api.Test; @@ -53,10 +55,11 @@ void testValidToDecrypt() { @Test void testEncryptDecryptExistingDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .plaintextDataKey(DATA_KEY) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setCleartextDataKey(DATA_KEY) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); @@ -75,14 +78,15 @@ void testEncryptDecryptExistingDataKey() { assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().contains(KeyringTraceFlag.ENCRYPTED_DATA_KEY)); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().contains(KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, encryptionMaterials.getEncryptedDataKeys()); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(KEYNAME, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyName()); assertEquals(KEYNAMESPACE, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyNamespace()); assertEquals(2, decryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().size()); @@ -92,15 +96,16 @@ void testEncryptDecryptExistingDataKey() { @Test void testEncryptDecryptGenerateDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); - assertNotNull(encryptionMaterials.getPlaintextDataKey()); - assertEquals(encryptionMaterials.getPlaintextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); + assertNotNull(encryptionMaterials.getCleartextDataKey()); + assertEquals(encryptionMaterials.getCleartextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); final EncryptedDataKey actualEncryptedDataKey = encryptionMaterials.getEncryptedDataKeys().get(0); @@ -115,14 +120,15 @@ void testEncryptDecryptGenerateDataKey() { assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(1).getFlags().contains(KeyringTraceFlag.ENCRYPTED_DATA_KEY)); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(1).getFlags().contains(KeyringTraceFlag.SIGNED_ENCRYPTION_CONTEXT)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, encryptionMaterials.getEncryptedDataKeys()); - assertEquals(encryptionMaterials.getPlaintextDataKey(), decryptionMaterials.getPlaintextDataKey()); + assertEquals(encryptionMaterials.getCleartextDataKey(), decryptionMaterials.getCleartextDataKey()); assertEquals(KEYNAME, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyName()); assertEquals(KEYNAMESPACE, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyNamespace()); assertEquals(2, decryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().size()); diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java index 3fe1fb416..be87bafc7 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java @@ -16,6 +16,8 @@ import com.amazonaws.encryptionsdk.CryptoAlgorithm; import com.amazonaws.encryptionsdk.EncryptedDataKey; import com.amazonaws.encryptionsdk.internal.JceKeyCipher; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import com.amazonaws.encryptionsdk.model.KeyBlob; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,8 +37,8 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -71,10 +73,11 @@ boolean validToDecrypt(EncryptedDataKey encryptedDataKey) { @Test void testEncryptDecryptExistingDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .plaintextDataKey(DATA_KEY) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setCleartextDataKey(DATA_KEY) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); @@ -84,32 +87,34 @@ void testEncryptDecryptExistingDataKey() { assertEquals(1, encryptionMaterials.getKeyringTrace().getEntries().size()); assertEquals(ENCRYPTED_DATA_KEY_TRACE, encryptionMaterials.getKeyringTrace().getEntries().get(0)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, Collections.singletonList(ENCRYPTED_DATA_KEY)); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(DECRYPTED_DATA_KEY_TRACE, decryptionMaterials.getKeyringTrace().getEntries().get(0)); } @Test void testEncryptNullDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); ArgumentCaptor dataKeyCaptor = ArgumentCaptor.forClass(byte[].class); when(jceKeyCipher.encryptKey(dataKeyCaptor.capture(), eq(KEYNAME), eq(KEYNAMESPACE), eq(ENCRYPTION_CONTEXT))).thenReturn(ENCRYPTED_DATA_KEY); keyring.onEncrypt(encryptionMaterials); - assertEquals(encryptionMaterials.getPlaintextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); - assertArrayEquals(encryptionMaterials.getPlaintextDataKey().getEncoded(), dataKeyCaptor.getValue()); + assertEquals(encryptionMaterials.getCleartextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); + assertArrayEquals(encryptionMaterials.getCleartextDataKey().getEncoded(), dataKeyCaptor.getValue()); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); - assertNotNull(encryptionMaterials.getPlaintextDataKey()); + assertNotNull(encryptionMaterials.getCleartextDataKey()); assertEncryptedDataKeyEquals(ENCRYPTED_DATA_KEY, encryptionMaterials.getEncryptedDataKeys().get(0)); assertEquals(2, encryptionMaterials.getKeyringTrace().getEntries().size()); assertEquals(GENERATED_DATA_KEY_TRACE, encryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -118,50 +123,54 @@ void testEncryptNullDataKey() { @Test void testDecryptAlreadyDecryptedDataKey() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .plaintextDataKey(DATA_KEY) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setCleartextDataKey(DATA_KEY) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, Collections.singletonList(ENCRYPTED_DATA_KEY)); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } @Test void testDecryptNoValidDataKey() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, Collections.singletonList(INVALID_DATA_KEY)); - assertFalse(decryptionMaterials.hasPlaintextDataKey()); + assertNull(decryptionMaterials.getCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } @Test void testDecryptNoDataKey() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, Collections.emptyList()); - assertFalse(decryptionMaterials.hasPlaintextDataKey()); + assertNull(decryptionMaterials.getCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } @Test void testDecryptMultipleKeysOneInvalid() { - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); final List edks = new ArrayList<>(); @@ -170,7 +179,7 @@ void testDecryptMultipleKeysOneInvalid() { keyring.onDecrypt(decryptionMaterials, edks); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(DECRYPTED_DATA_KEY_TRACE, decryptionMaterials.getKeyringTrace().getEntries().get(0)); } @@ -178,9 +187,10 @@ void testDecryptMultipleKeysOneInvalid() { void testDecryptMultipleKeysOneException() throws GeneralSecurityException { final EncryptedDataKey BAD_DATA_KEY = new KeyBlob("exceptionProvider", new byte[]{1, 2, 3}, new byte[]{4, 5, 6}); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); when(jceKeyCipher.decryptKey(BAD_DATA_KEY, KEYNAME, ENCRYPTION_CONTEXT)) @@ -192,7 +202,7 @@ void testDecryptMultipleKeysOneException() throws GeneralSecurityException { keyring.onDecrypt(decryptionMaterials, edks); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(DECRYPTED_DATA_KEY_TRACE, decryptionMaterials.getKeyringTrace().getEntries().get(0)); } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java index 6e43d5d37..9107cf447 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java @@ -14,6 +14,8 @@ package com.amazonaws.encryptionsdk.keyrings; import com.amazonaws.encryptionsdk.EncryptedDataKey; +import com.amazonaws.encryptionsdk.model.DecryptionMaterials; +import com.amazonaws.encryptionsdk.model.EncryptionMaterials; import com.amazonaws.encryptionsdk.model.KeyBlob; import org.apache.commons.lang3.ArrayUtils; import org.junit.jupiter.api.BeforeAll; @@ -61,10 +63,11 @@ void testValidToDecrypt() { @Test void testEncryptDecryptExistingDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .plaintextDataKey(DATA_KEY) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setCleartextDataKey(DATA_KEY) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); @@ -81,14 +84,15 @@ void testEncryptDecryptExistingDataKey() { assertEquals(1, encryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().size()); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().contains(KeyringTraceFlag.ENCRYPTED_DATA_KEY)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, encryptionMaterials.getEncryptedDataKeys()); - assertEquals(DATA_KEY, decryptionMaterials.getPlaintextDataKey()); + assertEquals(DATA_KEY, decryptionMaterials.getCleartextDataKey()); assertEquals(KEYNAME, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyName()); assertEquals(KEYNAMESPACE, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyNamespace()); assertEquals(1, decryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().size()); @@ -97,15 +101,16 @@ void testEncryptDecryptExistingDataKey() { @Test void testEncryptDecryptGenerateDataKey() { - EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder(ALGORITHM) - .keyringTrace(new KeyringTrace()) - .encryptionContext(ENCRYPTION_CONTEXT) + EncryptionMaterials encryptionMaterials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setKeyringTrace(new KeyringTrace()) + .setEncryptionContext(ENCRYPTION_CONTEXT) .build(); keyring.onEncrypt(encryptionMaterials); - assertNotNull(encryptionMaterials.getPlaintextDataKey()); - assertEquals(encryptionMaterials.getPlaintextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); + assertNotNull(encryptionMaterials.getCleartextDataKey()); + assertEquals(encryptionMaterials.getCleartextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); final EncryptedDataKey actualEncryptedDataKey = encryptionMaterials.getEncryptedDataKeys().get(0); @@ -118,14 +123,15 @@ void testEncryptDecryptGenerateDataKey() { assertEquals(1, encryptionMaterials.getKeyringTrace().getEntries().get(1).getFlags().size()); assertTrue(encryptionMaterials.getKeyringTrace().getEntries().get(1).getFlags().contains(KeyringTraceFlag.ENCRYPTED_DATA_KEY)); - DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder(ALGORITHM) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(new KeyringTrace()) + DecryptionMaterials decryptionMaterials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(new KeyringTrace()) .build(); keyring.onDecrypt(decryptionMaterials, encryptionMaterials.getEncryptedDataKeys()); - assertEquals(encryptionMaterials.getPlaintextDataKey(), decryptionMaterials.getPlaintextDataKey()); + assertEquals(encryptionMaterials.getCleartextDataKey(), decryptionMaterials.getCleartextDataKey()); assertEquals(KEYNAME, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyName()); assertEquals(KEYNAMESPACE, decryptionMaterials.getKeyringTrace().getEntries().get(0).getKeyNamespace()); assertEquals(1, decryptionMaterials.getKeyringTrace().getEntries().get(0).getFlags().size()); diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterialsTest.java b/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java similarity index 60% rename from src/test/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterialsTest.java rename to src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java index 68687d4ad..a5764e15d 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/DecryptionMaterialsTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020 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 @@ -11,10 +11,13 @@ * specific language governing permissions and limitations under the License. */ -package com.amazonaws.encryptionsdk.keyrings; +package com.amazonaws.encryptionsdk.model; import com.amazonaws.encryptionsdk.CryptoAlgorithm; import com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm; +import com.amazonaws.encryptionsdk.keyrings.KeyringTrace; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceEntry; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -29,7 +32,9 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; class DecryptionMaterialsTest { @@ -49,68 +54,47 @@ static void setup() throws Exception { VERIFICATION_KEY = keyPair.getPublic(); } - @Test - void testBuilderNullCryptoAlgorithm() { - assertThrows(NullPointerException.class, () -> DecryptionMaterials.newBuilder(null).build()); - } - @Test void testBuilder() { - DecryptionMaterials result = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(KEYRING_TRACE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .verificationKey(VERIFICATION_KEY) + DecryptionMaterials result = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(KEYRING_TRACE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setTrailingSignatureKey(VERIFICATION_KEY) .build(); - assertEquals(ALGORITHM_SUITE, result.getAlgorithmSuite()); + assertEquals(ALGORITHM_SUITE, result.getAlgorithm()); assertEquals(ENCRYPTION_CONTEXT, result.getEncryptionContext()); assertEquals(KEYRING_TRACE, result.getKeyringTrace()); - assertEquals(PLAINTEXT_DATA_KEY, result.getPlaintextDataKey()); - assertEquals(VERIFICATION_KEY, result.getVerificationKey()); + assertEquals(PLAINTEXT_DATA_KEY, result.getCleartextDataKey()); + assertEquals(VERIFICATION_KEY, result.getTrailingSignatureKey()); } @Test void testInvalidPlaintextDataKey() { SecretKey wrongLength = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength() + 1), ALGORITHM_SUITE.getDataKeyAlgo()); - assertThrows(IllegalArgumentException.class, () -> DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(wrongLength) - .verificationKey(VERIFICATION_KEY) - .build()); - SecretKey wrongAlgorithm = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength()), "InvalidAlgorithm"); - assertThrows(IllegalArgumentException.class, () -> DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(wrongAlgorithm) - .verificationKey(VERIFICATION_KEY) - .build()); - DecryptionMaterials materials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .verificationKey(VERIFICATION_KEY) + + DecryptionMaterials materials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setTrailingSignatureKey(VERIFICATION_KEY) .build(); assertThrows(IllegalArgumentException.class, () -> materials - .setPlaintextDataKey(wrongAlgorithm, KEYRING_TRACE_ENTRY)); + .setCleartextDataKey(wrongAlgorithm, KEYRING_TRACE_ENTRY)); assertThrows(IllegalArgumentException.class, () -> materials - .setPlaintextDataKey(wrongLength, KEYRING_TRACE_ENTRY)); - } - - @Test - void testInvalidVerificationKey() { - assertThrows(IllegalArgumentException.class, () -> DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .verificationKey(null) - .build()); - assertThrows(IllegalArgumentException.class, () -> DecryptionMaterials.newBuilder(CryptoAlgorithm.ALG_AES_128_GCM_IV12_TAG16_HKDF_SHA256) - .verificationKey(VERIFICATION_KEY) - .build()); - + .setCleartextDataKey(wrongLength, KEYRING_TRACE_ENTRY)); } @Test void testToBuilder() { - DecryptionMaterials expected = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(KEYRING_TRACE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .verificationKey(VERIFICATION_KEY) + DecryptionMaterials expected = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(KEYRING_TRACE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setTrailingSignatureKey(VERIFICATION_KEY) .build(); DecryptionMaterials actual = expected.toBuilder().build(); @@ -121,28 +105,33 @@ void testToBuilder() { @Test void testSetPlaintextDataKey() { - DecryptionMaterials materials = DecryptionMaterials.newBuilder(ALGORITHM_SUITE) - .verificationKey(VERIFICATION_KEY) + DecryptionMaterials materials = DecryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setTrailingSignatureKey(VERIFICATION_KEY) .build(); - assertThrows(NullPointerException.class, () -> materials.setPlaintextDataKey(null, KEYRING_TRACE_ENTRY)); - assertThrows(NullPointerException.class, () -> materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, null)); + assertThrows(NullPointerException.class, () -> materials.setCleartextDataKey(null, KEYRING_TRACE_ENTRY)); + assertThrows(NullPointerException.class, () -> materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, null)); - materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY); - assertEquals(PLAINTEXT_DATA_KEY, materials.getPlaintextDataKey()); + materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY); + assertEquals(PLAINTEXT_DATA_KEY, materials.getCleartextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, materials.getDataKey().getKey()); assertEquals(1, materials.getKeyringTrace().getEntries().size()); assertEquals(KEYRING_TRACE_ENTRY, materials.getKeyringTrace().getEntries().get(0)); - assertThrows(IllegalStateException.class, () -> materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY)); + assertThrows(IllegalStateException.class, () -> materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY)); } @Test void testGetOptionalProperties() { - DecryptionMaterials materials = DecryptionMaterials.newBuilder(CryptoAlgorithm.ALG_AES_128_GCM_IV12_TAG16_HKDF_SHA256) - .build(); - - assertThrows(IllegalStateException.class, materials::getPlaintextDataKey); - assertThrows(IllegalStateException.class, materials::getVerificationKey); + DecryptionMaterials materials = DecryptionMaterials.newBuilder() + .build(); + + assertNull(materials.getAlgorithm()); + assertNull(materials.getCleartextDataKey()); + assertNull(materials.getTrailingSignatureKey()); + assertTrue(materials.getEncryptionContext().isEmpty()); + assertTrue(materials.getKeyringTrace().getEntries().isEmpty()); } } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterialsTest.java b/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java similarity index 63% rename from src/test/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterialsTest.java rename to src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java index d1c207dbd..148a16f4d 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/EncryptionMaterialsTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020 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 @@ -11,11 +11,13 @@ * specific language governing permissions and limitations under the License. */ -package com.amazonaws.encryptionsdk.keyrings; +package com.amazonaws.encryptionsdk.model; import com.amazonaws.encryptionsdk.CryptoAlgorithm; -import com.amazonaws.encryptionsdk.EncryptedDataKey; import com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm; +import com.amazonaws.encryptionsdk.keyrings.KeyringTrace; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceEntry; +import com.amazonaws.encryptionsdk.keyrings.KeyringTraceFlag; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,7 +35,9 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith(MockitoExtension.class) class EncryptionMaterialsTest { @@ -44,7 +48,7 @@ class EncryptionMaterialsTest { private static final KeyringTraceEntry KEYRING_TRACE_ENTRY = new KeyringTraceEntry("Namespace", "Name", KeyringTraceFlag.ENCRYPTED_DATA_KEY); private static final SecretKey PLAINTEXT_DATA_KEY = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength()), ALGORITHM_SUITE.getDataKeyAlgo()); @Mock - private static EncryptedDataKey ENCRYPTED_DATA_KEY; + private static KeyBlob ENCRYPTED_DATA_KEY; private static PrivateKey SIGNING_KEY; @BeforeAll @@ -56,72 +60,50 @@ static void setup() throws Exception { SIGNING_KEY = keyPair.getPrivate(); } - @Test - void testBuilderNullCryptoAlgorithm() { - assertThrows(NullPointerException.class, () -> EncryptionMaterials.newBuilder(null).build()); - } - @Test void testBuilder() { - EncryptionMaterials result = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(KEYRING_TRACE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .encryptedDataKeys(Collections.singletonList(ENCRYPTED_DATA_KEY)) - .signingKey(SIGNING_KEY) + EncryptionMaterials result = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(KEYRING_TRACE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setEncryptedDataKeys(Collections.singletonList(ENCRYPTED_DATA_KEY)) + .setTrailingSignatureKey(SIGNING_KEY) .build(); - assertEquals(ALGORITHM_SUITE, result.getAlgorithmSuite()); + assertEquals(ALGORITHM_SUITE, result.getAlgorithm()); assertEquals(ENCRYPTION_CONTEXT, result.getEncryptionContext()); assertEquals(KEYRING_TRACE, result.getKeyringTrace()); - assertEquals(PLAINTEXT_DATA_KEY, result.getPlaintextDataKey()); + assertEquals(PLAINTEXT_DATA_KEY, result.getCleartextDataKey()); assertEquals(1, result.getEncryptedDataKeys().size()); assertEquals(ENCRYPTED_DATA_KEY, result.getEncryptedDataKeys().get(0)); - assertEquals(SIGNING_KEY, result.getSigningKey()); + assertEquals(SIGNING_KEY, result.getTrailingSignatureKey()); } @Test void testInvalidPlaintextDataKey() { SecretKey wrongLength = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength() + 1), ALGORITHM_SUITE.getDataKeyAlgo()); - assertThrows(IllegalArgumentException.class, () -> EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(wrongLength) - .signingKey(SIGNING_KEY) - .build()); - SecretKey wrongAlgorithm = new SecretKeySpec(generate(ALGORITHM_SUITE.getDataKeyLength()), "InvalidAlgorithm"); - assertThrows(IllegalArgumentException.class, () -> EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .plaintextDataKey(wrongAlgorithm) - .signingKey(SIGNING_KEY) - .build()); - EncryptionMaterials materials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .signingKey(SIGNING_KEY) + EncryptionMaterials materials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setTrailingSignatureKey(SIGNING_KEY) .build(); assertThrows(IllegalArgumentException.class, () -> materials - .setPlaintextDataKey(wrongAlgorithm, KEYRING_TRACE_ENTRY)); + .setCleartextDataKey(wrongAlgorithm, KEYRING_TRACE_ENTRY)); assertThrows(IllegalArgumentException.class, () -> materials - .setPlaintextDataKey(wrongLength, KEYRING_TRACE_ENTRY)); - } - - @Test - void testInvalidSigningKey() { - assertThrows(IllegalArgumentException.class, () -> EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .signingKey(null) - .build()); - assertThrows(IllegalArgumentException.class, () -> EncryptionMaterials.newBuilder(CryptoAlgorithm.ALG_AES_128_GCM_IV12_TAG16_HKDF_SHA256) - .signingKey(SIGNING_KEY) - .build()); - + .setCleartextDataKey(wrongLength, KEYRING_TRACE_ENTRY)); } @Test void testToBuilder() { - EncryptionMaterials expected = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .encryptionContext(ENCRYPTION_CONTEXT) - .keyringTrace(KEYRING_TRACE) - .plaintextDataKey(PLAINTEXT_DATA_KEY) - .encryptedDataKeys(Collections.singletonList(ENCRYPTED_DATA_KEY)) - .signingKey(SIGNING_KEY) + EncryptionMaterials expected = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setEncryptionContext(ENCRYPTION_CONTEXT) + .setKeyringTrace(KEYRING_TRACE) + .setCleartextDataKey(PLAINTEXT_DATA_KEY) + .setEncryptedDataKeys(Collections.singletonList(ENCRYPTED_DATA_KEY)) + .setTrailingSignatureKey(SIGNING_KEY) .build(); EncryptionMaterials actual = expected.toBuilder().build(); @@ -132,8 +114,9 @@ void testToBuilder() { @Test void testAddEncryptedDataKey() { - EncryptionMaterials materials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .signingKey(SIGNING_KEY) + EncryptionMaterials materials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setTrailingSignatureKey(SIGNING_KEY) .build(); assertThrows(NullPointerException.class, () -> materials.addEncryptedDataKey(null, KEYRING_TRACE_ENTRY)); @@ -148,28 +131,33 @@ void testAddEncryptedDataKey() { @Test void testSetPlaintextDataKey() { - EncryptionMaterials materials = EncryptionMaterials.newBuilder(ALGORITHM_SUITE) - .signingKey(SIGNING_KEY) + EncryptionMaterials materials = EncryptionMaterials.newBuilder() + .setAlgorithm(ALGORITHM_SUITE) + .setTrailingSignatureKey(SIGNING_KEY) .build(); - assertThrows(NullPointerException.class, () -> materials.setPlaintextDataKey(null, KEYRING_TRACE_ENTRY)); - assertThrows(NullPointerException.class, () -> materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, null)); + assertThrows(NullPointerException.class, () -> materials.setCleartextDataKey(null, KEYRING_TRACE_ENTRY)); + assertThrows(NullPointerException.class, () -> materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, null)); - materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY); - assertEquals(PLAINTEXT_DATA_KEY, materials.getPlaintextDataKey()); + materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY); + assertEquals(PLAINTEXT_DATA_KEY, materials.getCleartextDataKey()); assertEquals(1, materials.getKeyringTrace().getEntries().size()); assertEquals(KEYRING_TRACE_ENTRY, materials.getKeyringTrace().getEntries().get(0)); - assertThrows(IllegalStateException.class, () -> materials.setPlaintextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY)); + assertThrows(IllegalStateException.class, () -> materials.setCleartextDataKey(PLAINTEXT_DATA_KEY, KEYRING_TRACE_ENTRY)); } @Test void testGetOptionalProperties() { - EncryptionMaterials materials = EncryptionMaterials.newBuilder(CryptoAlgorithm.ALG_AES_128_GCM_IV12_TAG16_HKDF_SHA256) - .build(); - - assertThrows(IllegalStateException.class, materials::getPlaintextDataKey); - assertThrows(IllegalStateException.class, materials::getSigningKey); + EncryptionMaterials materials = EncryptionMaterials.newBuilder() + .build(); + + assertNull(materials.getAlgorithm()); + assertNull(materials.getCleartextDataKey()); + assertTrue(materials.getEncryptedDataKeys().isEmpty()); + assertNull(materials.getTrailingSignatureKey()); + assertTrue(materials.getKeyringTrace().getEntries().isEmpty()); + assertTrue(materials.getEncryptionContext().isEmpty()); } } From f862c1a5884bf1c46450a0e510d8785052cf15ed Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Wed, 22 Jan 2020 15:49:37 -0800 Subject: [PATCH 2/2] Adding back hasCleartextDataKey methods --- .../encryptionsdk/keyrings/KmsKeyring.java | 6 +++--- .../encryptionsdk/keyrings/MultiKeyring.java | 6 +++--- .../encryptionsdk/keyrings/RawKeyring.java | 4 ++-- .../model/DecryptionMaterials.java | 11 ++++++++++- .../model/EncryptionMaterials.java | 11 ++++++++++- .../encryptionsdk/keyrings/KmsKeyringTest.java | 6 +++--- .../keyrings/MultiKeyringTest.java | 18 +++++++++--------- .../encryptionsdk/keyrings/RawKeyringTest.java | 10 +++++----- .../keyrings/RawRsaKeyringTest.java | 3 +-- .../model/DecryptionMaterialsTest.java | 2 ++ .../model/EncryptionMaterialsTest.java | 2 ++ 11 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java b/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java index d0450ec29..528b4a1dc 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java +++ b/src/main/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyring.java @@ -80,7 +80,7 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { // If the input encryption materials do not contain a plaintext data key and this keyring does not // have a generator defined, OnEncrypt MUST not modify the encryption materials and MUST fail. - if (encryptionMaterials.getCleartextDataKey() == null && generatorKeyId == null) { + if (!encryptionMaterials.hasCleartextDataKey() && generatorKeyId == null) { throw new AwsCryptoException("Encryption materials must contain either a plaintext data key or a generator"); } @@ -88,7 +88,7 @@ public void onEncrypt(EncryptionMaterials encryptionMaterials) { // If the input encryption materials do not contain a plaintext data key and a generator is defined onEncrypt // MUST attempt to generate a new plaintext data key and encrypt that data key by calling KMS GenerateDataKey. - if (encryptionMaterials.getCleartextDataKey() == null) { + if (!encryptionMaterials.hasCleartextDataKey()) { generateDataKey(encryptionMaterials); } else if (generatorKeyId != null) { // If this keyring's generator is defined and was not used to generate a data key, OnEncrypt @@ -126,7 +126,7 @@ public void onDecrypt(DecryptionMaterials decryptionMaterials, List getDataKey() { * @param keyringTraceEntry The keyring trace entry recording this action. */ public void setCleartextDataKey(SecretKey cleartextDataKey, KeyringTraceEntry keyringTraceEntry) { - if (this.dataKey != null) { + if (hasCleartextDataKey()) { throw new IllegalStateException("cleartextDataKey was already populated"); } requireNonNull(cleartextDataKey, "cleartextDataKey is required"); @@ -74,6 +74,15 @@ public SecretKey getCleartextDataKey() { return dataKey == null ? null : dataKey.getKey(); } + /** + * Returns true if a cleartext data key has been populated. + * + * @return True if cleartext data key is populated, false otherwise. + */ + public boolean hasCleartextDataKey() { + return this.dataKey != null; + } + public PublicKey getTrailingSignatureKey() { return trailingSignatureKey; } diff --git a/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java b/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java index 776eee722..ed46dabf8 100644 --- a/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java +++ b/src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterials.java @@ -101,7 +101,7 @@ public SecretKey getCleartextDataKey() { * @param keyringTraceEntry The keyring trace entry recording this action. */ public void setCleartextDataKey(SecretKey cleartextDataKey, KeyringTraceEntry keyringTraceEntry) { - if (this.cleartextDataKey != null) { + if (hasCleartextDataKey()) { throw new IllegalStateException("cleartextDataKey was already populated"); } requireNonNull(cleartextDataKey, "cleartextDataKey is required"); @@ -111,6 +111,15 @@ public void setCleartextDataKey(SecretKey cleartextDataKey, KeyringTraceEntry ke keyringTrace.add(keyringTraceEntry); } + /** + * Returns true if a cleartext data key has been populated. + * + * @return True is a cleartext data key has been populated, false otherwise. + */ + public boolean hasCleartextDataKey() { + return this.cleartextDataKey != null; + } + /** * The private key to be used to sign the message trailer. Must be present if any only if required by the * crypto algorithm, and the key type must likewise match the algorithm in use. diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java index ef820f7e9..30ba8ba41 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/KmsKeyringTest.java @@ -45,7 +45,7 @@ import static com.amazonaws.encryptionsdk.kms.KmsUtils.KMS_PROVIDER_ID; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; @@ -231,7 +231,7 @@ void testDiscoveryEncrypt() { .build(); keyring.onEncrypt(encryptionMaterials); - assertNull(encryptionMaterials.getCleartextDataKey()); + assertFalse(encryptionMaterials.hasCleartextDataKey()); assertEquals(0, encryptionMaterials.getKeyringTrace().getEntries().size()); } @@ -344,7 +344,7 @@ void testDecryptNoDataKey() { keyring.onDecrypt(decryptionMaterials, Collections.emptyList()); - assertNull(decryptionMaterials.getCleartextDataKey()); + assertFalse(decryptionMaterials.hasCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java index ba5f97d92..a9d414754 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/MultiKeyringTest.java @@ -67,7 +67,7 @@ void testConstructor() { @Test void testOnEncryptWithGenerator() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(encryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); + when(encryptionMaterials.hasCleartextDataKey()).thenReturn(true); keyring.onEncrypt(encryptionMaterials); @@ -79,7 +79,7 @@ void testOnEncryptWithGenerator() { @Test void testOnEncryptWithoutGenerator() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(encryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); + when(encryptionMaterials.hasCleartextDataKey()).thenReturn(true); keyring.onEncrypt(encryptionMaterials); @@ -91,7 +91,7 @@ void testOnEncryptWithoutGenerator() { @Test void testOnEncryptNoPlaintextDataKey() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(encryptionMaterials.getCleartextDataKey()).thenReturn(null); + when(encryptionMaterials.hasCleartextDataKey()).thenReturn(false); assertThrows(AwsCryptoException.class, () -> keyring.onEncrypt(encryptionMaterials)); } @@ -100,7 +100,7 @@ void testOnEncryptNoPlaintextDataKey() { void testOnDecryptWithPlaintextDataKey() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(cleartextDataKey); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(true); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); verifyNoInteractions(generatorKeyring, keyring1, keyring2); @@ -110,7 +110,7 @@ void testOnDecryptWithPlaintextDataKey() { void testOnDecryptWithGenerator() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(null).thenReturn(cleartextDataKey); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(false).thenReturn(false).thenReturn(true); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(generatorKeyring, keyring1); @@ -123,7 +123,7 @@ void testOnDecryptWithGenerator() { void testOnDecryptWithoutGenerator() { MultiKeyring keyring = new MultiKeyring(null, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(null).thenReturn(cleartextDataKey); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(false).thenReturn(false).thenReturn(true); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(keyring1, keyring2); @@ -136,7 +136,7 @@ void testOnDecryptWithoutGenerator() { void testOnDecryptFailureThenSuccess() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(null).thenReturn(cleartextDataKey); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(false).thenReturn(true); doThrow(new IllegalStateException()).when(generatorKeyring).onDecrypt(decryptionMaterials, encryptedDataKeys); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); @@ -151,7 +151,7 @@ void testOnDecryptFailureThenSuccess() { void testOnDecryptFailure() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(null); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(false); doThrow(new AwsCryptoException()).when(generatorKeyring).onDecrypt(decryptionMaterials, encryptedDataKeys); doThrow(new IllegalStateException()).when(keyring1).onDecrypt(decryptionMaterials, encryptedDataKeys); doThrow(new IllegalArgumentException()).when(keyring2).onDecrypt(decryptionMaterials, encryptedDataKeys); @@ -176,7 +176,7 @@ void testOnDecryptFailure() { void testOnDecryptNoFailuresNoPlaintextDataKeys() { MultiKeyring keyring = new MultiKeyring(generatorKeyring, childrenKeyrings); - when(decryptionMaterials.getCleartextDataKey()).thenReturn(null, null, null, null); + when(decryptionMaterials.hasCleartextDataKey()).thenReturn(false, false, false, false); keyring.onDecrypt(decryptionMaterials, encryptedDataKeys); InOrder inOrder = inOrder(generatorKeyring, keyring1, keyring2); diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java index be87bafc7..60482d403 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawKeyringTest.java @@ -37,8 +37,8 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -114,7 +114,7 @@ void testEncryptNullDataKey() { assertEquals(encryptionMaterials.getCleartextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); assertArrayEquals(encryptionMaterials.getCleartextDataKey().getEncoded(), dataKeyCaptor.getValue()); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); - assertNotNull(encryptionMaterials.getCleartextDataKey()); + assertTrue(encryptionMaterials.hasCleartextDataKey()); assertEncryptedDataKeyEquals(ENCRYPTED_DATA_KEY, encryptionMaterials.getEncryptedDataKeys().get(0)); assertEquals(2, encryptionMaterials.getKeyringTrace().getEntries().size()); assertEquals(GENERATED_DATA_KEY_TRACE, encryptionMaterials.getKeyringTrace().getEntries().get(0)); @@ -146,7 +146,7 @@ void testDecryptNoValidDataKey() { keyring.onDecrypt(decryptionMaterials, Collections.singletonList(INVALID_DATA_KEY)); - assertNull(decryptionMaterials.getCleartextDataKey()); + assertFalse(decryptionMaterials.hasCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } @@ -160,7 +160,7 @@ void testDecryptNoDataKey() { keyring.onDecrypt(decryptionMaterials, Collections.emptyList()); - assertNull(decryptionMaterials.getCleartextDataKey()); + assertFalse(decryptionMaterials.hasCleartextDataKey()); assertEquals(0, decryptionMaterials.getKeyringTrace().getEntries().size()); } diff --git a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java index 9107cf447..1f3f1fe63 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/keyrings/RawRsaKeyringTest.java @@ -33,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; class RawRsaKeyringTest { @@ -109,7 +108,7 @@ void testEncryptDecryptGenerateDataKey() { keyring.onEncrypt(encryptionMaterials); - assertNotNull(encryptionMaterials.getCleartextDataKey()); + assertTrue(encryptionMaterials.hasCleartextDataKey()); assertEquals(encryptionMaterials.getCleartextDataKey().getAlgorithm(), ALGORITHM.getDataKeyAlgo()); assertEquals(1, encryptionMaterials.getEncryptedDataKeys().size()); diff --git a/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java b/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java index a5764e15d..444908478 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java @@ -31,6 +31,7 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -129,6 +130,7 @@ void testGetOptionalProperties() { assertNull(materials.getAlgorithm()); assertNull(materials.getCleartextDataKey()); + assertFalse(materials.hasCleartextDataKey()); assertNull(materials.getTrailingSignatureKey()); assertTrue(materials.getEncryptionContext().isEmpty()); assertTrue(materials.getKeyringTrace().getEntries().isEmpty()); diff --git a/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java b/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java index 148a16f4d..54c89ac59 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java +++ b/src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsTest.java @@ -34,6 +34,7 @@ import static com.amazonaws.encryptionsdk.internal.RandomBytesGenerator.generate; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -154,6 +155,7 @@ void testGetOptionalProperties() { assertNull(materials.getAlgorithm()); assertNull(materials.getCleartextDataKey()); + assertFalse(materials.hasCleartextDataKey()); assertTrue(materials.getEncryptedDataKeys().isEmpty()); assertNull(materials.getTrailingSignatureKey()); assertTrue(materials.getKeyringTrace().getEntries().isEmpty());