Add the option to specify both a keystore and key password
Previously, we always used the keystore password as the key password, which does not work if a user specifies a different password when generating the key with keytool. If the key password is not specified, the keystore password will be used. Closes elastic/elasticsearch#473 Original commit: elastic/x-pack-elasticsearch@8a6efdbf21
This commit is contained in:
parent
9bfab4d8d5
commit
88162d142b
|
@ -58,6 +58,7 @@ public class SSLService extends AbstractComponent {
|
||||||
String keyStorePath = settings.get("keystore.path", componentSettings.get("keystore.path", System.getProperty("javax.net.ssl.keyStore")));
|
String keyStorePath = settings.get("keystore.path", componentSettings.get("keystore.path", System.getProperty("javax.net.ssl.keyStore")));
|
||||||
String keyStorePassword = settings.get("keystore.password", componentSettings.get("keystore.password", System.getProperty("javax.net.ssl.keyStorePassword")));
|
String keyStorePassword = settings.get("keystore.password", componentSettings.get("keystore.password", System.getProperty("javax.net.ssl.keyStorePassword")));
|
||||||
String keyStoreAlgorithm = settings.get("keystore.algorithm", componentSettings.get("keystore.algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm", KeyManagerFactory.getDefaultAlgorithm())));
|
String keyStoreAlgorithm = settings.get("keystore.algorithm", componentSettings.get("keystore.algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm", KeyManagerFactory.getDefaultAlgorithm())));
|
||||||
|
String keyPassword = settings.get("keystore.key_password", componentSettings.get("keystore.key_password", keyStorePassword));
|
||||||
|
|
||||||
String trustStorePath = settings.get("truststore.path", componentSettings.get("truststore.path", System.getProperty("javax.net.ssl.trustStore")));
|
String trustStorePath = settings.get("truststore.path", componentSettings.get("truststore.path", System.getProperty("javax.net.ssl.trustStore")));
|
||||||
String trustStorePassword = settings.get("truststore.password", componentSettings.get("truststore.password", System.getProperty("javax.net.ssl.trustStorePassword")));
|
String trustStorePassword = settings.get("truststore.password", componentSettings.get("truststore.password", System.getProperty("javax.net.ssl.trustStorePassword")));
|
||||||
|
@ -88,7 +89,7 @@ public class SSLService extends AbstractComponent {
|
||||||
keyStorePath, keyStoreAlgorithm, trustStorePath, trustStoreAlgorithm, sslProtocol);
|
keyStorePath, keyStoreAlgorithm, trustStorePath, trustStoreAlgorithm, sslProtocol);
|
||||||
|
|
||||||
TrustManagerFactory trustFactory = getTrustFactory(trustStorePath, trustStorePassword, trustStoreAlgorithm);
|
TrustManagerFactory trustFactory = getTrustFactory(trustStorePath, trustStorePassword, trustStoreAlgorithm);
|
||||||
KeyManagerFactory keyManagerFactory = createKeyManagerFactory(keyStorePath, keyStorePassword, keyStoreAlgorithm);
|
KeyManagerFactory keyManagerFactory = createKeyManagerFactory(keyStorePath, keyStorePassword, keyStoreAlgorithm, keyPassword);
|
||||||
sslContext = createSslContext(keyManagerFactory, trustFactory, sslProtocol);
|
sslContext = createSslContext(keyManagerFactory, trustFactory, sslProtocol);
|
||||||
sslContexts.put(key, sslContext);
|
sslContexts.put(key, sslContext);
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,7 +109,7 @@ public class SSLService extends AbstractComponent {
|
||||||
return sslEngine;
|
return sslEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyManagerFactory createKeyManagerFactory(String keyStore, String keyStorePassword, String keyStoreAlgorithm) {
|
private KeyManagerFactory createKeyManagerFactory(String keyStore, String keyStorePassword, String keyStoreAlgorithm, String keyPassword) {
|
||||||
try (FileInputStream in = new FileInputStream(keyStore)) {
|
try (FileInputStream in = new FileInputStream(keyStore)) {
|
||||||
// Load KeyStore
|
// Load KeyStore
|
||||||
KeyStore ks = KeyStore.getInstance("jks");
|
KeyStore ks = KeyStore.getInstance("jks");
|
||||||
|
@ -116,7 +117,7 @@ public class SSLService extends AbstractComponent {
|
||||||
|
|
||||||
// Initialize KeyManagerFactory
|
// Initialize KeyManagerFactory
|
||||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyStoreAlgorithm);
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyStoreAlgorithm);
|
||||||
kmf.init(ks, keyStorePassword.toCharArray());
|
kmf.init(ks, keyPassword.toCharArray());
|
||||||
return kmf;
|
return kmf;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ElasticsearchSSLException("Failed to initialize a KeyManagerFactory", e);
|
throw new ElasticsearchSSLException("Failed to initialize a KeyManagerFactory", e);
|
||||||
|
|
|
@ -12,42 +12,43 @@ import org.junit.Test;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import java.io.File;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
public class SSLServiceTests extends ElasticsearchTestCase {
|
public class SSLServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
File testnodeStore;
|
Path testnodeStore;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
testnodeStore = new File(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks").toURI());
|
testnodeStore = Paths.get(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks").toURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = ElasticsearchSSLException.class)
|
@Test(expected = ElasticsearchSSLException.class)
|
||||||
public void testThatInvalidProtocolThrowsException() throws Exception {
|
public void testThatInvalidProtocolThrowsException() throws Exception {
|
||||||
new SSLService(settingsBuilder()
|
new SSLService(settingsBuilder()
|
||||||
.put("shield.ssl.protocol", "non-existing")
|
.put("shield.ssl.protocol", "non-existing")
|
||||||
.put("shield.ssl.keystore.path", testnodeStore.getPath())
|
.put("shield.ssl.keystore.path", testnodeStore)
|
||||||
.put("shield.ssl.keystore.password", "testnode")
|
.put("shield.ssl.keystore.password", "testnode")
|
||||||
.put("shield.ssl.truststore.path", testnodeStore.getPath())
|
.put("shield.ssl.truststore.path", testnodeStore)
|
||||||
.put("shield.ssl.truststore.password", "testnode")
|
.put("shield.ssl.truststore.password", "testnode")
|
||||||
.build()).createSSLEngine();
|
.build()).createSSLEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThatCustomTruststoreCanBeSpecified() throws Exception {
|
public void testThatCustomTruststoreCanBeSpecified() throws Exception {
|
||||||
File testClientStore = new File(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks").toURI());
|
Path testClientStore = Paths.get(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks").toURI());
|
||||||
|
|
||||||
SSLService sslService = new SSLService(settingsBuilder()
|
SSLService sslService = new SSLService(settingsBuilder()
|
||||||
.put("shield.ssl.keystore.path", testnodeStore.getPath())
|
.put("shield.ssl.keystore.path", testnodeStore)
|
||||||
.put("shield.ssl.keystore.password", "testnode")
|
.put("shield.ssl.keystore.password", "testnode")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
ImmutableSettings.Builder settingsBuilder = settingsBuilder()
|
ImmutableSettings.Builder settingsBuilder = settingsBuilder()
|
||||||
.put("truststore.path", testClientStore.getPath())
|
.put("truststore.path", testClientStore)
|
||||||
.put("truststore.password", "testclient");
|
.put("truststore.password", "testclient");
|
||||||
|
|
||||||
SSLEngine sslEngineWithTruststore = sslService.createSSLEngine(settingsBuilder.build());
|
SSLEngine sslEngineWithTruststore = sslService.createSSLEngine(settingsBuilder.build());
|
||||||
|
@ -60,7 +61,7 @@ public class SSLServiceTests extends ElasticsearchTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testThatSslContextCachingWorks() throws Exception {
|
public void testThatSslContextCachingWorks() throws Exception {
|
||||||
SSLService sslService = new SSLService(settingsBuilder()
|
SSLService sslService = new SSLService(settingsBuilder()
|
||||||
.put("shield.ssl.keystore.path", testnodeStore.getPath())
|
.put("shield.ssl.keystore.path", testnodeStore)
|
||||||
.put("shield.ssl.keystore.password", "testnode")
|
.put("shield.ssl.keystore.password", "testnode")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
@ -69,4 +70,23 @@ public class SSLServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
assertThat(sslContext, is(sameInstance(cachedSslContext)));
|
assertThat(sslContext, is(sameInstance(cachedSslContext)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThatKeyStoreAndKeyCanHaveDifferentPasswords() throws Exception {
|
||||||
|
Path differentPasswordsStore = Paths.get(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode-different-passwords.jks").toURI());
|
||||||
|
new SSLService(settingsBuilder()
|
||||||
|
.put("shield.ssl.keystore.path", differentPasswordsStore)
|
||||||
|
.put("shield.ssl.keystore.password", "testnode")
|
||||||
|
.put("shield.ssl.keystore.key_password", "testnode1")
|
||||||
|
.build()).createSSLEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElasticsearchSSLException.class)
|
||||||
|
public void testIncorrectKeyPasswordThrowsException() throws Exception {
|
||||||
|
Path differentPasswordsStore = Paths.get(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode-different-passwords.jks").toURI());
|
||||||
|
new SSLService(settingsBuilder()
|
||||||
|
.put("shield.ssl.keystore.path", differentPasswordsStore)
|
||||||
|
.put("shield.ssl.keystore.password", "testnode")
|
||||||
|
.build()).createSSLEngine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue