@@ -71,6 +71,243 @@ public static void setUp() throws NoSuchAlgorithmException {
7171 THIRD_PARTY_RSA_KEY_PAIR = keyPairGen .generateKeyPair ();
7272 }
7373
74+ @ Test
75+ public void testAesReEncryptInstructionFileFailsWithSameMaterialsDescription () {
76+ AesKeyring oldKeyring = AesKeyring .builder ()
77+ .wrappingKey (AES_KEY )
78+ .secureRandom (new SecureRandom ())
79+ .materialsDescription (MaterialsDescription .builder ()
80+ .put ("rotated" , "no" )
81+ .build ())
82+ .build ();
83+
84+ S3Client wrappedClient = S3Client .create ();
85+ S3EncryptionClient client = S3EncryptionClient .builder ()
86+ .keyring (oldKeyring )
87+ .instructionFileConfig (InstructionFileConfig .builder ()
88+ .instructionFileClient (wrappedClient )
89+ .enableInstructionFilePutObject (true )
90+ .build ())
91+ .build ();
92+
93+ final String objectKey = appendTestSuffix ("aes-re-encrypt-instruction-file-test" );
94+ final String input = "Testing re-encryption of instruction file with AES Keyring" ;
95+
96+ client .putObject (builder -> builder
97+ .bucket (BUCKET )
98+ .key (objectKey )
99+ .build (), RequestBody .fromString (input ));
100+
101+ AesKeyring newKeyring = AesKeyring .builder ()
102+ .wrappingKey (AES_KEY_TWO )
103+ .secureRandom (new SecureRandom ())
104+ .materialsDescription (MaterialsDescription .builder ()
105+ .put ("rotated" , "no" )
106+ .build ())
107+ .build ();
108+
109+ ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest .builder ()
110+ .bucket (BUCKET )
111+ .key (objectKey )
112+ .newKeyring (newKeyring )
113+ .build ();
114+
115+ try {
116+ client .reEncryptInstructionFile (reEncryptInstructionFileRequest );
117+ throw new RuntimeException ("Expected failure" );
118+ } catch (S3EncryptionClientException e ) {;
119+ assertTrue (e .getMessage ().contains ("New keyring must have new materials description!" ));
120+ }
121+
122+ deleteObject (BUCKET , objectKey , client );
123+ }
124+
125+ @ Test
126+ public void testRsaReEncryptInstructionFileFailsWithSameMaterialsDescription () {
127+ PublicKey clientPublicKey = RSA_KEY_PAIR .getPublic ();
128+ PrivateKey clientPrivateKey = RSA_KEY_PAIR .getPrivate ();
129+
130+ PartialRsaKeyPair clientPartialRsaKeyPair = PartialRsaKeyPair .builder ()
131+ .publicKey (clientPublicKey )
132+ .privateKey (clientPrivateKey )
133+ .build ();
134+
135+ RsaKeyring clientKeyring = RsaKeyring .builder ()
136+ .wrappingKeyPair (clientPartialRsaKeyPair )
137+ .secureRandom (new SecureRandom ())
138+ .materialsDescription (MaterialsDescription .builder ()
139+ .put ("isOwner" , "yes" )
140+ .put ("access-level" , "admin" )
141+ .build ())
142+ .build ();
143+
144+ S3Client wrappedClient = S3Client .create ();
145+ S3EncryptionClient client = S3EncryptionClient .builder ()
146+ .keyring (clientKeyring )
147+ .instructionFileConfig (InstructionFileConfig .builder ()
148+ .instructionFileClient (wrappedClient )
149+ .enableInstructionFilePutObject (true )
150+ .build ())
151+ .build ();
152+
153+ final String objectKey = appendTestSuffix ("rsa-re-encrypt-instruction-file-test" );
154+ final String input = "Testing re-encryption of instruction file with RSA Keyring" ;
155+
156+ client .putObject (builder -> builder
157+ .bucket (BUCKET )
158+ .key (objectKey )
159+ .build (), RequestBody .fromString (input ));
160+
161+ PublicKey thirdPartyPublicKey = THIRD_PARTY_RSA_KEY_PAIR .getPublic ();
162+ PrivateKey thirdPartyPrivateKey = THIRD_PARTY_RSA_KEY_PAIR .getPrivate ();
163+
164+ PartialRsaKeyPair thirdPartyPartialRsaKeyPair = PartialRsaKeyPair .builder ()
165+ .publicKey (thirdPartyPublicKey )
166+ .privateKey (thirdPartyPrivateKey )
167+ .build ();
168+
169+ RsaKeyring thirdPartyKeyring = RsaKeyring .builder ()
170+ .wrappingKeyPair (thirdPartyPartialRsaKeyPair )
171+ .secureRandom (new SecureRandom ())
172+ .materialsDescription (MaterialsDescription .builder ()
173+ .put ("isOwner" , "yes" )
174+ .put ("access-level" , "admin" )
175+ .build ())
176+ .build ();
177+
178+ ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest .builder ()
179+ .bucket (BUCKET )
180+ .key (objectKey )
181+ .instructionFileSuffix ("third-party-access-instruction-file" )
182+ .newKeyring (thirdPartyKeyring )
183+ .build ();
184+
185+ try {
186+ client .reEncryptInstructionFile (reEncryptInstructionFileRequest );
187+ throw new RuntimeException ("Expected failure" );
188+ } catch (S3EncryptionClientException e ) {
189+ assertTrue (e .getMessage ().contains ("New keyring must have new materials description!" ));
190+ }
191+
192+ deleteObject (BUCKET , objectKey , client );
193+ }
194+
195+ @ Test
196+ public void testReEncryptInstructionFileRejectsAesKeyringWithCustomSuffix () {
197+ AesKeyring oldKeyring = AesKeyring .builder ()
198+ .wrappingKey (AES_KEY )
199+ .secureRandom (new SecureRandom ())
200+ .materialsDescription (MaterialsDescription .builder ()
201+ .put ("rotated" , "no" )
202+ .build ())
203+ .build ();
204+
205+ S3Client wrappedClient = S3Client .create ();
206+ S3EncryptionClient client = S3EncryptionClient .builder ()
207+ .keyring (oldKeyring )
208+ .instructionFileConfig (InstructionFileConfig .builder ()
209+ .instructionFileClient (wrappedClient )
210+ .enableInstructionFilePutObject (true )
211+ .build ())
212+ .build ();
213+
214+ final String objectKey = appendTestSuffix ("aes-re-encrypt-instruction-file-test" );
215+ final String input = "Testing re-encryption of instruction file with AES Keyring" ;
216+
217+ client .putObject (builder -> builder
218+ .bucket (BUCKET )
219+ .key (objectKey )
220+ .build (), RequestBody .fromString (input ));
221+
222+ AesKeyring newKeyring = AesKeyring .builder ()
223+ .wrappingKey (AES_KEY_TWO )
224+ .secureRandom (new SecureRandom ())
225+ .materialsDescription (MaterialsDescription .builder ()
226+ .put ("rotated" , "yes" )
227+ .build ())
228+ .build ();
229+
230+ try {
231+ ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest .builder ()
232+ .bucket (BUCKET )
233+ .key (objectKey )
234+ .newKeyring (newKeyring )
235+ .instructionFileSuffix ("custom-suffix" )
236+ .build ();
237+ } catch (S3EncryptionClientException e ) {
238+ assertTrue (e .getMessage ().contains ("Custom Instruction file suffix is not applicable for AES keyring!" ));
239+ }
240+
241+ deleteObject (BUCKET , objectKey , client );
242+ }
243+
244+ @ Test
245+ public void testReEncryptInstructionFileRejectsRsaKeyringWithDefaultSuffix () {
246+ PublicKey clientPublicKey = RSA_KEY_PAIR .getPublic ();
247+ PrivateKey clientPrivateKey = RSA_KEY_PAIR .getPrivate ();
248+
249+ PartialRsaKeyPair clientPartialRsaKeyPair = PartialRsaKeyPair .builder ()
250+ .publicKey (clientPublicKey )
251+ .privateKey (clientPrivateKey )
252+ .build ();
253+
254+ RsaKeyring clientKeyring = RsaKeyring .builder ()
255+ .wrappingKeyPair (clientPartialRsaKeyPair )
256+ .secureRandom (new SecureRandom ())
257+ .materialsDescription (MaterialsDescription .builder ()
258+ .put ("isOwner" , "yes" )
259+ .put ("access-level" , "admin" )
260+ .build ())
261+ .build ();
262+
263+ S3Client wrappedClient = S3Client .create ();
264+ S3EncryptionClient client = S3EncryptionClient .builder ()
265+ .keyring (clientKeyring )
266+ .instructionFileConfig (InstructionFileConfig .builder ()
267+ .instructionFileClient (wrappedClient )
268+ .enableInstructionFilePutObject (true )
269+ .build ())
270+ .build ();
271+
272+ final String objectKey = appendTestSuffix ("rsa-re-encrypt-instruction-file-test" );
273+ final String input = "Testing re-encryption of instruction file with RSA Keyring" ;
274+
275+ client .putObject (builder -> builder
276+ .bucket (BUCKET )
277+ .key (objectKey )
278+ .build (), RequestBody .fromString (input ));
279+
280+ PublicKey thirdPartyPublicKey = THIRD_PARTY_RSA_KEY_PAIR .getPublic ();
281+ PrivateKey thirdPartyPrivateKey = THIRD_PARTY_RSA_KEY_PAIR .getPrivate ();
282+
283+ PartialRsaKeyPair thirdPartyPartialRsaKeyPair = PartialRsaKeyPair .builder ()
284+ .publicKey (thirdPartyPublicKey )
285+ .privateKey (thirdPartyPrivateKey )
286+ .build ();
287+
288+ RsaKeyring thirdPartyKeyring = RsaKeyring .builder ()
289+ .wrappingKeyPair (thirdPartyPartialRsaKeyPair )
290+ .secureRandom (new SecureRandom ())
291+ .materialsDescription (MaterialsDescription .builder ()
292+ .put ("isOwner" , "no" )
293+ .put ("access-level" , "user" )
294+ .build ())
295+ .build ();
296+
297+ try {
298+ ReEncryptInstructionFileRequest reEncryptInstructionFileRequest = ReEncryptInstructionFileRequest .builder ()
299+ .bucket (BUCKET )
300+ .key (objectKey )
301+ .instructionFileSuffix ("instruction" )
302+ .newKeyring (thirdPartyKeyring )
303+ .build ();
304+ } catch (S3EncryptionClientException e ) {
305+ assertTrue (e .getMessage ().contains ("Instruction file suffix must be different than the default one for RSA keyring!" ));
306+ }
307+
308+ deleteObject (BUCKET , objectKey , client );
309+ }
310+
74311 @ Test
75312 public void testAesKeyringReEncryptInstructionFile () {
76313 AesKeyring oldKeyring = AesKeyring .builder ()
@@ -1030,7 +1267,4 @@ public void testReEncryptInstructionFileUpgradesV1RsaEncryptionOnlyToV3() throws
10301267 deleteObject (BUCKET , objectKey , v3OriginalClient );
10311268
10321269 }
1033-
1034-
1035-
10361270}
0 commit comments