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());