Skip to content

Commit 0336fea

Browse files
author
Anirav Kareddy
committed
wrote some more test cases to test for enforceRotation for legacy wrapping algorithm upgrades from V1/V2 to V3
1 parent 9b41d81 commit 0336fea

File tree

2 files changed

+177
-11
lines changed

2 files changed

+177
-11
lines changed

src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ private void enforceRotation(EncryptionMaterials newEncryptionMaterials, GetObje
293293
} catch (S3EncryptionClientException e) {
294294
return;
295295
}
296-
throw new S3EncryptionClientException("Key rotation is not enforced! Old keyring is still able to decrypt the new encrypted data key");
296+
throw new S3EncryptionClientException("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key");
297297
}
298298

299299
/**

src/test/java/software/amazon/encryption/s3/S3EncryptionClientReEncryptInstructionFileTest.java

Lines changed: 176 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ public void testAesKeyringReEncryptInstructionFileEnforceRotation() {
12211221
.build();
12221222

12231223
final String objectKey = appendTestSuffix("aes-re-encrypt-instruction-file-test-with-enforce-rotation");
1224-
final String input = "Testing re-encryption of instruction file with AES Keyring and enforce rotation";
1224+
final String input = "Testing re-encryption of instruction file with AES Keyring and enforce rotation enabled";
12251225

12261226
client.putObject(builder -> builder
12271227
.bucket(BUCKET)
@@ -1271,8 +1271,8 @@ public void testAesKeyringReEncryptInstructionFileEnforceRotationThrowsException
12711271
.build())
12721272
.build();
12731273

1274-
final String objectKey = appendTestSuffix("aes-re-encrypt-instruction-file-test-with-enforce-rotation-same-key-throws-exception");
1275-
final String input = "Testing re-encryption of instruction file with AES Keyring and enforce rotation";
1274+
final String objectKey = appendTestSuffix("aes-re-encrypt-instruction-file-test-with-enforce-rotation-and-same-key-throws-exception");
1275+
final String input = "Testing re-encryption of instruction file with the same AES keyring and enforce rotation enabled";
12761276

12771277
client.putObject(builder -> builder
12781278
.bucket(BUCKET)
@@ -1298,7 +1298,7 @@ public void testAesKeyringReEncryptInstructionFileEnforceRotationThrowsException
12981298
ReEncryptInstructionFileResponse response = client.reEncryptInstructionFile(reEncryptInstructionFileRequest);
12991299
throw new RuntimeException("Enforce rotation should throw exception");
13001300
} catch (S3EncryptionClientException e) {
1301-
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the new encrypted data key"));
1301+
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key"));
13021302
}
13031303

13041304
deleteObject(BUCKET, objectKey, client);
@@ -1332,7 +1332,7 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationThrowsException
13321332
.build();
13331333

13341334
final String objectKey = appendTestSuffix("rsa-re-encrypt-instruction-file-test-enforce-rotation-same-key-throws-exception");
1335-
final String input = "Testing re-encryption of instruction file with RSA Keyring";
1335+
final String input = "Testing re-encryption of instruction file with same RSA Keyring with enforce rotation enabled";
13361336

13371337
client.putObject(builder -> builder
13381338
.bucket(BUCKET)
@@ -1358,7 +1358,7 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationThrowsException
13581358
ReEncryptInstructionFileResponse response = client.reEncryptInstructionFile(reEncryptInstructionFileRequest);
13591359
throw new RuntimeException("Enforce rotation should throw exception");
13601360
} catch (S3EncryptionClientException e) {
1361-
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the new encrypted data key"));
1361+
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key"));
13621362
}
13631363

13641364
deleteObject(BUCKET, objectKey, client);
@@ -1393,7 +1393,7 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationWithCustomSuffi
13931393
.build();
13941394

13951395
final String objectKey = appendTestSuffix("test-enforce-rotation-for-rsa-re-encrypt-instruction-file-custom-suffix");
1396-
final String input = "Testing re-encryption of instruction file with RSA Keyring";
1396+
final String input = "Testing re-encryption of instruction file with RSA Keyring and both custom suffix and enforce rotation enabled";
13971397

13981398
client.putObject(builder -> builder
13991399
.bucket(BUCKET)
@@ -1408,7 +1408,7 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationWithCustomSuffi
14081408
.privateKey(thirdPartyPrivateKey)
14091409
.build();
14101410

1411-
RsaKeyring newKeyring = RsaKeyring.builder()
1411+
RsaKeyring thirdPartyKeyring = RsaKeyring.builder()
14121412
.wrappingKeyPair(thirdPartyPartialRsaKeyPair)
14131413
.secureRandom(new SecureRandom())
14141414
.materialsDescription(MaterialsDescription.builder()
@@ -1420,7 +1420,7 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationWithCustomSuffi
14201420
ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest.builder()
14211421
.bucket(BUCKET)
14221422
.key(objectKey)
1423-
.newKeyring(newKeyring)
1423+
.newKeyring(thirdPartyKeyring)
14241424
.enforceRotation(true)
14251425
.instructionFileSuffix("third-party-access-instruction-file")
14261426
.build();
@@ -1491,10 +1491,176 @@ public void testRsaKeyringReEncryptInstructionFileEnforceRotationWithCustomSuffi
14911491
ReEncryptInstructionFileResponse response = client.reEncryptInstructionFile(reEncryptInstructionFileRequest);
14921492
throw new RuntimeException("Enforce rotation should throw exception");
14931493
} catch (S3EncryptionClientException e) {
1494-
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the new encrypted data key"));
1494+
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key"));
14951495
}
14961496

14971497
deleteObject(BUCKET, objectKey, client);
14981498

14991499
}
1500+
1501+
@Test
1502+
public void testAesKeyringReEncryptInstructionFileV1ToV3UpgradeEnforceRotationThrowsExceptionWithSameKey() {
1503+
final String input = "Testing re-encryption of instruction file with enforce rotation enabled, upgrading legacy V1 to V3 with same AES keyring";
1504+
final String objectKey = appendTestSuffix("v1-aes-to-v3-re-encrypt-instruction-file-with-enforce-rotation-same-key-test");
1505+
1506+
EncryptionMaterialsProvider materialsProvider =
1507+
new StaticEncryptionMaterialsProvider(new EncryptionMaterials(AES_KEY)
1508+
.addDescription("rotated", "no")
1509+
.addDescription("isLegacy", "yes")
1510+
);
1511+
1512+
CryptoConfiguration cryptoConfig = new CryptoConfiguration(CryptoMode.AuthenticatedEncryption)
1513+
.withStorageMode(CryptoStorageMode.InstructionFile);
1514+
1515+
AmazonS3Encryption v1Client = AmazonS3EncryptionClient.encryptionBuilder()
1516+
.withCryptoConfiguration(cryptoConfig)
1517+
.withEncryptionMaterials(materialsProvider)
1518+
.build();
1519+
1520+
v1Client.putObject(BUCKET, objectKey, input);
1521+
1522+
AesKeyring oldKeyring = AesKeyring.builder()
1523+
.wrappingKey(AES_KEY)
1524+
.enableLegacyWrappingAlgorithms(true)
1525+
.secureRandom(new SecureRandom())
1526+
.materialsDescription(MaterialsDescription.builder()
1527+
.put("rotated", "no")
1528+
.put("isLegacy", "yes")
1529+
.build())
1530+
.build();
1531+
1532+
S3Client wrappedClient = S3Client.create();
1533+
S3EncryptionClient v3OriginalClient = S3EncryptionClient.builder()
1534+
.keyring(oldKeyring)
1535+
.enableLegacyUnauthenticatedModes(true)
1536+
.enableLegacyWrappingAlgorithms(true)
1537+
.instructionFileConfig(InstructionFileConfig.builder()
1538+
.instructionFileClient(wrappedClient)
1539+
.enableInstructionFilePutObject(true)
1540+
.build())
1541+
.build();
1542+
1543+
AesKeyring newKeyring = AesKeyring.builder()
1544+
.wrappingKey(AES_KEY)
1545+
.secureRandom(new SecureRandom())
1546+
.materialsDescription(MaterialsDescription.builder()
1547+
.put("rotated", "yes")
1548+
.put("isLegacy", "no")
1549+
.build())
1550+
.build();
1551+
1552+
S3EncryptionClient v3RotatedClient = S3EncryptionClient.builder()
1553+
.keyring(newKeyring)
1554+
.instructionFileConfig(InstructionFileConfig.builder()
1555+
.instructionFileClient(wrappedClient)
1556+
.enableInstructionFilePutObject(true)
1557+
.build())
1558+
.build();
1559+
1560+
ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest.builder()
1561+
.bucket(BUCKET)
1562+
.key(objectKey)
1563+
.newKeyring(newKeyring)
1564+
.enforceRotation(true)
1565+
.build();
1566+
1567+
try {
1568+
ReEncryptInstructionFileResponse response = v3OriginalClient.reEncryptInstructionFile(reEncryptInstructionFileRequest);
1569+
throw new RuntimeException("Enforce rotation should throw exception");
1570+
} catch (S3EncryptionClientException e) {
1571+
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key"));
1572+
}
1573+
1574+
deleteObject(BUCKET, objectKey, v3RotatedClient);
1575+
}
1576+
1577+
@Test
1578+
public void testRsaKeyringReEncryptInstructionFileWithCustomSuffixV2ToV3UpgradeEnforceRotationThrowsExceptionWithSameKey() {
1579+
final String input = "Testing re-encryption of instruction file with enforce rotation enabled, upgrading legacy V2 to V3 with same RSA Keyring";
1580+
final String objectKey = appendTestSuffix("v2-rsa-to-v3-re-encrypt-instruction-file-with-enforce-rotation-same-key-test");
1581+
1582+
EncryptionMaterialsProvider materialsProvider =
1583+
new StaticEncryptionMaterialsProvider(new EncryptionMaterials(RSA_KEY_PAIR)
1584+
.addDescription("isOwner", "yes")
1585+
.addDescription("access-level", "admin")
1586+
);
1587+
CryptoConfigurationV2 cryptoConfig =
1588+
new CryptoConfigurationV2(CryptoMode.AuthenticatedEncryption)
1589+
.withStorageMode(CryptoStorageMode.InstructionFile);
1590+
1591+
AmazonS3EncryptionV2 v2OriginalClient = AmazonS3EncryptionClientV2.encryptionBuilder()
1592+
.withCryptoConfiguration(cryptoConfig)
1593+
.withEncryptionMaterialsProvider(materialsProvider)
1594+
.build();
1595+
1596+
v2OriginalClient.putObject(BUCKET, objectKey, input);
1597+
1598+
PublicKey clientPublicKey = RSA_KEY_PAIR.getPublic();
1599+
PrivateKey clientPrivateKey = RSA_KEY_PAIR.getPrivate();
1600+
1601+
PartialRsaKeyPair clientPartialRsaKeyPair = PartialRsaKeyPair.builder()
1602+
.publicKey(clientPublicKey)
1603+
.privateKey(clientPrivateKey)
1604+
.build();
1605+
1606+
RsaKeyring clientKeyring = RsaKeyring.builder()
1607+
.wrappingKeyPair(clientPartialRsaKeyPair)
1608+
.secureRandom(new SecureRandom())
1609+
.enableLegacyWrappingAlgorithms(true)
1610+
.materialsDescription(MaterialsDescription.builder()
1611+
.put("isOwner", "yes")
1612+
.put("access-level", "admin")
1613+
.build())
1614+
.build();
1615+
1616+
S3Client wrappedClient = S3Client.create();
1617+
S3EncryptionClient v3OriginalClient = S3EncryptionClient.builder()
1618+
.keyring(clientKeyring)
1619+
.enableLegacyWrappingAlgorithms(true)
1620+
.enableLegacyUnauthenticatedModes(true)
1621+
.instructionFileConfig(InstructionFileConfig.builder()
1622+
.instructionFileClient(wrappedClient)
1623+
.enableInstructionFilePutObject(true)
1624+
.build())
1625+
.build();
1626+
1627+
RsaKeyring thirdPartyKeyring = RsaKeyring.builder()
1628+
.wrappingKeyPair(clientPartialRsaKeyPair)
1629+
.secureRandom(new SecureRandom())
1630+
.enableLegacyWrappingAlgorithms(true)
1631+
.materialsDescription(MaterialsDescription.builder()
1632+
.put("isOwner", "no")
1633+
.put("access-level", "user")
1634+
.build())
1635+
.build();
1636+
1637+
S3EncryptionClient v3ThirdPartyClient = S3EncryptionClient.builder()
1638+
.keyring(thirdPartyKeyring)
1639+
.enableLegacyWrappingAlgorithms(true)
1640+
.enableLegacyUnauthenticatedModes(true)
1641+
.secureRandom(new SecureRandom())
1642+
.instructionFileConfig(InstructionFileConfig.builder()
1643+
.instructionFileClient(wrappedClient)
1644+
.enableInstructionFilePutObject(true)
1645+
.build())
1646+
.build();
1647+
1648+
ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest.builder()
1649+
.bucket(BUCKET)
1650+
.key(objectKey)
1651+
.newKeyring(thirdPartyKeyring)
1652+
.instructionFileSuffix("third-party-access-instruction-file")
1653+
.enforceRotation(true)
1654+
.build();
1655+
1656+
try {
1657+
ReEncryptInstructionFileResponse response = v3OriginalClient.reEncryptInstructionFile(reEncryptInstructionFileRequest);
1658+
throw new RuntimeException("Enforce rotation should throw exception");
1659+
} catch (S3EncryptionClientException e) {
1660+
assertTrue(e.getMessage().contains("Key rotation is not enforced! Old keyring is still able to decrypt the newly encrypted data key"));
1661+
}
1662+
1663+
deleteObject(BUCKET, objectKey, v3OriginalClient);
1664+
}
1665+
15001666
}

0 commit comments

Comments
 (0)