Skip to content

Commit 5b90bd4

Browse files
authored
Merge branch 'main' into aniravk/validateAgainstLegacyWrappingOnClientButCustomerPassesKeyring
2 parents 32c9582 + 1bc2ca3 commit 5b90bd4

22 files changed

+1061
-99
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
# Changelog
22

3-
## [3.3.5](https://github.com/aws/aws-s3-encryption-client-java/compare/v3.3.4...v3.3.5) (2025-05-20)
3+
## [3.3.5](https://github.com/aws/aws-s3-encryption-client-java/compare/v3.3.4...v3.3.5) (2025-05-21)
44

55
### Fixes
66

77
* determine effective contentLength, account for tagLength on decrypt ([#463](https://github.com/aws/aws-s3-encryption-client-java/issues/463)) ([969d721](https://github.com/aws/aws-s3-encryption-client-java/commit/969d7213b7bd6250fbce159bd5705a19ee439f23))
88
* disable low-level Multipart Upload in Async client ([#461](https://github.com/aws/aws-s3-encryption-client-java/issues/461)) ([599f941](https://github.com/aws/aws-s3-encryption-client-java/commit/599f9417335efac4cf952e555a99bbc6d7d8cc0f))
99
* support PutObjectResponse fields ([#462](https://github.com/aws/aws-s3-encryption-client-java/issues/462)) ([dec503b](https://github.com/aws/aws-s3-encryption-client-java/commit/dec503b49f3e57113de16fcc861ee1ecedbd2ff6))
1010

11+
### Maintenance
12+
13+
* Revert "Amazon S3 Encryption Client 3.3.5 Release -- 2025-05-20" ([#465](https://github.com/aws/aws-s3-encryption-client-java/issues/465)) ([3f9ac8e](https://github.com/aws/aws-s3-encryption-client-java/commit/3f9ac8e419f5ed55f59fb0daf742fc2945eea9d0))
14+
* update dependency needed for semantic-release ([#464](https://github.com/aws/aws-s3-encryption-client-java/issues/464)) ([0fd3b58](https://github.com/aws/aws-s3-encryption-client-java/commit/0fd3b5826964b41a07a4c004fd0500404e347360))
15+
1116
## [3.3.4](https://github.com/aws/aws-s3-encryption-client-java/compare/v3.3.3...v3.3.4) (2025-05-12)
1217

1318
### Fixes

cfn/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ Resources:
189189
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Maven-GPG-Keys-CI-Credentials-eBrSNB",
190190
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Github/aws-crypto-tools-ci-bot-AGUB3U",
191191
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Sonatype-User-Token-zK61bM",
192+
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Sonatype-Central-Portal-XrYUs2",
192193
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Maven-GPG-Keys-Release-haLIjZ",
193194
"arn:aws:secretsmanager:us-west-2:${AWS::AccountId}:secret:Maven-GPG-Keys-Release-Credentials-WgJanS"
194195
],

codebuild/release/release-prod.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ env:
1010
secrets-manager:
1111
GPG_KEY: Maven-GPG-Keys-Release-Credentials:Keyname
1212
GPG_PASS: Maven-GPG-Keys-Release-Credentials:Passphrase
13-
SONA_USERNAME: Sonatype-User-Token:username
14-
SONA_PASSWORD: Sonatype-User-Token:password
13+
SONA_USERNAME: Sonatype-Central-Portal:Username
14+
SONA_PASSWORD: Sonatype-Central-Portal:Password
1515

1616
phases:
1717
install:

codebuild/release/settings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0
1313
<password>${codeartifact.token}</password>
1414
</server>
1515
<server>
16-
<id>sonatype-nexus-staging</id>
16+
<id>central</id>
1717
<username>${sonatype.username}</username>
1818
<password>${sonatype.password}</password>
1919
</server>

codebuild/release/version.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ phases:
1919
- npm install @semantic-release/changelog -d
2020
- npm install @semantic-release/exec -d
2121
- npm install @semantic-release/git -d
22+
- npm install conventional-changelog-conventionalcommits -d
2223
- npm install --save conventional-changelog
2324
runtime-versions:
2425
nodejs: 16
@@ -30,4 +31,4 @@ phases:
3031
build:
3132
commands:
3233
# semantic-release uses config stored in ~/.releaserc
33-
- npx semantic-release --branches $BRANCH --no-ci
34+
- npx semantic-release --branches $BRANCH --no-ci

pom.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</developers>
3434

3535
<scm>
36-
<url>https://github.com/aws/amazon-s3-encryption-client.git</url>
36+
<url>https://github.com/aws/amazon-s3-encryption-client-java.git</url>
3737
</scm>
3838

3939
<properties>
@@ -308,8 +308,8 @@
308308

309309
<distributionManagement>
310310
<snapshotRepository>
311-
<id>sonatype-nexus-staging</id>
312-
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
311+
<id>central</id>
312+
<url>https://ossrh-staging-api.central.sonatype.com/content/repositories/snapshots</url>
313313
</snapshotRepository>
314314
</distributionManagement>
315315

@@ -336,13 +336,13 @@
336336
</executions>
337337
</plugin>
338338
<plugin>
339-
<groupId>org.sonatype.plugins</groupId>
340-
<artifactId>nexus-staging-maven-plugin</artifactId>
341-
<version>1.6.13</version>
339+
<groupId>org.sonatype.central</groupId>
340+
<artifactId>central-publishing-maven-plugin</artifactId>
341+
<version>0.7.0</version>
342342
<extensions>true</extensions>
343343
<configuration>
344-
<serverId>sonatype-nexus-staging</serverId>
345-
<nexusUrl>https://aws.oss.sonatype.org</nexusUrl>
344+
<publishingServerId>central</publishingServerId>
345+
<autoPublish>true</autoPublish>
346346
</configuration>
347347
</plugin>
348348
</plugins>

src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient {
7979
private final boolean _enableDelayedAuthenticationMode;
8080
private final boolean _enableMultipartPutObject;
8181
private final long _bufferSize;
82-
private InstructionFileConfig _instructionFileConfig;
82+
private final InstructionFileConfig _instructionFileConfig;
8383

8484
private S3AsyncEncryptionClient(Builder builder) {
8585
super(builder._wrappedClient);
@@ -151,6 +151,7 @@ public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObject
151151
.s3AsyncClient(_wrappedClient)
152152
.cryptoMaterialsManager(_cryptoMaterialsManager)
153153
.secureRandom(_secureRandom)
154+
.instructionFileConfig(_instructionFileConfig)
154155
.build();
155156

156157
return pipeline.putObject(putObjectRequest, requestBody);
@@ -169,6 +170,7 @@ private CompletableFuture<PutObjectResponse> multipartPutObject(PutObjectRequest
169170
.s3AsyncClient(mpuClient)
170171
.cryptoMaterialsManager(_cryptoMaterialsManager)
171172
.secureRandom(_secureRandom)
173+
.instructionFileConfig(_instructionFileConfig)
172174
.build();
173175
// Ensures parts are not retried to avoid corrupting ciphertext
174176
AsyncRequestBody noRetryBody = new NoRetriesAsyncRequestBody(requestBody);
@@ -289,6 +291,7 @@ public void close() {
289291
_instructionFileConfig.closeClient();
290292
}
291293

294+
292295
// This is very similar to the S3EncryptionClient builder
293296
// Make sure to keep both clients in mind when adding new builder options
294297
public static class Builder implements S3AsyncClientBuilder {

src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public PutObjectResponse putObject(PutObjectRequest putObjectRequest, RequestBod
203203
.s3AsyncClient(_wrappedAsyncClient)
204204
.cryptoMaterialsManager(_cryptoMaterialsManager)
205205
.secureRandom(_secureRandom)
206+
.instructionFileConfig(_instructionFileConfig)
206207
.build();
207208

208209
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
@@ -1171,6 +1172,7 @@ public S3EncryptionClient build() {
11711172
.s3AsyncClient(_wrappedAsyncClient)
11721173
.cryptoMaterialsManager(_cryptoMaterialsManager)
11731174
.secureRandom(_secureRandom)
1175+
.instructionFileConfig(_instructionFileConfig)
11741176
.build();
11751177

11761178
return new S3EncryptionClient(this);

src/main/java/software/amazon/encryption/s3/internal/ContentMetadataDecodingStrategy.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ private ContentMetadata readFromMap(Map<String, String> metadata, GetObjectRespo
169169

170170
public ContentMetadata decode(GetObjectRequest request, GetObjectResponse response) {
171171
Map<String, String> metadata = response.metadata();
172-
ContentMetadataDecodingStrategy strategy;
173172
if (metadata != null
174173
&& metadata.containsKey(MetadataKeyConstants.CONTENT_IV)
175174
&& (metadata.containsKey(MetadataKeyConstants.ENCRYPTED_DATA_KEY_V1)

src/main/java/software/amazon/encryption/s3/internal/ContentMetadataEncodingStrategy.java

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,94 @@
22
// SPDX-License-Identifier: Apache-2.0
33
package software.amazon.encryption.s3.internal;
44

5+
import software.amazon.awssdk.protocols.jsoncore.JsonWriter;
6+
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest;
7+
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
8+
import software.amazon.encryption.s3.S3EncryptionClientException;
9+
import software.amazon.encryption.s3.materials.EncryptedDataKey;
510
import software.amazon.encryption.s3.materials.EncryptionMaterials;
611

12+
import java.nio.charset.StandardCharsets;
13+
import java.util.Base64;
14+
import java.util.HashMap;
715
import java.util.Map;
816

9-
@FunctionalInterface
10-
public interface ContentMetadataEncodingStrategy {
17+
public class ContentMetadataEncodingStrategy {
1118

12-
Map<String, String> encodeMetadata(EncryptionMaterials materials, byte[] iv,
13-
Map<String, String> metadata);
19+
private static final Base64.Encoder ENCODER = Base64.getEncoder();
20+
private final InstructionFileConfig _instructionFileConfig;
21+
22+
public ContentMetadataEncodingStrategy(InstructionFileConfig instructionFileConfig) {
23+
_instructionFileConfig = instructionFileConfig;
24+
}
25+
26+
public PutObjectRequest encodeMetadata(EncryptionMaterials materials, byte[] iv, PutObjectRequest putObjectRequest) {
27+
if (_instructionFileConfig.isInstructionFilePutEnabled()) {
28+
final String metadataString = metadataToString(materials, iv);
29+
_instructionFileConfig.putInstructionFile(putObjectRequest, metadataString);
30+
// the original request object is returned as-is
31+
return putObjectRequest;
32+
} else {
33+
Map<String, String> newMetadata = addMetadataToMap(putObjectRequest.metadata(), materials, iv);
34+
return putObjectRequest.toBuilder()
35+
.metadata(newMetadata)
36+
.build();
37+
}
38+
}
39+
40+
public CreateMultipartUploadRequest encodeMetadata(EncryptionMaterials materials, byte[] iv, CreateMultipartUploadRequest createMultipartUploadRequest) {
41+
if(_instructionFileConfig.isInstructionFilePutEnabled()) {
42+
final String metadataString = metadataToString(materials, iv);
43+
PutObjectRequest putObjectRequest = ConvertSDKRequests.convertRequest(createMultipartUploadRequest);
44+
_instructionFileConfig.putInstructionFile(putObjectRequest, metadataString);
45+
// the original request object is returned as-is
46+
return createMultipartUploadRequest;
47+
} else {
48+
Map<String, String> newMetadata = addMetadataToMap(createMultipartUploadRequest.metadata(), materials, iv);
49+
return createMultipartUploadRequest.toBuilder()
50+
.metadata(newMetadata)
51+
.build();
52+
}
53+
}
54+
private String metadataToString(EncryptionMaterials materials, byte[] iv) {
55+
// this is just the metadata map serialized as JSON
56+
// so first get the Map
57+
final Map<String, String> metadataMap = addMetadataToMap(new HashMap<>(), materials, iv);
58+
// then serialize it
59+
try (JsonWriter jsonWriter = JsonWriter.create()) {
60+
jsonWriter.writeStartObject();
61+
for (Map.Entry<String, String> entry : metadataMap.entrySet()) {
62+
jsonWriter.writeFieldName(entry.getKey()).writeValue(entry.getValue());
63+
}
64+
jsonWriter.writeEndObject();
65+
66+
return new String(jsonWriter.getBytes(), StandardCharsets.UTF_8);
67+
} catch (JsonWriter.JsonGenerationException e) {
68+
throw new S3EncryptionClientException("Cannot serialize materials to JSON.", e);
69+
}
70+
}
71+
72+
private Map<String, String> addMetadataToMap(Map<String, String> map, EncryptionMaterials materials, byte[] iv) {
73+
Map<String, String> metadata = new HashMap<>(map);
74+
EncryptedDataKey edk = materials.encryptedDataKeys().get(0);
75+
metadata.put(MetadataKeyConstants.ENCRYPTED_DATA_KEY_V2, ENCODER.encodeToString(edk.encryptedDatakey()));
76+
metadata.put(MetadataKeyConstants.CONTENT_IV, ENCODER.encodeToString(iv));
77+
metadata.put(MetadataKeyConstants.CONTENT_CIPHER, materials.algorithmSuite().cipherName());
78+
metadata.put(MetadataKeyConstants.CONTENT_CIPHER_TAG_LENGTH, Integer.toString(materials.algorithmSuite().cipherTagLengthBits()));
79+
metadata.put(MetadataKeyConstants.ENCRYPTED_DATA_KEY_ALGORITHM, new String(edk.keyProviderInfo(), StandardCharsets.UTF_8));
80+
81+
try (JsonWriter jsonWriter = JsonWriter.create()) {
82+
jsonWriter.writeStartObject();
83+
for (Map.Entry<String, String> entry : materials.encryptionContext().entrySet()) {
84+
jsonWriter.writeFieldName(entry.getKey()).writeValue(entry.getValue());
85+
}
86+
jsonWriter.writeEndObject();
87+
88+
String jsonEncryptionContext = new String(jsonWriter.getBytes(), StandardCharsets.UTF_8);
89+
metadata.put(MetadataKeyConstants.ENCRYPTED_DATA_KEY_CONTEXT, jsonEncryptionContext);
90+
} catch (JsonWriter.JsonGenerationException e) {
91+
throw new S3EncryptionClientException("Cannot serialize encryption context to JSON.", e);
92+
}
93+
return metadata;
94+
}
1495
}

0 commit comments

Comments
 (0)