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 ;
109import software .amazon .awssdk .core .ResponseInputStream ;
1110import software .amazon .awssdk .core .async .AsyncRequestBody ;
1211import software .amazon .awssdk .core .async .AsyncResponseTransformer ;
6867import software .amazon .encryption .s3 .materials .EncryptionMaterials ;
6968import software .amazon .encryption .s3 .materials .Keyring ;
7069import software .amazon .encryption .s3 .materials .KmsKeyring ;
71- import software .amazon .encryption .s3 .materials .MaterialsDescription ;
7270import software .amazon .encryption .s3 .materials .MultipartConfiguration ;
7371import software .amazon .encryption .s3 .materials .PartialRsaKeyPair ;
7472import software .amazon .encryption .s3 .materials .RawKeyring ;
7573import software .amazon .encryption .s3 .materials .RsaKeyring ;
7674
77- import javax .crypto .DecapsulateException ;
7875import javax .crypto .SecretKey ;
7976import java .io .IOException ;
8077import java .net .URI ;
8582import java .util .Collections ;
8683import java .util .List ;
8784import java .util .Map ;
85+ import java .util .Objects ;
8886import java .util .Optional ;
8987import java .util .concurrent .CompletableFuture ;
9088import java .util .concurrent .CompletionException ;
@@ -110,6 +108,7 @@ public class S3EncryptionClient extends DelegatingS3Client {
110108 // Used for request-scoped encryption contexts for supporting keys
111109 public static final ExecutionAttribute <Map <String , String >> ENCRYPTION_CONTEXT = new ExecutionAttribute <>("EncryptionContext" );
112110 public static final ExecutionAttribute <MultipartConfiguration > CONFIGURATION = new ExecutionAttribute <>("MultipartConfiguration" );
111+ public static final ExecutionAttribute <String > CUSTOM_INSTRUCTION_FILE_SUFFIX = new ExecutionAttribute <>("CustomInstructionFileSuffix" );
113112
114113 private final S3Client _wrappedClient ;
115114 private final S3AsyncClient _wrappedAsyncClient ;
@@ -157,6 +156,11 @@ public static Consumer<AwsRequestOverrideConfiguration.Builder> withAdditionalCo
157156 builder .putExecutionAttribute (S3EncryptionClient .ENCRYPTION_CONTEXT , encryptionContext );
158157 }
159158
159+ public static Consumer <AwsRequestOverrideConfiguration .Builder > withCustomInstructionFileSuffix (String customInstructionFileSuffix ) {
160+ return builder ->
161+ builder .putExecutionAttribute (S3EncryptionClient .CUSTOM_INSTRUCTION_FILE_SUFFIX , customInstructionFileSuffix );
162+ }
163+
160164 /**
161165 * Attaches multipart configuration to a request. Must be used as a parameter to
162166 * {@link S3Request#overrideConfiguration()} in the request.
@@ -204,13 +208,15 @@ public ReEncryptInstructionFileResponse reEncryptInstructionFile(ReEncryptInstru
204208 DecryptMaterialsRequest .builder ()
205209 .algorithmSuite (algorithmSuite )
206210 .encryptedDataKeys (Collections .singletonList (encryptedDataKey ))
211+ .s3Request (request )
207212 .build ()
208213 );
209214 byte [] plaintextDataKey = decryptedMaterials .plaintextDataKey ();
210215
211216 EncryptionMaterials encryptionMaterials = EncryptionMaterials .builder ()
212217 .algorithmSuite (algorithmSuite )
213218 .plaintextDataKey (plaintextDataKey )
219+ .s3Request (request )
214220 .build ();
215221
216222 RawKeyring newKeyring = reEncryptInstructionFileRequest .newKeyring ();
@@ -221,11 +227,18 @@ public ReEncryptInstructionFileResponse reEncryptInstructionFile(ReEncryptInstru
221227 }
222228
223229 ContentMetadataEncodingStrategy encodeStrategy = new ContentMetadataEncodingStrategy (_instructionFileConfig );
224- encodeStrategy .encodeMetadata (encryptedMaterials , iv , PutObjectRequest .builder ()
225- .bucket (reEncryptInstructionFileRequest .bucket ())
226- .key (reEncryptInstructionFileRequest .key ())
227- .build ());
228230
231+ if (reEncryptInstructionFileRequest .instructionFileSuffix ().equals (INSTRUCTION_FILE_SUFFIX )) {
232+ encodeStrategy .encodeMetadata (encryptedMaterials , iv , PutObjectRequest .builder ()
233+ .bucket (reEncryptInstructionFileRequest .bucket ())
234+ .key (reEncryptInstructionFileRequest .key ())
235+ .build ());
236+ } else {
237+ encodeStrategy .encodeMetadata (encryptedMaterials , iv , PutObjectRequest .builder ()
238+ .bucket (reEncryptInstructionFileRequest .bucket ())
239+ .key (reEncryptInstructionFileRequest .key ())
240+ .build (), reEncryptInstructionFileRequest .instructionFileSuffix ());
241+ }
229242 return new ReEncryptInstructionFileResponse (reEncryptInstructionFileRequest .bucket (),
230243 reEncryptInstructionFileRequest .key (), reEncryptInstructionFileRequest .instructionFileSuffix ());
231244
0 commit comments