Skip to content

Commit ac282f2

Browse files
committed
ARTEMIS-5599 Support key password in Netty SSL
1 parent 730940c commit ac282f2

12 files changed

Lines changed: 386 additions & 6 deletions

File tree

artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ public class NettyConnector extends AbstractConnector {
241241

242242
private String keyStorePassword;
243243

244+
private String keyPassword;
245+
244246
private String keyStoreAlias;
245247

246248
private String trustStoreProvider;
@@ -418,6 +420,8 @@ public NettyConnector(final Map<String, Object> configuration,
418420

419421
keyStorePassword = ConfigurationHelper.getPasswordProperty(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_KEYSTORE_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
420422

423+
keyPassword = ConfigurationHelper.getPasswordProperty(TransportConstants.KEY_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_KEY_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
424+
421425
keyStoreAlias = ConfigurationHelper.getStringProperty(TransportConstants.KEYSTORE_ALIAS_PROP_NAME, TransportConstants.DEFAULT_KEYSTORE_ALIAS, configuration);
422426

423427
trustStoreProvider = ConfigurationHelper.getStringProperty(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER, configuration);
@@ -456,6 +460,7 @@ public NettyConnector(final Map<String, Object> configuration,
456460
keyStoreType = TransportConstants.DEFAULT_KEYSTORE_TYPE;
457461
keyStorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
458462
keyStorePassword = TransportConstants.DEFAULT_KEYSTORE_PASSWORD;
463+
keyPassword = TransportConstants.DEFAULT_KEY_PASSWORD;
459464
keyStoreAlias = TransportConstants.DEFAULT_KEYSTORE_ALIAS;
460465
crcOptions = TransportConstants.DEFAULT_CRC_OPTIONS;
461466
ocspResponderURL = TransportConstants.DEFAULT_OCSP_RESPONDER_URL;
@@ -604,6 +609,7 @@ public synchronized void start() {
604609
final String realKeyStoreProvider;
605610
final String realKeyStoreType;
606611
final String realKeyStorePassword;
612+
final String realKeyPassword;
607613
final String realKeyStoreAlias;
608614
final String realTrustStorePath;
609615
final String realTrustStoreProvider;
@@ -616,6 +622,7 @@ public synchronized void start() {
616622
realKeyStoreProvider = keyStoreProvider;
617623
realKeyStoreType = keyStoreType;
618624
realKeyStorePassword = keyStorePassword;
625+
realKeyPassword = keyPassword;
619626
realKeyStoreAlias = keyStoreAlias;
620627
realTrustStorePath = trustStorePath;
621628
realTrustStoreProvider = trustStoreProvider;
@@ -630,6 +637,7 @@ public synchronized void start() {
630637
tempKeyStorePassword = processSslPasswordProperty(tempKeyStorePassword, tempPasswordCodecClass);
631638
}
632639
realKeyStorePassword = tempKeyStorePassword;
640+
realKeyPassword = keyPassword;
633641
realKeyStoreAlias = keyStoreAlias;
634642

635643
Pair<String, String> keyStoreCompat = SSLSupport.getValidProviderAndType(Stream.of(System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME), System.getProperty(JAVAX_KEYSTORE_PROVIDER_PROP_NAME), keyStoreProvider).map(v -> useDefaultSslContext ? keyStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null),
@@ -654,6 +662,7 @@ public synchronized void start() {
654662
realKeyStoreProvider = null;
655663
realKeyStoreType = null;
656664
realKeyStorePassword = null;
665+
realKeyPassword = null;
657666
realKeyStoreAlias = null;
658667
realTrustStorePath = null;
659668
realTrustStoreProvider = null;
@@ -690,6 +699,7 @@ public void initChannel(Channel channel) throws Exception {
690699
.keystorePath(realKeyStorePath)
691700
.keystoreType(realKeyStoreType)
692701
.keystorePassword(realKeyStorePassword)
702+
.keyPassword(realKeyPassword)
693703
.keystoreAlias(realKeyStoreAlias)
694704
.truststoreProvider(realTrustStoreProvider)
695705
.truststorePath(realTrustStorePath)

artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ public class TransportConstants {
112112

113113
public static final String KEYSTORE_PASSWORD_PROP_NAME = "keyStorePassword";
114114

115+
public static final String KEY_PASSWORD_PROP_NAME = "keyPassword";
116+
115117
public static final String KEYSTORE_ALIAS_PROP_NAME = "keyStoreAlias";
116118

117119
public static final String TRUSTSTORE_PROVIDER_PROP_NAME = "trustStoreProvider";
@@ -248,6 +250,8 @@ public class TransportConstants {
248250

249251
public static final String DEFAULT_KEYSTORE_PASSWORD = null;
250252

253+
public static final String DEFAULT_KEY_PASSWORD = null;
254+
251255
public static final String DEFAULT_TRUSTSTORE_PROVIDER = null;
252256

253257
public static final String DEFAULT_TRUSTSTORE_TYPE = "JKS";
@@ -449,6 +453,7 @@ private static int parseDefaultVariable(String variableName, int defaultValue) {
449453
allowableAcceptorKeys.add(TransportConstants.KEYSTORE_TYPE_PROP_NAME);
450454
allowableAcceptorKeys.add(TransportConstants.KEYSTORE_PATH_PROP_NAME);
451455
allowableAcceptorKeys.add(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME);
456+
allowableAcceptorKeys.add(TransportConstants.KEY_PASSWORD_PROP_NAME);
452457
allowableAcceptorKeys.add(TransportConstants.KEYSTORE_ALIAS_PROP_NAME);
453458
allowableAcceptorKeys.add(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME);
454459
allowableAcceptorKeys.add(TransportConstants.TRUSTSTORE_TYPE_PROP_NAME);
@@ -526,6 +531,7 @@ private static int parseDefaultVariable(String variableName, int defaultValue) {
526531
allowableConnectorKeys.add(TransportConstants.KEYSTORE_TYPE_PROP_NAME);
527532
allowableConnectorKeys.add(TransportConstants.KEYSTORE_PATH_PROP_NAME);
528533
allowableConnectorKeys.add(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME);
534+
allowableConnectorKeys.add(TransportConstants.KEY_PASSWORD_PROP_NAME);
529535
allowableConnectorKeys.add(TransportConstants.KEYSTORE_ALIAS_PROP_NAME);
530536
allowableConnectorKeys.add(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME);
531537
allowableConnectorKeys.add(TransportConstants.TRUSTSTORE_TYPE_PROP_NAME);

artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public class SSLSupport {
8080
private String keystoreType = TransportConstants.DEFAULT_KEYSTORE_TYPE;
8181
private String keystorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
8282
private String keystorePassword = TransportConstants.DEFAULT_KEYSTORE_PASSWORD;
83+
private String keyPassword = TransportConstants.DEFAULT_KEY_PASSWORD;
8384
private String truststoreProvider = TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER;
8485
private String truststoreType = TransportConstants.DEFAULT_TRUSTSTORE_TYPE;
8586
private String truststorePath = TransportConstants.DEFAULT_TRUSTSTORE_PATH;
@@ -100,6 +101,7 @@ public SSLSupport(final SSLContextConfig config) {
100101
keystorePath = config.getKeystorePath();
101102
keystoreType = config.getKeystoreType();
102103
keystorePassword = config.getKeystorePassword();
104+
keyPassword = config.getKeyPassword();
103105
truststoreProvider = config.getTruststoreProvider();
104106
truststorePath = config.getTruststorePath();
105107
truststoreType = config.getTruststoreType();
@@ -148,6 +150,15 @@ public SSLSupport setKeystorePassword(String keystorePassword) {
148150
return this;
149151
}
150152

153+
public String getKeyPassword() {
154+
return keyPassword;
155+
}
156+
157+
public SSLSupport setKeyPassword(String keyPassword) {
158+
this.keyPassword = keyPassword;
159+
return this;
160+
}
161+
151162
public String getKeystoreAlias() {
152163
return keystoreAlias;
153164
}
@@ -262,7 +273,7 @@ public SslContext createNettyContext() throws Exception {
262273
Pair<PrivateKey, X509Certificate[]> privateKeyAndCertChain = getPrivateKeyAndCertChain(keyStore);
263274
sslContextBuilder = SslContextBuilder.forServer(privateKeyAndCertChain.getA(), privateKeyAndCertChain.getB());
264275
} else {
265-
sslContextBuilder = SslContextBuilder.forServer(getKeyManagerFactory(keyStore, keystorePassword == null ? null : keystorePassword.toCharArray()));
276+
sslContextBuilder = SslContextBuilder.forServer(getKeyManagerFactory(keyStore, getKeyPasswordOrDefault()));
266277
}
267278
return sslContextBuilder
268279
.sslProvider(SslProvider.valueOf(sslProvider))
@@ -280,7 +291,7 @@ public SslContext createNettyClientContext() throws Exception {
280291
Pair<PrivateKey, X509Certificate[]> privateKeyAndCertChain = getPrivateKeyAndCertChain(keyStore);
281292
sslContextBuilder.keyManager(privateKeyAndCertChain.getA(), privateKeyAndCertChain.getB());
282293
} else {
283-
sslContextBuilder.keyManager(getKeyManagerFactory(keyStore, keystorePassword == null ? null : keystorePassword.toCharArray()));
294+
sslContextBuilder.keyManager(getKeyManagerFactory(keyStore, getKeyPasswordOrDefault()));
284295
}
285296

286297
return sslContextBuilder.build();
@@ -509,7 +520,7 @@ private KeyManagerFactory loadKeyManagerFactory() throws Exception {
509520
} else {
510521
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
511522
KeyStore ks = SSLSupport.loadKeystore(keystoreProvider, keystoreType, keystorePath, keystorePassword);
512-
kmf.init(ks, keystorePassword == null ? null : keystorePassword.toCharArray());
523+
kmf.init(ks, getKeyPasswordOrDefault());
513524
return kmf;
514525
}
515526
}
@@ -545,7 +556,7 @@ private static URL findResource(final String resourceName) {
545556
}
546557

547558
private Pair<PrivateKey, X509Certificate[]> getPrivateKeyAndCertChain(KeyStore keyStore) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
548-
PrivateKey key = (PrivateKey) keyStore.getKey(keystoreAlias, keystorePassword.toCharArray());
559+
PrivateKey key = (PrivateKey) keyStore.getKey(keystoreAlias, getKeyPasswordOrDefault());
549560
if (key == null) {
550561
throw ActiveMQClientMessageBundle.BUNDLE.keystoreAliasNotFound(keystoreAlias, keystorePath);
551562
}
@@ -562,6 +573,13 @@ private KeyManagerFactory getKeyManagerFactory(KeyStore keyStore, char[] keystor
562573
return keyManagerFactory;
563574
}
564575

576+
private char[] getKeyPasswordOrDefault() {
577+
if (keyPassword != null) {
578+
return keyPassword.toCharArray();
579+
}
580+
return keystorePassword != null ? keystorePassword.toCharArray() : null;
581+
}
582+
565583
/**
566584
* The changes ARTEMIS-3155 introduced an incompatibility with old clients using the keyStoreProvider and
567585
* trustStoreProvider URL properties. These old clients use these properties to set the *type* of store (e.g. PKCS12,

artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextConfig.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public static final class Builder {
3232
private String keystorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
3333
private String keystoreType = TransportConstants.DEFAULT_KEYSTORE_TYPE;
3434
private String keystorePassword = TransportConstants.DEFAULT_KEYSTORE_PASSWORD;
35+
private String keyPassword = TransportConstants.DEFAULT_KEY_PASSWORD;
3536
private String keystoreProvider = TransportConstants.DEFAULT_KEYSTORE_PROVIDER;
3637
private String truststorePath = TransportConstants.DEFAULT_TRUSTSTORE_PATH;
3738
private String truststoreType = TransportConstants.DEFAULT_TRUSTSTORE_TYPE;
@@ -55,6 +56,7 @@ public Builder from(final SSLContextConfig config) {
5556
keystorePath = config.getKeystorePath();
5657
keystoreType = config.getKeystoreType();
5758
keystorePassword = config.getKeystorePassword();
59+
keyPassword = config.getKeyPassword();
5860
keystoreProvider = config.getKeystoreProvider();
5961
truststorePath = config.getTruststorePath();
6062
truststoreType = config.getTruststoreType();
@@ -70,7 +72,7 @@ public Builder from(final SSLContextConfig config) {
7072

7173
public SSLContextConfig build() {
7274
return new SSLContextConfig(
73-
keystoreProvider, keystorePath, keystoreType, keystorePassword,
75+
keystoreProvider, keystorePath, keystoreType, keystorePassword, keyPassword,
7476
truststoreProvider, truststorePath, truststoreType, truststorePassword,
7577
crlPath, trustManagerFactoryPlugin, trustAll, keystoreAlias, crcOptions, ocspResponderURL
7678
);
@@ -91,6 +93,11 @@ public Builder keystorePassword(final String keystorePassword) {
9193
return this;
9294
}
9395

96+
public Builder keyPassword(final String keyPassword) {
97+
this.keyPassword = keyPassword;
98+
return this;
99+
}
100+
94101
public Builder keystoreProvider(final String keystoreProvider) {
95102
this.keystoreProvider = keystoreProvider;
96103
return this;
@@ -154,6 +161,7 @@ public static Builder builder() {
154161
private final String keystorePath;
155162
private final String keystoreType;
156163
private final String keystorePassword;
164+
private final String keyPassword;
157165
private final String keystoreProvider;
158166
private final String truststorePath;
159167
private final String truststoreType;
@@ -171,6 +179,7 @@ private SSLContextConfig(final String keystoreProvider,
171179
final String keystorePath,
172180
final String keystoreType,
173181
final String keystorePassword,
182+
final String keyPassword,
174183
final String truststoreProvider,
175184
final String truststorePath,
176185
final String truststoreType,
@@ -185,6 +194,7 @@ private SSLContextConfig(final String keystoreProvider,
185194
this.keystoreType = keystoreType;
186195
this.keystoreProvider = keystoreProvider;
187196
this.keystorePassword = keystorePassword;
197+
this.keyPassword = keyPassword;
188198
this.truststorePath = truststorePath;
189199
this.truststoreType = truststoreType;
190200
this.truststorePassword = truststorePassword;
@@ -233,6 +243,10 @@ public String getKeystorePassword() {
233243
return keystorePassword;
234244
}
235245

246+
public String getKeyPassword() {
247+
return keyPassword;
248+
}
249+
236250
public String getKeystorePath() {
237251
return keystorePath;
238252
}
@@ -293,6 +307,7 @@ public String toString() {
293307
", keystorePath=" + keystorePath +
294308
", keystoreType=" + keystoreType +
295309
", keystorePassword=" + (keystorePassword == null ? null : "******") +
310+
", keyPassword=" + (keyPassword == null ? null : "******") +
296311
", truststoreProvider=" + truststoreProvider +
297312
", truststorePath=" + truststorePath +
298313
", truststoreType=" + truststoreType +

artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ public class NettyAcceptor extends AbstractAcceptor {
173173

174174
private final String keyStorePassword;
175175

176+
private final String keyPassword;
177+
176178
private final String keystoreAlias;
177179

178180
private final String trustStoreProvider;
@@ -332,6 +334,8 @@ public NettyAcceptor(final String name,
332334

333335
keyStorePassword = ConfigurationHelper.getPasswordProperty(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_KEYSTORE_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
334336

337+
keyPassword = ConfigurationHelper.getPasswordProperty(TransportConstants.KEY_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_KEY_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
338+
335339
Pair<String, String> trustStoreCompat = SSLSupport.getValidProviderAndType(ConfigurationHelper.getStringProperty(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER, configuration),
336340
ConfigurationHelper.getStringProperty(TransportConstants.TRUSTSTORE_TYPE_PROP_NAME, TransportConstants.DEFAULT_TRUSTSTORE_TYPE, configuration));
337341

@@ -372,6 +376,7 @@ public NettyAcceptor(final String name,
372376
.keystorePath(keyStorePath)
373377
.keystoreType(keyStoreType)
374378
.keystorePassword(keyStorePassword)
379+
.keyPassword(keyPassword)
375380
.keystoreAlias(keystoreAlias)
376381
.truststoreProvider(trustStoreProvider)
377382
.truststorePath(trustStorePath)
@@ -388,6 +393,7 @@ public NettyAcceptor(final String name,
388393
keyStoreType = TransportConstants.DEFAULT_KEYSTORE_TYPE;
389394
keyStorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
390395
keyStorePassword = TransportConstants.DEFAULT_KEYSTORE_PASSWORD;
396+
keyPassword = TransportConstants.DEFAULT_KEY_PASSWORD;
391397
keystoreAlias = TransportConstants.DEFAULT_KEYSTORE_ALIAS;
392398
trustStoreProvider = TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER;
393399
trustStoreType = TransportConstants.DEFAULT_TRUSTSTORE_TYPE;

docs/user-manual/configuring-transports.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,15 @@ Although this value can be configured on the server, it is downloaded and used b
321321
If the client needs to use a different password from that set on the server then it can override the server-side setting by either using the customary "javax.net.ssl.keyStorePassword" system property or the Artemis-specific "org.apache.activemq.ssl.keyStorePassword" system property.
322322
The Artemis-specific system property is useful if another component on the client is already making use of the standard Java system property.
323323

324+
keyPassword::
325+
The password used to access the private key within the keystore.
326+
When not set (the default), `keyStorePassword` is used for both opening the keystore and accessing the private key.
327+
This is useful when the keystore and its private key have different passwords, which is supported by JKS and JCEKS keystore types.
328+
+
329+
NOTE: PKCS12 keystores do not support separate key and store passwords.
330+
+
331+
Default is `null`.
332+
324333
keyStoreType::
325334
The type of keystore being used.
326335
For example, `JKS`, `JCEKS`, `PKCS12`, `PEM` etc.

0 commit comments

Comments
 (0)