Skip to content

Commit 8525e7c

Browse files
kannappanrnitisht
authored andcommitted
Set encryption headers in SSE-C multi-part uploads (#704)
Also add a functional test to test multi-part uploads.
1 parent a5b145f commit 8525e7c

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

api/src/main/java/io/minio/MinioClient.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,7 +3043,7 @@ public void putObject(String bucketName, String objectName, String fileName, Str
30433043
headerMap.put("Content-Type", contentType);
30443044

30453045
try {
3046-
putObject(bucketName, objectName, size, file, headerMap);
3046+
putObject(bucketName, objectName, size, file, headerMap, null);
30473047
} finally {
30483048
file.close();
30493049
}
@@ -3149,7 +3149,7 @@ public void putObject(String bucketName, String objectName, InputStream stream,
31493149
Map<String, String> headerMap = new HashMap<>();
31503150
headerMap.put("Content-Type", contentType);
31513151

3152-
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headerMap);
3152+
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headerMap, null);
31533153
}
31543154

31553155

@@ -3220,7 +3220,7 @@ public void putObject(String bucketName, String objectName, InputStream stream,
32203220
headerMap = new HashMap<>();
32213221
}
32223222

3223-
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headerMap);
3223+
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headerMap, null);
32243224
}
32253225

32263226
/**
@@ -3288,10 +3288,8 @@ public void putObject(String bucketName, String objectName, InputStream stream,
32883288
} else if ((sse.getType() == (ServerSideEncryption.Type.SSE_KMS)) && (!this.baseUrl.isHttps())) {
32893289
throw new InvalidArgumentException("SSE_KMS operations must be performed over a secure connection.");
32903290
}
3291-
3292-
Map<String, String> headers = new HashMap<>();
3293-
sse.marshal(headers);
3294-
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headers);
3291+
Map<String, String> headerMap = new HashMap<>();
3292+
putObject(bucketName, objectName, size, new BufferedInputStream(stream), headerMap, sse);
32953293
}
32963294

32973295

@@ -3359,7 +3357,7 @@ public void putObject(String bucketName, String objectName, InputStream stream,
33593357
Map<String, String> headerMap = new HashMap<>();
33603358
headerMap.put("Content-Type", contentType);
33613359

3362-
putObject(bucketName, objectName, null, new BufferedInputStream(stream), headerMap);
3360+
putObject(bucketName, objectName, null, new BufferedInputStream(stream), headerMap, null);
33633361
}
33643362

33653363
/**
@@ -3414,7 +3412,7 @@ private String putObject(String bucketName, String objectName, int length,
34143412
* Object data.
34153413
*/
34163414
private void putObject(String bucketName, String objectName, Long size, Object data,
3417-
Map<String, String> headerMap)
3415+
Map<String, String> headerMap, ServerSideEncryption sse)
34183416
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
34193417
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
34203418
InternalException,
@@ -3433,6 +3431,9 @@ private void putObject(String bucketName, String objectName, Long size, Object d
34333431

34343432
if (size <= MIN_MULTIPART_SIZE) {
34353433
// Single put object.
3434+
if (sse != null) {
3435+
sse.marshal(headerMap);
3436+
}
34363437
putObject(bucketName, objectName, size.intValue(), data, null, 0, headerMap);
34373438
return;
34383439
}
@@ -3459,6 +3460,9 @@ private void putObject(String bucketName, String objectName, Long size, Object d
34593460
} else {
34603461
// initiate new multipart upload ie no previous multipart found or no previous valid parts for
34613462
// multipart found
3463+
if (sse != null) {
3464+
sse.marshal(headerMap);
3465+
}
34623466
uploadId = initMultipartUpload(bucketName, objectName, headerMap);
34633467
}
34643468

@@ -3503,7 +3507,13 @@ private void putObject(String bucketName, String objectName, Long size, Object d
35033507
}
35043508
}
35053509

3506-
String etag = putObject(bucketName, objectName, expectedReadSize, data, uploadId, partNumber, null);
3510+
// In multi-part uploads, Set encryption headers in the case of SSE-C.
3511+
Map<String, String> encryptionHeaders = new HashMap<>();
3512+
if (sse != null && sse.getType() == ServerSideEncryption.Type.SSE_C) {
3513+
sse.marshal(encryptionHeaders);
3514+
}
3515+
3516+
String etag = putObject(bucketName, objectName, expectedReadSize, data, uploadId, partNumber, encryptionHeaders);
35073517
totalParts[partNumber - 1] = new Part(partNumber, etag);
35083518
}
35093519

functional/FunctionalTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,42 @@ public static void putObject_test15() throws Exception {
873873
}
874874
}
875875

876+
/**
877+
* Test: putObject(String bucketName, String objectName, InputStream stream, long size,
878+
* ServerSideEncryption sse). To test SSE_C (multi-part upload).
879+
*/
880+
public static void putObject_test16() throws Exception {
881+
if (!mintEnv) {
882+
System.out.println("Test: putObject(String bucketName, String objectName, InputStream stream, "
883+
+ "long size, ServerSideEncryption sse) using SSE_C (Multi-part upload). ");
884+
}
885+
long startTime = System.currentTimeMillis();
886+
// Generate a new 256 bit AES key - This key must be remembered by the client.
887+
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
888+
keyGen.init(256);
889+
ServerSideEncryption sse = ServerSideEncryption.withCustomerKey(keyGen.generateKey());
890+
891+
892+
try {
893+
String objectName = getRandomName();
894+
try (final InputStream is = new ContentInputStream(6 * MB)) {
895+
client.putObject(bucketName, objectName, is, 6 * MB, sse);
896+
}
897+
898+
client.removeObject(bucketName, objectName);
899+
900+
mintSuccessLog("putObject(String bucketName, String objectName, InputStream stream, "
901+
+ "long size, ServerSideEncryption sse) using SSE_C (Multi-part upload).",
902+
"size: 6 MB", startTime);
903+
} catch (Exception e) {
904+
mintFailedLog("putObject(String bucketName, String objectName, InputStream stream, "
905+
+ "long size, ServerSideEncryption sse) using SSE_C (Multi-part upload).",
906+
"size: 6 MB", startTime, null, e.toString() + " >>> " + Arrays.toString(e.getStackTrace()));
907+
throw e;
908+
}
909+
}
910+
911+
876912
/**
877913
* Test: statObject(String bucketName, String objectName).
878914
*/
@@ -2813,6 +2849,7 @@ public static void runTests() throws Exception {
28132849
statObject_test2();
28142850
getObject_test7();
28152851
putObject_test13();
2852+
putObject_test16();
28162853
copyObject_test10();
28172854
}
28182855

0 commit comments

Comments
 (0)