Enable testing in FIPS140 JVM (#31666)

Ensure our tests can run in a FIPS JVM

JKS keystores cannot be used in a FIPS JVM as attempting to use one
in order to init a KeyManagerFactory or a TrustManagerFactory is not
allowed.( JKS keystore algorithms for private key encryption are not
FIPS 140 approved)
This commit replaces JKS keystores in our tests with the
corresponding PEM encoded key and certificates both for key and trust
configurations.
Whenever it's not possible to refactor the test, i.e. when we are
testing that we can load a JKS keystore, etc. we attempt to
mute the test when we are running in FIPS 140 JVM. Testing for the
JVM is naive and is based on the name of the security provider as
we would control the testing infrastrtucture and so this would be
reliable enough.
Other cases of tests being muted are the ones that involve custom
TrustStoreManagers or KeyStoreManagers, null TLS Ciphers and the
SAMLAuthneticator class as we cannot sign XML documents in the
way we were doing. SAMLAuthenticator tests in a FIPS JVM can be
reenabled with precomputed and signed SAML messages at a later stage.

IT will be covered in a subsequent PR
This commit is contained in:
Ioannis Kakavas 2018-07-17 10:54:10 +03:00 committed by GitHub
parent 36165265ce
commit 9e529d9d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 1215 additions and 610 deletions

View File

@ -59,6 +59,10 @@ forbiddenApisMain {
PrecommitTasks.getResource('/forbidden/http-signatures.txt')]
}
forbiddenPatterns {
exclude '**/*.der'
}
forbiddenApisTest {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'

View File

@ -36,7 +36,13 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
@ -101,12 +107,20 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
private static SSLContext getSslContext() throws Exception {
SSLContext sslContext = SSLContext.getInstance("TLS");
try (InputStream in = RestClientBuilderIntegTests.class.getResourceAsStream("/testks.jks")) {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(in, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
try (InputStream certFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test.crt")) {
// Build a keystore of default type programmatically since we can't use JKS keystores to
// init a KeyManagerFactory in FIPS 140 JVMs.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, "password".toCharArray());
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(RestClientBuilderIntegTests.class
.getResource("/test.der").toURI())));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
keyStore.setKeyEntry("mykey", keyFactory.generatePrivate(privateKeySpec), "password".toCharArray(),
new Certificate[]{certFactory.generateCertificate(certFile)});
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
}

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEATCCAumgAwIBAgIEObhDZDANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJV
UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEDAOBgNVBAoT
B2VsYXN0aWMxDTALBgNVBAsTBHRlc3QxEjAQBgNVBAMTCXRlc3Qgbm9kZTAeFw0x
NzA3MTcxNjEyNTZaFw0yNzA3MTUxNjEyNTZaMGcxCzAJBgNVBAYTAlVTMQswCQYD
VQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHZWxhc3Rp
YzENMAsGA1UECxMEdGVzdDESMBAGA1UEAxMJdGVzdCBub2RlMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXtuGIgAq6vWzUD34HXkYF+0u103hb8d1h35
kjeuNApkUhS6x/VbuNp7TpWmprfDgG5w9TourHvyiqcQMDEWrBunS6rmKo1jK1Wm
le3qA3F2l9VIZSNeeYQgezmzuElEPPmBjN8XBByIWKYjZcGd5u7DiquPUh9QLIev
itgB2jfi9D8ewyvaSbVAQuQwyIaDN9L74wKyMC8EuzzAWNSDjgIhhwcR5qg17msa
ItyM44/3hik+ObIGpMlLSxQu2V1U9bOaq48JjQBLHVg1vzC9VzGuNdEb8haFnhJN
UrdESdHymbtBSUvy30iB+kHq5R8wQ4pC+WxChQnbA2GskuFrMQIDAQABo4G0MIGx
MIGPBgNVHREEgYcwgYSHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9z
dIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghdsb2NhbGhvc3Q0
LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5sb2NhbGRvbWFp
bjYwHQYDVR0OBBYEFFwNcqIKfGBCBGo9faQJ3TsHmp0SMA0GCSqGSIb3DQEBCwUA
A4IBAQBvUJTRjSOf/+vtyS3OokwRilg1ZGF3psg0DWhjH2ehIRfNibU1Y8FVQo3I
VU8LjcIUK1cN85z+AsYqLXo/C4qmJPydQ1tGpQL7uIrPD4h+Xh3tY6A2DKRJRQFO
w2LjswPidGufMztpPbXxLREqvkvn80VkDnc44UPxYfHvZFqYwYyxZccA5mm+BhYu
IerjfvgX+8zMWIQZOd+jRq8EaVTmVK2Azwwhc5ImWfc0DA3pmGPdECzE4N0VVoIJ
N8PCVltXXP3F7K3LoT6CLSiJ3c/IDVNoVS4pRV6R6Y4oIKD9T/T1kAgAvOrUGRWY
ejWQ41GdUmkmxrqCaMbVCO4s72BC
-----END CERTIFICATE-----

Binary file not shown.

View File

@ -61,6 +61,7 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.PosixPermissionsResetter;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@ -139,6 +140,11 @@ public class InstallPluginCommandTests extends ESTestCase {
System.setProperty("java.io.tmpdir", temp.apply("tmpdir").toString());
}
@BeforeClass
public static void testIfFipsMode() {
assumeFalse("Can't run in a FIPS JVM because this depends on BouncyCastle (non-fips)", inFipsJvm());
}
@Override
@Before
public void setUp() throws Exception {

View File

@ -114,6 +114,8 @@ public class DateProcessorTests extends ESTestCase {
}
public void testJodaPatternLocale() {
//TODO investigate if this is a bug in Joda
assumeFalse("Can't run in a FIPS JVM, Joda parse date error", inFipsJvm());
DateProcessor dateProcessor = new DateProcessor(randomAlphaOfLength(10),
templatize(ZoneId.of("Europe/Amsterdam")), templatize(Locale.ITALIAN),
"date_as_string", Collections.singletonList("yyyy dd MMM"), "date_as_date");

View File

@ -40,6 +40,8 @@ import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.transport.TcpTransport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.rules.ExternalResource;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@ -87,6 +89,14 @@ public class AzureDiscoveryClusterFormationTests extends ESIntegTestCase {
private static Path keyStoreFile;
@ClassRule
public static final ExternalResource MUTE_IN_FIPS_JVM = new ExternalResource() {
@Override
protected void before() {
assumeFalse("Can't run in a FIPS JVM because none of the supported Keystore types can be used", inFipsJvm());
}
};
@BeforeClass
public static void setupKeyStore() throws IOException {
Path tempDir = createTempDir();

View File

@ -290,6 +290,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
}
public void testBackcompatV1() throws Exception {
assumeFalse("Can't run in a FIPS JVM as PBE is not available", inFipsJvm());
Path configDir = env.configFile();
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
try (IndexOutput output = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
@ -320,6 +321,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
}
public void testBackcompatV2() throws Exception {
assumeFalse("Can't run in a FIPS JVM as PBE is not available", inFipsJvm());
Path configDir = env.configFile();
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
byte[] fileBytes = new byte[20];

View File

@ -125,6 +125,7 @@ import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.ZoneId;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -132,6 +133,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
@ -1363,4 +1365,8 @@ public abstract class ESTestCase extends LuceneTestCase {
}
}
public static boolean inFipsJvm() {
return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips");
}
}

View File

@ -158,7 +158,7 @@ public class CertParsingUtils {
private static KeyStore getKeyStore(Certificate[] certificateChain, PrivateKey privateKey, char[] password)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
KeyStore keyStore = KeyStore.getInstance("jks");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
// password must be non-null for keystore...
keyStore.setKeyEntry("key", privateKey, password, certificateChain);
@ -242,7 +242,7 @@ public class CertParsingUtils {
static KeyStore trustStore(Certificate[] certificates)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
assert certificates != null : "Cannot create trust store with null certificates";
KeyStore store = KeyStore.getInstance("jks");
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, null);
int counter = 0;
for (Certificate certificate : certificates) {

View File

@ -153,6 +153,7 @@ public class LicenseServiceClusterTests extends AbstractLicensesIntegrationTestC
}
public void testClusterRestartWithOldSignature() throws Exception {
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
wipeAllLicenses();
internalCluster().startNode();
ensureGreen();

View File

@ -76,6 +76,7 @@ public class SelfGeneratedLicenseTests extends ESTestCase {
}
public void testTrialLicenseVerifyWithOlderVersion() throws Exception {
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
long issueDate = System.currentTimeMillis();
License.Builder specBuilder = License.builder()
.issuedTo("customer")

View File

@ -12,6 +12,7 @@ import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.test.ESTestCase;
import org.junit.BeforeClass;
import java.math.BigInteger;
import java.net.InetAddress;
@ -32,6 +33,11 @@ import static org.mockito.Mockito.when;
*/
public class CertGenUtilsTests extends ESTestCase {
@BeforeClass
public static void muteInFips(){
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
}
public void testSerialNotRepeated() {
int iterations = scaledRandomIntBetween(10, 100);
List<BigInteger> list = new ArrayList<>(iterations);

View File

@ -53,6 +53,7 @@ public class PemUtilsTests extends ESTestCase {
}
public void testReadEncryptedPKCS8Key() throws Exception {
assumeFalse("Can't run in a FIPS JVM, PBE KeySpec is not available", inFipsJvm());
Key key = getKeyFromKeystore("RSA");
assertThat(key, notNullValue());
assertThat(key, instanceOf(PrivateKey.class));

View File

@ -42,7 +42,10 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@ -76,6 +79,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
* Tests reloading a keystore that is used in the KeyManager of SSLContext
*/
public void testReloadingKeyStore() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
final Path tempDir = createTempDir();
final Path keystorePath = tempDir.resolve("testnode.jks");
final Path updatedKeystorePath = tempDir.resolve("testnode_updated.jks");
@ -133,12 +137,10 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
Path updatedKeyPath = tempDir.resolve("testnode_updated.pem");
Path certPath = tempDir.resolve("testnode.crt");
Path updatedCertPath = tempDir.resolve("testnode_updated.crt");
final Path clientTruststorePath = tempDir.resolve("testnode.jks");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.pem"), updatedKeyPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCertPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), clientTruststorePath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
final Settings settings = Settings.builder()
@ -150,7 +152,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
final Environment env = randomBoolean() ? null :
TestEnvironment.newEnvironment(Settings.builder().put("path.home", createTempDir()).build());
// Load HTTPClient once. Client uses a keystore containing testnode key/cert as a truststore
try (CloseableHttpClient client = getSSLClient(clientTruststorePath, "testnode")) {
try (CloseableHttpClient client = getSSLClient(Collections.singletonList(certPath))) {
final Consumer<SSLContext> keyMaterialPreChecks = (context) -> {
try (MockWebServer server = new MockWebServer(context, false)) {
server.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
@ -190,6 +192,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
* reloadable SSLContext used in the HTTPClient) and as a KeyStore for the MockWebServer
*/
public void testReloadingTrustStore() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
Path tempDir = createTempDir();
Path trustStorePath = tempDir.resolve("testnode.jks");
Path updatedTruststorePath = tempDir.resolve("testnode_updated.jks");
@ -240,19 +243,21 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
*/
public void testReloadingPEMTrustConfig() throws Exception {
Path tempDir = createTempDir();
Path clientCertPath = tempDir.resolve("testnode.crt");
Path keyStorePath = tempDir.resolve("testnode.jks");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keyStorePath);
Path serverCertPath = tempDir.resolve("testnode.crt");
Path serverKeyPath = tempDir.resolve("testnode.pem");
Path updatedCert = tempDir.resolve("updated.crt");
//Our keystore contains two Certificates it can present. One build from the RSA keypair and one build from the EC keypair. EC is
// used since it keyManager presents the first one in alias alphabetical order (and testnode_ec comes before testnode_rsa)
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"), clientCertPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), serverCertPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), serverKeyPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCert);
Settings settings = Settings.builder()
.putList("xpack.ssl.certificate_authorities", clientCertPath.toString())
.put("path.home", createTempDir())
.build();
.put("xpack.ssl.certificate_authorities", serverCertPath)
.put("path.home", createTempDir())
.build();
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
// Create the MockWebServer once for both pre and post checks
try (MockWebServer server = getSslServer(keyStorePath, "testnode")) {
try (MockWebServer server = getSslServer(serverKeyPath, serverCertPath, "testnode")) {
final Consumer<SSLContext> trustMaterialPreChecks = (context) -> {
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(context).build()) {
privilegedConnect(() -> client.execute(new HttpGet("https://localhost:" + server.getPort())).close());
@ -263,10 +268,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
final Runnable modifier = () -> {
try {
Path updatedCert = tempDir.resolve("updated.crt");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"),
updatedCert, StandardCopyOption.REPLACE_EXISTING);
atomicMoveIfPossible(updatedCert, clientCertPath);
atomicMoveIfPossible(updatedCert, serverCertPath);
} catch (Exception e) {
throw new RuntimeException("failed to modify file", e);
}
@ -277,7 +279,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(updatedContext).build()) {
SSLHandshakeException sslException = expectThrows(SSLHandshakeException.class, () ->
privilegedConnect(() -> client.execute(new HttpGet("https://localhost:" + server.getPort())).close()));
assertThat(sslException.getCause().getMessage(), containsString("PKIX path building failed"));
assertThat(sslException.getCause().getMessage(), containsString("PKIX path validation failed"));
} catch (Exception e) {
throw new RuntimeException("Error closing CloseableHttpClient", e);
}
@ -291,16 +293,17 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
* that is being monitored
*/
public void testReloadingKeyStoreException() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
Path tempDir = createTempDir();
Path keystorePath = tempDir.resolve("testnode.jks");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", keystorePath)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
.put("xpack.ssl.keystore.path", keystorePath)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
final SSLService sslService = new SSLService(settings, env);
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
@ -336,12 +339,12 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.putList("xpack.ssl.certificate_authorities", certPath.toString(), clientCertPath.toString())
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.putList("xpack.ssl.certificate_authorities", certPath.toString(), clientCertPath.toString())
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
final SSLService sslService = new SSLService(settings, env);
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
@ -373,10 +376,10 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.truststore.path", trustStorePath)
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.truststore.path", trustStorePath)
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
final SSLService sslService = new SSLService(settings, env);
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
@ -482,6 +485,20 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
return server;
}
private static MockWebServer getSslServer(Path keyPath, Path certPath, String password) throws KeyStoreException, CertificateException,
NoSuchAlgorithmException, IOException, KeyManagementException, UnrecoverableKeyException {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, password.toCharArray());
keyStore.setKeyEntry("testnode_ec", PemUtils.readPrivateKey(keyPath, password::toCharArray), password.toCharArray(),
CertParsingUtils.readCertificates(Collections.singletonList(certPath)));
final SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore, password.toCharArray())
.build();
MockWebServer server = new MockWebServer(sslContext, false);
server.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
server.start();
return server;
}
private static CloseableHttpClient getSSLClient(Path trustStorePath, String trustStorePass) throws KeyStoreException,
NoSuchAlgorithmException,
KeyManagementException, IOException, CertificateException {
@ -493,6 +510,23 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
return HttpClients.custom().setSSLContext(sslContext).build();
}
/**
* Creates a {@link CloseableHttpClient} that only trusts the given certificate(s)
*
* @param trustedCertificatePaths The certificates this client trusts
**/
private static CloseableHttpClient getSSLClient(List<Path> trustedCertificatePaths) throws KeyStoreException,
NoSuchAlgorithmException,
KeyManagementException, IOException, CertificateException {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
for (Certificate cert : CertParsingUtils.readCertificates(trustedCertificatePaths)) {
trustStore.setCertificateEntry(cert.toString(), cert);
}
final SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore, null).build();
return HttpClients.custom().setSSLContext(sslContext).build();
}
private static void privilegedConnect(CheckedRunnable<Exception> runnable) throws Exception {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {

View File

@ -72,6 +72,8 @@ public class SSLServiceTests extends ESTestCase {
private Path testnodeStore;
private String testnodeStoreType;
private Path testclientStore;
private Path testnodeCert;
private Path testnodeKey;
private Environment env;
@Before
@ -80,17 +82,20 @@ public class SSLServiceTests extends ESTestCase {
if (randomBoolean()) {
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
// The default is to use JKS. Randomly test with explicit and with the default value.
testnodeStoreType = randomBoolean() ? "jks" : null;
testnodeStoreType = "jks";
} else {
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
testnodeStoreType = randomBoolean() ? "PKCS12" : null;
}
logger.info("Using [{}] key/truststore [{}]", testnodeStoreType, testnodeStore);
testnodeCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
testnodeKey = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
testclientStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks");
env = TestEnvironment.newEnvironment(Settings.builder().put("path.home", createTempDir()).build());
}
public void testThatCustomTruststoreCanBeSpecified() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
Path testClientStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
@ -110,7 +115,7 @@ public class SSLServiceTests extends ESTestCase {
.setSecureSettings(secureCustomSettings)
.build();
SSLConfiguration configuration = new SSLConfiguration(customTruststoreSettings, globalConfiguration(sslService));
SSLConfiguration configuration = new SSLConfiguration(customTruststoreSettings, globalConfiguration(sslService));
SSLEngine sslEngineWithTruststore = sslService.createSSLEngine(configuration, null, -1);
assertThat(sslEngineWithTruststore, is(not(nullValue())));
@ -126,10 +131,10 @@ public class SSLServiceTests extends ESTestCase {
public void testThatSslContextCachingWorks() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
@ -145,6 +150,7 @@ public class SSLServiceTests extends ESTestCase {
}
public void testThatKeyStoreAndKeyCanHaveDifferentPasswords() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
Path differentPasswordsStore =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-different-passwords.jks");
MockSecureSettings secureSettings = new MockSecureSettings();
@ -160,6 +166,7 @@ public class SSLServiceTests extends ESTestCase {
}
public void testIncorrectKeyPasswordThrowsException() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
Path differentPasswordsStore =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-different-passwords.jks");
try {
@ -180,12 +187,12 @@ public class SSLServiceTests extends ESTestCase {
public void testThatSSLv3IsNotEnabled() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
SSLConfiguration configuration = globalConfiguration(sslService);
SSLEngine engine = sslService.createSSLEngine(configuration, null, -1);
@ -214,6 +221,7 @@ public class SSLServiceTests extends ESTestCase {
public void testCreateWithKeystoreIsValidForServer() throws Exception {
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
Settings settings = Settings.builder()
@ -227,6 +235,7 @@ public class SSLServiceTests extends ESTestCase {
}
public void testValidForServerWithFallback() throws Exception {
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
Settings settings = Settings.builder()
@ -251,6 +260,7 @@ public class SSLServiceTests extends ESTestCase {
}
public void testGetVerificationMode() throws Exception {
assumeFalse("Can't run in a FIPS JVM, TrustAllConfig is not a SunJSSE TrustManagers", inFipsJvm());
SSLService sslService = new SSLService(Settings.EMPTY, env);
assertThat(globalConfiguration(sslService).verificationMode(), is(XPackSettings.VERIFICATION_MODE_DEFAULT));
@ -273,7 +283,7 @@ public class SSLServiceTests extends ESTestCase {
Settings settings = Settings.builder()
.put("xpack.ssl.client_authentication", "none")
.put("xpack.security.transport.ssl.client_authentication", "optional")
.put("transport.profiles.foo.port", "9400-9410")
.put("transport.profiles.foo.port", "9400-9410")
.build();
sslService = new SSLService(settings, env);
assertFalse(sslService.isSSLClientAuthEnabled(globalConfiguration(sslService)));
@ -325,13 +335,12 @@ public class SSLServiceTests extends ESTestCase {
ciphers.add("foo");
ciphers.add("bar");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.putList("xpack.ssl.ciphers", ciphers.toArray(new String[ciphers.size()]))
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
SSLConfiguration configuration = globalConfiguration(sslService);
SSLEngine engine = sslService.createSSLEngine(configuration, null, -1);
@ -342,14 +351,14 @@ public class SSLServiceTests extends ESTestCase {
public void testInvalidCiphersOnlyThrowsException() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.putList("xpack.ssl.cipher_suites", new String[] { "foo", "bar" })
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.putList("xpack.ssl.cipher_suites", new String[]{"foo", "bar"})
.setSecureSettings(secureSettings)
.build();
IllegalArgumentException e =
expectThrows(IllegalArgumentException.class, () -> new SSLService(settings, env));
assertThat(e.getMessage(), is("none of the ciphers [foo, bar] are supported by this JVM"));
@ -357,12 +366,12 @@ public class SSLServiceTests extends ESTestCase {
public void testThatSSLEngineHasCipherSuitesOrderSet() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
SSLConfiguration configuration = globalConfiguration(sslService);
SSLEngine engine = sslService.createSSLEngine(configuration, null, -1);
@ -372,12 +381,12 @@ public class SSLServiceTests extends ESTestCase {
public void testThatSSLSocketFactoryHasProperCiphersAndProtocols() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
SSLConfiguration config = globalConfiguration(sslService);
final SSLSocketFactory factory = sslService.sslSocketFactory(config);
@ -397,12 +406,12 @@ public class SSLServiceTests extends ESTestCase {
public void testThatSSLEngineHasProperCiphersAndProtocols() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testnodeStore)
.put("xpack.ssl.keystore.type", testnodeStoreType)
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.certificate", testnodeCert)
.put("xpack.ssl.key", testnodeKey)
.setSecureSettings(secureSettings)
.build();
SSLService sslService = new SSLService(settings, env);
SSLConfiguration configuration = globalConfiguration(sslService);
SSLEngine engine = sslService.createSSLEngine(configuration, null, -1);
@ -462,8 +471,8 @@ public class SSLServiceTests extends ESTestCase {
assertThat(trustManager.getAcceptedIssuers(), emptyArray());
}
public void testGetConfigurationByContextName() throws Exception {
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
final String[] cipherSuites = sslContext.getSupportedSSLParameters().getCipherSuites();
@ -525,7 +534,8 @@ public class SSLServiceTests extends ESTestCase {
assertThat(mon3Config, sameInstance(global));
}
public void testReadCertificateInformation () throws Exception {
public void testReadCertificateInformation() throws Exception {
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
final Path jksPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
final Path p12Path = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
final Path pemPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/active-directory-ca.crt");

View File

@ -22,10 +22,12 @@ import static org.hamcrest.Matchers.notNullValue;
public class StoreKeyConfigTests extends ESTestCase {
public void testCreateKeyManagerUsingJKS() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
tryReadPrivateKeyFromKeyStore("jks", ".jks");
}
public void testCreateKeyManagerUsingPKCS12() throws Exception {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
tryReadPrivateKeyFromKeyStore("PKCS12", ".p12");
}

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIUMVGoHuyNTjTFaoRmqFELz75jzDEwDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMTgwMjE1MTc0OTExWhcNMjEwMjE0MTc0OTExWjARMQ8wDQYD
VQQDEwZzYW1iYTQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtGBwa
n+7JN2vweSUsYh4zPmh8RPIE+nEVjK1lx/rADUBY7UVjfTYC+MVKKiezZe7gYCNT
7JNKazPpgVI9e3ZFKw/UxomLqRuuvn5bTh+1tMs3afY5+GGzi7oPmEbBO3ceg0Hi
rNSTDa1rfroZnRYK8uIeSZacQnAW90plITI7rBBt9jq+W9albFbDybfDgNv+yS/C
rzIsofm4rbFC3SMRYfrT6HvwDhjOmmYKZci5x7tsn0T+3tSiR44Bw5/DgiN5kX3m
/kl9qg1eoYWbCUy1dKmQlb4Nb4uNcxrIugLB3zjBkfhMZ0OHoveKh/lJASTWik9k
xQ9rEYbpsRbuXpsHAgMBAAGjgcwwgckwHQYDVR0OBBYEFJOLa7UXKtLPibgKeFh7
Kq1+rS0/MG8GA1UdIwRoMGaAFGaNmN5mi9jaMW25MEWYgt+5OkDBoTikNjA0MTIw
MAYDVQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBD
QYIUdwsnIxjgSneHNVKT6JNCCsrQ3T0wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
AAABhxAAAAAAAAAAAAAAAAAAAAABMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD
ggEBAEHqT1WHkcF8DuOgyIBx7wKcUVQ5H1qYYlJ1xgMGrKFFZLUzouLcON7oadEu
HLIJ4Z3AKD3bqWpcls5XJ9MTECGR48tou67x9cXqTV7jR3Rh0H/VGwzwhR85vbpu
o8ielOPL8XAQOfnAFESJii5sfCU4ZwLg+3evmGZdKfhU6rqQtLimgG/Gm96vOJne
y0a/TZTWrfAarithkOHHXSSAhEI5SdW5SlZAytF4AmYqFvafwxe1+NyFwfCRy0Xl
H40WgVsq+z84psU+WyORb3THX5rgB4au9nuMXOqFKAtrJSI/uApncYraaqU28rqB
gYd8XrtjhKOLw+6viqAKu8l7/cs=
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-192-CBC,D097C279AD03E97C34B81B834539C0BB
rQkO27X8phcP9ydaFArZy4SFDcoCGFsr2TcR0M6Vn8g0ZT9MIrnj2xHCmeMExlKT
MViBQzmupBs0IW7y/ovpEUBgRd4TnSigKNF2XZ3+C6F4rkziTheWOlaUq7PIqOnW
dTmf/WZDLlgms6hzrc7B447lO2FcNUDB6uXkxS1dAhh9T6DFcq9KuW7KJOWt9Dre
75z6rh5nHboUw2i01VqJK+86aL5V3vNK3bjYcbIHKHrgM/+V+hFUNJ6aEepVf+G0
jzicgEBJwtzOg4MTSqR2z3niNbz9LLBJkH+uR+tN941+JPFmEwsLtkq3OBH7nraG
Srqz/5YcdA45jdZNme+KqorT8mNX/Hx2BsmQYnw+A0ZAqnSWeMcNZgFaAn8OcVxy
d5VS0KFlQD7DPnZi89cyTRScKhcj451NhwOPWIE7w1UpNPVGRj5FBMAtDVaE2Wkc
wuQ0nSwsC3EOvVDMe/fmv2VcoWceh1V9esA2H0n9NWQApGSqz17PPebwQadPX3Y0
atrbbXT7fYTD3Ij38bmYZiDOluHiXxFchWxVUReq6nHJD3yo8ch2CKpx9XzjElLv
6leUZhlIlq026QxGNVf+OQLTlLXjF8jGbRC31Y4yiHj1I12P0+dic0W8YvUkC5Pp
w7NHMtYG6VHLGkPbCQxzTMS+JU24j/wMIokZWlmaRNDf2DZZAS0asQ/EOG/I1afc
SXyHDQUhi0/8N7CJWE/i1xLrazFKiIkxucxY+WDqGrk5sZnP+cH0cM7Zja253NTy
2B8LZJX360peCD15grkMt1oRtdMvZxF1rS/3BDPuANC59yg5i4eC+P39wkeMf8hu
o8I2Hp5021mT9AWE1Dxf8gSZIJZxIeEgioRvoY1LOEfghe/OXQHR0SXJq9k5GNiA
z4Tz3cfCT3WrHbReY585o2qtbpWu2OeSdxrv8p9kYi8GkevbR+nLq8NaH5WPRD4E
b9RLUz1NfiK8DOW7tk8+gwsNun3hmil7xubw1uhc6a0OGKb9ijMS0rslYW9zeowu
dkROuVwhUhXHOx0ZGWUGauJifERzICWR8Jx48/8DWD4xW3DkIRt5gh3CvzHcdSbv
4VEFSyndWeyNk2Yc6+sX0H35Rngc7gjedCAn8hUBnUq9srfhGKaZ6bahlUt0xsmK
Y3cxcd1or/2S2hONcN4NE2MfB/RRUVeHxdp34RPeW6L8qH/YZFxqt8dUm19QXr0c
CdgSEmVyKOpCPebGJwPwdJEmbxPS/98AjiqOpt83JLUhMeUGhjawXvLzl0YEBJV9
+6waTV4Xl94aJszyvDeW/+cKIgeso9SeQSN6fLsXgdAVABCZ5yJ+liw6I84G0f2n
D6e51P0JQAL8v28bBACdoB0Qxr9UTV/X8smGTwWobv/KW1BPdvWETsc7TrtWLZ6F
qiZj7mI0h1oeyrC1h1+1oVuUTpy7JICCBloL4ir56lcSWmNZm1GRfar8UhXA7aNw
klAkS6rYHH4gDxhvwd1k/pN1HlCtbmwLyYC/f11+89RnPr0FFW48qMqmwBls63dp
4aAqneUiEow/evE4fBTLhFrgkvfZnjhd41IpzXfMWB5x9SHjrrS4/rjsHXcHUrAh
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-192-CBC,2F36F79E75ACA7803AF1BC1B70C2360C
d4/f7dnpPW9DfhGXuGDx7r56BjQ64iNcsQdrC1CTZB363iAvBBeHaoJFaWpQOUmT
WCBdM6YmRuMi6z4sMtm8Vre3i+Mu2Jti0LTDXqH8Y6FMpptxAYoFb9hkM0OvUGDJ
ASLGTa1XKyCzZWOe2IGLtWIS8zkGv/fSXHqDJV8ddq8uLHGZXBxAye5oJUD0654T
DasIllbiTlBEYlEJ10OyIAspS47n4LWVE5ggyGdiyIgh5s3lAMPO3+yenDU3/dzj
YF2zHKnfe0Nx2lUQVJRYknQvFCx0WTGH9gNl40FovoOMHyRjEuOHD9PFNvL/TCh6
9h0jJPWu/SsIiYaIqR0pDgqWdHXHA5Ea3s2+w0YHbv7DqkGXWZdceLUdZtcXCBJk
P8QL9IWa7VE50SS6wV5uXX9tV5lHzMFsNGkwtGcR1UMU5cXYqckFXgoBqDN0fyWe
V5iEknSJ4Na+MHv75rvRat0kv6upu9i5NSpYTc5jLHdWZWsYMZ/ZMiMoLBP+KAPT
DQ3eyph/84BU3DePaQF3Rsp0ZvPxqQ361Zwc4zC5CKbHur1QX8WAY5XlBMfuBpkf
CKr5wgwF+ZpS7zsfUpMPPe9Y1E8TWnhx/DtCVLEslBpr2u/rMaxPp6ev9/Wry7N+
UFBOwodipBhlfSvLqjc511L+bXRzqXiINuW0eSKUQv0J/G0Ur894kJJ6feDYlskj
JiZjOgOyyKhB+K9AXmkfRdvWUJeweL8pgDuYSyQdQ0zoUCZALEoYK2cBWzti/wep
QPFD5oz8076aXNHKMHLsRmSFuEZb6IN0PtUNVf958EbrtABNIuoufKlKtJsEnUyK
VHIEUxExEgyECiozKnxvhr7RQ9nTQXhNdgtec6jJblYnla/+OWAfHdxtHhBjp5AX
WvLyUhmgrmLNdKd1KSzcXynBHgh0hi0HJXYx31FilwbxsdhwN1LwN/Do4T4qGkUr
InrQC3ZHRuh0yAOPrwRFEWbW5m/PzVP/xYVgFtVWP7w38ftZbaBy5xPmtswn+PH+
cIMt1Y9PaAlhLNpW/Vfn503T9M+05vu73vbU1xgu/B1kePOqE/WO0cOZl0KdaMmT
wAQBKuI7qTACH+/8g3Uir1YSChLthH+1Gs6h686EP6ZydwXq9GYXXkNmJNJJsnmU
RDjoT0F4XBKvcQdX3EeQYs3Af2yZWFDC59c1Ews2dqMK7vy2tYITbx2yn30DBDAl
xvjp2izzmAgQJEG/RqCYsUHCCEv7wz3tpsSOkFem9IHZpR2h8Rqy88GH9qYOkgwo
+fKSmIgC4RLQXsHuh7RRuyNc2FaWDgRgSxs5V4f9xOSU/ZbUftYWnwEyCwbu3RJp
CIXQFZhzU2t5l1Eh+x40rwpEJDXBEwmOIUO3x1oOqGZPPEQ674uMal5TRjvdOVGD
h665Fpo5Xu9EQwQZHYddeRl/7yw8F6LCxBLgHlngKRHHGDUHlTscLfYRqNh+x3jT
3S8dfaGzlnwdQEx32gyLAV0/nsFnzh1AknFMT8jesIYF7PLiAi67PNyNwRCc7TFp
jpKvzkDRVP72bivTmCyP5aKR0Q2oIrAw51MMinT6R2VaoR7COjoVbqYsRLwkxu+p
-----END RSA PRIVATE KEY-----

View File

@ -1,23 +1,34 @@
-----BEGIN CERTIFICATE-----
MIID0zCCArugAwIBAgIJAPqdcmPxQKraMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
MIIF0zCCA7ugAwIBAgIJAJZQBp49qNzmMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTgwNDMwMTUzODM1WhcNMjIwNDI5MTUzODM1
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTgwNzEyMTUyMjU0WhcNNDMwMzAzMTUyMjU0
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA0wNzfQ9K9WIs9Le6pfiEHdCI97zGZRqOREKb+zFoDllXEEWW
Y5mfXRlTYXbxBiCIV5DDW0yaXlleq62j7/O/6prNUBiYo5sK4Wfj+1UlXLmMikkv
bShm9XzBAXHK20coLJTKOH8QOnFyuVYUvHPCLsoEhQtCHU4zoGaaPmk8w1JU/bfR
+kWmU+x0Ak4rGuRWvMMqg/bu/W/1LmESO5Jsm2CnIyB/22vB08kFn1pO0IIrPQhr
dXqPxddzxc7DuAyyMyzsrLi5msugynEwm1CTBNL9cG45ujNhWzd1rqQe1HF94mEw
RinFe2Ui+vLFpNbh8EesLsy0p18J3QkGQ/0xjQIDAQABo4G/MIG8MAkGA1UdEwQC
MAAwHQYDVR0OBBYEFLUR8gs3uCNdLIwJlkp7SwngpjfhMIGPBgNVHREEgYcwgYSC
CWxvY2FsaG9zdIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghds
b2NhbGhvc3Q0LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5s
b2NhbGRvbWFpbjaHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQEL
BQADggEBAB73kmak89jgW1q3wIUMfxisokCsk7XuYqPBpc8D06UZBaArCvW2cuLP
5PLI2bR7fSIhgZmlbawa3adOLZ9n9lOJrWUHTh43kKyiSX8EobE0T/MSGVMfTEFu
c92erLS2gSDk4wLahzm5htd1h1KwzJ5j5kdzlLGaQsnxDDjbu9BiX/otEyCl8n69
AZKOXoYscl2NxBgr2V6C2frthJFfQ9Gxzg5q6V/P3aIUyV0xsC3Ve1wdfXqNeRfO
nrnFbKRDsxJAJ/JtO3GTtqBrFjods0sepKNxFg13r/QLJnYjYW6t7o91JZj2AFOs
1INZnCOAMV3vR/FOwwOT86HDgrwSy2o=
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEAqLiqAPYBBEBvSJCiQOzV/NPgr0kLQkZGaxQ29PPoKbsKXVp+
0Uyv9DUitPw+G04h/eOC2wiu2u5sn2rD4Ew09L41qiaViQRY6dHazAkPVq8Chet/
GWrc+umLJUKLU7MTyC8ozmKjgkyvIuvQ6ndEP31z3JG/j9DsBAX8NWIIJSm9Jaz5
XUS4fIXwSce141k8zb39+oStyA1qIhv6n59+oNIuuXu1XIJzjQnZCnyAO8/9i7LI
uoL93zu7xNT+ns6Tt7zhweUQEI8FeRdj/k/Of8prbaulFH9oM1g/lnGKLV7E5vh/
foP1+SRW+MWRjAUA8MExTCtvFhRAb3x6FYzCPX3VERKn8M3m6Rewz/LQ7XG2VzdM
/dw/JSZilAWBZItkY9H1InTeIz9Sw9Z53um7tO5nzq1QQxZijh6n9vzSLoFn6qA5
SDQl2YycjBE35i/9JBUl0KmVMOfFzpoWLiKzTJMRzNJIeRxJl3MvscbRl8fY0Kco
XQ+w84QMTo+Tn+8Ztfme4uGtHHCTRzrLSo+Hyh8BTm9jJKCaUbMnNW1p2LoxJlq5
ah+W8QRLaFbWt4xl9TQR0kVnoOyfSGx+3SmTBODa+6Wg038eim8Tw8K+EBvxynWU
sKF1ReL0aOZLi2zqPiQTUtR2y5ue/xjsFWx+tMMGTz3Ci6UoFs9yKqQ++qkCAwEA
AaOBvzCBvDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQLFB6mVsZpiHNMkxOgriN53HZv
ODCBjwYDVR0RBIGHMIGEgglsb2NhbGhvc3SCFWxvY2FsaG9zdC5sb2NhbGRvbWFp
boIKbG9jYWxob3N0NIIXbG9jYWxob3N0NC5sb2NhbGRvbWFpbjSCCmxvY2FsaG9z
dDaCF2xvY2FsaG9zdDYubG9jYWxkb21haW42hwR/AAABhxAAAAAAAAAAAAAAAAAA
AAABMA0GCSqGSIb3DQEBCwUAA4ICAQAQtteI+//qUZ7pNQ5tBuwc24UlSH4dbHFr
79pA0YN/Y7Y/PfU60YeGpPf/QzZWLnRk/8mELWy2Ok7KzhlNjr/nAksiF97LUUnl
6dP15a4ATzheYAtv/47In8ShOrPZ7YG+VAmNWRB8Rj62RuE5khcoL8BpWzCHL8Gx
Kif7lN5SOV06ExGHrBr4Y20QtZsTgkWhAP1UC5EwXxKcchCAIrb60Rx1OShzQrxz
I0RF4mfJ06Jad6qUePkPoUm1lPcFfNvAnJ+hBA210J87NSMFTSsgXT197upnCdhl
9QmKHyk12oVoMtTtf2kc1yTZQ1fnm/V4/PZ7ypyhy+jMsIQSTwEKQr7JYEQoYpdt
yTMHc9L4gPkLTwAbxUx/M1lSuQ4yD3SclBt77CxCM8I9Z76qCVakalb4VhplRbsU
sYs3dgvslFOAJKoOIPeTqm+2L6psxiV9WxA6tvEAk6P/AwjOK6Y4hclnoQDgNI2Q
U+T+ZPi5WRmibs0WxfQv4Vv4MQG/LRT3pwsKWQ76TzgtHKNHgtAKd9Sn0Nylacsh
yhDbvI0jnvwoOlUPUVWerSJLxzazG5mRLi94ZxZMb+7TUUtDBEPtkCquCAA2b4Kh
ykHbmBqhC8Pn9qc9iP0uHuuQETUl/zd7E2ZD3RIj4uYYspovihE5D1Svi5m+3NuS
sCsfHRjmMw==
-----END CERTIFICATE-----

View File

@ -1,27 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0wNzfQ9K9WIs9Le6pfiEHdCI97zGZRqOREKb+zFoDllXEEWW
Y5mfXRlTYXbxBiCIV5DDW0yaXlleq62j7/O/6prNUBiYo5sK4Wfj+1UlXLmMikkv
bShm9XzBAXHK20coLJTKOH8QOnFyuVYUvHPCLsoEhQtCHU4zoGaaPmk8w1JU/bfR
+kWmU+x0Ak4rGuRWvMMqg/bu/W/1LmESO5Jsm2CnIyB/22vB08kFn1pO0IIrPQhr
dXqPxddzxc7DuAyyMyzsrLi5msugynEwm1CTBNL9cG45ujNhWzd1rqQe1HF94mEw
RinFe2Ui+vLFpNbh8EesLsy0p18J3QkGQ/0xjQIDAQABAoIBAG4zFTMws2LnPLco
5I8c9FJlv8IxkiLm9Xlsl+1dZgxoV/Glhd7KMdH7EfKKnWEnyEyCy6N4o/22Cpz5
9+2ujIHHCoZT8hMvO0Vwbj2pv/Nm66Cki+IkAXEfD+TjOp+9z5tIsTtEEIOVD+b+
r6GjirvIwQeCU6reVlPkgZUqfJM8Drh2vOKzTqalJ7Ud4lsHeOaCvAaLp5RKz6sl
BSX1m3UyRkrOQRFNeD8FwXGgPmxZCbCdLka8em9b2IHFZmfFm+R63NeOWx4wQIF8
Wh2ncLf3enQU9Xsti1bQ3Q1SALG5Xjf0rtjlk5LklnQ17MuFKLgsIbJ5e9Lg82Bd
DyrwuMECgYEA+orKql23N9x6J2GdpUHIcJ465b8o8DK/HPE880pwkMKzxaKSMhuP
VmOi9lJl0QzxL+cqIKoDxQxr9rzY8/fRa+FHPn2ypJeV7osyDCZKcwJyh8PfHD69
XIhBXlcr9qLLXj1EqKEMGnCAcbDTiLPsReYfpJ4elrtE9gNstIqqOrkCgYEA15w3
5Y4aqmjCABQW3SyVah772xYJWmscwxJWTrMuBm4EUoMjx2M2qHf8xLPoay4Q9YTR
v+HtaTw1LAC7tTvuPIGB3Iopj4pyhBWX4m0kxicV7clJFB3eDrl4Dy/70IEJtWxk
xxdEjxwgFhChWOeB4IdcLc/QnGqIZq9v1WGps3UCgYEA2jU9dAoxRAbToS8EtWTI
5UT6eRT329Pm3ZdCBYdE6N+a4TvJZrjYK16WFUEIin1iJt2HtHE+3UUHVxt9PWcO
T44ilcu2ZmHb5Kn5Cdnjp61vAM3YqOn/1PKbNEZp9OIui8KC5Pd26iQnyl0+r2Y9
F1fpIV/RtmgeFMJA0DGhN4kCgYB5jvzAsmZ8TwWZb7oYRmuS4hcSxRDO5nbX0D3S
rxiyzVIohwEkB96oCsX6zIer7dPn6FMtQJ5OZ4B+54bsvfYqLMXfZhHaeK7poxb3
tJs4EI8/ee12pwQr/wseXOo2+plTrOIAkTC5Ep1Qc13UNum1gftJZNHzbeirJBwE
DMTVhQKBgQCN7jA7Y7eyXdm6fQpCn/gOkKb4dGhKPlrNOrRoD2S/L1YBJjreGZPm
NARLPO0H1Wrkg54KSIvf69COjVJeyw8L0HGE2eQQOwS7dAvy8rdj+UvABXgaQCxv
wJsTOZEycAeCyp4wJOLeksMB58bzIXPDOPNlN6buWBVLjm33q7g3Rg==
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,50C44E2D186DDB06
rofPrFk6MlImSnj1Gx2qwUl9N45Ao4u6FoqxMvw2F3X/MqnZ/0hvA+7Yh65C13Hb
uTMBfSXDMpaWd3tV+1CA6fEVfMCq1Z894Chqvw6ygHzIMlCwDvar4jUEYOjOsRQE
9wzngqGSd+uVz93im6NSFvt2LJ77qKHE8R/REX5c7fr2eq4rgZU/58q2RxvXXnWV
rQGnAPoRIeyRStMKaV5gytIxME+88XDx5jr86a4wr4wraw7mbRlJG1ERWqNfSCNP
tzBPo5LXZMQIvMs3qieclUWYH4vL3gKBcOVmKlsUB/0ov3vC/nrCE3BmvgsL9SFj
ZUCrGsVH+nsRj6mzHSJtUQVSXHvoRGVh8erBCt5H8KmMyv8F8aiUERWeOX63Erk9
2x4g9trewa6CCXXB+sKKCwqP06HNajjPo5WnTEPPag6WE06O3//yduagcR1QD3Os
Xw0pyZQxf2/4nX4jLNipHCyuYkgcDCarRG4/AgTTI5+cv3CS7C73HwVqz8v5Dh5P
I0ZCdqeK7R5wSlF58HzVGfv9lyjvUohSiQrCDQBhjVrnTjXR0kc0lE0GaoMnOsPR
X0UAIxRnpM43q9A/7z+VEEV4CtzWAt6dIwqFaHr8iVHROy4UUcoC7aMa8rVq4PX7
YX+vBInOiY+APK/mF22Ao3Ho7uehDTIeBfbF1ED6ugTJvhCIiObsCTh79SDEH1PC
zvVVWl3SO8Std5KnuoQMEqi3kv2I3mBlGjWshjVz856OudX57KTcEAkrJhUD4SFb
cwwDdxY0I/jTD0/oE3VL/d1qhh8mt6oj74z8a68BL7B7xo9mgPuVO5z0ZblizulN
6S+vyb5q0DJIpPDkI0IEx1eEiNiM+WkTHG28SCZR/sq3TGH0B5o/qQzp9O2JlwLB
KiZ8qAbzsYJo0VAIAYBuWdM+pKXcrIIoqa278Af4nmwoSkBzyx3wIGZLWYrzdGd5
bx+S8OXdDp7YQraFvtJmNC5KqVY8wsZr77oXyQua5iRANh/5AWKbQWdawkOj34KT
DFDsuLIYCrpInor2JoSMBagq1PSh8FzlzvY+Tsof3U1LpP4cVQYtgeSu+0TPhqFP
L8PYaqeLfPGB3Yt+hPBMtFA21jgv+BSGRSqwQYfcpvaO5+Dy8OAKRlzwc9rRZY4I
XBU56WtRvJHUaGPFiAizgR2w0//SPRtVXNIyfS3GjkjnYofx8agXVKhFyL31fCUv
qVvJ3L1MPynp0voOLObiMIskU5vQLY7UWRzb/wbGknfurAV8xQhnJgcL4+VeoCBO
JPjd8yz7FWwdEXhMyOB8GZNzIGDxY3hsfDR1uNwx45264e2tjcW/ZPUoC1lTO/v5
U6eYk9VZybvJaeb/NNDQLUCwV3T4TEFSvDSgld/GFZNvGBqZYwuAhBKbkrO1f66l
6q4fZgG07uBobOsuvY7Adr1Y4iz09Yjw2F2G5SJ+liZ4rijeN0+fkvV0vwp7GRiP
2WmQIYvdWSek4EDJaEQyUJxLTskveyHLRDV2bo+QhSuh4bB6pCzNoS8Kco6mr1Tg
hx47UrsW/w/KKx90Yl/NUjCMoX77QeHLKcDNreJ6xqGNfQDmcTt962uHm68ZwwFe
qnWxqCQ9stXNh7M0AuG47hAOPEBZzpMRN6ek8akOuZKo3YzdYVneWofav53OwMMU
N1Aj2ktX/IIvYiYbhF9RfiwYJ/UfVOjaiBtfAWgLdY7ZxQWQWL2Ld1Zf4SJ0orAM
ffy3rFAn8A0HpFZOhpOi/IciwOcGvWtJOmLIIxEpnpYY6333poo9oiN3+FYKhUlL
E94Mc7CLnI8Z5TlMdqdE9EFQLUQRjeUxMWwqd8o2s2BNI6vtgIwWTJvnOOQ2YuaZ
hFzGrIef+6Nz2Za2jORj7KyfKDNEcc9YXugBFefXUmU8TkstDpM3BNPk9qjBX4//
D3Nz/8hFugujw/KPb+hFy2knB9jZrmqgDykj8Pf8KA3iWWc/hEr1uv/QveJcJzjp
OSOx7fYjJ9giZFDcbcc3oFFseo1IVzfUFGc5rb3y0KqZd7XS8eKPiw5X9NTZIYaM
ynos8jsYEH65zDdilAMpqlA0Daa+2Az7661Gk7mMIsNyt1eanyYbVJswqOu2IzFd
CjmaDQCeTqAoxOzLHoYxusM3vX3CkQg/e1ZNjqbCNB/RtPOj83rWbf8+Iujkzah7
80v0B3wwXXlZQCk6Wq8nM1vK2W9k37GwPCalibMD+McvOrgblWwUKn9snWLSXym0
d+QPjobJzH8DezMWbE+LgaFB7O2F4cC18WRPGZLUa+Wc9bQJODbxrpfvFE8NcR7r
PjqXHmcSxbIAJdPzcclKSuibSzhh6QwcZrckoMSH6gWVWJ0lfz/UQZAeCU0MkboR
hpOT24urjQ3yr37ScsuZPfPQhaYr9ML/AWJ9bhotoucCcs7KGrGOc4uXo4thuZG7
cBO6ZBDHIiEx3njGQVpCxNOij5gmNYetAQARkmBVJiaU2i7gCR6sQB8EkHOjHrGW
5iNbXsNOKGXQzRFe7tA2DOSV7Lsy0Gbr6/xf3NA4oDzKU06gQmT46CJ3wHWTuZ1P
pUn5mJNBJFcqLP+XPfQ/bSzqu81TYCm2/ZTmJw9POgdejYglpeGgHzKuUZef4bJA
8l9pEa2suE89+Ag4WyPb9izox3qObVUahDuulgBDXLkOJxBpr3oN0JKFGUxjvG5Y
A5DEq1Ya7i64cNmAc4S52cHmnBsEzfDZscv4yL5Cp3XbBTIbE5G0bi/0FxfJQ2gU
T3TtNxVkFxtvoSEl2yNt5aq1hZZlNOVla65w8Rcmv7IHZC4GT4PaOuB3IBrr0Kc0
BZFJEj8rRuNiegvdnXNcbMNH7nXgnQYhZTZH8wNI35VntByOmrjc4GXgpdK144aj
1KwQ/klmJuvmJR+3FI0BauIFJvbe6kcsUlCvI4E5QApVMMUUwt3bH4aek+7MjqPS
1dB0L0a95MV4jQUaRVIAwXeQinkefIj1wYpIKnCL34Lc5EF/QVd8xNF2uL4JsLxD
ptjilmER7nuBvtgJd3uLmGHpzB8oKMVf5CK1bsWqGPUTffpUM2fz0/gMa1/aOt1l
q2OEDs6k5OScHHYSHs10ObRyD6yehNmFCIVSSgz2gu9h9D8xHshKR7OMmFxFkAlf
-----END RSA PRIVATE KEY-----

View File

@ -42,6 +42,7 @@ import java.util.function.Consumer;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
import static org.apache.lucene.util.LuceneTestCase.createTempFile;
import static org.elasticsearch.test.ESTestCase.inFipsJvm;
import static org.elasticsearch.test.ESTestCase.randomFrom;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.xpack.security.test.SecurityTestUtils.writeFile;
@ -103,7 +104,12 @@ public class SecuritySettingsSource extends ClusterDiscoveryConfiguration.Unicas
this.subfolderPrefix = scope.name();
this.sslEnabled = sslEnabled;
this.hostnameVerificationEnabled = randomBoolean();
this.usePEM = randomBoolean();
// Use PEM instead of JKS stores so that we can run these in a FIPS 140 JVM
if (inFipsJvm()) {
this.usePEM = true;
} else {
this.usePEM = randomBoolean();
}
}
Path nodePath(final int nodeOrdinal) {
@ -137,7 +143,7 @@ public class SecuritySettingsSource extends ClusterDiscoveryConfiguration.Unicas
.put("xpack.security.authc.realms.file.type", FileRealmSettings.TYPE)
.put("xpack.security.authc.realms.file.order", 0)
.put("xpack.security.authc.realms.index.type", NativeRealmSettings.TYPE)
.put("xpack.security.authc.realms.index.order", "1");
.put("xpack.security.authc.realms.index.order", "1");
addNodeSSLSettings(builder);
return builder.build();
}
@ -288,6 +294,23 @@ public class SecuritySettingsSource extends ClusterDiscoveryConfiguration.Unicas
}
}
/**
* Returns the SSL related configuration settings given the location of a key and certificate and the location
* of the PEM certificates to be trusted
*
* @param builder
* @param keyPath The path to the Private key to be used for SSL
* @param password The password with which the private key is protected
* @param certificatePath The path to the PEM formatted Certificate encapsulating the public key that corresponds
* to the Private Key specified in {@code keyPath}. Will be presented to incoming
* SSL connections.
* @param trustedCertificates A list of PEM formatted certificates that will be trusted.
*/
public static void addSSLSettingsForPEMFiles(Settings.Builder builder, String keyPath, String password,
String certificatePath, List<String> trustedCertificates) {
addSSLSettingsForPEMFiles(builder, "", keyPath, password, certificatePath, trustedCertificates, true, true, true);
}
private static void addSSLSettingsForPEMFiles(Settings.Builder builder, String prefix, String keyPath, String password,
String certificatePath, List<String> trustedCertificates, boolean sslEnabled,
boolean hostnameVerificationEnabled, boolean transportClient) {

View File

@ -60,13 +60,16 @@ public class SettingsFilterTests extends ESTestCase {
// pki filtering
configureUnfilteredSetting("xpack.security.authc.realms.pki1.type", "pki");
configureUnfilteredSetting("xpack.security.authc.realms.pki1.order", "0");
configureFilteredSetting("xpack.security.authc.realms.pki1.truststore.path",
if (inFipsJvm() == false) {
configureFilteredSetting("xpack.security.authc.realms.pki1.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks").toString());
configureFilteredSetting("xpack.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks").toString());
}
configureSecureSetting("xpack.security.authc.realms.pki1.truststore.secure_password", "truststore-testnode-only");
configureFilteredSetting("xpack.security.authc.realms.pki1.truststore.algorithm", "SunX509");
configureFilteredSetting("xpack.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks").toString());
configureFilteredSetting("xpack.ssl.cipher_suites",
Strings.arrayToCommaDelimitedString(XPackSettings.DEFAULT_CIPHERS.toArray()));
configureFilteredSetting("xpack.ssl.supported_protocols", randomFrom("TLSv1", "TLSv1.1", "TLSv1.2"));
@ -78,8 +81,10 @@ public class SettingsFilterTests extends ESTestCase {
// client profile
configureUnfilteredSetting("transport.profiles.client.port", "9500-9600");
configureFilteredSetting("transport.profiles.client.xpack.security.ssl.keystore.path",
if (inFipsJvm() == false) {
configureFilteredSetting("transport.profiles.client.xpack.security.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks").toString());
}
configureFilteredSetting("transport.profiles.client.xpack.security.ssl.cipher_suites",
Strings.arrayToCommaDelimitedString(XPackSettings.DEFAULT_CIPHERS.toArray()));
configureFilteredSetting("transport.profiles.client.xpack.security.ssl.supported_protocols",

View File

@ -100,16 +100,18 @@ public class PkiRealmBootstrapCheckTests extends ESTestCase {
public void testBootstrapCheckWithClosedSecuredSetting() throws Exception {
final boolean expectFail = randomBoolean();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.http.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.security.http.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.security.authc.realms.test_pki.type", PkiRealmSettings.TYPE)
.put("xpack.security.http.ssl.enabled", true)
.put("xpack.security.http.ssl.client_authentication", expectFail ? "none" : "optional")
.put("xpack.security.http.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
.put("xpack.security.authc.realms.test_pki.type", PkiRealmSettings.TYPE)
.put("xpack.security.http.ssl.enabled", true)
.put("xpack.security.http.ssl.client_authentication", expectFail ? "none" : "optional")
.put("xpack.security.http.ssl.key",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.put("xpack.security.http.ssl.certificate",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
Environment env = TestEnvironment.newEnvironment(settings);
final PkiRealmBootstrapCheck check = new PkiRealmBootstrapCheck(new SSLService(settings, env));

View File

@ -20,6 +20,7 @@ import org.junit.BeforeClass;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@ -92,8 +93,12 @@ public class ESNativeMigrateToolTests extends NativeRealmIntegTestCase {
Settings.Builder builder = Settings.builder()
.put("path.home", home)
.put("path.conf", conf.toString());
SecuritySettingsSource.addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
SecuritySettingsSource.addSSLSettingsForPEMFiles(
builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
"testnode",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
Settings settings = builder.build();
logger.error("--> retrieving users using URL: {}, home: {}", url, home);
@ -134,8 +139,11 @@ public class ESNativeMigrateToolTests extends NativeRealmIntegTestCase {
String url = getHttpURL();
ESNativeRealmMigrateTool.MigrateUserOrRoles muor = new ESNativeRealmMigrateTool.MigrateUserOrRoles();
Settings.Builder builder = Settings.builder().put("path.home", home);
SecuritySettingsSource.addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient");
SecuritySettingsSource.addSSLSettingsForPEMFiles(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.pem",
"testclient",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
Settings settings = builder.build();
logger.error("--> retrieving roles using URL: {}, home: {}", url, home);

View File

@ -49,20 +49,23 @@ public class CommandLineHttpClientTests extends ESTestCase {
}
public void testCommandLineHttpClientCanExecuteAndReturnCorrectResultUsingSSLSettings() throws Exception {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
MockSecureSettings secureSettings = new MockSecureSettings();
Settings settings;
if (randomBoolean()) {
// with http ssl settings
secureSettings.setString("xpack.security.http.ssl.truststore.secure_password", "testnode");
settings = Settings.builder().put("xpack.security.http.ssl.truststore.path", resource.toString())
settings = Settings.builder().put("xpack.security.http.ssl.certificate_authorities", certPath.toString())
.put("xpack.security.http.ssl.verification_mode", VerificationMode.CERTIFICATE).setSecureSettings(secureSettings)
.build();
} else {
// with global settings
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
settings = Settings.builder().put("xpack.ssl.truststore.path", resource.toString())
.put("xpack.ssl.verification_mode", VerificationMode.CERTIFICATE).setSecureSettings(secureSettings).build();
settings = Settings.builder()
.put("xpack.ssl.certificate_authorities", certPath.toString())
.put("xpack.ssl.verification_mode", VerificationMode.CERTIFICATE)
.setSecureSettings(secureSettings)
.build();
}
CommandLineHttpClient client = new CommandLineHttpClient(settings, environment);
HttpResponse httpResponse = client.execute("GET", new URL("https://localhost:" + webServer.getPort() + "/test"), "u1",
@ -74,11 +77,15 @@ public class CommandLineHttpClientTests extends ESTestCase {
}
private MockWebServer createMockWebServer() {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
Settings settings =
Settings.builder().put("xpack.ssl.keystore.path", resource.toString()).setSecureSettings(secureSettings).build();
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.key", keyPath.toString())
.put("xpack.ssl.certificate", certPath.toString())
.setSecureSettings(secureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(settings, environment);
return new MockWebServer(sslService.sslContext(), false);
}

View File

@ -34,8 +34,8 @@ public abstract class GroupsResolverTestCase extends ESTestCase {
@Before
public void setUpLdapConnection() throws Exception {
Path truststore = getDataPath(trustPath());
this.ldapConnection = LdapTestUtils.openConnection(ldapUrl(), bindDN(), bindPassword(), truststore);
Path trustPath = getDataPath(trustPath());
this.ldapConnection = LdapTestUtils.openConnection(ldapUrl(), bindDN(), bindPassword(), trustPath);
}
@After

View File

@ -67,6 +67,6 @@ public class LdapTestUtils {
sslConfiguration = sslService.getSSLConfiguration("xpack.security.authc.realms.foo.ssl");
}
return LdapUtils.privilegedConnect(() -> new LDAPConnection(sslService.sslSocketFactory(sslConfiguration), options,
ldapurl.getHost(), ldapurl.getPort(), bindDN, bindPassword));
ldapurl.getHost(), ldapurl.getPort(), bindDN, bindPassword));
}
}

View File

@ -54,7 +54,7 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase {
@Before
public void init() throws Exception {
Path keystore = getDataPath("support/ADtrust.jks");
Path certPath = getDataPath("support/smb_ca.crt");
Environment env = TestEnvironment.newEnvironment(Settings.builder().put("path.home", createTempDir()).build());
/*
* Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext.
@ -63,10 +63,9 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase {
*/
globalSettings = Settings.builder()
.put("path.home", createTempDir())
.put("xpack.ssl.truststore.path", keystore)
.setSecureSettings(newSecureSettings("xpack.ssl.truststore.secure_password", "changeit"))
.build();
.put("path.home", createTempDir())
.put("xpack.ssl.certificate_authorities", certPath)
.build();
sslService = new SSLService(globalSettings, env);
threadPool = new TestThreadPool("LdapUserSearchSessionFactoryTests");
}

View File

@ -26,22 +26,24 @@ import org.elasticsearch.xpack.core.common.socket.SocketAccess;
import org.elasticsearch.xpack.core.security.SecurityField;
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
import org.elasticsearch.xpack.core.security.authc.pki.PkiRealmSettings;
import org.elasticsearch.xpack.core.ssl.CertParsingUtils;
import org.elasticsearch.xpack.core.ssl.PemUtils;
import org.elasticsearch.xpack.core.ssl.SSLClientAuth;
import org.elasticsearch.xpack.security.LocalStateSecurity;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForStore;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForPEMFiles;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
@ -60,16 +62,16 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
SSLClientAuth sslClientAuth = randomBoolean() ? SSLClientAuth.REQUIRED : SSLClientAuth.OPTIONAL;
Settings.Builder builder = Settings.builder()
.put(super.nodeSettings())
.put("xpack.security.http.ssl.enabled", true)
.put("xpack.security.http.ssl.client_authentication", sslClientAuth)
.put("xpack.security.authc.realms.file.type", FileRealmSettings.TYPE)
.put("xpack.security.authc.realms.file.order", "0")
.put("xpack.security.authc.realms.pki1.type", PkiRealmSettings.TYPE)
.put("xpack.security.authc.realms.pki1.order", "1")
.put("xpack.security.authc.realms.pki1.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks"))
.put("xpack.security.authc.realms.pki1.files.role_mapping", getDataPath("role_mapping.yml"));
.put(super.nodeSettings())
.put("xpack.security.http.ssl.enabled", true)
.put("xpack.security.http.ssl.client_authentication", sslClientAuth)
.put("xpack.security.authc.realms.file.type", FileRealmSettings.TYPE)
.put("xpack.security.authc.realms.file.order", "0")
.put("xpack.security.authc.realms.pki1.type", PkiRealmSettings.TYPE)
.put("xpack.security.authc.realms.pki1.order", "1")
.put("xpack.security.authc.realms.pki1.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put("xpack.security.authc.realms.pki1.files.role_mapping", getDataPath("role_mapping.yml"));
SecuritySettingsSource.addSecureSettings(builder, secureSettings ->
secureSettings.setString("xpack.security.authc.realms.pki1.truststore.secure_password", "truststore-testnode-only"));
@ -90,7 +92,13 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
public void testTransportClientCanAuthenticateViaPki() {
Settings.Builder builder = Settings.builder();
addSSLSettingsForStore(builder, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
addSSLSettingsForPEMFiles(
builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
"testnode",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
Arrays.asList
("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (TransportClient client = createTransportClient(builder.build())) {
client.addTransportAddress(randomFrom(node().injector().getInstance(Transport.class).boundAddress().boundAddresses()));
IndexResponse response = client.prepareIndex("foo", "bar").setSource("pki", "auth").get();
@ -113,7 +121,11 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
}
public void testRestAuthenticationViaPki() throws Exception {
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
"testnode",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(context).build()) {
HttpPut put = new HttpPut(getNodeUrl() + "foo");
try (CloseableHttpResponse response = SocketAccess.doPrivileged(() -> client.execute(put))) {
@ -124,7 +136,10 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
}
public void testRestAuthenticationFailure() throws Exception {
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient");
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.pem",
"testclient", "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(context).build()) {
HttpPut put = new HttpPut(getNodeUrl() + "foo");
try (CloseableHttpResponse response = SocketAccess.doPrivileged(() -> client.execute(put))) {
@ -135,21 +150,13 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
}
}
private SSLContext getRestSSLContext(String keystoreResourcePath, String password) throws Exception {
private SSLContext getRestSSLContext(String keyPath, String password, String certPath, List<String> trustedCertPaths) throws Exception {
SSLContext context = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
Path store = getDataPath(keystoreResourcePath);
KeyStore ks;
try (InputStream in = Files.newInputStream(store)) {
ks = KeyStore.getInstance("jks");
ks.load(in, password.toCharArray());
}
kmf.init(ks, password.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
TrustManager tm = CertParsingUtils.trustManager(CertParsingUtils.readCertificates(trustedCertPaths.stream().map(p -> getDataPath
(p)).collect(Collectors.toList())));
KeyManager km = CertParsingUtils.keyManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), password::toCharArray), password.toCharArray());
context.init(new KeyManager[]{km}, new TrustManager[]{tm}, new SecureRandom());
return context;
}

View File

@ -128,6 +128,8 @@ public class SamlAuthenticatorTests extends SamlTestCase {
@BeforeClass
public static void init() throws Exception {
assumeFalse("Can't run in a FIPS JVM, there is no DOM XMLSignature Factory so we can't sign XML documents", inFipsJvm());
// TODO: Refactor the signing to use org.opensaml.xmlsec.signature.support.Signer so that we can run the tests
SamlUtils.initialize(Loggers.getLogger(SamlAuthenticatorTests.class));
// Initialise Apache XML security so that the signDoc methods work correctly.
Init.init();
@ -218,7 +220,7 @@ public class SamlAuthenticatorTests extends SamlTestCase {
"<saml2:Issuer xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">" +
IDP_ENTITY_ID + "</saml2:Issuer>" +
"<saml2p:Status><saml2p:StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\"/></saml2p:Status>" +
"</saml2p:Response>");
"</saml2p:Response>");
final ElasticsearchSecurityException exception = expectSamlException(() -> authenticator.authenticate(token));
assertThat(exception.getMessage(), containsString("No assertions found in SAML response"));
assertThat(exception.getCause(), nullValue());

View File

@ -296,6 +296,7 @@ public class SamlMetadataCommandTests extends SamlTestCase {
}
public void testSigningMetadataWithPfx() throws Exception {
assumeFalse("Can't run in a FIPS JVM, PKCS12 keystores are not usable", inFipsJvm());
final Path certPath = getDataPath("saml.crt");
final Path keyPath = getDataPath("saml.key");
final Path p12Path = getDataPath("saml.p12");
@ -355,6 +356,7 @@ public class SamlMetadataCommandTests extends SamlTestCase {
}
public void testSigningMetadataWithPasswordProtectedPfx() throws Exception {
assumeFalse("Can't run in a FIPS JVM, PKCS12 keystores are not usable", inFipsJvm());
final Path certPath = getDataPath("saml.crt");
final Path keyPath = getDataPath("saml.key");
final Path p12Path = getDataPath("saml_with_password.p12");
@ -393,11 +395,13 @@ public class SamlMetadataCommandTests extends SamlTestCase {
public void testErrorSigningMetadataWithWrongPassword() throws Exception {
final Path certPath = getDataPath("saml.crt");
final Path keyPath = getDataPath("saml.key");
final Path p12Path = getDataPath("saml_with_password.p12");
final Path signingKeyPath = getDataPath("saml_with_password.key");
final SamlMetadataCommand command = new SamlMetadataCommand((e) -> randomFrom(keyStore, null));
final OptionSet options = command.getParser().parse(new String[]{
"-signing-bundle", p12Path.toString(),
"-signing-key-password", "wrong_password"
"-signing-cert", certPath.toString(),
"-signing-key", signingKeyPath.toString(),
"-signing-key-password", "wrongpassword"
});
final boolean useSigningCredentials = randomBoolean();
@ -422,7 +426,7 @@ public class SamlMetadataCommandTests extends SamlTestCase {
final UserException userException = expectThrows(UserException.class, () -> command.possiblySignDescriptor(terminal, options,
descriptor, env));
assertThat(userException.getMessage(), containsString("Unable to create metadata document"));
assertThat(terminal.getOutput(), containsString("keystore password was incorrect"));
assertThat(terminal.getOutput(), containsString("Error parsing Private Key from"));
}
public void testSigningMetadataWithPem() throws Exception {
@ -473,7 +477,7 @@ public class SamlMetadataCommandTests extends SamlTestCase {
final OptionSet options = command.getParser().parse(new String[]{
"-signing-cert", certPath.toString(),
"-signing-key", signingKeyPath.toString(),
"-signing-key-password", "saml"
"-signing-key-password", "saml"
});

View File

@ -105,13 +105,17 @@ public class SamlRealmTests extends SamlTestCase {
final Path path = getDataPath("idp1.xml");
final String body = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
final MockSecureSettings mockSecureSettings = new MockSecureSettings();
mockSecureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
mockSecureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
final Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.put("path.home", createTempDir())
.setSecureSettings(mockSecureSettings)
.build();
.put("xpack.ssl.key",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.put("xpack.ssl.certificate",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put("xpack.ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put("path.home", createTempDir())
.setSecureSettings(mockSecureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(settings, TestEnvironment.newEnvironment(settings));
try (MockWebServer proxyServer = new MockWebServer(sslService.sslContext(Settings.EMPTY), false)) {
proxyServer.start();
@ -563,17 +567,21 @@ public class SamlRealmTests extends SamlTestCase {
private Settings.Builder buildSettings(String idpMetaDataPath) {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(REALM_SETTINGS_PREFIX + ".ssl.keystore.secure_password", "testnode");
secureSettings.setString(REALM_SETTINGS_PREFIX + ".ssl.secure_key_passphrase", "testnode");
return Settings.builder()
.put(REALM_SETTINGS_PREFIX + ".ssl.verification_mode", "certificate")
.put(REALM_SETTINGS_PREFIX + ".ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.put(REALM_SETTINGS_PREFIX + ".type", "saml")
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_METADATA_PATH.getKey(), idpMetaDataPath)
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_ENTITY_ID.getKey(), TEST_IDP_ENTITY_ID)
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_METADATA_HTTP_REFRESH.getKey(), METADATA_REFRESH + "ms")
.put("path.home", createTempDir())
.setSecureSettings(secureSettings);
.put(REALM_SETTINGS_PREFIX + ".ssl.verification_mode", "certificate")
.put(REALM_SETTINGS_PREFIX + ".ssl.key",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.put(REALM_SETTINGS_PREFIX + ".ssl.certificate",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put(REALM_SETTINGS_PREFIX + ".ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put(REALM_SETTINGS_PREFIX + ".type", "saml")
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_METADATA_PATH.getKey(), idpMetaDataPath)
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_ENTITY_ID.getKey(), TEST_IDP_ENTITY_ID)
.put(REALM_SETTINGS_PREFIX + "." + SamlRealmSettings.IDP_METADATA_HTTP_REFRESH.getKey(), METADATA_REFRESH + "ms")
.put("path.home", createTempDir())
.setSecureSettings(secureSettings);
}
private RealmConfig realmConfigFromRealmSettings(Settings realmSettings) {

View File

@ -43,11 +43,10 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForStore;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForPEMFiles;
import static org.elasticsearch.xpack.security.test.SecurityTestUtils.writeFile;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase {
private static int randomClientPort;
@ -66,25 +65,18 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
protected Settings nodeSettings(int nodeOrdinal) {
Settings.Builder settingsBuilder = Settings.builder();
String randomClientPortRange = randomClientPort + "-" + (randomClientPort+100);
Path store;
try {
store = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
assertThat(Files.exists(store), is(true));
} catch (Exception e) {
throw new RuntimeException(e);
}
Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
settingsBuilder.put(super.nodeSettings(nodeOrdinal))
.put("transport.profiles.client.xpack.security.ssl.truststore.path", store) // settings for client truststore
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("transport.profiles.client.xpack.security.type", "client")
.put("transport.profiles.client.port", randomClientPortRange)
// make sure this is "localhost", no matter if ipv4 or ipv6, but be consistent
.put("transport.profiles.client.bind_host", "localhost")
.put("xpack.security.audit.enabled", false)
.put(XPackSettings.WATCHER_ENABLED.getKey(), false)
.put(TestZenDiscovery.USE_MOCK_PINGS.getKey(), false);
.putList("transport.profiles.client.xpack.security.ssl.certificate_authorities",
Arrays.asList(certPath.toString())) // settings for client truststore
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("transport.profiles.client.xpack.security.type", "client")
.put("transport.profiles.client.port", randomClientPortRange)
// make sure this is "localhost", no matter if ipv4 or ipv6, but be consistent
.put("transport.profiles.client.bind_host", "localhost")
.put("xpack.security.audit.enabled", false)
.put(XPackSettings.WATCHER_ENABLED.getKey(), false)
.put(TestZenDiscovery.USE_MOCK_PINGS.getKey(), false);
if (randomBoolean()) {
settingsBuilder.put("transport.profiles.default.xpack.security.type", "node"); // this is default lets set it randomly
}
@ -120,7 +112,12 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
//.put("xpack.ml.autodetect_process", false);
Collection<Class<? extends Plugin>> mockPlugins = Arrays.asList(
LocalStateSecurity.class, TestZenDiscovery.TestPlugin.class, MockHttpTransport.TestPlugin.class);
addSSLSettingsForStore(nodeSettings, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
addSSLSettingsForPEMFiles(
nodeSettings,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
"testnode",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (Node node = new MockNode(nodeSettings.build(), mockPlugins)) {
node.start();
ensureStableCluster(cluster().size() + 1);
@ -159,7 +156,12 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
//.put("xpack.ml.autodetect_process", false);
Collection<Class<? extends Plugin>> mockPlugins = Arrays.asList(
LocalStateSecurity.class, TestZenDiscovery.TestPlugin.class, MockHttpTransport.TestPlugin.class);
addSSLSettingsForStore(nodeSettings, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
addSSLSettingsForPEMFiles(
nodeSettings,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
"testnode",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (Node node = new MockNode(nodeSettings.build(), mockPlugins)) {
node.start();
TransportService instance = node.injector().getInstance(TransportService.class);

View File

@ -21,7 +21,8 @@ import static org.hamcrest.CoreMatchers.is;
// TODO delete this test?
public class IPHostnameVerificationTests extends SecurityIntegTestCase {
Path keystore;
private Path certPath;
private Path keyPath;
@Override
protected boolean transportSSLEnabled() {
@ -46,36 +47,37 @@ public class IPHostnameVerificationTests extends SecurityIntegTestCase {
.putList("discovery.zen.ping.unicast.hosts", newUnicastAddresses);
try {
//This keystore uses a cert with a CN of "Elasticsearch Test Node" and IPv4+IPv6 ip addresses as SubjectAlternativeNames
keystore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-ip-only.jks");
assertThat(Files.exists(keystore), is(true));
//Use a cert with a CN of "Elasticsearch Test Node" and IPv4+IPv6 ip addresses as SubjectAlternativeNames
certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-ip-only.crt");
keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-ip-only.pem");
assertThat(Files.exists(certPath), is(true));
} catch (Exception e) {
throw new RuntimeException(e);
}
SecuritySettingsSource.addSecureSettings(settingsBuilder, secureSettings -> {
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode-ip-only");
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode-ip-only");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode-ip-only");
});
return settingsBuilder.put("xpack.ssl.keystore.path", keystore.toAbsolutePath()) // settings for client truststore
.put("xpack.ssl.truststore.path", keystore.toAbsolutePath()) // settings for client truststore
.put(TcpTransport.BIND_HOST.getKey(), "127.0.0.1")
.put("network.host", "127.0.0.1")
.put("xpack.ssl.client_authentication", SSLClientAuth.NONE)
.put("xpack.ssl.verification_mode", "full")
.build();
return settingsBuilder.put("xpack.ssl.key", keyPath.toAbsolutePath())
.put("xpack.ssl.certificate", certPath.toAbsolutePath())
.put("xpack.ssl.certificate_authorities", certPath.toAbsolutePath())
.put(TcpTransport.BIND_HOST.getKey(), "127.0.0.1")
.put("network.host", "127.0.0.1")
.put("xpack.ssl.client_authentication", SSLClientAuth.NONE)
.put("xpack.ssl.verification_mode", "full")
.build();
}
@Override
protected Settings transportClientSettings() {
Settings clientSettings = super.transportClientSettings();
return Settings.builder().put(clientSettings.filter(k -> k.startsWith("xpack.ssl.") == false))
.put("xpack.ssl.verification_mode", "certificate")
.put("xpack.ssl.keystore.path", keystore.toAbsolutePath())
.put("xpack.ssl.keystore.password", "testnode-ip-only")
.put("xpack.ssl.truststore.path", keystore.toAbsolutePath())
.put("xpack.ssl.truststore.password", "testnode-ip-only")
.build();
.put("xpack.ssl.verification_mode", "certificate")
.put("xpack.ssl.key", keyPath.toAbsolutePath())
.put("xpack.ssl.certificate", certPath.toAbsolutePath())
.put("xpack.ssl.key_passphrase", "testnode-ip-only")
.put("xpack.ssl.certificate_authorities", certPath)
.build();
}
public void testTransportClientConnectionWorksWithIPOnlyHostnameVerification() throws Exception {

View File

@ -39,17 +39,21 @@ public class SecurityNetty4HttpServerTransportTests extends ESTestCase {
private SSLService sslService;
private Environment env;
private Path testnodeCert;
private Path testnodeKey;
@Before
public void createSSLService() throws Exception {
Path testNodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
testnodeCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
testnodeKey = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", testNodeStore)
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.key", testnodeKey)
.put("xpack.ssl.certificate", testnodeCert)
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
env = TestEnvironment.newEnvironment(settings);
sslService = new SSLService(settings, env);
}
@ -144,15 +148,11 @@ public class SecurityNetty4HttpServerTransportTests extends ESTestCase {
}
public void testThatExceptionIsThrownWhenConfiguredWithoutSslKey() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.setSecureSettings(secureSettings)
.put(XPackSettings.HTTP_SSL_ENABLED.getKey(), true)
.put("path.home", createTempDir())
.build();
.put("xpack.ssl.certificate_authorities", testnodeCert)
.put(XPackSettings.HTTP_SSL_ENABLED.getKey(), true)
.put("path.home", createTempDir())
.build();
env = TestEnvironment.newEnvironment(settings);
sslService = new SSLService(settings, env);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
@ -163,13 +163,13 @@ public class SecurityNetty4HttpServerTransportTests extends ESTestCase {
public void testNoExceptionWhenConfiguredWithoutSslKeySSLDisabled() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
.put("xpack.ssl.key", testnodeKey)
.put("xpack.ssl.certificate", testnodeCert)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
env = TestEnvironment.newEnvironment(settings);
sslService = new SSLService(settings, env);
SecurityNetty4HttpServerTransport transport = new SecurityNetty4HttpServerTransport(settings,

View File

@ -41,15 +41,17 @@ public class SecurityNetty4ServerTransportTests extends ESTestCase {
@Before
public void createSSLService() throws Exception {
Path testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
Path testnodeCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
Path testnodeKey = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.keystore.path", testnodeStore)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.key", testnodeKey)
.put("xpack.ssl.certificate", testnodeCert)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
env = TestEnvironment.newEnvironment(settings);
sslService = new SSLService(settings, env);
}
@ -179,17 +181,18 @@ public class SecurityNetty4ServerTransportTests extends ESTestCase {
public void testTransportSSLOverridesGlobalSSL() throws Exception {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.truststore.secure_password", "truststore-testnode-only");
secureSettings.setString("xpack.security.transport.ssl.secure_key_passphrase", "testnode");
Settings.Builder builder = Settings.builder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"))
.put("xpack.security.transport.ssl.client_authentication", "none")
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks"))
.setSecureSettings(secureSettings)
.put("path.home", createTempDir());
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.key",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.put("xpack.security.transport.ssl.certificate",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.put("xpack.security.transport.ssl.client_authentication", "none")
.put("xpack.ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.setSecureSettings(secureSettings)
.put("path.home", createTempDir());
Settings settings = builder.build();
env = TestEnvironment.newEnvironment(settings);
sslService = new SSLService(settings, env);

View File

@ -19,6 +19,7 @@ import org.elasticsearch.xpack.security.LocalStateSecurity;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.containsString;
@ -35,25 +36,33 @@ public class SslHostnameVerificationTests extends SecurityIntegTestCase {
Settings settings = super.nodeSettings(nodeOrdinal);
Settings.Builder settingsBuilder = Settings.builder();
settingsBuilder.put(settings.filter(k -> k.startsWith("xpack.ssl.") == false), false);
Path keystore;
Path keyPath;
Path certPath;
Path nodeCertPath;
try {
/*
* This keystore uses a cert without any subject alternative names and a CN of "Elasticsearch Test Node No SAN"
* that will not resolve to a DNS name and will always cause hostname verification failures
*/
keystore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.jks");
assert keystore != null;
assertThat(Files.exists(keystore), is(true));
keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.pem");
certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.crt");
nodeCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
assert keyPath != null;
assert certPath != null;
assert nodeCertPath != null;
assertThat(Files.exists(certPath), is(true));
assertThat(Files.exists(nodeCertPath), is(true));
assertThat(Files.exists(keyPath), is(true));
} catch (Exception e) {
throw new RuntimeException(e);
}
SecuritySettingsSource.addSecureSettings(settingsBuilder, secureSettings -> {
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode-no-subjaltname");
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode-no-subjaltname");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode-no-subjaltname");
});
return settingsBuilder.put("xpack.ssl.keystore.path", keystore.toAbsolutePath())
.put("xpack.ssl.truststore.path", keystore.toAbsolutePath())
return settingsBuilder.put("xpack.ssl.key", keyPath.toAbsolutePath())
.put("xpack.ssl.certificate", certPath.toAbsolutePath())
.putList("xpack.ssl.certificate_authorities", Arrays.asList(certPath.toString(), nodeCertPath.toString()))
// disable hostname verification as this test uses certs without a valid SAN or DNS in the CN
.put("xpack.ssl.verification_mode", "certificate")
.build();
@ -61,22 +70,32 @@ public class SslHostnameVerificationTests extends SecurityIntegTestCase {
@Override
protected Settings transportClientSettings() {
Path keystore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.jks");
assert keystore != null;
Path keyPath;
Path certPath;
Path nodeCertPath;
try {
keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.pem");
certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.crt");
nodeCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
assert keyPath != null;
assert certPath != null;
assert nodeCertPath != null;
assertThat(Files.exists(certPath), is(true));
assertThat(Files.exists(nodeCertPath), is(true));
assertThat(Files.exists(keyPath), is(true));
} catch (Exception e) {
throw new RuntimeException(e);
}
Settings settings = super.transportClientSettings();
// remove all ssl settings
Settings.Builder builder = Settings.builder();
builder.put(settings.filter( k -> k.startsWith("xpack.ssl.") == false), false);
builder.put("xpack.ssl.verification_mode", "certificate")
.put("xpack.ssl.keystore.path", keystore.toAbsolutePath()) // settings for client keystore
.put("xpack.ssl.keystore.password", "testnode-no-subjaltname");
if (randomBoolean()) {
// randomly set the truststore, if not set the keystore should be used
builder.put("xpack.ssl.truststore.path", keystore.toAbsolutePath())
.put("xpack.ssl.truststore.password", "testnode-no-subjaltname");
}
.put("xpack.ssl.key", keyPath.toAbsolutePath())
.put("xpack.ssl.key_passphrase", "testnode-no-subjaltname")
.put("xpack.ssl.certificate", certPath.toAbsolutePath())
.putList("xpack.ssl.certificate_authorities", Arrays.asList(certPath.toString(), nodeCertPath.toString()));
return builder.build();
}

View File

@ -7,21 +7,21 @@ package org.elasticsearch.xpack.security.transport.nio;
import org.elasticsearch.nio.InboundChannelBuffer;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.ssl.CertParsingUtils;
import org.elasticsearch.xpack.core.ssl.PemUtils;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Supplier;
public class SSLDriverTests extends ESTestCase {
@ -205,19 +205,16 @@ public class SSLDriverTests extends ESTestCase {
}
private SSLContext getSSLContext() throws Exception {
String relativePath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks";
String certPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt";
String keyPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.pem";
SSLContext sslContext;
try (InputStream in = Files.newInputStream(getDataPath(relativePath))) {
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(in, "testclient".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "testclient".toCharArray());
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}
TrustManager tm = CertParsingUtils.trustManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
(certPath))));
KeyManager km = CertParsingUtils.keyManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), "testclient"::toCharArray), "testclient".toCharArray());
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(new KeyManager[] { km }, new TrustManager[] { tm }, new SecureRandom());
return sslContext;
}
private void normalClose(SSLDriver sendDriver, SSLDriver receiveDriver) throws IOException {

View File

@ -55,15 +55,17 @@ import static org.hamcrest.Matchers.instanceOf;
public class SimpleSecurityNioTransportTests extends AbstractSimpleTransportTestCase {
private SSLService createSSLService() {
Path testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
Path testnodeCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
Path testnodeKey = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.keystore.path", testnodeStore)
.setSecureSettings(secureSettings)
.put("path.home", createTempDir())
.build();
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.key", testnodeKey)
.put("xpack.ssl.certificate", testnodeCert)
.put("path.home", createTempDir())
.setSecureSettings(secureSettings)
.build();
try {
return new SSLService(settings, TestEnvironment.newEnvironment(settings));
} catch (Exception e) {

View File

@ -5,7 +5,6 @@
*/
package org.elasticsearch.xpack.security.transport.ssl;
import com.unboundid.util.ssl.TrustAllTrustManager;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
@ -77,7 +76,8 @@ public class EllipticCurveSSLTests extends SecurityIntegTestCase {
X509ExtendedKeyManager x509ExtendedKeyManager = CertParsingUtils.keyManager(certs, privateKey, new char[0]);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(new X509ExtendedKeyManager[] { x509ExtendedKeyManager },
new TrustManager[] { new TrustAllTrustManager(false) }, new SecureRandom());
new TrustManager[]{CertParsingUtils.trustManager(CertParsingUtils.readCertificates(Collections.singletonList(certPath)))},
new SecureRandom());
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
NodesInfoResponse response = client().admin().cluster().prepareNodesInfo().setTransport(true).get();
TransportAddress address = randomFrom(response.getNodes()).getTransport().getAddress().publishAddress();

View File

@ -42,12 +42,13 @@ import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForStore;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForPEMFiles;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
@ -97,6 +98,7 @@ public class SslIntegrationTests extends SecurityIntegTestCase {
// no SSL exception as this is the exception is returned when connecting
public void testThatTransportClientUsingSSLv3ProtocolIsRejected() {
assumeFalse("Can't run in a FIPS JVM as SSLv3 SSLContext not available", inFipsJvm());
try (TransportClient transportClient = new TestXPackTransportClient(Settings.builder()
.put(transportClientSettings())
.put("node.name", "programmatic_transport_client")
@ -116,7 +118,11 @@ public class SslIntegrationTests extends SecurityIntegTestCase {
public void testThatConnectionToHTTPWorks() throws Exception {
Settings.Builder builder = Settings.builder();
addSSLSettingsForStore(builder, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient");
addSSLSettingsForPEMFiles(
builder, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.pem",
"testclient",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
SSLService service = new SSLService(builder.build(), null);
CredentialsProvider provider = new BasicCredentialsProvider();
@ -135,6 +141,7 @@ public class SslIntegrationTests extends SecurityIntegTestCase {
}
public void testThatHttpUsingSSLv3IsRejected() throws Exception {
assumeFalse("Can't run in a FIPS JVM as we can't even get an instance of SSL SSL Context", inFipsJvm());
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init((KeyStore) null);

View File

@ -20,10 +20,11 @@ import org.junit.BeforeClass;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import static org.elasticsearch.test.SecuritySettingsSource.TEST_USER_NAME;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForStore;
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForPEMFiles;
import static org.elasticsearch.test.SecuritySettingsSourceField.TEST_PASSWORD;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.containsString;
@ -42,9 +43,9 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
/**
* On each node sets up the following profiles:
* <ul>
* <li>default: testnode keystore. Requires client auth</li>
* <li>client: testnode-client-profile keystore that only trusts the testclient cert. Requires client auth</li>
* <li>no_client_auth: testnode keystore. Does not require client auth</li>
* <li>default: testnode keypair. Requires client auth</li>
* <li>client: testnode-client-profile profile that only trusts the testclient cert. Requires client auth</li>
* <li>no_client_auth: testnode keypair. Does not require client auth</li>
* </ul>
*/
@Override
@ -52,26 +53,25 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
String randomClientPortRange = randomClientPort + "-" + (randomClientPort+100);
String randomNoClientAuthPortRange = randomNoClientAuthPort + "-" + (randomNoClientAuthPort+100);
Path store;
Path trustCert;
try {
store = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-client-profile.jks");
assertThat(Files.exists(store), is(true));
trustCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.crt");
assertThat(Files.exists(trustCert), is(true));
} catch (Exception e) {
throw new RuntimeException(e);
}
Settings settings = Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
// client set up here
.put("transport.profiles.client.port", randomClientPortRange)
// make sure this is "localhost", no matter if ipv4 or ipv6, but be consistent
.put("transport.profiles.client.bind_host", "localhost")
.put("transport.profiles.client.xpack.security.ssl.truststore.path", store.toAbsolutePath())
.put("transport.profiles.client.xpack.security.ssl.truststore.password", "testnode-client-profile")
.put("transport.profiles.no_client_auth.port", randomNoClientAuthPortRange)
.put("transport.profiles.no_client_auth.bind_host", "localhost")
.put("transport.profiles.no_client_auth.xpack.security.ssl.client_authentication", SSLClientAuth.NONE)
.build();
.put(super.nodeSettings(nodeOrdinal))
// client set up here
.put("transport.profiles.client.port", randomClientPortRange)
// make sure this is "localhost", no matter if ipv4 or ipv6, but be consistent
.put("transport.profiles.client.bind_host", "localhost")
.put("transport.profiles.client.xpack.security.ssl.certificate_authorities", trustCert.toAbsolutePath())
.put("transport.profiles.no_client_auth.port", randomNoClientAuthPortRange)
.put("transport.profiles.no_client_auth.bind_host", "localhost")
.put("transport.profiles.no_client_auth.xpack.security.ssl.client_authentication", SSLClientAuth.NONE)
.build();
logger.info("node {} settings:\n{}", nodeOrdinal, settings);
return settings;
}
@ -140,15 +140,18 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom keystore; this keystore testclient-client-profile.jks trusts the testnode
* Uses a transport client with a custom key pair; TransportClient only trusts the testnode
* certificate and had its own self signed certificate. This test connects to the client profile, which is only
* set to trust the testclient-client-profile certificate so the connection should always succeed
*/
public void testThatProfileTransportClientCanConnectToClientProfile() throws Exception {
Settings.Builder builder = Settings.builder();
addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.jks",
"testclient-client-profile");
addSSLSettingsForPEMFiles(
builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.pem",
"testclient-client-profile",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (TransportClient transportClient = createTransportClient(builder.build())) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(), getProfilePort("client")));
assertGreenClusterState(transportClient);
@ -156,16 +159,19 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom keystore; this keystore testclient-client-profile.jks trusts the testnode
* Uses a transport client with a custom key pair; TransportClient only trusts the testnode
* certificate and had its own self signed certificate. This test connects to the no_client_auth profile, which
* uses a truststore that does not trust the testclient-client-profile certificate but does not require client
* authentication
*/
public void testThatProfileTransportClientCanConnectToNoClientAuthProfile() throws Exception {
Settings.Builder builder = Settings.builder();
addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.jks",
"testclient-client-profile");
addSSLSettingsForPEMFiles(
builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.pem",
"testclient-client-profile",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (TransportClient transportClient = createTransportClient(builder.build())) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(),
getProfilePort("no_client_auth")));
@ -174,16 +180,19 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom keystore; this keystore testclient-client-profile.jks trusts the testnode
* Uses a transport client with a custom key pair; TransportClient only trusts the testnode
* certificate and had its own self signed certificate. This test connects to the default profile, which
* uses a truststore that does not trust the testclient-client-profile certificate and requires client authentication
* so the connection should always fail
*/
public void testThatProfileTransportClientCannotConnectToDefaultProfile() throws Exception {
Settings.Builder builder = Settings.builder();
addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.jks",
"testclient-client-profile");
addSSLSettingsForPEMFiles(
builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.pem",
"testclient-client-profile",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.crt",
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
try (TransportClient transportClient = createTransportClient(builder.build())) {
TransportAddress transportAddress = randomFrom(internalCluster().getInstance(Transport.class).boundAddress().boundAddresses());
transportClient.addTransportAddress(transportAddress);
@ -253,19 +262,17 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom truststore; this truststore truststore-testnode-only only trusts the testnode
* certificate and contains no other certification. This test connects to the no_client_auth profile, which uses
* the testnode certificate and does not require to present a certificate, so this connection should always succeed
* Uses a transport client that only trusts the testnode certificate. This test connects to the no_client_auth profile,
* which uses the testnode certificate and does not require to present a certificate, so this connection should always succeed
*/
public void testThatTransportClientWithOnlyTruststoreCanConnectToNoClientAuthProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks"))
.put("xpack.ssl.truststore.password", "truststore-testnode-only")
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(),
@ -274,21 +281,19 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom truststore; this truststore truststore-testnode-only only trusts the testnode
* certificate and contains no other certification. This test connects to the client profile, which uses
* Uses a transport client that only trusts the testnode certificate. This test connects to the client profile, which uses
* the testnode certificate and requires the client to present a certificate, so this connection will never work as
* the client has no certificate to present
*/
public void testThatTransportClientWithOnlyTruststoreCannotConnectToClientProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks"))
.put("xpack.ssl.truststore.password", "truststore-testnode-only")
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(), getProfilePort("client")));
@ -300,21 +305,19 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
}
/**
* Uses a transport client with a custom truststore; this truststore truststore-testnode-only only trusts the testnode
* certificate and contains no other certification. This test connects to the default profile, which uses
* Uses a transport client that only trusts the testnode certificate. This test connects to the default profile, which uses
* the testnode certificate and requires the client to present a certificate, so this connection will never work as
* the client has no certificate to present
*/
public void testThatTransportClientWithOnlyTruststoreCannotConnectToDefaultProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.ssl.truststore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/truststore-testnode-only.jks"))
.put("xpack.ssl.truststore.password", "truststore-testnode-only")
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.ssl.certificate_authorities",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(randomFrom(internalCluster().getInstance(Transport.class).boundAddress().boundAddresses()));
@ -332,11 +335,11 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
*/
public void testThatSSLTransportClientWithNoTruststoreCannotConnectToDefaultProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(randomFrom(internalCluster().getInstance(Transport.class).boundAddress().boundAddresses()));
@ -354,11 +357,11 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
*/
public void testThatSSLTransportClientWithNoTruststoreCannotConnectToClientProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(), getProfilePort("client")));
@ -376,11 +379,11 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
*/
public void testThatSSLTransportClientWithNoTruststoreCannotConnectToNoClientAuthProfile() throws Exception {
Settings settings = Settings.builder()
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
.put("cluster.name", internalCluster().getClusterName())
.put("xpack.ssl.client_authentication", SSLClientAuth.REQUIRED)
.put("xpack.security.transport.ssl.enabled", true)
.build();
try (TransportClient transportClient = new TestXPackTransportClient(settings,
Collections.singletonList(LocalStateSecurity.class))) {
transportClient.addTransportAddress(new TransportAddress(InetAddress.getLoopbackAddress(),

View File

@ -10,12 +10,18 @@ import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.junit.BeforeClass;
/**
* An extremely simple test that shows SSL will work with a cipher that does not perform encryption
*/
public class SslNullCipherTests extends SecurityIntegTestCase {
@BeforeClass
public static void muteInFips() {
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
}
@Override
public boolean transportSSLEnabled() {
return true;

View File

@ -22,20 +22,22 @@ import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.xpack.core.TestXPackTransportClient;
import org.elasticsearch.xpack.core.security.SecurityField;
import org.elasticsearch.xpack.core.ssl.CertParsingUtils;
import org.elasticsearch.xpack.core.ssl.PemUtils;
import org.elasticsearch.xpack.core.ssl.SSLClientAuth;
import org.elasticsearch.xpack.security.LocalStateSecurity;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertPathBuilderException;
import java.util.Arrays;
import java.util.Collections;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.containsString;
@ -74,7 +76,11 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
} catch (IOException e) {
Throwable t = ExceptionsHelper.unwrap(e, CertPathBuilderException.class);
assertThat(t, instanceOf(CertPathBuilderException.class));
assertThat(t.getMessage(), containsString("unable to find valid certification path to requested target"));
if (inFipsJvm()) {
assertThat(t.getMessage(), containsString("Unable to find certificate chain"));
} else {
assertThat(t.getMessage(), containsString("unable to find valid certification path to requested target"));
}
}
}
@ -89,24 +95,27 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
}
public void testThatTransportWorksWithoutSslClientAuth() throws IOException {
// specify an arbitrary keystore, that does not include the certs needed to connect to the transport protocol
Path store = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.jks");
// specify an arbitrary key and certificate - not the certs needed to connect to the transport protocol
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.pem");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient-client-profile.crt");
Path nodeCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
if (Files.notExists(store)) {
throw new ElasticsearchException("store path doesn't exist");
if (Files.notExists(keyPath) || Files.notExists(certPath)) {
throw new ElasticsearchException("key or certificate path doesn't exist");
}
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testclient-client-profile");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testclient-client-profile");
Settings settings = Settings.builder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.NONE)
.put("xpack.ssl.keystore.path", store)
.setSecureSettings(secureSettings)
.put("cluster.name", internalCluster().getClusterName())
.put(SecurityField.USER_SETTING.getKey(),
transportClientUsername() + ":" + new String(transportClientPassword().getChars()))
.build();
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.ssl.client_authentication", SSLClientAuth.NONE)
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.put("xpack.ssl.certificate_authorities", nodeCertPath)
.setSecureSettings(secureSettings)
.put("cluster.name", internalCluster().getClusterName())
.put(SecurityField.USER_SETTING.getKey(), transportClientUsername() + ":" + new String(transportClientPassword().getChars()))
.build();
try (TransportClient client = new TestXPackTransportClient(settings, LocalStateSecurity.class)) {
Transport transport = internalCluster().getDataNodeInstance(Transport.class);
TransportAddress transportAddress = transport.boundAddress().publishAddress();
@ -117,19 +126,19 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
}
private SSLContext getSSLContext() {
try (InputStream in =
Files.newInputStream(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks"))) {
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(in, "testclient".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "testclient".toCharArray());
try {
String certPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt";
String nodeCertPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt";
String keyPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.pem";
TrustManager tm = CertParsingUtils.trustManager(CertParsingUtils.readCertificates(Arrays.asList(getDataPath
(certPath), getDataPath(nodeCertPath))));
KeyManager km = CertParsingUtils.keyManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), "testclient"::toCharArray), "testclient".toCharArray());
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
context.init(new KeyManager[] { km }, new TrustManager[] { tm }, new SecureRandom());
return context;
} catch (Exception e) {
throw new ElasticsearchException("failed to initialize a TrustManagerFactory", e);
throw new ElasticsearchException("failed to initialize SSLContext", e);
}
}
}

View File

@ -12,9 +12,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.env.TestEnvironment;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.xpack.core.ssl.CertParsingUtils;
import org.elasticsearch.xpack.core.ssl.SSLConfiguration;
import org.elasticsearch.xpack.core.ssl.SSLService;
@ -23,16 +21,12 @@ import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import static org.hamcrest.Matchers.containsString;
@ -43,34 +37,51 @@ import static org.hamcrest.Matchers.is;
*/
public class SSLReloadIntegTests extends SecurityIntegTestCase {
private Path nodeStorePath;
private Path nodeKeyPath;
private Path nodeCertPath;
private Path clientCertPath;
private Path updateableCertPath;
@Override
public Settings nodeSettings(int nodeOrdinal) {
//Node starts with testnode.jks
if (nodeStorePath == null) {
Path origPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
Path tempDir = createTempDir();
nodeStorePath = tempDir.resolve("testnode.jks");
try {
Files.copy(origPath, nodeStorePath);
} catch (IOException e) {
throw new ElasticsearchException("failed to copy keystore");
// Nodes start trusting testnode.crt and testclient.crt
Path origKeyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem");
Path origCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
Path origClientCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt");
Path tempDir = createTempDir();
try {
if (nodeKeyPath == null) {
nodeKeyPath = tempDir.resolve("testnode.pem");
Files.copy(origKeyPath, nodeKeyPath);
}
if (nodeCertPath == null) {
nodeCertPath = tempDir.resolve("testnode.crt");
Files.copy(origCertPath, nodeCertPath);
}
if (clientCertPath == null) {
clientCertPath = tempDir.resolve("testclient.crt");
Files.copy(origClientCertPath, clientCertPath);
}
// Placeholder trusted certificate that will be updated later on
if (updateableCertPath == null) {
updateableCertPath = tempDir.resolve("updateable.crt");
Files.copy(origCertPath, updateableCertPath);
}
} catch (IOException e) {
throw new ElasticsearchException("failed to copy key or certificate", e);
}
Settings settings = super.nodeSettings(nodeOrdinal);
Settings.Builder builder = Settings.builder()
.put(settings.filter((s) -> s.startsWith("xpack.ssl.") == false));
SecuritySettingsSource.addSSLSettingsForStore(builder,
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
builder.put("resource.reload.interval.high", "1s")
.put("xpack.ssl.keystore.path", nodeStorePath);
if (builder.get("xpack.ssl.truststore.path") != null) {
builder.put("xpack.ssl.truststore.path", nodeStorePath);
}
builder.put("path.home", createTempDir())
.put("xpack.ssl.key", nodeKeyPath)
.put("xpack.ssl.key_passphrase", "testnode")
.put("xpack.ssl.certificate", nodeCertPath)
.putList("xpack.ssl.certificate_authorities", Arrays.asList(nodeCertPath.toString(), clientCertPath.toString(),
updateableCertPath.toString()))
.put("resource.reload.interval.high", "1s");
return builder.build();
}
@ -81,25 +92,27 @@ public class SSLReloadIntegTests extends SecurityIntegTestCase {
}
public void testThatSSLConfigurationReloadsOnModification() throws Exception {
Path keystorePath = createTempDir().resolve("testnode_updated.jks");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.jks"), keystorePath);
X509Certificate certificate = CertParsingUtils.readX509Certificates(Collections.singletonList(getDataPath
("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt")))[0];
Path keyPath = createTempDir().resolve("testnode_updated.pem");
Path certPath = createTempDir().resolve("testnode_updated.crt");
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.pem"), keyPath);
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), certPath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("path.home", createTempDir())
.put("xpack.ssl.keystore.path", keystorePath)
.put("xpack.ssl.truststore.path", nodeStorePath)
.setSecureSettings(secureSettings)
.build();
.put("path.home", createTempDir())
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.putList("xpack.ssl.certificate_authorities", Arrays.asList(nodeCertPath.toString(), clientCertPath.toString(),
updateableCertPath.toString()))
.setSecureSettings(secureSettings)
.build();
String node = randomFrom(internalCluster().getNodeNames());
SSLService sslService = new SSLService(settings, TestEnvironment.newEnvironment(settings));
SSLConfiguration sslConfiguration = sslService.getSSLConfiguration("xpack.ssl");
SSLSocketFactory sslSocketFactory = sslService.sslSocketFactory(sslConfiguration);
TransportAddress address = internalCluster()
.getInstance(Transport.class, node).boundAddress().publishAddress();
.getInstance(Transport.class, node).boundAddress().publishAddress();
// Fails as our nodes do not trust testnode_updated.crt
try (SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(address.getAddress(), address.getPort())) {
assertThat(socket.isConnected(), is(true));
socket.startHandshake();
@ -107,19 +120,11 @@ public class SSLReloadIntegTests extends SecurityIntegTestCase {
} catch (SSLHandshakeException | SocketException expected) {
logger.trace("expected exception", expected);
}
KeyStore nodeStore = KeyStore.getInstance("jks");
try (InputStream in = Files.newInputStream(nodeStorePath)) {
nodeStore.load(in, "testnode".toCharArray());
}
nodeStore.setCertificateEntry("newcert", certificate);
Path path = nodeStorePath.getParent().resolve("updated.jks");
try (OutputStream out = Files.newOutputStream(path)) {
nodeStore.store(out, "testnode".toCharArray());
}
// Copy testnode_updated.crt to the placeholder updateable.crt so that the nodes will start trusting it now
try {
Files.move(path, nodeStorePath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
Files.move(certPath, updateableCertPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} catch (AtomicMoveNotSupportedException e) {
Files.move(path, nodeStorePath, StandardCopyOption.REPLACE_EXISTING);
Files.move(certPath, updateableCertPath, StandardCopyOption.REPLACE_EXISTING);
}
CountDownLatch latch = new CountDownLatch(1);
assertBusy(() -> {

View File

@ -72,6 +72,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
@BeforeClass
public static void setupCertificates() throws Exception {
assumeFalse("Can't run in a FIPS JVM, custom TrustManager implementations cannot be used.", inFipsJvm());
configPath = createTempDir();
Path caCertPath = PathUtils.get(SSLTrustRestrictionsTests.class.getResource
("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/nodes/ca.crt").toURI());

View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIQWA24rVK7FopAgOHfEio/VjANBgkqhkiG9w0BAQsFADB+
MRMwEQYKCZImiZPyLGQBGRYDY29tMR0wGwYKCZImiZPyLGQBGRYNZWxhc3RpY3Nl
YXJjaDEUMBIGCgmSJomT8ixkARkWBHRlc3QxEjAQBgoJkiaJk/IsZAEZFgJhZDEe
MBwGA1UEAxMVYWQtRUxBU1RJQ1NFQVJDSEFELUNBMB4XDTE0MDgyNzE2MjI0MloX
DTI5MDgyNzE2MzI0MlowfjETMBEGCgmSJomT8ixkARkWA2NvbTEdMBsGCgmSJomT
8ixkARkWDWVsYXN0aWNzZWFyY2gxFDASBgoJkiaJk/IsZAEZFgR0ZXN0MRIwEAYK
CZImiZPyLGQBGRYCYWQxHjAcBgNVBAMTFWFkLUVMQVNUSUNTRUFSQ0hBRC1DQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNNZsDJ+lhsE/pCIkNlq6/F
xwv3PU2M+E1/SbWrLEtfbb1ATnn98DwxjpCj00wS0bt26/7zrhHKyX5LaxyS27ER
8bKpLSO4qcVWzDIQnVNk2XfBrYS/Og+6Pi/Lw/ylt/vE++kHWIJBc4O6i+pPByOM
oypM6bh71kTkpK8OTPqf+HiPp0qKhRah6XVtqTc+kOCOku2+wkELbCz8RNzF9ca6
Uu3YxLi73pNdk0wDTmg6JVaUyVRpSkjJH4BAp9SVma6Rxy6tbh4e5P+8K8lY9ptM
TBzTsDS1EhNK/92xULfQbGT814Z294pF3ARMEJ89N+aegS++kz7CqjciZ1+bA6EC
AwEAAaNRME8wCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FIEKG0KdSVNknKcMZkbTlKo7N8MjMBAGCSsGAQQBgjcVAQQDAgEAMA0GCSqGSIb3
DQEBCwUAA4IBAQBgbWBXPbEMTEsiVWzoxmTw1wJASBdPahx6CggutjGq3ASjby4p
nVCTwE4xdDEVyFGmeslSp9+23XjBuaiqVPtYw8P8hnG269J0q4cOF/VXOccRLeOw
HVDBv2a7xzgBSwc1KB50TLv07stcBmBYNu8anN6EwGksdgjb8IjRV6U3U+IvFNrI
rGifuIc/iRZD4Clhnpxw8tCsgcrcmz9CU7CN5RxKVEpZ6ou6ZjHO8l8H0t9zWrSI
PL+33iBGHNWlyU63N93XgJtxV1em1hHryLtTTtaVZJJ3R0OrLrUpG8SQ7zCUy62f
YtImFPClUMXY03yH+4DAhflueRvY/D1AKL12
-----END CERTIFICATE-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDmzCCAoOgAwIBAgIUdwsnIxjgSneHNVKT6JNCCsrQ3T0wDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMTgwMjE1MTc0ODQ2WhcNMjEwMjE0MTc0ODQ2WjA0MTIwMAYD
VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKQAP/hdsWdu3Ck/Zteosity
nmXJTCnkecBYSLtjgYh9rPDFppj9KdsZ7+5P9FvxLv/t4Yw81YI24TrHk0CnMrD/
QBaXDiPGeT9b6T/gWWVm1zQj2/567gH2UaIkIffy7q09BI9ICXSKDBRXRMLgVR19
iiJkwWb3b5TVvaQI4M8sEmJIHXei2/cfEKVR5hBprtzeKkvg6o9DXx+nDv2ZEUZ7
it5pEN5AjD5t0S3ymtlUU5lqnr8er6/Qcrua2EXxE1HyPEkpN/Cwl7tF1ICMdguf
vght5ql1/Pk43VmBMulI/6z5e+7GZ1+x79YA17gabtGJ+onB0zJxgDBj0tto7H8C
AwEAAaOBpDCBoTAdBgNVHQ4EFgQUZo2Y3maL2NoxbbkwRZiC37k6QMEwbwYDVR0j
BGgwZoAUZo2Y3maL2NoxbbkwRZiC37k6QMGhOKQ2MDQxMjAwBgNVBAMTKUVsYXN0
aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2VuZXJhdGVkIENBghR3CycjGOBKd4c1
UpPok0IKytDdPTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBf
mkc4bvUR5+We/2rRqCmP4LFnl/LxfbZ9/pUPRdcxuowuK7YfxN8i44VXGpJvLtec
izhA8gvlj6GbYB/GNlHMogqEORbrMlu2o5Cev4HE/pcWpoqtVaDJqI5Hq4763EmJ
p2dXGMmU04H4LtkcCEt3xQfLQ+QIP4Dl2yEsNd248BKSsscCGm9V3vgzFzbdgndo
zUWv9hQCaEsKNtqvnkTqDy2uFjnf+xNoXFr/bI94gvD9HlZHnIC+g0TL5jjtSfCH
gjeXhC2bBKFtlSt4ClIdZTXWievYs6YDRREfaOi4F0757A/gf+hT0fjZ+9WWnUeM
UuvUnl71CNRnJ5JlNKBA
-----END CERTIFICATE-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIUMVGoHuyNTjTFaoRmqFELz75jzDEwDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMTgwMjE1MTc0OTExWhcNMjEwMjE0MTc0OTExWjARMQ8wDQYD
VQQDEwZzYW1iYTQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtGBwa
n+7JN2vweSUsYh4zPmh8RPIE+nEVjK1lx/rADUBY7UVjfTYC+MVKKiezZe7gYCNT
7JNKazPpgVI9e3ZFKw/UxomLqRuuvn5bTh+1tMs3afY5+GGzi7oPmEbBO3ceg0Hi
rNSTDa1rfroZnRYK8uIeSZacQnAW90plITI7rBBt9jq+W9albFbDybfDgNv+yS/C
rzIsofm4rbFC3SMRYfrT6HvwDhjOmmYKZci5x7tsn0T+3tSiR44Bw5/DgiN5kX3m
/kl9qg1eoYWbCUy1dKmQlb4Nb4uNcxrIugLB3zjBkfhMZ0OHoveKh/lJASTWik9k
xQ9rEYbpsRbuXpsHAgMBAAGjgcwwgckwHQYDVR0OBBYEFJOLa7UXKtLPibgKeFh7
Kq1+rS0/MG8GA1UdIwRoMGaAFGaNmN5mi9jaMW25MEWYgt+5OkDBoTikNjA0MTIw
MAYDVQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBD
QYIUdwsnIxjgSneHNVKT6JNCCsrQ3T0wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
AAABhxAAAAAAAAAAAAAAAAAAAAABMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD
ggEBAEHqT1WHkcF8DuOgyIBx7wKcUVQ5H1qYYlJ1xgMGrKFFZLUzouLcON7oadEu
HLIJ4Z3AKD3bqWpcls5XJ9MTECGR48tou67x9cXqTV7jR3Rh0H/VGwzwhR85vbpu
o8ielOPL8XAQOfnAFESJii5sfCU4ZwLg+3evmGZdKfhU6rqQtLimgG/Gm96vOJne
y0a/TZTWrfAarithkOHHXSSAhEI5SdW5SlZAytF4AmYqFvafwxe1+NyFwfCRy0Xl
H40WgVsq+z84psU+WyORb3THX5rgB4au9nuMXOqFKAtrJSI/uApncYraaqU28rqB
gYd8XrtjhKOLw+6viqAKu8l7/cs=
-----END CERTIFICATE-----

View File

@ -44,12 +44,14 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
@Override
protected Settings nodeSettings(int nodeOrdinal) {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.pem");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.crt");
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("xpack.http.ssl.keystore.path", resource.toString())
.put("xpack.http.ssl.keystore.password", "testnode")
.build();
.put(super.nodeSettings(nodeOrdinal))
.put("xpack.http.ssl.key", keyPath)
.put("xpack.http.ssl.certificate", certPath)
.put("xpack.http.ssl.keystore.password", "testnode")
.build();
}
@Before

View File

@ -169,30 +169,31 @@ public class HttpClientTests extends ESTestCase {
}
public void testHttps() throws Exception {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/truststore-testnode-only.jks");
Path trustedCertPath = getDataPath("/org/elasticsearch/xpack/security/keystore/truststore-testnode-only.crt");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.crt");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
Settings settings;
if (randomBoolean()) {
secureSettings.setString("xpack.http.ssl.truststore.secure_password", "truststore-testnode-only");
settings = Settings.builder()
.put("xpack.http.ssl.truststore.path", resource.toString())
.setSecureSettings(secureSettings)
.build();
.put("xpack.http.ssl.certificate_authorities", trustedCertPath)
.setSecureSettings(secureSettings)
.build();
} else {
secureSettings.setString("xpack.ssl.truststore.secure_password", "truststore-testnode-only");
settings = Settings.builder()
.put("xpack.ssl.truststore.path", resource.toString())
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.certificate_authorities", trustedCertPath)
.setSecureSettings(secureSettings)
.build();
}
try (HttpClient client = new HttpClient(settings, authRegistry, new SSLService(settings, environment))) {
secureSettings = new MockSecureSettings();
// We can't use the client created above for the server since it is only a truststore
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings2 = Settings.builder()
.put("xpack.ssl.keystore.path", getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks"))
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.setSecureSettings(secureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(settings2, environment);
testSslMockWebserver(client, sslService.sslContext(), false);
@ -200,34 +201,40 @@ public class HttpClientTests extends ESTestCase {
}
public void testHttpsDisableHostnameVerification() throws Exception {
Path resource = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.jks");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.crt");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.pem");
Settings settings;
if (randomBoolean()) {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.http.ssl.truststore.secure_password", "testnode-no-subjaltname");
settings = Settings.builder()
.put("xpack.http.ssl.truststore.path", resource.toString())
.put("xpack.http.ssl.verification_mode", randomFrom(VerificationMode.NONE, VerificationMode.CERTIFICATE))
.setSecureSettings(secureSettings)
.build();
Settings.Builder builder = Settings.builder()
.put("xpack.http.ssl.certificate_authorities", certPath);
if (inFipsJvm()) {
//Can't use TrustAllConfig in FIPS mode
builder.put("xpack.http.ssl.verification_mode", VerificationMode.CERTIFICATE);
} else {
builder.put("xpack.http.ssl.verification_mode", randomFrom(VerificationMode.NONE, VerificationMode.CERTIFICATE));
}
settings = builder.build();
} else {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.truststore.secure_password", "testnode-no-subjaltname");
settings = Settings.builder()
.put("xpack.ssl.truststore.path", resource.toString())
.put("xpack.ssl.verification_mode", randomFrom(VerificationMode.NONE, VerificationMode.CERTIFICATE))
.setSecureSettings(secureSettings)
.build();
Settings.Builder builder = Settings.builder()
.put("xpack.ssl.certificate_authorities", certPath);
if (inFipsJvm()) {
//Can't use TrustAllConfig in FIPS mode
builder.put("xpack.ssl.verification_mode", VerificationMode.CERTIFICATE);
} else {
builder.put("xpack.ssl.verification_mode", randomFrom(VerificationMode.NONE, VerificationMode.CERTIFICATE));
}
settings = builder.build();
}
try (HttpClient client = new HttpClient(settings, authRegistry, new SSLService(settings, environment))) {
MockSecureSettings secureSettings = new MockSecureSettings();
// We can't use the client created above for the server since it only defines a truststore
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode-no-subjaltname");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode-no-subjaltname");
Settings settings2 = Settings.builder()
.put("xpack.ssl.keystore.path",
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.jks"))
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.setSecureSettings(secureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(settings2, environment);
testSslMockWebserver(client, sslService.sslContext(), false);
@ -235,13 +242,15 @@ public class HttpClientTests extends ESTestCase {
}
public void testHttpsClientAuth() throws Exception {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.crt");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.pem");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
secureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", resource.toString())
.setSecureSettings(secureSettings)
.build();
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.setSecureSettings(secureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(settings, environment);
try (HttpClient client = new HttpClient(settings, authRegistry, sslService)) {
@ -365,30 +374,31 @@ public class HttpClientTests extends ESTestCase {
}
public void testProxyCanHaveDifferentSchemeThanRequest() throws Exception {
Path trustedCertPath = getDataPath("/org/elasticsearch/xpack/security/keystore/truststore-testnode-only.crt");
Path certPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.crt");
Path keyPath = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.pem");
// this test fakes a proxy server that sends a response instead of forwarding it to the mock web server
// on top of that the proxy request is HTTPS but the real request is HTTP only
MockSecureSettings serverSecureSettings = new MockSecureSettings();
// We can't use the client created above for the server since it is only a truststore
serverSecureSettings.setString("xpack.ssl.keystore.secure_password", "testnode");
serverSecureSettings.setString("xpack.ssl.secure_key_passphrase", "testnode");
Settings serverSettings = Settings.builder()
.put("xpack.ssl.keystore.path", getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks"))
.setSecureSettings(serverSecureSettings)
.build();
.put("xpack.ssl.key", keyPath)
.put("xpack.ssl.certificate", certPath)
.setSecureSettings(serverSecureSettings)
.build();
TestsSSLService sslService = new TestsSSLService(serverSettings, environment);
try (MockWebServer proxyServer = new MockWebServer(sslService.sslContext(), false)) {
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
proxyServer.start();
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/truststore-testnode-only.jks");
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.http.ssl.truststore.secure_password", "truststore-testnode-only");
Settings settings = Settings.builder()
.put(HttpSettings.PROXY_HOST.getKey(), "localhost")
.put(HttpSettings.PROXY_PORT.getKey(), proxyServer.getPort())
.put(HttpSettings.PROXY_SCHEME.getKey(), "https")
.put("xpack.http.ssl.truststore.path", resource.toString())
.setSecureSettings(secureSettings)
.put("xpack.http.ssl.certificate_authorities", trustedCertPath)
.build();
HttpRequest.Builder requestBuilder = HttpRequest.builder("localhost", webServer.getPort())

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIJAJ+K5mGS3n/AMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTQxMjE2MTcwNDQ1WhcNMTgxMjE1MTcwNDQ1
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAzhpW7iwkm+Og+HP7U00nbmh0Hy9Z2Ldp5i8tJSlSQwTxCCvO
rse6jwJQN98Dk1ApaSzimZrlKOotFyPV1L3fnOzJbTp1Yq/VsYP4zJkjWtID0qUf
8Rg8bLhjKAG+ZlLuai5XZqnLkdmqvQeR61VhpXWFm0Om153tWmAiHL18ywY71gXN
EnkeFo9OW4fDqkz6h7NJziYvU6URSKErZDEixk5GIPv9K9hiIfi0KQM6xaHp0d2w
VCyFVC0OUdugz6untURzJVx4U3X1bQcv/o2BoUotWh/5h8o5eeiiv2OGZ1XlO+33
1tweYI4wFjDwnAyHHRr/rk2ZIBiBYGaSzHnuhQIDAQABo1owWDAJBgNVHRMEAjAA
MB0GA1UdDgQWBBTwGg2LF8+mzsvBBWxJKv6VXv3dMTAsBgNVHREEJTAjgglsb2Nh
bGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEB
ABP4ufLToJhcUselVxV9LPD5VGPEHGLdIFqsUEix7DMsiNpR76X6a8qNQbZpdbd6
+qPKqoaMgC7znX7qZtCqRbIXTWbudZPxFkcHdiWx3SiALMQYabeUGetClX3sCndU
SUoV8f34i8dJxfNcqhLcsh4zpgxtmwsvs5OLMTBvm0Xo2zUFUjlmrt41pBrWEuq9
nkObc/cr6Syiz3sy4pYVJO1/YwHaZgE/URqjVlari70DR3ES4YnIUnLQajKx2Q0/
gXVgzjbe68KPOUGCz6GYiWq+d4tcWdHzLv1GsaqQ1MD9P21ArfrX4DpzgPDrO6MP
9Ppq5DQGa2q4mz3kipd5RIs=
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzhpW7iwkm+Og+HP7U00nbmh0Hy9Z2Ldp5i8tJSlSQwTxCCvO
rse6jwJQN98Dk1ApaSzimZrlKOotFyPV1L3fnOzJbTp1Yq/VsYP4zJkjWtID0qUf
8Rg8bLhjKAG+ZlLuai5XZqnLkdmqvQeR61VhpXWFm0Om153tWmAiHL18ywY71gXN
EnkeFo9OW4fDqkz6h7NJziYvU6URSKErZDEixk5GIPv9K9hiIfi0KQM6xaHp0d2w
VCyFVC0OUdugz6untURzJVx4U3X1bQcv/o2BoUotWh/5h8o5eeiiv2OGZ1XlO+33
1tweYI4wFjDwnAyHHRr/rk2ZIBiBYGaSzHnuhQIDAQABAoIBAQCWgv3A6VPC1DUV
u/1qFAobwwQqUfYXIbqgcwtQ/CAq+UzcXsGNOiavkUzrwF1oEz5qpHDHJCr9+iX7
pBvgRNksTG+86NgYvbgc7vee0qbTCFPqXNQ6ySw3aWBgMwXMy/t4Z2dEffNAC+l4
KjMR3UR2BKERhhItnBNd0J6Yxnh/+jg1Uf5fVMEh1/WOGLYCJnnn5oEHNKeon6XR
dobIn2QjD/PB8ZX7UubrSXmyezU0e9h3ARoI3oPMV6f8XQSa5K/KRrk8FUkVQ4vI
5+YAMjtY/K2I8xAEoPyprD/ILAVN+3E47J0K14EfKNTajSzQFVJhaaCvs7btxScA
Sx/zRsvxAoGBAP5KMH6vamdnBlZTPT2jtrsmzjyC0Z+9lbNokzRmVribps+DFdAW
YsGCbfApcbOYmpdLSeccFTA+uT5IbQ8hwBbWn/HKm+y8EDAPklf5tL0+w7pCZ4kU
50pKk6cjSTv/CDjO+hy4KIz2H/zXivXEV+4FtFKOZ3qUVg7m+1c/u5lDAoGBAM99
L8/S9jwCkOjv+TKhmK+2/S5tVy1fdjlurTu9nI46CYa9MaOndZKY6EJ9ekBLIHUQ
h1QAsdPRHgkObuKDUHmpLr7qmoTRE7vtWC3sHK382j5CBEK00p+09wFHA03Bf40f
Jdjlzqe9F9jO6LH2RL/TECQDe7RJaTOQJrNlVtiXAoGBAOUUsNtv68t7ZJogIuuE
sPmo2+Jnd7EQeexGKVbrWvS0RHJtBRmRESaC+ceBjozczWe+y7UH946e8wLI/HbF
UOdCMpUAkbeTNIIXhR78NXbHNEx3xg4YZsTmql3HzBHgjueejnOQ8/cJQ4fkJauC
VjR3rxswbshfGagTLhpLsBVBAoGBAMBf5mN+ynRLQMXoMRlDgIhyVf2kvO5BkyCe
wBkirTOlFc4KPirpCXZ5NObo5d8UiKxhPcehuT6VpY5qBl8XtxaFyOSUKd24594W
qeox/0lFpaeRl9etRZdztoxFpgeCv1s9pN6b+2XESYboGBFgLs/XxiBN5nT6l4KK
RYeRDttTAoGAMoAreVa/i1l5YChhyskBTt+nePHGomsXC9tv7mZFLOrPQ+CLy5Xd
4PQqqYjRaJT/aP3N/q0NcauSKxYKmgnhInXpaasSVzGrM60DQLVw+SXfTiwXN0dH
V/bq2ybdSxEh2xQoyrfpiFDkCEecY0nYCL1Ff7UYY6g8P/Qj8DBiZGI=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIJAJ+K5mGS3n/AMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTQxMjE2MTcwNDQ1WhcNMTgxMjE1MTcwNDQ1
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAzhpW7iwkm+Og+HP7U00nbmh0Hy9Z2Ldp5i8tJSlSQwTxCCvO
rse6jwJQN98Dk1ApaSzimZrlKOotFyPV1L3fnOzJbTp1Yq/VsYP4zJkjWtID0qUf
8Rg8bLhjKAG+ZlLuai5XZqnLkdmqvQeR61VhpXWFm0Om153tWmAiHL18ywY71gXN
EnkeFo9OW4fDqkz6h7NJziYvU6URSKErZDEixk5GIPv9K9hiIfi0KQM6xaHp0d2w
VCyFVC0OUdugz6untURzJVx4U3X1bQcv/o2BoUotWh/5h8o5eeiiv2OGZ1XlO+33
1tweYI4wFjDwnAyHHRr/rk2ZIBiBYGaSzHnuhQIDAQABo1owWDAJBgNVHRMEAjAA
MB0GA1UdDgQWBBTwGg2LF8+mzsvBBWxJKv6VXv3dMTAsBgNVHREEJTAjgglsb2Nh
bGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEB
ABP4ufLToJhcUselVxV9LPD5VGPEHGLdIFqsUEix7DMsiNpR76X6a8qNQbZpdbd6
+qPKqoaMgC7znX7qZtCqRbIXTWbudZPxFkcHdiWx3SiALMQYabeUGetClX3sCndU
SUoV8f34i8dJxfNcqhLcsh4zpgxtmwsvs5OLMTBvm0Xo2zUFUjlmrt41pBrWEuq9
nkObc/cr6Syiz3sy4pYVJO1/YwHaZgE/URqjVlari70DR3ES4YnIUnLQajKx2Q0/
gXVgzjbe68KPOUGCz6GYiWq+d4tcWdHzLv1GsaqQ1MD9P21ArfrX4DpzgPDrO6MP
9Ppq5DQGa2q4mz3kipd5RIs=
-----END CERTIFICATE-----

View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDTTCCAjWgAwIBAgIJALL7dwEsWamvMA0GCSqGSIb3DQEBCwUAME8xDDAKBgNV
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEnMCUGA1UEAxMeRWxhc3Rp
Y3NlYXJjaCBUZXN0IE5vZGUgTm8gU0FOMB4XDTE0MTIxNjE5NTcyNloXDTE4MTIx
NTE5NTcyNlowTzEMMAoGA1UEChMDb3JnMRYwFAYDVQQLEw1lbGFzdGljc2VhcmNo
MScwJQYDVQQDEx5FbGFzdGljc2VhcmNoIFRlc3QgTm9kZSBObyBTQU4wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkIGS7A/V6TesR34ajMyNYL3tB1OjW
Raq4KtF8FfW1H6nHGrWa/qXjZWPirczy1k2n6ZL7YOCcv/YeY8xAqC9mGQxvEuqo
EaqXq2cjRdAs/7zqzRkdPPi3Jw/p/RHrDfOAzOsMnBGc0G2Hrsj//aP44vp85pek
fM3t2kNAYZWYCzXUqWAIUoxBDK4DcQdsN8H4KTMIwQEEiRtcKnL/b8QGKsyGLfLq
36ZABHZ4kY2SmcP3bWxZtbFN4hamdwoAtYe+lS0/ee8/fOTLyZ3Ey+X6EEmGO1lk
WR4XLli15k1L2HBzWGG7zwxVEC5r2h3Sx1njYh/Jq3khIdSvDbiMmM+VAgMBAAGj
LDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGm8wrYF9mJweJ1vloDw19e0PUuIMA0G
CSqGSIb3DQEBCwUAA4IBAQBbEZ73weDphNIcmvN25v6NIfjBebqgm0/2grDFwmZe
Z1DibzRoVfoQ7WeUqbPS7SHUQ+KzIN1GdfHXhW9r6mmLbtzPv90Q/8zBcNv5HNZZ
YK+T2r9hoAWEY6nB1fiOJ4udkFMYfAi6LiSxave4IPWp/WIqd0IWtPtkPl+MmG41
TfRom8TnO+o+VsjgDkY5Q1JDsNQKy1BrtxzIZyz7d1zYKTQ+HXZ4yeYJoVoc3k4y
6w9eX2zAUZ6Z3d4an6CLr6Hew9Dj2VX1vqCj1a5/VvHZVyVxyh4hg8sHYm7tZOJX
wN3B5GcKwbbFjaMVBLaMlP62OdGg7tCh61evWm+l06S0
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-192-CBC,2F36F79E75ACA7803AF1BC1B70C2360C
d4/f7dnpPW9DfhGXuGDx7r56BjQ64iNcsQdrC1CTZB363iAvBBeHaoJFaWpQOUmT
WCBdM6YmRuMi6z4sMtm8Vre3i+Mu2Jti0LTDXqH8Y6FMpptxAYoFb9hkM0OvUGDJ
ASLGTa1XKyCzZWOe2IGLtWIS8zkGv/fSXHqDJV8ddq8uLHGZXBxAye5oJUD0654T
DasIllbiTlBEYlEJ10OyIAspS47n4LWVE5ggyGdiyIgh5s3lAMPO3+yenDU3/dzj
YF2zHKnfe0Nx2lUQVJRYknQvFCx0WTGH9gNl40FovoOMHyRjEuOHD9PFNvL/TCh6
9h0jJPWu/SsIiYaIqR0pDgqWdHXHA5Ea3s2+w0YHbv7DqkGXWZdceLUdZtcXCBJk
P8QL9IWa7VE50SS6wV5uXX9tV5lHzMFsNGkwtGcR1UMU5cXYqckFXgoBqDN0fyWe
V5iEknSJ4Na+MHv75rvRat0kv6upu9i5NSpYTc5jLHdWZWsYMZ/ZMiMoLBP+KAPT
DQ3eyph/84BU3DePaQF3Rsp0ZvPxqQ361Zwc4zC5CKbHur1QX8WAY5XlBMfuBpkf
CKr5wgwF+ZpS7zsfUpMPPe9Y1E8TWnhx/DtCVLEslBpr2u/rMaxPp6ev9/Wry7N+
UFBOwodipBhlfSvLqjc511L+bXRzqXiINuW0eSKUQv0J/G0Ur894kJJ6feDYlskj
JiZjOgOyyKhB+K9AXmkfRdvWUJeweL8pgDuYSyQdQ0zoUCZALEoYK2cBWzti/wep
QPFD5oz8076aXNHKMHLsRmSFuEZb6IN0PtUNVf958EbrtABNIuoufKlKtJsEnUyK
VHIEUxExEgyECiozKnxvhr7RQ9nTQXhNdgtec6jJblYnla/+OWAfHdxtHhBjp5AX
WvLyUhmgrmLNdKd1KSzcXynBHgh0hi0HJXYx31FilwbxsdhwN1LwN/Do4T4qGkUr
InrQC3ZHRuh0yAOPrwRFEWbW5m/PzVP/xYVgFtVWP7w38ftZbaBy5xPmtswn+PH+
cIMt1Y9PaAlhLNpW/Vfn503T9M+05vu73vbU1xgu/B1kePOqE/WO0cOZl0KdaMmT
wAQBKuI7qTACH+/8g3Uir1YSChLthH+1Gs6h686EP6ZydwXq9GYXXkNmJNJJsnmU
RDjoT0F4XBKvcQdX3EeQYs3Af2yZWFDC59c1Ews2dqMK7vy2tYITbx2yn30DBDAl
xvjp2izzmAgQJEG/RqCYsUHCCEv7wz3tpsSOkFem9IHZpR2h8Rqy88GH9qYOkgwo
+fKSmIgC4RLQXsHuh7RRuyNc2FaWDgRgSxs5V4f9xOSU/ZbUftYWnwEyCwbu3RJp
CIXQFZhzU2t5l1Eh+x40rwpEJDXBEwmOIUO3x1oOqGZPPEQ674uMal5TRjvdOVGD
h665Fpo5Xu9EQwQZHYddeRl/7yw8F6LCxBLgHlngKRHHGDUHlTscLfYRqNh+x3jT
3S8dfaGzlnwdQEx32gyLAV0/nsFnzh1AknFMT8jesIYF7PLiAi67PNyNwRCc7TFp
jpKvzkDRVP72bivTmCyP5aKR0Q2oIrAw51MMinT6R2VaoR7COjoVbqYsRLwkxu+p
-----END RSA PRIVATE KEY-----

View File

@ -17,6 +17,7 @@ task openLdapFixture {
String outputDir = "${project.buildDir}/generated-resources/${project.name}"
task copyIdpTrust(type: Copy) {
from idpFixtureProject.file('src/main/resources/certs/idptrust.jks');
from idpFixtureProject.file('src/main/resources/certs/ca.crt');
into outputDir
}
if (project.rootProject.vagrantSupported) {

View File

@ -34,7 +34,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import static org.elasticsearch.test.OpenLdapTests.LDAPTRUST_PATH;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@ -45,22 +44,20 @@ public class OpenLdapUserSearchSessionFactoryTests extends ESTestCase {
private Settings globalSettings;
private ThreadPool threadPool;
private MockSecureSettings globalSecureSettings;
private static final String LDAPCACERT_PATH = "/ca.crt";
@Before
public void init() throws Exception {
Path keystore = getDataPath(LDAPTRUST_PATH);
Path caPath = getDataPath(LDAPCACERT_PATH);
/*
* Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext.
* If we re-use a SSLContext, previously connected sessions can get re-established which breaks hostname
* verification tests since a re-established connection does not perform hostname verification.
*/
globalSecureSettings = newSecureSettings("xpack.ssl.truststore.secure_password", "changeit");
globalSettings = Settings.builder()
.put("path.home", createTempDir())
.put("xpack.ssl.truststore.path", keystore)
.setSecureSettings(globalSecureSettings)
.build();
.put("path.home", createTempDir())
.put("xpack.ssl.certificate_authorities", caPath)
.build();
threadPool = new TestThreadPool("LdapUserSearchSessionFactoryTests");
}
@ -94,7 +91,6 @@ public class OpenLdapUserSearchSessionFactoryTests extends ESTestCase {
.put(globalSettings, false);
builder.put(Settings.builder().put(config.settings(), false).normalizePrefix("xpack.security.authc.realms.oldap-test.").build());
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.merge(globalSecureSettings);
if (useSecureBindPassword) {
secureSettings.setString("xpack.security.authc.realms.oldap-test.secure_bind_password", OpenLdapTests.PASSWORD);
}

View File

@ -177,4 +177,4 @@ public class SearchGroupsResolverTests extends GroupsResolverTestCase {
protected String trustPath() {
return "/idptrust.jks";
}
}
}

View File

@ -38,6 +38,7 @@ import org.elasticsearch.xpack.core.ssl.CertificateGenerateTool.CertificateInfor
import org.elasticsearch.xpack.core.ssl.CertificateGenerateTool.Name;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.BeforeClass;
import javax.security.auth.x500.X500Principal;
@ -96,6 +97,11 @@ public class CertificateGenerateToolTests extends ESTestCase {
return tempDir;
}
@BeforeClass
public static void checkFipsJvm() {
assumeFalse("Can't run in a FIPS JVM, depends on Non FIPS BouncyCastle", inFipsJvm());
}
@After
public void tearDown() throws Exception {
IOUtils.close(jimfs);

View File

@ -47,6 +47,7 @@ import org.elasticsearch.xpack.core.ssl.CertificateTool.GenerateCertificateComma
import org.elasticsearch.xpack.core.ssl.CertificateTool.Name;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.BeforeClass;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
@ -108,6 +109,11 @@ public class CertificateToolTests extends ESTestCase {
return tempDir;
}
@BeforeClass
public static void chechFipsJvm() {
assumeFalse("Can't run in a FIPS JVM, depends on Non FIPS BouncyCastle", inFipsJvm());
}
@After
public void tearDown() throws Exception {
IOUtils.close(jimfs);

View File

@ -40,7 +40,7 @@ public class ADLdapUserSearchSessionFactoryTests extends AbstractActiveDirectory
@Before
public void init() throws Exception {
Path keystore = getDataPath("support/ADtrust.jks");
Path certPath = getDataPath("support/smb_ca.crt");
Environment env = TestEnvironment.newEnvironment(Settings.builder().put("path.home", createTempDir()).build());
/*
* Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext.
@ -49,10 +49,9 @@ public class ADLdapUserSearchSessionFactoryTests extends AbstractActiveDirectory
*/
globalSettings = Settings.builder()
.put("path.home", createTempDir())
.put("xpack.ssl.truststore.path", keystore)
.setSecureSettings(newSecureSettings("xpack.ssl.truststore.secure_password", "changeit"))
.build();
.put("path.home", createTempDir())
.put("xpack.ssl.certificate_authorities", certPath)
.build();
sslService = new SSLService(globalSettings, env);
threadPool = new TestThreadPool("ADLdapUserSearchSessionFactoryTests");
}

View File

@ -23,9 +23,16 @@ import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.core.ssl.VerificationMode;
import org.junit.Before;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractActiveDirectoryTestCase extends ESTestCase {
@ -48,11 +55,25 @@ public abstract class AbstractActiveDirectoryTestCase extends ESTestCase {
protected SSLService sslService;
protected Settings globalSettings;
protected boolean useGlobalSSL;
protected List<String> certificatePaths;
@Before
public void initializeSslSocketFactory() throws Exception {
useGlobalSSL = randomBoolean();
Path truststore = getDataPath("../ldap/support/ADtrust.jks");
// We use certificates in PEM format and `ssl.certificate_authorities` instead of ssl.trustore
// so that these tests can also run in a FIPS JVM where JKS keystores can't be used.
certificatePaths = new ArrayList<>();
Files.walkFileTree(getDataPath
("../ldap/support"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileName = file.getFileName().toString();
if (fileName.endsWith(".crt")) {
certificatePaths.add(getDataPath("../ldap/support/" + fileName).toString());
}
return FileVisitResult.CONTINUE;
}
});
/*
* Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext.
* If we re-use a SSLContext, previously connected sessions can get re-established which breaks hostname
@ -60,20 +81,16 @@ public abstract class AbstractActiveDirectoryTestCase extends ESTestCase {
*/
Settings.Builder builder = Settings.builder().put("path.home", createTempDir());
if (useGlobalSSL) {
builder.put("xpack.ssl.truststore.path", truststore)
.put("xpack.ssl.truststore.password", "changeit");
builder.putList("xpack.ssl.certificate_authorities", certificatePaths);
// fake realm to load config with certificate verification mode
builder.put("xpack.security.authc.realms.bar.ssl.truststore.path", truststore);
builder.put("xpack.security.authc.realms.bar.ssl.truststore.password", "changeit");
builder.putList("xpack.security.authc.realms.bar.ssl.certificate_authorities", certificatePaths);
builder.put("xpack.security.authc.realms.bar.ssl.verification_mode", VerificationMode.CERTIFICATE);
} else {
// fake realms so ssl will get loaded
builder.put("xpack.security.authc.realms.foo.ssl.truststore.path", truststore);
builder.put("xpack.security.authc.realms.foo.ssl.truststore.password", "changeit");
builder.putList("xpack.security.authc.realms.foo.ssl.certificate_authorities", certificatePaths);
builder.put("xpack.security.authc.realms.foo.ssl.verification_mode", VerificationMode.FULL);
builder.put("xpack.security.authc.realms.bar.ssl.truststore.path", truststore);
builder.put("xpack.security.authc.realms.bar.ssl.truststore.password", "changeit");
builder.putList("xpack.security.authc.realms.bar.ssl.certificate_authorities", certificatePaths);
builder.put("xpack.security.authc.realms.bar.ssl.verification_mode", VerificationMode.CERTIFICATE);
}
globalSettings = builder.build();
@ -99,8 +116,7 @@ public abstract class AbstractActiveDirectoryTestCase extends ESTestCase {
builder.put(SessionFactorySettings.HOSTNAME_VERIFICATION_SETTING, hostnameVerification);
}
if (useGlobalSSL == false) {
builder.put("ssl.truststore.path", getDataPath("../ldap/support/ADtrust.jks"))
.put("ssl.truststore.password", "changeit");
builder.putList("ssl.certificate_authorities", certificatePaths);
}
return builder.build();
}

View File

@ -21,7 +21,6 @@ import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingRequestBuilder;
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingResponse;
import org.elasticsearch.xpack.core.security.authc.ldap.ActiveDirectorySessionFactorySettings;
@ -100,7 +99,8 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
)
};
protected static final String TESTNODE_KEYSTORE = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks";
protected static final String TESTNODE_KEY = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem";
protected static final String TESTNODE_CERT = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt";
protected static RealmConfig realmConfig;
protected static List<RoleMappingEntry> roleMappings;
protected static boolean useGlobalSSL;
@ -122,7 +122,8 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
@Override
protected Settings nodeSettings(int nodeOrdinal) {
final RealmConfig realm = AbstractAdLdapRealmTestCase.realmConfig;
Path store = getDataPath(TESTNODE_KEYSTORE);
final Path nodeCert = getDataPath(TESTNODE_CERT);
final Path nodeKey = getDataPath(TESTNODE_KEY);
Settings.Builder builder = Settings.builder();
// don't use filter since it returns a prefixed secure setting instead of mock!
Settings settingsToAdd = super.nodeSettings(nodeOrdinal);
@ -156,14 +157,15 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
}
}
}
addSslSettingsForStore(builder, store, "testnode");
builder.put(buildRealmSettings(realm, roleMappings, store));
addSslSettingsForKeyPair(builder, nodeKey, "testnode", nodeCert, getNodeTrustedCertificates());
builder.put(buildRealmSettings(realm, roleMappings, getNodeTrustedCertificates()));
return builder.build();
}
protected Settings buildRealmSettings(RealmConfig realm, List<RoleMappingEntry> roleMappingEntries, Path store) {
protected Settings buildRealmSettings(RealmConfig realm, List<RoleMappingEntry> roleMappingEntries, List<String>
certificateAuthorities) {
Settings.Builder builder = Settings.builder();
builder.put(realm.buildSettings(store, "testnode"));
builder.put(realm.buildSettings(certificateAuthorities));
configureFileRoleMappings(builder, roleMappingEntries);
return builder.build();
}
@ -216,10 +218,11 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
@Override
protected Settings transportClientSettings() {
if (useGlobalSSL) {
Path store = getDataPath(TESTNODE_KEYSTORE);
Path key = getDataPath(TESTNODE_KEY);
Path cert = getDataPath(TESTNODE_CERT);
Settings.Builder builder = Settings.builder()
.put(super.transportClientSettings().filter((s) -> s.startsWith("xpack.ssl.") == false));
addSslSettingsForStore(builder, store, "testnode");
addSslSettingsForKeyPair(builder, key, "testnode", cert, getNodeTrustedCertificates());
return builder.build();
} else {
return super.transportClientSettings();
@ -304,14 +307,35 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
return UsernamePasswordToken.basicAuthHeaderValue(username, new SecureString(password.toCharArray()));
}
private void addSslSettingsForStore(Settings.Builder builder, Path store, String password) {
SecuritySettingsSource.addSecureSettings(builder, secureSettings -> {
secureSettings.setString("xpack.ssl.keystore.secure_password", password);
secureSettings.setString("xpack.ssl.truststore.secure_password", password);
});
builder.put("xpack.ssl.keystore.path", store)
.put("xpack.ssl.verification_mode", "certificate")
.put("xpack.ssl.truststore.path", store);
private void addSslSettingsForKeyPair(Settings.Builder builder, Path key, String keyPassphrase, Path cert,
List<String> certificateAuthorities) {
builder.put("xpack.ssl.key", key)
.put("xpack.ssl.key_passphrase", keyPassphrase)
.put("xpack.ssl.verification_mode", "certificate")
.put("xpack.ssl.certificate", cert)
.putList("xpack.ssl.certificate_authorities", certificateAuthorities);
}
/**
* Collects all the certificates that are normally trusted by the node ( contained in testnode.jks )
*
* @return
*/
List<String> getNodeTrustedCertificates() {
Path testnodeCert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
Path testnodeClientProfileCert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-client-profile.crt");
Path activedirCert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/active-directory-ca.crt");
Path testclientCert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt");
Path openldapCert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/openldap.crt");
Path samba4Cert =
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/samba4.crt");
return Arrays.asList(testnodeCert.toString(), testnodeClientProfileCert.toString(), activedirCert.toString(), testclientCert
.toString(), openldapCert.toString(), samba4Cert.toString());
}
static class RoleMappingEntry {
@ -429,19 +453,19 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
this.mapGroupsAsRoles = randomBoolean();
}
public Settings buildSettings(Path store, String password) {
return buildSettings(store, password, 1);
public Settings buildSettings(List<String> certificateAuthorities) {
return buildSettings(certificateAuthorities, 1);
}
protected Settings buildSettings(Path store, String password, int order) {
protected Settings buildSettings(List<String> certificateAuthorities, int order) {
Settings.Builder builder = Settings.builder()
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".order", order)
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".hostname_verification", false)
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".unmapped_groups_as_roles", mapGroupsAsRoles)
.put(this.settings);
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".order", order)
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".hostname_verification", false)
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".unmapped_groups_as_roles", mapGroupsAsRoles)
.put(this.settings);
if (useGlobalSSL == false) {
builder.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".ssl.truststore.path", store)
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".ssl.truststore.password", password);
builder.putList(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".ssl.certificate_authorities", certificateAuthorities);
}
return builder.build();

View File

@ -132,4 +132,4 @@ public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
protected String trustPath() {
return "/org/elasticsearch/xpack/security/authc/ldap/support/ADtrust.jks";
}
}
}

View File

@ -280,10 +280,9 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
.build();
if (useGlobalSSL == false) {
settings = Settings.builder()
.put(settings)
.put("ssl.truststore.path", getDataPath("../ldap/support/ADtrust.jks"))
.put("ssl.truststore.password", "changeit")
.build();
.put(settings)
.putList("ssl.certificate_authorities", certificatePaths)
.build();
}
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
new ThreadContext(globalSettings));
@ -317,10 +316,9 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
ignoreReferralErrors);
if (useGlobalSSL == false) {
settings = Settings.builder()
.put(settings)
.put("ssl.truststore.path", getDataPath("../ldap/support/ADtrust.jks"))
.put("ssl.truststore.password", "changeit")
.build();
.put(settings)
.putList("ssl.certificate_authorities", certificatePaths)
.build();
}
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
new ThreadContext(globalSettings));
@ -346,10 +344,9 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
Settings settings = LdapTestCase.buildLdapSettings(new String[] { AD_LDAP_URL }, userTemplate, false);
if (useGlobalSSL == false) {
settings = Settings.builder()
.put(settings)
.put("ssl.truststore.path", getDataPath("../ldap/support/ADtrust.jks"))
.put("ssl.truststore.password", "changeit")
.build();
.put(settings)
.putList("ssl.certificate_authorities", certificatePaths)
.build();
}
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
new ThreadContext(globalSettings));
@ -408,8 +405,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
}
if (useGlobalSSL == false) {
builder.put("ssl.truststore.path", getDataPath("../ldap/support/ADtrust.jks"))
.put("ssl.truststore.password", "changeit");
builder.putList("ssl.certificate_authorities", certificatePaths);
}
if (useBindUser) {

View File

@ -10,7 +10,6 @@ import org.elasticsearch.common.settings.Settings;
import org.junit.BeforeClass;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -46,9 +45,9 @@ public class MultipleAdRealmIT extends AbstractAdLdapRealmTestCase {
Settings.Builder builder = Settings.builder();
builder.put(super.nodeSettings(nodeOrdinal));
Path store = getDataPath(TESTNODE_KEYSTORE);
final List<RoleMappingEntry> secondaryRoleMappings = secondaryRealmConfig.selectRoleMappings(() -> true);
final Settings secondarySettings = super.buildRealmSettings(secondaryRealmConfig, secondaryRoleMappings, store);
final Settings secondarySettings = super.buildRealmSettings(secondaryRealmConfig, secondaryRoleMappings,
getNodeTrustedCertificates());
secondarySettings.keySet().forEach(name -> {
String newName = name.replace(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL, XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + "2");
builder.copy(newName, name, secondarySettings);