diff --git a/specification b/specification index 616da1e36..85d4c1769 160000 --- a/specification +++ b/specification @@ -1 +1 @@ -Subproject commit 616da1e364a48c118cd19f42efc6cfc653c929ad +Subproject commit 85d4c176901e29fb795ec551abd11fc7df076f94 diff --git a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java index c4d043cc9..e1c275bd5 100644 --- a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java @@ -210,7 +210,7 @@ public static Consumer withAdditionalCo .putExecutionAttribute(S3EncryptionClient.CONFIGURATION, multipartConfiguration); } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# ReEncryptInstructionFile MAY be implemented by the S3EC. /** @@ -250,7 +250,7 @@ public ReEncryptInstructionFileResponse reEncryptInstructionFile(ReEncryptInstru final byte[] iv = contentMetadata.contentIv(); //Decrypt the data key using the current keyring - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# ReEncryptInstructionFile MUST decrypt the instruction file's encrypted data key for the given object using the client's CMM. DecryptionMaterials decryptedMaterials = this._cryptoMaterialsManager.decryptMaterials( @@ -271,7 +271,7 @@ public ReEncryptInstructionFileResponse reEncryptInstructionFile(ReEncryptInstru .build(); //Re-encrypt the data key with the new keyring while preserving other cryptographic parameters - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# ReEncryptInstructionFile MUST re-encrypt the plaintext data key with a provided keyring. RawKeyring newKeyring = reEncryptInstructionFileRequest.newKeyring(); @@ -315,7 +315,7 @@ private void enforceRotation(EncryptionMaterials newEncryptionMaterials, GetObje throw new S3EncryptionClientException("Re-encryption failed due to enforced rotation! Old keyring is still able to decrypt the newly encrypted data key"); } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# PutObject MUST be implemented by the S3EC. /** @@ -355,7 +355,7 @@ public PutObjectResponse putObject(PutObjectRequest putObjectRequest, RequestBod ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); try { - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# PutObject MUST encrypt its input data before it is uploaded to S3. CompletableFuture futurePut = pipeline.putObject(putObjectRequest, @@ -382,7 +382,7 @@ public PutObjectResponse putObject(PutObjectRequest putObjectRequest, RequestBod } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# GetObject MUST be implemented by the S3EC. /** @@ -406,7 +406,7 @@ public T getObject(GetObjectRequest getObjectRequest, ResponseTransformer responseTransformer) throws AwsServiceException, SdkClientException { - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# GetObject MUST decrypt data received from the S3 server and return it as plaintext. GetEncryptedObjectPipeline pipeline = GetEncryptedObjectPipeline.builder() @@ -516,7 +516,7 @@ private T onAbort(UploadObjectObserver observer, T t) { throw new S3EncryptionClientException(t.getMessage(), t); } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# DeleteObject MUST be implemented by the S3EC. /** @@ -536,11 +536,11 @@ public DeleteObjectResponse deleteObject(DeleteObjectRequest deleteObjectRequest .build(); try { - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implementation //# DeleteObject MUST delete the given object key. DeleteObjectResponse deleteObjectResponse = _wrappedAsyncClient.deleteObject(actualRequest).join(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implementation //# DeleteObject MUST delete the associated instruction file using the default instruction file suffix. String instructionObjectKey = deleteObjectRequest.key() + DEFAULT_INSTRUCTION_FILE_SUFFIX; @@ -557,7 +557,7 @@ public DeleteObjectResponse deleteObject(DeleteObjectRequest deleteObjectRequest } } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implication //# DeleteObjects MUST be implemented by the S3EC. /** @@ -576,11 +576,11 @@ public DeleteObjectsResponse deleteObjects(DeleteObjectsRequest deleteObjectsReq .overrideConfiguration(API_NAME_INTERCEPTOR) .build(); try { - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implementation //# DeleteObjects MUST delete each of the given objects. DeleteObjectsResponse deleteObjectsResponse = _wrappedAsyncClient.deleteObjects(actualRequest).join(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=implementation //# DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. List deleteObjects = instructionFileKeysToDelete(deleteObjectsRequest); @@ -597,7 +597,7 @@ public DeleteObjectsResponse deleteObjects(DeleteObjectsRequest deleteObjectsReq } } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# CreateMultipartUpload MAY be implemented by the S3EC. /** @@ -621,7 +621,7 @@ public CreateMultipartUploadResponse createMultipartUpload(CreateMultipartUpload } } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# UploadPart MAY be implemented by the S3EC. /** @@ -647,7 +647,7 @@ public UploadPartResponse uploadPart(UploadPartRequest request, RequestBody requ } } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# CompleteMultipartUpload MAY be implemented by the S3EC. /** @@ -667,7 +667,7 @@ public CompleteMultipartUploadResponse completeMultipartUpload(CompleteMultipart } } - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# AbortMultipartUpload MAY be implemented by the S3EC. /** @@ -965,7 +965,7 @@ public Builder enableMultipartPutObject(boolean _enableMultipartPutObject) { //= specification/s3-encryption/client.md#set-buffer-size //= type=implication - //# The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length to store in memory when delayed authentication mode is disabled. + //# The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length in bytes to store in memory when Delayed Authentication mode is disabled. /** * Sets the buffer size for safe authentication used when delayed authentication mode is disabled. * If buffer size is not given during client configuration, default buffer size is set to 64MiB. diff --git a/src/main/java/software/amazon/encryption/s3/internal/MultipartUploadObjectPipeline.java b/src/main/java/software/amazon/encryption/s3/internal/MultipartUploadObjectPipeline.java index 01c48a578..ccec2e064 100644 --- a/src/main/java/software/amazon/encryption/s3/internal/MultipartUploadObjectPipeline.java +++ b/src/main/java/software/amazon/encryption/s3/internal/MultipartUploadObjectPipeline.java @@ -74,7 +74,7 @@ public CreateMultipartUploadResponse createMultipartUpload(CreateMultipartUpload .overrideConfiguration(API_NAME_INTERCEPTOR) .build(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# If implemented, CreateMultipartUpload MUST initiate a multipart upload. CreateMultipartUploadResponse response = _s3AsyncClient.createMultipartUpload(request).join(); @@ -136,11 +136,11 @@ public UploadPartResponse uploadPart(UploadPartRequest request, RequestBody requ throw new S3EncryptionClientException("No client-side information available on upload ID " + uploadId); } final UploadPartResponse response; - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# Each part MUST be encrypted in sequence. materials.beginPartUpload(actualRequest.partNumber(), partContentLength); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# Each part MUST be encrypted using the same cipher instance for each part. Cipher cipher = materials.getCipher(materials.getIv()); @@ -148,7 +148,7 @@ public UploadPartResponse uploadPart(UploadPartRequest request, RequestBody requ ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); try { - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# UploadPart MUST encrypt each part. final AsyncRequestBody cipherAsyncRequestBody = new CipherAsyncRequestBody( @@ -170,7 +170,7 @@ public UploadPartResponse uploadPart(UploadPartRequest request, RequestBody requ } // Ensures parts are not retried to avoid corrupting ciphertext AsyncRequestBody noRetryBody = new NoRetriesAsyncRequestBody(cipherAsyncRequestBody); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication response = _s3AsyncClient.uploadPart(actualRequest, noRetryBody).join(); } finally { @@ -200,7 +200,7 @@ public CompleteMultipartUploadResponse completeMultipartUpload(CompleteMultipart .overrideConfiguration(API_NAME_INTERCEPTOR) .build(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# CompleteMultipartUpload MUST complete the multipart upload. CompleteMultipartUploadResponse response = _s3AsyncClient.completeMultipartUpload(actualRequest).join(); @@ -214,7 +214,7 @@ public AbortMultipartUploadResponse abortMultipartUpload(AbortMultipartUploadReq AbortMultipartUploadRequest actualRequest = request.toBuilder() .overrideConfiguration(API_NAME_INTERCEPTOR) .build(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#optional-api-operations //= type=implication //# AbortMultipartUpload MUST abort the multipart upload. return _s3AsyncClient.abortMultipartUpload(actualRequest).join(); diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index 37c18a6fe..04d5fc346 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -166,13 +166,13 @@ public void deleteObjectWithInstructionFileSuccess() { v3Client.deleteObject(builder -> builder.bucket(BUCKET).key(objectKey)); S3Client s3Client = S3Client.builder().build(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=test //# DeleteObject MUST delete the given object key. assertThrows(S3Exception.class, () -> s3Client.getObject(builder -> builder .bucket(BUCKET) .key(objectKey))); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=test //# DeleteObject MUST delete the associated instruction file using the default instruction file suffix. assertThrows(S3Exception.class, () -> s3Client.getObject(builder -> builder @@ -218,13 +218,13 @@ public void deleteObjectsWithInstructionFilesSuccess() { .delete(builder1 -> builder1.objects(objects))); S3Client s3Client = S3Client.builder().build(); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=test //# DeleteObjects MUST delete each of the given objects. assertThrows(S3Exception.class, () -> s3Client.getObject(builder -> builder .bucket(BUCKET) .key(objectKeys[0]))); - //= specification/s3-encryption/client.md#api-operations + //= specification/s3-encryption/client.md#required-api-operations //= type=test //# DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. assertThrows(S3Exception.class, () -> s3Client.getObject(builder -> builder