Skip to content

Commit 006cdc4

Browse files
authored
feat: AWS SDK v2 support
1 parent 0ab1db0 commit 006cdc4

39 files changed

+6102
-105
lines changed

pom.xml

+20-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@
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>
4255
<dependency>
4356
<groupId>com.amazonaws</groupId>
@@ -46,6 +59,13 @@
4659
<optional>true</optional>
4760
</dependency>
4861

62+
<dependency>
63+
<groupId>software.amazon.awssdk</groupId>
64+
<artifactId>kms</artifactId>
65+
<version>2.17.136</version>
66+
<optional>true</optional>
67+
</dependency>
68+
4969
<dependency>
5070
<groupId>org.bouncycastle</groupId>
5171
<artifactId>bcprov-ext-jdk15on</artifactId>
@@ -79,7 +99,6 @@
7999
<scope>test</scope>
80100
</dependency>
81101

82-
83102
<dependency>
84103
<groupId>com.google.code.findbugs</groupId>
85104
<artifactId>jsr305</artifactId>

src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CryptoResult;
13-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
13+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1515
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1616

1717
/**

src/examples/java/com/amazonaws/crypto/examples/BasicMultiRegionKeyEncryptionExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import com.amazonaws.encryptionsdk.AwsCrypto;
77
import com.amazonaws.encryptionsdk.CommitmentPolicy;
88
import com.amazonaws.encryptionsdk.CryptoResult;
9-
import com.amazonaws.encryptionsdk.kms.AwsKmsMrkAwareMasterKey;
10-
import com.amazonaws.encryptionsdk.kms.AwsKmsMrkAwareMasterKeyProvider;
9+
import com.amazonaws.encryptionsdk.kmssdkv2.AwsKmsMrkAwareMasterKey;
10+
import com.amazonaws.encryptionsdk.kmssdkv2.AwsKmsMrkAwareMasterKeyProvider;
1111

1212
import java.nio.charset.StandardCharsets;
1313
import java.util.Arrays;

src/examples/java/com/amazonaws/crypto/examples/DiscoveryDecryptionExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CryptoResult;
13-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
13+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1515
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1616
import com.amazonaws.encryptionsdk.kms.DiscoveryFilter;
1717

src/examples/java/com/amazonaws/crypto/examples/DiscoveryMultiRegionDecryptionExample.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import com.amazonaws.encryptionsdk.CommitmentPolicy;
88
import com.amazonaws.encryptionsdk.CryptoResult;
99
import com.amazonaws.encryptionsdk.kms.DiscoveryFilter;
10-
import com.amazonaws.encryptionsdk.kms.AwsKmsMrkAwareMasterKey;
11-
import com.amazonaws.encryptionsdk.kms.AwsKmsMrkAwareMasterKeyProvider;
10+
import com.amazonaws.encryptionsdk.kmssdkv2.AwsKmsMrkAwareMasterKey;
11+
import com.amazonaws.encryptionsdk.kmssdkv2.AwsKmsMrkAwareMasterKeyProvider;
1212

1313
import java.nio.charset.StandardCharsets;
1414
import java.util.Arrays;
1515
import java.util.Collections;
1616
import java.util.Map;
17+
import software.amazon.awssdk.regions.Region;
1718

1819
/**
1920
* <p>
@@ -39,7 +40,7 @@ public static void main(final String[] args) {
3940
final String keyName = args[0];
4041
final String partition = args[1];
4142
final String accountId = args[2];
42-
final String discoveryMrkRegion = args[3];
43+
final Region discoveryMrkRegion = Region.of(args[3]);
4344

4445
encryptAndDecrypt(keyName, partition, accountId, discoveryMrkRegion);
4546
}
@@ -48,7 +49,7 @@ static void encryptAndDecrypt(
4849
final String keyName,
4950
final String partition,
5051
final String accountId,
51-
final String discoveryMrkRegion
52+
final Region discoveryMrkRegion
5253
) {
5354
// 1. Instantiate the SDK
5455
// This builds the AwsCrypto client with
@@ -113,7 +114,7 @@ static void encryptAndDecrypt(
113114
// it is limited to the Region configured for the AWS SDK.
114115
final AwsKmsMrkAwareMasterKeyProvider decryptingKeyProvider = AwsKmsMrkAwareMasterKeyProvider
115116
.builder()
116-
.withDiscoveryMrkRegion(discoveryMrkRegion)
117+
.discoveryMrkRegion(discoveryMrkRegion)
117118
.buildDiscovery(discoveryFilter);
118119

119120
// 7. Decrypt the data

src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import com.amazonaws.encryptionsdk.CryptoOutputStream;
1818
import com.amazonaws.encryptionsdk.MasterKeyProvider;
1919
import com.amazonaws.encryptionsdk.jce.JceMasterKey;
20-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
20+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
2121
import com.amazonaws.encryptionsdk.multi.MultipleProviderFactory;
2222
import com.amazonaws.encryptionsdk.CommitmentPolicy;
2323
import com.amazonaws.util.IOUtils;

src/examples/java/com/amazonaws/crypto/examples/MultipleCmkEncryptExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CryptoResult;
13-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
13+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1515
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1616

1717
/**

src/examples/java/com/amazonaws/crypto/examples/RestrictRegionExample.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CryptoResult;
1313
import com.amazonaws.encryptionsdk.exception.AwsCryptoException;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
15-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
15+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1616
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1717
import com.amazonaws.encryptionsdk.kms.DiscoveryFilter;
18-
import com.amazonaws.services.kms.AWSKMSClientBuilder;
19-
import com.amazonaws.services.kms.AWSKMS;
18+
import software.amazon.awssdk.regions.Region;
19+
import software.amazon.awssdk.services.kms.KmsClient;
2020

2121
/**
2222
* <p>
@@ -43,12 +43,12 @@ public static void main(final String[] args) {
4343
final String keyName = args[0];
4444
final String partition = args[1];
4545
final String accountId = args[2];
46-
final String region = args[3];
46+
final Region region = Region.of(args[3]);
4747

4848
encryptAndDecrypt(keyName, partition, accountId, region);
4949
}
5050

51-
static void encryptAndDecrypt(final String keyName, final String partition, final String accountId, final String region) {
51+
static void encryptAndDecrypt(final String keyName, final String partition, final String accountId, final Region region) {
5252
// Instantiate the SDK.
5353
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
5454
// which enforces that this client only encrypts using committing algorithm suites and enforces
@@ -60,7 +60,7 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
6060
.build();
6161

6262
// 2. Instantiate the AWS KMS client for the desired region
63-
final AWSKMS kmsClient = AWSKMSClientBuilder.standard().withRegion(region).build();
63+
final KmsClient kmsClient = KmsClient.builder().region(region).build();
6464

6565
// 3. Instantiate an AWS KMS master key provider for encryption.
6666
//
@@ -101,14 +101,14 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
101101
// This example also configures the AWS KMS master key provider with a Discovery Filter to limit
102102
// the attempted AWS KMS CMKs to a particular partition and account.
103103
final KmsMasterKeyProvider decryptingKeyProvider = KmsMasterKeyProvider.builder()
104-
.withCustomClientFactory(cmkRegion -> {
104+
.customRegionalClientSupplier(cmkRegion -> {
105105
if(cmkRegion.equals(region)) {
106106
// return the previously built AWS KMS client so that we do
107107
// not create a new client on every decrypt call.
108108
return kmsClient;
109109
}
110110

111-
throw new AwsCryptoException("Only " + region + " is supported");
111+
throw new AwsCryptoException("Only " + region.id() + " is supported");
112112
})
113113
.buildDiscovery(discoveryFilter);
114114

src/examples/java/com/amazonaws/crypto/examples/SetCommitmentPolicyExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1313
import com.amazonaws.encryptionsdk.CryptoResult;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
15-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
15+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1616

1717
/**
1818
* <p>

src/examples/java/com/amazonaws/crypto/examples/SetEncryptionAlgorithmExample.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import com.amazonaws.encryptionsdk.AwsCrypto;
1212
import com.amazonaws.encryptionsdk.CryptoAlgorithm;
1313
import com.amazonaws.encryptionsdk.CryptoResult;
14-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
15-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
14+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
15+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1616

1717
/**
1818
* <p>

src/examples/java/com/amazonaws/crypto/examples/SimpleDataKeyCachingExample.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414
import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
1515
import com.amazonaws.encryptionsdk.caching.CryptoMaterialsCache;
1616
import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache;
17-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
18-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
19-
import com.amazonaws.encryptionsdk.CommitmentPolicy;
17+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
18+
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
2019

2120
/**
2221
* <p>

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

+18-2
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

-6
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

-42
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)