@@ -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