66import software .amazon .awssdk .auth .credentials .AwsCredentialsProvider ;
77import software .amazon .awssdk .awscore .AwsRequestOverrideConfiguration ;
88import software .amazon .awssdk .awscore .exception .AwsServiceException ;
9+ import software .amazon .awssdk .core .ResponseBytes ;
910import software .amazon .awssdk .core .ResponseInputStream ;
1011import software .amazon .awssdk .core .async .AsyncRequestBody ;
1112import software .amazon .awssdk .core .async .AsyncResponseTransformer ;
4647import software .amazon .awssdk .services .s3 .model .UploadPartRequest ;
4748import software .amazon .awssdk .services .s3 .model .UploadPartResponse ;
4849import software .amazon .encryption .s3 .algorithms .AlgorithmSuite ;
50+ import software .amazon .encryption .s3 .internal .ContentMetadata ;
51+ import software .amazon .encryption .s3 .internal .ContentMetadataDecodingStrategy ;
52+ import software .amazon .encryption .s3 .internal .ContentMetadataEncodingStrategy ;
4953import software .amazon .encryption .s3 .internal .ConvertSDKRequests ;
5054import software .amazon .encryption .s3 .internal .GetEncryptedObjectPipeline ;
5155import software .amazon .encryption .s3 .internal .InstructionFileConfig ;
5256import software .amazon .encryption .s3 .internal .MultiFileOutputStream ;
5357import software .amazon .encryption .s3 .internal .MultipartUploadObjectPipeline ;
5458import software .amazon .encryption .s3 .internal .PutEncryptedObjectPipeline ;
59+ import software .amazon .encryption .s3 .internal .ReEncryptInstructionFileRequest ;
60+ import software .amazon .encryption .s3 .internal .ReEncryptInstructionFileResponse ;
5561import software .amazon .encryption .s3 .internal .UploadObjectObserver ;
5662import software .amazon .encryption .s3 .materials .AesKeyring ;
5763import software .amazon .encryption .s3 .materials .CryptographicMaterialsManager ;
64+ import software .amazon .encryption .s3 .materials .DecryptMaterialsRequest ;
65+ import software .amazon .encryption .s3 .materials .DecryptionMaterials ;
5866import software .amazon .encryption .s3 .materials .DefaultCryptoMaterialsManager ;
67+ import software .amazon .encryption .s3 .materials .EncryptedDataKey ;
68+ import software .amazon .encryption .s3 .materials .EncryptionMaterials ;
5969import software .amazon .encryption .s3 .materials .Keyring ;
6070import software .amazon .encryption .s3 .materials .KmsKeyring ;
71+ import software .amazon .encryption .s3 .materials .MaterialsDescription ;
6172import software .amazon .encryption .s3 .materials .MultipartConfiguration ;
6273import software .amazon .encryption .s3 .materials .PartialRsaKeyPair ;
74+ import software .amazon .encryption .s3 .materials .RawKeyring ;
6375import software .amazon .encryption .s3 .materials .RsaKeyring ;
6476
77+ import javax .crypto .DecapsulateException ;
6578import javax .crypto .SecretKey ;
6679import java .io .IOException ;
6780import java .net .URI ;
6881import java .security .KeyPair ;
6982import java .security .Provider ;
7083import java .security .SecureRandom ;
7184import java .util .ArrayList ;
85+ import java .util .Collections ;
7286import java .util .List ;
7387import java .util .Map ;
7488import java .util .Optional ;
@@ -154,7 +168,6 @@ public static Consumer<AwsRequestOverrideConfiguration.Builder> withAdditionalCo
154168 builder .putExecutionAttribute (S3EncryptionClient .CONFIGURATION , multipartConfiguration );
155169 }
156170
157-
158171 /**
159172 * Attaches encryption context and multipart configuration to a request.
160173 * * Must be used as a parameter to
@@ -172,6 +185,52 @@ public static Consumer<AwsRequestOverrideConfiguration.Builder> withAdditionalCo
172185 .putExecutionAttribute (S3EncryptionClient .CONFIGURATION , multipartConfiguration );
173186 }
174187
188+ public ReEncryptInstructionFileResponse reEncryptInstructionFile (ReEncryptInstructionFileRequest reEncryptInstructionFileRequest ) {
189+ GetObjectRequest request = GetObjectRequest .builder ()
190+ .bucket (reEncryptInstructionFileRequest .bucket ())
191+ .key (reEncryptInstructionFileRequest .key ())
192+ .build ();
193+
194+ ResponseInputStream <GetObjectResponse > response = this .getObject (request );
195+ ContentMetadataDecodingStrategy decodingStrategy = new ContentMetadataDecodingStrategy (_instructionFileConfig );
196+ ContentMetadata contentMetadata = decodingStrategy .decode (request , response .response ());
197+
198+ AlgorithmSuite algorithmSuite = contentMetadata .algorithmSuite ();
199+ EncryptedDataKey encryptedDataKey = contentMetadata .encryptedDataKey ();
200+ Map <String , String > currentKeyringMaterialsDescription = contentMetadata .encryptedDataKeyContext ();
201+ byte [] iv = contentMetadata .contentIv ();
202+
203+ DecryptionMaterials decryptedMaterials = this ._cryptoMaterialsManager .decryptMaterials (
204+ DecryptMaterialsRequest .builder ()
205+ .algorithmSuite (algorithmSuite )
206+ .encryptedDataKeys (Collections .singletonList (encryptedDataKey ))
207+ .build ()
208+ );
209+ byte [] plaintextDataKey = decryptedMaterials .plaintextDataKey ();
210+
211+ EncryptionMaterials encryptionMaterials = EncryptionMaterials .builder ()
212+ .algorithmSuite (algorithmSuite )
213+ .plaintextDataKey (plaintextDataKey )
214+ .build ();
215+
216+ RawKeyring newKeyring = reEncryptInstructionFileRequest .newKeyring ();
217+ EncryptionMaterials encryptedMaterials = newKeyring .onEncrypt (encryptionMaterials );
218+
219+ if (encryptedMaterials .materialsDescription ().equals (currentKeyringMaterialsDescription )) {
220+ throw new S3EncryptionClientException ("New keyring must generate new materials description!" );
221+ }
222+
223+ ContentMetadataEncodingStrategy encodeStrategy = new ContentMetadataEncodingStrategy (_instructionFileConfig );
224+ encodeStrategy .encodeMetadata (encryptedMaterials , iv , PutObjectRequest .builder ()
225+ .bucket (reEncryptInstructionFileRequest .bucket ())
226+ .key (reEncryptInstructionFileRequest .key ())
227+ .build ());
228+
229+ return new ReEncryptInstructionFileResponse (reEncryptInstructionFileRequest .bucket (),
230+ reEncryptInstructionFileRequest .key (), reEncryptInstructionFileRequest .instructionFileSuffix ());
231+
232+ }
233+
175234 /**
176235 * See {@link S3EncryptionClient#putObject(PutObjectRequest, RequestBody)}.
177236 * <p>
0 commit comments