Skip to content

Commit a033c52

Browse files
authored
feat: AWS SDK v2 support (#516)
Now supports using either v1 or v2 (or both) of the AWS SDK for Java with the encryption SDK. The new classes to support AWS SDK for Java v2 can be found in the `com.amazonaws.encryptionsdk.kmssdkv2` package.
1 parent bb27129 commit a033c52

30 files changed

+1667
-1733
lines changed

pom.xml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,31 @@
3838
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3939
</properties>
4040

41+
<dependencyManagement>
42+
<dependencies>
43+
<dependency>
44+
<groupId>software.amazon.awssdk</groupId>
45+
<artifactId>bom</artifactId>
46+
<version>2.17.136</version>
47+
<optional>true</optional>
48+
<type>pom</type>
49+
<scope>import</scope>
50+
</dependency>
51+
</dependencies>
52+
</dependencyManagement>
53+
4154
<dependencies>
42-
<!-- Support AWS SDK v1 -->
4355
<dependency>
4456
<groupId>com.amazonaws</groupId>
4557
<artifactId>aws-java-sdk</artifactId>
46-
<version>1.12.131</version>
47-
<optional>true</optional>
48-
</dependency>
49-
50-
<!-- Support AWS SDK v2 -->
51-
<dependency>
52-
<groupId>software.amazon.awssdk</groupId>
53-
<artifactId>bom</artifactId>
54-
<version>2.17.110</version>
58+
<version>1.12.146</version>
5559
<optional>true</optional>
56-
<type>pom</type>
57-
<scope>import</scope>
5860
</dependency>
5961

6062
<dependency>
6163
<groupId>software.amazon.awssdk</groupId>
6264
<artifactId>kms</artifactId>
63-
<version>2.17.109</version>
65+
<version>2.17.136</version>
6466
<optional>true</optional>
6567
</dependency>
6668

src/main/java/com/amazonaws/encryptionsdk/internal/VersionInfo.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,29 @@ public class VersionInfo {
2424
* Loads the version of the library
2525
*/
2626
public static String loadUserAgent() {
27+
return USER_AGENT_PREFIX + versionNumber();
28+
}
29+
30+
/**
31+
* This returns the API name compatible with the AWS SDK v2
32+
*
33+
* @return the name of the library with a tag indicating intended for AWS SDK v2
34+
*/
35+
public static String apiName() {
36+
return USER_AGENT_PREFIX.substring(0, USER_AGENT_PREFIX.length() - 1);
37+
}
38+
39+
/*
40+
* String representation of the library version e.g. 2.3.3
41+
*/
42+
public static String versionNumber() {
2743
try {
2844
final Properties properties = new Properties();
2945
final ClassLoader loader = VersionInfo.class.getClassLoader();
3046
properties.load(loader.getResourceAsStream("project.properties"));
31-
return USER_AGENT_PREFIX + properties.getProperty("version");
47+
return properties.getProperty("version");
3248
} catch (final IOException ex) {
33-
return USER_AGENT_PREFIX + UNKNOWN_VERSION;
49+
return UNKNOWN_VERSION;
3450
}
3551
}
3652
}

src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKey.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ private AwsKmsMrkAwareMasterKey(
9090
"AwsKmsMrkAwareMasterKey must be configured with an AWS KMS client.");
9191
}
9292

93-
/* Precondition: A provider is required. */
9493
if (provider == null) {
9594
throw new IllegalArgumentException(
9695
"AwsKmsMrkAwareMasterKey must be configured with a source provider.");
@@ -177,7 +176,6 @@ public DataKey<AwsKmsMrkAwareMasterKey> generateDataKey(
177176
// # The response's "KeyId"
178177
// # MUST be valid.
179178
final String gdkResultKeyId = gdkResult.getKeyId();
180-
/* Exceptional Postcondition: Must have an AWS KMS ARN from AWS KMS generateDataKey. */
181179
if (parseInfoFromKeyArn(gdkResultKeyId) == null) {
182180
throw new IllegalStateException("Received an empty or invalid keyId from KMS");
183181
}
@@ -212,7 +210,6 @@ public DataKey<AwsKmsMrkAwareMasterKey> encryptDataKey(
212210
final Map<String, String> encryptionContext,
213211
final DataKey<?> dataKey) {
214212
final SecretKey key = dataKey.getKey();
215-
/* Precondition: The key format MUST be RAW. */
216213
if (!key.getFormat().equals("RAW")) {
217214
throw new IllegalArgumentException("Only RAW encoded keys are supported");
218215
}
@@ -237,7 +234,6 @@ public DataKey<AwsKmsMrkAwareMasterKey> encryptDataKey(
237234
final String encryptResultKeyId = encryptResult.getKeyId();
238235
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.11
239236
// # The AWS KMS Encrypt response MUST contain a valid "KeyId".
240-
/* Postcondition: Must have an AWS KMS ARN from AWS KMS encrypt. */
241237
if (parseInfoFromKeyArn(encryptResultKeyId) == null) {
242238
throw new IllegalStateException("Received an empty or invalid keyId from KMS");
243239
}
@@ -326,7 +322,6 @@ public DataKey<AwsKmsMrkAwareMasterKey> decryptDataKey(
326322
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.9
327323
// # The output MUST be the same as the Master Key Decrypt Data Key
328324
// # (../master-key-interface.md#decrypt-data-key) interface.
329-
/* Exceptional Postcondition: Master key was unable to decrypt. */
330325
.orElseThrow(() -> buildCannotDecryptDksException(exceptions));
331326
}
332327

@@ -358,7 +353,6 @@ static DataKey<AwsKmsMrkAwareMasterKey> decryptSingleEncryptedDataKey(
358353
.withKeyId(awsKmsIdentifier)));
359354

360355
final String decryptResultKeyId = decryptResult.getKeyId();
361-
/* Exceptional Postcondition: Must have a CMK ARN from AWS KMS to match. */
362356
if (decryptResultKeyId == null) {
363357
throw new IllegalStateException("Received an empty keyId from KMS");
364358
}

src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ static KmsMasterKeyProvider.RegionalClientSupplier clientFactory(
284284
: AWSKMSClientBuilder.standard();
285285

286286
return region -> {
287-
/* Check for early return (Postcondition): If a client already exists, use that. */
288287
if (clientCache.containsKey(region)) {
289288
return clientCache.get(region);
290289
}
@@ -381,10 +380,6 @@ private AwsKmsMrkAwareMasterKeyProvider(
381380
// # kms-mrk-are-unique.md#Implementation) and the function MUST return
382381
// # success.
383382
assertMrksAreUnique(keyIds);
384-
/* Precondition: A region is required to contact AWS KMS.
385-
* This is an edge case because the default region will be the same as the SDK default,
386-
* but it is still possible.
387-
*/
388383
if (!isDiscovery
389384
&& defaultRegion == null
390385
&& keyIds.stream()
@@ -447,16 +442,6 @@ static void assertMrksAreUnique(List<String> keyIdentifiers) {
447442
// # arn.md#identifying-an-aws-kms-multi-region-key) this function MUST
448443
// # exit successfully.
449444
//
450-
/* Postcondition: Filter out duplicate resources that are not multi-region keys.
451-
* I expect only have duplicates of specific multi-region keys.
452-
* In JSON something like
453-
* {
454-
* "mrk-edb7fe6942894d32ac46dbb1c922d574" : [
455-
* "arn:aws:kms:us-west-2:111122223333:key/mrk-edb7fe6942894d32ac46dbb1c922d574",
456-
* "arn:aws:kms:us-east-2:111122223333:key/mrk-edb7fe6942894d32ac46dbb1c922d574"
457-
* ]
458-
* }
459-
*/
460445
.filter(maybeMrk -> isMRK(maybeMrk.getKey()))
461446
/* Flatten the duplicate identifiers into a single list. */
462447
.flatMap(mrkEntry -> mrkEntry.getValue().stream())
@@ -481,35 +466,12 @@ static void assertMrksAreUnique(List<String> keyIdentifiers) {
481466
*/
482467
static String getResourceForResourceTypeKey(String identifier) {
483468
final AwsKmsCmkArnInfo info = parseInfoFromKeyArn(identifier);
484-
/* Check for early return (Postcondition): Non-ARNs may be raw resources.
485-
* Raw aliases ('alias/my-key')
486-
* or key ids ('mrk-edb7fe6942894d32ac46dbb1c922d574').
487-
*/
488469
if (info == null) return identifier;
489470

490-
/* Check for early return (Postcondition): Return the identifier for non-key resource types.
491-
* I only care about duplicate multi-region *keys*.
492-
* Any other resource type
493-
* should get filtered out.
494-
* I return the entire identifier
495-
* on the off chance that
496-
* a customer has created
497-
* an alias with a name `mrk-*`.
498-
* This way such an alias
499-
* can never accidentally
500-
* collided with an existing multi-region key
501-
* or a duplicate alias.
502-
*/
503471
if (!info.getResourceType().equals("key")) {
504472
return identifier;
505473
}
506474

507-
/* Postcondition: Return the key id.
508-
* This will be used
509-
* to find different regional replicas of
510-
* the same multi-region key
511-
* because the key id for replicas is always the same.
512-
*/
513475
return info.getResource();
514476
}
515477

@@ -559,10 +521,6 @@ public AwsKmsMrkAwareMasterKey getMasterKey(final String providerId, final Strin
559521
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.7
560522
// # In discovery mode, the requested
561523
// # AWS KMS key identifier MUST be a well formed AWS KMS ARN.
562-
/* Precondition: Discovery mode requires requestedKeyArn be an ARN.
563-
* This function is called on the encrypt path.
564-
* It _may_ be the case that a raw key id, for example, was configured.
565-
*/
566524
if (isDiscovery_ && requestedKeyArnInfo == null) {
567525
throw new NoSuchMasterKeyException(
568526
"Cannot use AWS KMS identifiers " + "when in discovery mode.");

0 commit comments

Comments
 (0)