Skip to content

Commit 9fe0563

Browse files
vedant-jaiswalVedant Jaiswal
andauthored
Add pqtls support (#189)
*Issue #, if available:* *Description of changes:* Add Post-Quantum TLS support to AWS Secrets Manager Java caching client. Adds configuration option `withPostQuantumTlsEnabled()` that uses AWS CRT HTTP client with PQTLS enabled. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Vedant Jaiswal <vedjasy@amazon.com>
1 parent 6b428ef commit 9fe0563

File tree

5 files changed

+139
-3
lines changed

5 files changed

+139
-3
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ public class SampleClass implements RequestHandler<String, String> {
8888
}
8989
```
9090

91+
### Enabling Post-Quantum TLS
92+
93+
To enable Post-Quantum TLS for enhanced security:
94+
95+
```java
96+
import com.amazonaws.secretsmanager.caching.SecretCache;
97+
import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration;
98+
99+
SecretCache cache = new SecretCache(
100+
new SecretCacheConfiguration()
101+
.withPostQuantumTlsEnabled(true)
102+
);
103+
104+
String secret = cache.getSecretString("my-secret-id");
105+
```
106+
91107
## License
92108

93109
This library is licensed under the Apache 2.0 License.

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
<artifactId>secretsmanager</artifactId>
4747
<version>2.41.3</version>
4848
</dependency>
49+
<dependency>
50+
<groupId>software.amazon.awssdk</groupId>
51+
<artifactId>aws-crt-client</artifactId>
52+
<version>2.41.3</version>
53+
</dependency>
4954
<dependency>
5055
<groupId>org.testng</groupId>
5156
<artifactId>testng</artifactId>

src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import com.amazonaws.secretsmanager.caching.cache.SecretCacheItem;
1919
import com.amazonaws.secretsmanager.caching.cache.internal.VersionInfo;
2020

21+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2122
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
2223
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
2324
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
2425
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder;
2526
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
27+
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
2628

2729
/**
2830
* Provides the primary entry-point to the AWS Secrets Manager client cache SDK.
@@ -69,6 +71,8 @@ public SecretCache() {
6971
* @param builder The builder to use for creating the AWS Secrets Manager
7072
* client.
7173
*/
74+
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW",
75+
justification = "Delegates to constructor that validates before field initialization")
7276
public SecretCache(SecretsManagerClientBuilder builder) {
7377
this(new SecretCacheConfiguration().withClient(builder
7478
.overrideConfiguration(
@@ -84,6 +88,8 @@ public SecretCache(SecretsManagerClientBuilder builder) {
8488
* @param client The AWS Secrets Manager client to use for requesting secret
8589
* values.
8690
*/
91+
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW",
92+
justification = "Delegates to constructor that validates before field initialization")
8793
public SecretCache(SecretsManagerClient client) {
8894
this(new SecretCacheConfiguration().withClient(client));
8995
}
@@ -92,17 +98,40 @@ public SecretCache(SecretsManagerClient client) {
9298
* Constructs a new secret cache using the provided cache configuration.
9399
*
94100
* @param config The secret cache configuration.
101+
* @throws IllegalArgumentException if both a custom client and postQuantumTlsEnabled
102+
* are specified in the configuration.
95103
*/
104+
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW",
105+
justification = "Validation occurs before any field initialization")
96106
public SecretCache(SecretCacheConfiguration config) {
97107
if (null == config) {
98108
config = new SecretCacheConfiguration();
99109
}
110+
111+
if (config.getClient() != null && config.isPostQuantumTlsEnabled()) {
112+
throw new IllegalArgumentException(
113+
"Cannot specify both a custom client and postQuantumTlsEnabled. " +
114+
"To use PQTLS, omit the custom client or configure your client with PQTLS support.");
115+
}
116+
100117
this.cache = new LRUCache<String, SecretCacheItem>(config.getMaxCacheSize());
101118
this.config = config;
102119
ClientOverrideConfiguration defaultOverride = ClientOverrideConfiguration.builder()
103120
.putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, VersionInfo.USER_AGENT).build();
104-
this.client = config.getClient() != null ? config.getClient()
105-
: SecretsManagerClient.builder().overrideConfiguration(defaultOverride).build();
121+
122+
if (config.getClient() != null) {
123+
this.client = config.getClient();
124+
} else {
125+
SecretsManagerClientBuilder builder = SecretsManagerClient.builder();
126+
127+
if (config.isPostQuantumTlsEnabled()) {
128+
builder.httpClient(AwsCrtHttpClient.builder()
129+
.postQuantumTlsEnabled(true)
130+
.build());
131+
}
132+
133+
this.client = builder.overrideConfiguration(defaultOverride).build();
134+
}
106135
}
107136

108137
/**

src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
1919
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
2020

21-
2221
/**
2322
* Cache configuration options such as max cache size, ttl for cached items, etc.
2423
*
@@ -73,6 +72,11 @@ public class SecretCacheConfiguration {
7372
*/
7473
private long forceRefreshJitterMillis = DEFAULT_FORCE_REFRESH_JITTER;
7574

75+
/**
76+
* Whether to enable Post-Quantum TLS.
77+
* */
78+
private boolean postQuantumTlsEnabled = false;
79+
7680
/**
7781
* Default constructor for the SecretCacheConfiguration object.
7882
*
@@ -291,4 +295,42 @@ public SecretCacheConfiguration withForceRefreshJitterMillis(long forceRefreshJi
291295
return this;
292296
}
293297

298+
/**
299+
* Returns whether Post-Quantum TLS is enabled.
300+
*
301+
* @return true if Post-Quantum TLS is enabled, false otherwise.
302+
*/
303+
public boolean isPostQuantumTlsEnabled() {
304+
return this.postQuantumTlsEnabled;
305+
}
306+
307+
/**
308+
* Sets whether to enable Post-Quantum TLS.
309+
*
310+
* <p>Note: This setting is mutually exclusive with providing a custom client via
311+
* {@link #withClient(SecretsManagerClient)}. If both are specified, an
312+
* {@link IllegalArgumentException} will be thrown.
313+
*
314+
* @param postQuantumTlsEnabled
315+
* Whether to enable Post-Quantum TLS.
316+
*/
317+
public void setPostQuantumTlsEnabled(boolean postQuantumTlsEnabled) {
318+
this.postQuantumTlsEnabled = postQuantumTlsEnabled;
319+
}
320+
321+
/**
322+
* Sets whether to enable Post-Quantum TLS.
323+
*
324+
* <p>Note: This setting is mutually exclusive with providing a custom client via
325+
* {@link #withClient(SecretsManagerClient)}. If both are specified, an
326+
* {@link IllegalArgumentException} will be thrown.
327+
*
328+
* @param postQuantumTlsEnabled
329+
* Whether to enable Post-Quantum TLS.
330+
* @return The updated SecretCacheConfiguration object with the new PQTLS setting.
331+
*/
332+
public SecretCacheConfiguration withPostQuantumTlsEnabled(boolean postQuantumTlsEnabled) {
333+
this.setPostQuantumTlsEnabled(postQuantumTlsEnabled);
334+
return this;
335+
}
294336
}

src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,4 +482,48 @@ public void basicSecretCacheVersionWithNullStageTest() {
482482
sc.close();
483483
}
484484

485+
@Test
486+
public void testPostQuantumTlsConfiguration() {
487+
// Test default is false
488+
SecretCacheConfiguration config = new SecretCacheConfiguration();
489+
Assert.assertFalse(config.isPostQuantumTlsEnabled());
490+
491+
// Test setter
492+
config.setPostQuantumTlsEnabled(true);
493+
Assert.assertTrue(config.isPostQuantumTlsEnabled());
494+
495+
// Test fluent method
496+
SecretCacheConfiguration config2 = new SecretCacheConfiguration()
497+
.withPostQuantumTlsEnabled(true);
498+
Assert.assertTrue(config2.isPostQuantumTlsEnabled());
499+
}
500+
501+
@Test(expectedExceptions = { IllegalArgumentException.class })
502+
public void testSecretCacheWithPQTLSEnabled() {
503+
// Verify that providing both client and PQTLS flag throws exception
504+
SecretCacheConfiguration config = new SecretCacheConfiguration()
505+
.withClient(asm)
506+
.withPostQuantumTlsEnabled(true);
507+
508+
new SecretCache(config);
509+
}
510+
511+
@Test
512+
public void testSecretCacheWithPQTLSEnabledNoClient() {
513+
String originalRegion = System.getProperty("aws.region");
514+
try {
515+
System.setProperty("aws.region", "us-east-1");
516+
SecretCacheConfiguration config = new SecretCacheConfiguration()
517+
.withPostQuantumTlsEnabled(true); // No .withClient() call
518+
SecretCache cache = new SecretCache(config);
519+
Assert.assertNotNull(cache);
520+
cache.close();
521+
} finally {
522+
if (originalRegion != null) {
523+
System.setProperty("aws.region", originalRegion);
524+
} else {
525+
System.clearProperty("aws.region");
526+
}
527+
}
528+
}
485529
}

0 commit comments

Comments
 (0)