Skip to content

Commit 771d323

Browse files
committed
support alias for keystore
1 parent df1be3d commit 771d323

File tree

2 files changed

+70
-6
lines changed

2 files changed

+70
-6
lines changed

clients/src/main/java/org/apache/kafka/common/config/SslConfigs.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ public class SslConfigs {
8989
public static final String SSL_KEYSTORE_LOCATION_DOC = "The location of the key store file. "
9090
+ "This is optional for client and can be used for two-way authentication for client.";
9191

92+
public static final String SSL_KEYSTORE_ALIAS_CONFIG = "ssl.keystore.alias";
93+
public static final String SSL_KEYSTORE_ALIAS_DOC = "The Alias of key in the key store file. "
94+
+ "This is optional for client and can be used for two-way authentication for client.";
95+
96+
9297
public static final String SSL_KEYSTORE_PASSWORD_CONFIG = "ssl.keystore.password";
9398
public static final String SSL_KEYSTORE_PASSWORD_DOC = "The store password for the key store file. "
9499
+ "This is optional for client and only needed if 'ssl.keystore.location' is configured. "
@@ -148,6 +153,7 @@ public static void addClientSslSupport(ConfigDef config) {
148153
.define(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, ConfigDef.Type.LIST, SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS, ConfigDef.Importance.MEDIUM, SslConfigs.SSL_ENABLED_PROTOCOLS_DOC)
149154
.define(SslConfigs.SSL_KEYSTORE_TYPE_CONFIG, ConfigDef.Type.STRING, SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE, ConfigDef.Importance.MEDIUM, SslConfigs.SSL_KEYSTORE_TYPE_DOC)
150155
.define(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, ConfigDef.Type.STRING, null, ConfigDef.Importance.HIGH, SslConfigs.SSL_KEYSTORE_LOCATION_DOC)
156+
.define(SslConfigs.SSL_KEYSTORE_ALIAS_CONFIG, ConfigDef.Type.STRING, null, ConfigDef.Importance.HIGH, SslConfigs.SSL_KEYSTORE_ALIAS_DOC)
151157
.define(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, ConfigDef.Type.PASSWORD, null, ConfigDef.Importance.HIGH, SslConfigs.SSL_KEYSTORE_PASSWORD_DOC)
152158
.define(SslConfigs.SSL_KEY_PASSWORD_CONFIG, ConfigDef.Type.PASSWORD, null, ConfigDef.Importance.HIGH, SslConfigs.SSL_KEY_PASSWORD_DOC)
153159
.define(SslConfigs.SSL_KEYSTORE_KEY_CONFIG, ConfigDef.Type.PASSWORD, null, ConfigDef.Importance.HIGH, SslConfigs.SSL_KEYSTORE_KEY_DOC)

clients/src/main/java/org/apache/kafka/common/security/ssl/DefaultSslEngineFactory.java

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.apache.kafka.common.security.auth.SslEngineFactory;
2727
import org.apache.kafka.common.utils.SecurityUtils;
2828
import org.apache.kafka.common.utils.Utils;
29-
29+
import java.net.Socket;
3030
import org.slf4j.Logger;
3131
import org.slf4j.LoggerFactory;
3232

@@ -41,7 +41,7 @@
4141
import org.apache.kafka.common.utils.Utils;
4242
import org.slf4j.Logger;
4343
import org.slf4j.LoggerFactory;
44-
44+
import java.security.PrivateKey;
4545
import javax.net.ssl.KeyManager;
4646
import javax.net.ssl.KeyManagerFactory;
4747
import javax.net.ssl.SSLContext;
@@ -54,7 +54,8 @@
5454
import javax.net.ssl.X509KeyManager;
5555
import java.io.ByteArrayInputStream;
5656
import java.io.InputStream;
57-
57+
import javax.net.ssl.X509ExtendedKeyManager;
58+
import javax.net.ssl.X509KeyManager;
5859
import java.io.ByteArrayInputStream;
5960
import java.io.IOException;
6061
import java.io.InputStream;
@@ -198,7 +199,7 @@ public void configure(Map<String, ?> configs) {
198199
(Password) configs.get(SslConfigs.SSL_TRUSTSTORE_CERTIFICATES_CONFIG)),
199200
Boolean.parseBoolean((String) configs.get(SslConfigs.SSL_TRUSTSTORE_AS_STRING)));
200201

201-
this.sslContext = createSSLContext(keystore, truststore);
202+
this.sslContext = createSSLContext(keystore, truststore, configs);
202203
}
203204

204205
@Override
@@ -261,7 +262,7 @@ private static SecureRandom createSecureRandom(String key) {
261262
}
262263
}
263264

264-
private SSLContext createSSLContext(SecurityStore keystore, SecurityStore truststore) {
265+
private SSLContext createSSLContext(SecurityStore keystore, SecurityStore truststore, Map<String, ?> configs) {
265266
try {
266267
SSLContext sslContext;
267268
if (provider != null)
@@ -285,7 +286,7 @@ private SSLContext createSSLContext(SecurityStore keystore, SecurityStore trusts
285286
String tmfAlgorithm = this.tmfAlgorithm != null ? this.tmfAlgorithm : TrustManagerFactory.getDefaultAlgorithm();
286287
TrustManager[] trustManagers = getTrustManagers(truststore, tmfAlgorithm);
287288

288-
sslContext.init(keyManagers, trustManagers, this.secureRandomImplementation);
289+
sslContext.init(applyAliasToKM(keyManagers, (String)configs.get("ssl.keystore.alias")), trustManagers, this.secureRandomImplementation);
289290
log.debug("Created SSL context with keystore {}, truststore {}, provider {}.",
290291
keystore, truststore, sslContext.getProvider().getName());
291292
return sslContext;
@@ -294,6 +295,63 @@ private SSLContext createSSLContext(SecurityStore keystore, SecurityStore trusts
294295
}
295296
}
296297

298+
private KeyManager[] applyAliasToKM(KeyManager[] kms, final String alias) {
299+
if(alias == null || alias.isEmpty()){
300+
return kms;
301+
}
302+
303+
log.debug("Applying the custom KeyManagers for alias: {}", alias);
304+
305+
KeyManager[] updatedKMs = new KeyManager[kms.length];
306+
307+
int i=0;
308+
for(KeyManager km : kms){
309+
final X509KeyManager origKM = (X509KeyManager)km;
310+
X509ExtendedKeyManager exKM = new X509ExtendedKeyManager() {
311+
/* (non-Javadoc)
312+
* @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineClientAlias(java.lang.String[], java.security.Principal[], javax.net.ssl.SSLEngine)
313+
*/
314+
@Override
315+
public String chooseEngineClientAlias(String[] arg0,
316+
Principal[] arg1, SSLEngine arg2) {
317+
return alias;
318+
}
319+
320+
@Override
321+
public String[] getServerAliases(String arg0, Principal[] arg1) {
322+
return origKM.getServerAliases(arg0, arg1);
323+
}
324+
325+
@Override
326+
public PrivateKey getPrivateKey(String arg0) {
327+
return origKM.getPrivateKey(arg0);
328+
}
329+
330+
@Override
331+
public String[] getClientAliases(String arg0, Principal[] arg1) {
332+
return origKM.getClientAliases(arg0, arg1);
333+
}
334+
335+
@Override
336+
public X509Certificate[] getCertificateChain(String arg0) {
337+
return origKM.getCertificateChain(arg0);
338+
}
339+
340+
@Override
341+
public String chooseServerAlias(String arg0, Principal[] arg1, Socket arg2) {
342+
return origKM.chooseServerAlias(arg0, arg1, arg2);
343+
}
344+
345+
@Override
346+
public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) {
347+
return alias;
348+
}
349+
};
350+
updatedKMs[i++] = exKM;
351+
}
352+
return updatedKMs;
353+
}
354+
297355
protected TrustManager[] getTrustManagers(SecurityStore truststore, String tmfAlgorithm) throws NoSuchAlgorithmException, KeyStoreException {
298356
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
299357
KeyStore ts = truststore == null ? null : truststore.get();

0 commit comments

Comments
 (0)