Skip to content

Commit 99477de

Browse files
alanrobinson-dwpSamBarkerk-wall
authored
Enable mTLS for downstream clients (kroxylicious#1631)
Signed-off-by: Alan Robinson <[email protected]> Co-authored-by: Sam Barker <[email protected]> Co-authored-by: kwall <[email protected]>
1 parent f8668cd commit 99477de

File tree

21 files changed

+519
-43
lines changed

21 files changed

+519
-43
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Format `<github issue/pr number>: <short description>`.
77

88
## SNAPSHOT
99

10+
* [#1561](https://github.com/kroxylicious/kroxylicious/pull/1631) Allow Trust and ClientAuth to be set for Downstream TLS
1011
* [#1550](https://github.com/kroxylicious/kroxylicious/pull/1550) Upgrade Apache Kafka from 3.8.0 to 3.9.0 #1550
1112
* [#1557](https://github.com/kroxylicious/kroxylicious/pull/1557) Bump io.micrometer:micrometer-bom from 1.13.5 to 1.13.6
1213
* [#1554](https://github.com/kroxylicious/kroxylicious/pull/1554) Bump apicurio-registry.version from 2.6.4.Final to 2.6.5.Final

kroxylicious-api/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@
7272
<artifactId>junit-jupiter-params</artifactId>
7373
<scope>test</scope>
7474
</dependency>
75+
<dependency>
76+
<groupId>io.kroxylicious</groupId>
77+
<artifactId>kroxylicious-annotations</artifactId>
78+
</dependency>
7579
</dependencies>
7680

7781
<build>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright Kroxylicious Authors.
3+
*
4+
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
package io.kroxylicious.proxy.config.tls;
8+
9+
import edu.umd.cs.findbugs.annotations.Nullable;
10+
11+
/**
12+
* Options that control TLS negotiation when in server mode.
13+
*/
14+
public record ServerOptions(@Nullable TlsClientAuth clientAuth) implements TrustOptions {
15+
@Override
16+
public boolean forClient() {
17+
return false;
18+
}
19+
}

kroxylicious-api/src/main/java/io/kroxylicious/proxy/config/tls/Tls.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
/**
1313
* Provides TLS configuration for this peer. This class is designed to be used for both TLS server and client roles.
1414
*
15-
* @param key specifies a key provider that provides the certificate/key used to identify this peer.
15+
* @param key specifies a key provider that provides the certificate/key used to identify this peer.
1616
* @param trust specifies a trust provider used by this peer to determine whether to trust the peer. If omitted platform trust is used instead.
17-
*
18-
* TODO ability to restrict by TLS protocol and cipher suite.
1917
*/
2018
public record Tls(KeyProvider key,
2119
TrustProvider trust) {
@@ -29,4 +27,5 @@ public static String getStoreTypeOrPlatformDefault(String storeType) {
2927
public boolean definesKey() {
3028
return key != null;
3129
}
30+
3231
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright Kroxylicious Authors.
3+
*
4+
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
package io.kroxylicious.proxy.config.tls;
8+
9+
public enum TlsClientAuth {
10+
11+
REQUIRED,
12+
REQUESTED,
13+
NONE;
14+
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright Kroxylicious Authors.
3+
*
4+
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
package io.kroxylicious.proxy.config.tls;
8+
9+
import com.fasterxml.jackson.annotation.JsonSubTypes;
10+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
11+
12+
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
13+
@JsonSubTypes({ @JsonSubTypes.Type(ServerOptions.class) })
14+
public interface TrustOptions {
15+
boolean forClient();
16+
}

kroxylicious-api/src/main/java/io/kroxylicious/proxy/config/tls/TrustProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import com.fasterxml.jackson.annotation.JsonSubTypes;
1010
import com.fasterxml.jackson.annotation.JsonTypeInfo;
1111

12+
import edu.umd.cs.findbugs.annotations.Nullable;
13+
1214
/**
1315
* A TrustProvider is a source of trust anchors used to determine whether a certificate present by a peer is trusted.
1416
* <ul>
@@ -27,4 +29,13 @@ public interface TrustProvider {
2729
* @param visitor visitor.
2830
*/
2931
<T> T accept(TrustProviderVisitor<T> visitor);
32+
33+
/**
34+
* Trust options that apply to this TLS peer..
35+
*
36+
* @return trust options
37+
*/
38+
default @Nullable TrustOptions trustOptions() {
39+
return null;
40+
}
3041
}

kroxylicious-api/src/main/java/io/kroxylicious/proxy/config/tls/TrustStore.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,41 @@
1313

1414
import io.kroxylicious.proxy.config.secret.PasswordProvider;
1515

16+
import edu.umd.cs.findbugs.annotations.Nullable;
1617
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
1718

1819
/**
1920
* A {@link TrustProvider} backed by a Java Truststore.
2021
*
21-
* @param storeFile location of a key store, or reference to a PEM file containing both private-key/certificate/intermediates.
22+
* @param storeFile location of a key store, or reference to a PEM file containing both private-key/certificate/intermediates.
2223
* @param storePasswordProvider provider for the store password or null if store does not require a password.
23-
* @param storeType specifies the server key type. Legal values are those types supported by the platform {@link KeyStore},
24-
* and PEM (for X-509 certificates express in PEM format).
24+
* @param storeType specifies the server key type. Legal values are those types supported by the platform {@link KeyStore},
25+
* and PEM (for X-509 certificates express in PEM format).
26+
* @param trustOptions the trust options that will be applied to this peer.
2527
*/
2628
@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "The paths provide the location for key material which may exist anywhere on the file-system. Paths are provided by the user in the administrator role via Kroxylicious configuration. ")
2729
public record TrustStore(@JsonProperty(required = true) String storeFile,
2830
@JsonProperty(value = "storePassword") PasswordProvider storePasswordProvider,
29-
String storeType)
31+
String storeType,
32+
@Nullable @JsonProperty(value = "trustOptions") TrustOptions trustOptions)
3033
implements TrustProvider {
3134

3235
public TrustStore {
3336
Objects.requireNonNull(storeFile);
3437
}
3538

39+
/**
40+
* A {@link TrustProvider} backed by a Java Truststore.
41+
*
42+
* @param storeFile location of a key store, or reference to a PEM file containing both private-key/certificate/intermediates.
43+
* @param storePasswordProvider provider for the store password or null if store does not require a password.
44+
* @param storeType specifies the server key type. Legal values are those types supported by the platform {@link KeyStore},
45+
* and PEM (for X-509 certificates express in PEM format).
46+
*/
47+
public TrustStore(String storeFile, PasswordProvider storePasswordProvider, String storeType) {
48+
this(storeFile, storePasswordProvider, storeType, null);
49+
}
50+
3651
public String getType() {
3752
return Tls.getStoreTypeOrPlatformDefault(storeType);
3853
}

kroxylicious-api/src/test/java/io/kroxylicious/proxy/config/tls/InsecureTlsTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ public InsecureTls visit(PlatformTrustProvider platformTrustProviderTls) {
3434
});
3535
assertThat(result).isSameAs(trustProvider);
3636
}
37+
38+
@Test
39+
void testNoTrustOptions() {
40+
TrustProvider trustProvider = new InsecureTls(true);
41+
assertThat(trustProvider.trustOptions()).isNull();
42+
}
3743
}

kroxylicious-api/src/test/java/io/kroxylicious/proxy/config/tls/TlsParseTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,25 @@ void testTrustStoreStoreFilePathPassword() throws IOException {
205205
assertThat(tls).isEqualTo(new Tls(null, new TrustStore("/tmp/file", new FilePassword("/tmp/pass"), null)));
206206
}
207207

208+
@Test
209+
void testTrustStoreStoreWithClientAuth() throws IOException {
210+
String json = """
211+
{
212+
"trust": {
213+
"storeFile": "/tmp/file",
214+
"storePassword": {
215+
"filePath": "/tmp/pass"
216+
},
217+
"trustOptions": {
218+
"clientAuth": "REQUIRED"
219+
}
220+
}
221+
}
222+
""";
223+
Tls tls = readTls(json);
224+
assertThat(tls).isEqualTo(new Tls(null, new TrustStore("/tmp/file", new FilePassword("/tmp/pass"), null, new ServerOptions(TlsClientAuth.REQUIRED))));
225+
}
226+
208227
@Test
209228
void testTrustStoreStoreFileType() throws IOException {
210229
String json = """

0 commit comments

Comments
 (0)