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 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 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 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);
|
||||
|
||||
TrustManagerFactory trustFactory = getTrustFactory(trustStorePath, trustStorePassword, trustStoreAlgorithm);
|
||||
KeyManagerFactory keyManagerFactory = createKeyManagerFactory(keyStorePath, keyStorePassword, keyStoreAlgorithm);
|
||||
KeyManagerFactory keyManagerFactory = createKeyManagerFactory(keyStorePath, keyStorePassword, keyStoreAlgorithm, keyPassword);
|
||||
sslContext = createSslContext(keyManagerFactory, trustFactory, sslProtocol);
|
||||
sslContexts.put(key, sslContext);
|
||||
} else {
|
||||
|
@ -108,7 +109,7 @@ public class SSLService extends AbstractComponent {
|
|||
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)) {
|
||||
// Load KeyStore
|
||||
KeyStore ks = KeyStore.getInstance("jks");
|
||||
|
@ -116,7 +117,7 @@ public class SSLService extends AbstractComponent {
|
|||
|
||||
// Initialize KeyManagerFactory
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyStoreAlgorithm);
|
||||
kmf.init(ks, keyStorePassword.toCharArray());
|
||||
kmf.init(ks, keyPassword.toCharArray());
|
||||
return kmf;
|
||||
} catch (Exception 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.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.hamcrest.Matchers.*;
|
||||
|
||||
public class SSLServiceTests extends ElasticsearchTestCase {
|
||||
|
||||
File testnodeStore;
|
||||
Path testnodeStore;
|
||||
|
||||
@Before
|
||||
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)
|
||||
public void testThatInvalidProtocolThrowsException() throws Exception {
|
||||
new SSLService(settingsBuilder()
|
||||
.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.truststore.path", testnodeStore.getPath())
|
||||
.put("shield.ssl.truststore.path", testnodeStore)
|
||||
.put("shield.ssl.truststore.password", "testnode")
|
||||
.build()).createSSLEngine();
|
||||
}
|
||||
|
||||
@Test
|
||||
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()
|
||||
.put("shield.ssl.keystore.path", testnodeStore.getPath())
|
||||
.put("shield.ssl.keystore.path", testnodeStore)
|
||||
.put("shield.ssl.keystore.password", "testnode")
|
||||
.build());
|
||||
|
||||
ImmutableSettings.Builder settingsBuilder = settingsBuilder()
|
||||
.put("truststore.path", testClientStore.getPath())
|
||||
.put("truststore.path", testClientStore)
|
||||
.put("truststore.password", "testclient");
|
||||
|
||||
SSLEngine sslEngineWithTruststore = sslService.createSSLEngine(settingsBuilder.build());
|
||||
|
@ -60,7 +61,7 @@ public class SSLServiceTests extends ElasticsearchTestCase {
|
|||
@Test
|
||||
public void testThatSslContextCachingWorks() throws Exception {
|
||||
SSLService sslService = new SSLService(settingsBuilder()
|
||||
.put("shield.ssl.keystore.path", testnodeStore.getPath())
|
||||
.put("shield.ssl.keystore.path", testnodeStore)
|
||||
.put("shield.ssl.keystore.password", "testnode")
|
||||
.build());
|
||||
|
||||
|
@ -69,4 +70,23 @@ public class SSLServiceTests extends ElasticsearchTestCase {
|
|||
|
||||
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