Update ciphers for TLSv1.3 and JDK11 if available (#42082)
This commit updates the default ciphers and TLS protocols that are used when the runtime JDK supports them. New cipher support has been introduced in JDK 11 and 12 along with performance fixes for AES GCM. The ciphers are ordered with PFS ciphers being most preferred, then AEAD ciphers, and finally those with mainstream hardware support. When available stronger encryption is preferred for a given cipher. This is a backport of #41385 and #41808. There are known JDK bugs with TLSv1.3 that have been fixed in various versions. These are: 1. The JDK's bundled HttpsServer will endless loop under JDK11 and JDK 12.0 (Fixed in 12.0.1) based on the way the Apache HttpClient performs a close (half close). 2. In all versions of JDK 11 and 12, the HttpsServer will endless loop when certificates are not trusted or another handshake error occurs. An email has been sent to the openjdk security-dev list and #38646 is open to track this. 3. In JDK 11.0.2 and prior there is a race condition with session resumption that leads to handshake errors when multiple concurrent handshakes are going on between the same client and server. This bug does not appear when client authentication is in use. This is JDK-8213202, which was fixed in 11.0.3 and 12.0. 4. In JDK 11.0.2 and prior there is a bug where resumed TLS sessions do not retain peer certificate information. This is JDK-8212885. The way these issues are addressed is that the current java version is checked and used to determine the supported protocols for tests that provoke these issues.
This commit is contained in:
parent
fd2d4d761b
commit
dbbdcea128
|
@ -38,8 +38,10 @@ import java.net.InetAddress;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.AccessController;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
@ -106,7 +108,7 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
|
|||
}
|
||||
|
||||
private static SSLContext getSslContext() throws Exception {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
SSLContext sslContext = SSLContext.getInstance(getProtocol());
|
||||
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.
|
||||
|
@ -126,4 +128,37 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
|
|||
}
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK that supports TLSv1.3 prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK.
|
||||
*/
|
||||
private static String getProtocol() {
|
||||
String version = AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty("java.version"));
|
||||
String[] components = version.split("\\.");
|
||||
if (components.length > 0) {
|
||||
final int major = Integer.valueOf(components[0]);
|
||||
if (major < 11) {
|
||||
return "TLS";
|
||||
} if (major > 12) {
|
||||
return "TLS";
|
||||
} else if (major == 12 && components.length > 2) {
|
||||
final int minor = Integer.valueOf(components[1]);
|
||||
if (minor > 0) {
|
||||
return "TLS";
|
||||
} else {
|
||||
String patch = components[2];
|
||||
final int index = patch.indexOf("_");
|
||||
if (index > -1) {
|
||||
patch = patch.substring(0, index);
|
||||
}
|
||||
|
||||
if (Integer.valueOf(patch) >= 1) {
|
||||
return "TLS";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "TLSv1.2";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1526,13 +1526,30 @@ Controls the verification of certificates. Valid values are:
|
|||
The default value is `full`.
|
||||
|
||||
`*.ssl.cipher_suites`::
|
||||
Supported cipher suites can be found in Oracle's http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html[
|
||||
Java Cryptography Architecture documentation]. Defaults to `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256`,
|
||||
`TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`,
|
||||
`TLS_RSA_WITH_AES_128_CBC_SHA256`, `TLS_RSA_WITH_AES_128_CBC_SHA`. If the _Java Cryptography Extension (JCE) Unlimited Strength
|
||||
Jurisdiction Policy Files_ has been installed, the default value also includes `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384`,
|
||||
`TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`,
|
||||
`TLS_RSA_WITH_AES_256_CBC_SHA256`, `TLS_RSA_WITH_AES_256_CBC_SHA`.
|
||||
Supported cipher suites can be found in Oracle's
|
||||
https://docs.oracle.com/en/java/javase/11/security/oracle-providers.html#GUID-7093246A-31A3-4304-AC5F-5FB6400405E2[Java
|
||||
Cryptography Architecture documentation].
|
||||
Defaults to `TLS_AES_256_GCM_SHA384`, `TLS_AES_128_GCM_SHA256`,
|
||||
`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`,
|
||||
`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`,
|
||||
`TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256`,
|
||||
`TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256`,
|
||||
`TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`,
|
||||
`TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`,
|
||||
`TLS_RSA_WITH_AES_256_GCM_SHA384`, `TLS_RSA_WITH_AES_128_GCM_SHA256`,
|
||||
`TLS_RSA_WITH_AES_256_CBC_SHA256`, `TLS_RSA_WITH_AES_128_CBC_SHA256`,
|
||||
`TLS_RSA_WITH_AES_256_CBC_SHA`, `TLS_RSA_WITH_AES_128_CBC_SHA`.
|
||||
+
|
||||
--
|
||||
NOTE: The default cipher suites list above includes TLSv1.3 ciphers and ciphers
|
||||
that require the _Java Cryptography Extension (JCE) Unlimited Strength
|
||||
Jurisdiction Policy Files_ for 256-bit AES encryption. If TLSv1.3 is not
|
||||
available, the TLSv1.3 ciphers TLS_AES_256_GCM_SHA384`, `TLS_AES_128_GCM_SHA256`
|
||||
will not be included in the default list. If 256-bit AES is unavailable, ciphers
|
||||
with `AES_256` in their names wil not be included in the default list. Finally,
|
||||
AES GCM has known performance issues in Java versions prior to 11 and will only
|
||||
be included in the default list when using Java 11 or above.
|
||||
--
|
||||
|
||||
[float]
|
||||
[[tls-ssl-key-settings]]
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.elasticsearch.common.ssl;
|
||||
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
@ -338,30 +340,53 @@ public abstract class SslConfigurationLoader {
|
|||
}
|
||||
|
||||
private static List<String> loadDefaultCiphers() {
|
||||
final List<String> ciphers128 = Arrays.asList(
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA"
|
||||
);
|
||||
final List<String> ciphers256 = Arrays.asList(
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA"
|
||||
);
|
||||
if (has256BitAES()) {
|
||||
List<String> ciphers = new ArrayList<>(ciphers256.size() + ciphers128.size());
|
||||
ciphers.addAll(ciphers256);
|
||||
ciphers.addAll(ciphers128);
|
||||
return ciphers;
|
||||
} else {
|
||||
return ciphers128;
|
||||
final boolean has256BitAES = has256BitAES();
|
||||
final boolean useGCM = JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0;
|
||||
final boolean tlsV13Supported = DEFAULT_PROTOCOLS.contains("TLSv1.3");
|
||||
List<String> ciphers = new ArrayList<>();
|
||||
if (tlsV13Supported) { // TLSv1.3 cipher has PFS, AEAD, hardware support
|
||||
if (has256BitAES) {
|
||||
ciphers.add("TLS_AES_256_GCM_SHA384");
|
||||
}
|
||||
ciphers.add("TLS_AES_128_GCM_SHA256");
|
||||
}
|
||||
if (useGCM) { // PFS, AEAD, hardware support
|
||||
if (has256BitAES) {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
}
|
||||
}
|
||||
|
||||
// PFS, hardware support
|
||||
if (has256BitAES) {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"));
|
||||
}
|
||||
|
||||
// AEAD, hardware support
|
||||
if (useGCM) {
|
||||
if (has256BitAES) {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
} else {
|
||||
ciphers.add("TLS_RSA_WITH_AES_128_GCM_SHA256");
|
||||
}
|
||||
}
|
||||
|
||||
// hardware support
|
||||
if (has256BitAES) {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA"));
|
||||
}
|
||||
return ciphers;
|
||||
}
|
||||
|
||||
private static boolean has256BitAES() {
|
||||
|
|
|
@ -120,6 +120,7 @@ public class ReindexRestClientSslTests extends ESTestCase {
|
|||
final List<Thread> threads = new ArrayList<>();
|
||||
final Settings settings = Settings.builder()
|
||||
.put("path.home", createTempDir())
|
||||
.put("reindex.ssl.supported_protocols", "TLSv1.2")
|
||||
.build();
|
||||
final Environment environment = TestEnvironment.newEnvironment(settings);
|
||||
final ReindexSslConfig ssl = new ReindexSslConfig(settings, environment, mock(ResourceWatcherService.class));
|
||||
|
@ -134,6 +135,7 @@ public class ReindexRestClientSslTests extends ESTestCase {
|
|||
final Settings settings = Settings.builder()
|
||||
.put("path.home", createTempDir())
|
||||
.putList("reindex.ssl.certificate_authorities", ca.toString())
|
||||
.put("reindex.ssl.supported_protocols", "TLSv1.2")
|
||||
.build();
|
||||
final Environment environment = TestEnvironment.newEnvironment(settings);
|
||||
final ReindexSslConfig ssl = new ReindexSslConfig(settings, environment, mock(ResourceWatcherService.class));
|
||||
|
@ -149,6 +151,7 @@ public class ReindexRestClientSslTests extends ESTestCase {
|
|||
final Settings settings = Settings.builder()
|
||||
.put("path.home", createTempDir())
|
||||
.put("reindex.ssl.verification_mode", "NONE")
|
||||
.put("reindex.ssl.supported_protocols", "TLSv1.2")
|
||||
.build();
|
||||
final Environment environment = TestEnvironment.newEnvironment(settings);
|
||||
final ReindexSslConfig ssl = new ReindexSslConfig(settings, environment, mock(ResourceWatcherService.class));
|
||||
|
@ -169,6 +172,7 @@ public class ReindexRestClientSslTests extends ESTestCase {
|
|||
.put("reindex.ssl.certificate", cert)
|
||||
.put("reindex.ssl.key", key)
|
||||
.put("reindex.ssl.key_passphrase", "client-password")
|
||||
.put("reindex.ssl.supported_protocols", "TLSv1.2")
|
||||
.build();
|
||||
AtomicReference<Certificate[]> clientCertificates = new AtomicReference<>();
|
||||
handler = https -> {
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.sun.net.httpserver.Headers;
|
|||
import com.sun.net.httpserver.HttpsConfigurator;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.cloud.azure.classic.management.AzureComputeService;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.io.FileSystemUtils;
|
||||
|
@ -59,7 +60,9 @@ import java.net.InetSocketAddress;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -262,11 +265,30 @@ public class AzureDiscoveryClusterFormationTests extends ESIntegTestCase {
|
|||
kmf.init(ks, passphrase);
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
||||
tmf.init(ks);
|
||||
SSLContext ssl = SSLContext.getInstance("TLS");
|
||||
SSLContext ssl = SSLContext.getInstance(getProtocol());
|
||||
ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK
|
||||
*/
|
||||
private static String getProtocol() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return "TLS";
|
||||
} else if (JavaVersion.current().compareTo(JavaVersion.parse("12")) < 0) {
|
||||
return "TLSv1.2";
|
||||
} else {
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("12.0.1")) < 0) {
|
||||
return "TLSv1.2";
|
||||
}
|
||||
}
|
||||
return "TLS";
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopHttpd() throws IOException {
|
||||
for (int i = 0; i < internalCluster().size(); i++) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.elasticsearch.xpack.core;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.xpack.core.security.SecurityField;
|
||||
|
@ -118,6 +119,20 @@ public class XPackSettings {
|
|||
/** Setting for enabling or disabling sql. Defaults to true. */
|
||||
public static final Setting<Boolean> SQL_ENABLED = Setting.boolSetting("xpack.sql.enabled", true, Setting.Property.NodeScope);
|
||||
|
||||
public static final List<String> DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
|
||||
static {
|
||||
boolean supportsTLSv13 = false;
|
||||
try {
|
||||
SSLContext.getInstance("TLSv1.3");
|
||||
supportsTLSv13 = true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
LogManager.getLogger(XPackSettings.class).debug("TLSv1.3 is not supported", e);
|
||||
}
|
||||
DEFAULT_SUPPORTED_PROTOCOLS = supportsTLSv13 ?
|
||||
Arrays.asList("TLSv1.3", "TLSv1.2", "TLSv1.1") : Arrays.asList("TLSv1.2", "TLSv1.1");
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL settings. These are the settings that are specifically registered for SSL. Many are private as we do not explicitly use them
|
||||
* but instead parse based on a prefix (eg *.ssl.*)
|
||||
|
@ -125,24 +140,58 @@ public class XPackSettings {
|
|||
public static final List<String> DEFAULT_CIPHERS;
|
||||
|
||||
static {
|
||||
List<String> ciphers = Arrays.asList("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA");
|
||||
List<String> ciphers = new ArrayList<>();
|
||||
final boolean useGCM = JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0;
|
||||
final boolean tlsV13Supported = DEFAULT_SUPPORTED_PROTOCOLS.contains("TLSv1.3");
|
||||
try {
|
||||
final boolean use256Bit = Cipher.getMaxAllowedKeyLength("AES") > 128;
|
||||
if (tlsV13Supported) { // TLSv1.3 cipher has PFS, AEAD, hardware support
|
||||
if (use256Bit) {
|
||||
ciphers.add("TLS_AES_256_GCM_SHA384");
|
||||
}
|
||||
ciphers.add("TLS_AES_128_GCM_SHA256");
|
||||
}
|
||||
if (useGCM) { // PFS, AEAD, hardware support
|
||||
if (use256Bit) {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
}
|
||||
}
|
||||
|
||||
// PFS, hardware support
|
||||
if (use256Bit) {
|
||||
List<String> strongerCiphers = new ArrayList<>(ciphers.size() * 2);
|
||||
strongerCiphers.addAll(Arrays.asList("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_256_CBC_SHA"));
|
||||
strongerCiphers.addAll(ciphers);
|
||||
ciphers = strongerCiphers;
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"));
|
||||
}
|
||||
|
||||
// AEAD, hardware support
|
||||
if (useGCM) {
|
||||
if (use256Bit) {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"));
|
||||
} else {
|
||||
ciphers.add("TLS_RSA_WITH_AES_128_GCM_SHA256");
|
||||
}
|
||||
}
|
||||
|
||||
// hardware support
|
||||
if (use256Bit) {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA"));
|
||||
} else {
|
||||
ciphers.addAll(Arrays.asList("TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA"));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// ignore it here - there will be issues elsewhere and its not nice to throw in a static initializer
|
||||
}
|
||||
|
||||
DEFAULT_CIPHERS = ciphers;
|
||||
DEFAULT_CIPHERS = Collections.unmodifiableList(ciphers);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -164,20 +213,6 @@ public class XPackSettings {
|
|||
}
|
||||
}, Setting.Property.NodeScope);
|
||||
|
||||
public static final List<String> DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
|
||||
static {
|
||||
boolean supportsTLSv13 = false;
|
||||
try {
|
||||
SSLContext.getInstance("TLSv1.3");
|
||||
supportsTLSv13 = true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
LogManager.getLogger(XPackSettings.class).debug("TLSv1.3 is not supported", e);
|
||||
}
|
||||
DEFAULT_SUPPORTED_PROTOCOLS = supportsTLSv13 ?
|
||||
Arrays.asList("TLSv1.3", "TLSv1.2", "TLSv1.1") : Arrays.asList("TLSv1.2", "TLSv1.1");
|
||||
}
|
||||
|
||||
public static final SSLClientAuth CLIENT_AUTH_DEFAULT = SSLClientAuth.REQUIRED;
|
||||
public static final SSLClientAuth HTTP_CLIENT_AUTH_DEFAULT = SSLClientAuth.NONE;
|
||||
public static final VerificationMode VERIFICATION_MODE_DEFAULT = VerificationMode.FULL;
|
||||
|
|
Binary file not shown.
|
@ -5,9 +5,11 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.monitoring.exporter.http;
|
||||
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import org.elasticsearch.action.ActionFuture;
|
||||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -15,6 +17,7 @@ import org.elasticsearch.env.TestEnvironment;
|
|||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.ESIntegTestCase.Scope;
|
||||
import org.elasticsearch.test.http.MockWebServer;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.ssl.TestsSSLService;
|
||||
import org.elasticsearch.xpack.core.ssl.VerificationMode;
|
||||
import org.elasticsearch.xpack.monitoring.exporter.Exporter;
|
||||
|
@ -28,6 +31,10 @@ import javax.net.ssl.SSLContext;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
@ -98,6 +105,7 @@ public class HttpExporterSslIT extends MonitoringIntegTestCase {
|
|||
.put("xpack.transport.security.ssl.certificate", cert)
|
||||
.put("xpack.transport.security.ssl.key", key)
|
||||
.put("xpack.transport.security.ssl.key_passphrase", "testnode")
|
||||
.putList("xpack.transport.security.ssl.supported_protocols", getProtocols())
|
||||
.put(globalSettings)
|
||||
.build();
|
||||
|
||||
|
@ -185,4 +193,23 @@ public class HttpExporterSslIT extends MonitoringIntegTestCase {
|
|||
updateSettings.transientSettings(builder.build());
|
||||
client().admin().cluster().updateSettings(updateSettings).actionGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
} else if (JavaVersion.current().compareTo(JavaVersion.parse("12")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
} else {
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("12.0.1")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,7 +438,7 @@ public class SSLDriver implements AutoCloseable {
|
|||
SSLEngineResult result = unwrap(encryptedBuffer, applicationBuffer);
|
||||
boolean renegotiationRequested = result.getStatus() != SSLEngineResult.Status.CLOSED
|
||||
&& maybeRenegotiation(result.getHandshakeStatus());
|
||||
continueUnwrap = result.bytesProduced() > 0 && renegotiationRequested == false;
|
||||
continueUnwrap = result.bytesConsumed() > 0 && renegotiationRequested == false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,8 @@ public class SecuritySettingsSource extends NodeConfigurationSource {
|
|||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/active-directory-ca.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/openldap.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"),
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"),
|
||||
hostnameVerificationEnabled, false);
|
||||
}
|
||||
|
||||
|
@ -244,7 +245,8 @@ public class SecuritySettingsSource extends NodeConfigurationSource {
|
|||
"/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",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"),
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"),
|
||||
hostnameVerificationEnabled, true);
|
||||
} else {
|
||||
addSSLSettingsForStore(builder, prefix, "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks",
|
||||
|
|
|
@ -66,8 +66,9 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
|
|||
.put("xpack.security.http.ssl.client_authentication", sslClientAuth)
|
||||
.put("xpack.security.authc.realms.file.file.order", "0")
|
||||
.put("xpack.security.authc.realms.pki.pki1.order", "1")
|
||||
.put("xpack.security.authc.realms.pki.pki1.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.putList("xpack.security.authc.realms.pki.pki1.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt").toString(),
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt").toString())
|
||||
.put("xpack.security.authc.realms.pki.pki1.files.role_mapping", getDataPath("role_mapping.yml"));
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -91,8 +92,8 @@ public class PkiAuthenticationTests extends SecuritySingleNodeTestCase {
|
|||
"/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"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.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();
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.security.authc.saml;
|
||||
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import org.apache.logging.log4j.message.ParameterizedMessage;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.PlainActionFuture;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -19,6 +21,7 @@ import org.elasticsearch.license.XPackLicenseState;
|
|||
import org.elasticsearch.test.http.MockResponse;
|
||||
import org.elasticsearch.test.http.MockWebServer;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
|
||||
import org.elasticsearch.xpack.core.security.authc.Realm;
|
||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||
|
@ -52,8 +55,10 @@ import java.io.OutputStream;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.Certificate;
|
||||
|
@ -131,6 +136,7 @@ public class SamlRealmTests extends SamlTestCase {
|
|||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.put("xpack.security.http.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.putList("xpack.security.http.ssl.supported_protocols", getProtocols())
|
||||
.put("path.home", createTempDir())
|
||||
.setSecureSettings(mockSecureSettings)
|
||||
.build();
|
||||
|
@ -715,4 +721,23 @@ public class SamlRealmTests extends SamlTestCase {
|
|||
assertEquals(SAMLConstants.SAML2_POST_BINDING_URI, ssoServices.get(0).getBinding());
|
||||
assertEquals(SAMLConstants.SAML2_REDIRECT_BINDING_URI, ssoServices.get(1).getBinding());
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
} else if (JavaVersion.current().compareTo(JavaVersion.parse("12")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
} else {
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("12.0.1")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,7 +155,9 @@ public abstract class AbstractSimpleSecurityTransportTestCase extends AbstractSi
|
|||
|
||||
@SuppressForbidden(reason = "Need to open socket connection")
|
||||
public void testRenegotiation() throws Exception {
|
||||
SSLService sslService = createSSLService();
|
||||
// force TLSv1.2 since renegotiation is not supported by 1.3
|
||||
SSLService sslService =
|
||||
createSSLService(Settings.builder().put("xpack.security.transport.ssl.supported_protocols", "TLSv1.2").build());
|
||||
final SSLConfiguration sslConfiguration = sslService.getSSLConfiguration("xpack.security.transport.ssl");
|
||||
SocketFactory factory = sslService.sslSocketFactory(sslConfiguration);
|
||||
try (SSLSocket socket = (SSLSocket) factory.createSocket()) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.elasticsearch.node.NodeValidationException;
|
|||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.MockHttpTransport;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.elasticsearch.test.SecuritySettingsSourceField;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.ConnectionProfile;
|
||||
|
@ -80,8 +79,6 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
|
|||
settingsBuilder.put("transport.profiles.default.xpack.security.type", "node"); // this is default lets set it randomly
|
||||
}
|
||||
|
||||
SecuritySettingsSource.addSecureSettings(settingsBuilder, secureSettings ->
|
||||
secureSettings.setString("transport.profiles.client.xpack.security.ssl.keystore.secure_password", "testnode"));
|
||||
return settingsBuilder.build();
|
||||
}
|
||||
|
||||
|
@ -112,7 +109,8 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
|
|||
"/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"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"));
|
||||
try (Node node = new MockNode(nodeSettings.build(), mockPlugins)) {
|
||||
node.start();
|
||||
ensureStableCluster(cluster().size() + 1);
|
||||
|
@ -151,7 +149,8 @@ public class ServerTransportFilterIntegrationTests extends SecurityIntegTestCase
|
|||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem",
|
||||
"testnode",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
Collections.singletonList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"));
|
||||
try (Node node = new MockNode(nodeSettings.build(), mockPlugins)) {
|
||||
node.start();
|
||||
TransportService instance = node.injector().getInstance(TransportService.class);
|
||||
|
|
|
@ -33,7 +33,9 @@ import java.util.Collections;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class EllipticCurveSSLTests extends SecurityIntegTestCase {
|
||||
|
||||
|
@ -106,7 +108,8 @@ public class EllipticCurveSSLTests extends SecurityIntegTestCase {
|
|||
Certificate[] peerChain = session.getPeerCertificates();
|
||||
assertEquals(1, peerChain.length);
|
||||
assertEquals(certs[0], peerChain[0]);
|
||||
assertThat(session.getCipherSuite(), containsString("ECDSA"));
|
||||
assertThat(session.getCipherSuite(),
|
||||
anyOf(containsString("ECDSA"), equalTo("TLS_AES_256_GCM_SHA384"), equalTo("TLS_AES_128_GCM_SHA256")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.security.transport.ssl;
|
||||
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.client.transport.NoNodeAvailableException;
|
||||
import org.elasticsearch.client.transport.TransportClient;
|
||||
import org.elasticsearch.common.network.NetworkAddress;
|
||||
|
@ -13,6 +14,7 @@ import org.elasticsearch.common.transport.TransportAddress;
|
|||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
import org.elasticsearch.xpack.core.TestXPackTransportClient;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.security.SecurityField;
|
||||
import org.elasticsearch.xpack.core.ssl.SSLClientAuth;
|
||||
import org.elasticsearch.xpack.security.LocalStateSecurity;
|
||||
|
@ -21,8 +23,11 @@ import org.junit.BeforeClass;
|
|||
import java.net.InetAddress;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.test.SecuritySettingsSource.TEST_USER_NAME;
|
||||
import static org.elasticsearch.test.SecuritySettingsSource.addSSLSettingsForNodePEMFiles;
|
||||
|
@ -116,6 +121,7 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
try(TransportClient transportClient = new TestXPackTransportClient(Settings.builder()
|
||||
.put(transportClientSettings())
|
||||
.put("xpack.security.transport.ssl.enabled", true)
|
||||
.putList("xpack.security.transport.ssl.supported_protocols", getProtocols())
|
||||
.put("node.name", "programmatic_transport_client")
|
||||
.put("cluster.name", internalCluster().getClusterName())
|
||||
.build(), LocalStateSecurity.class)) {
|
||||
|
@ -154,7 +160,8 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
"/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"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"));
|
||||
try (TransportClient transportClient = createTransportClient(builder.build())) {
|
||||
transportClient.addTransportAddress(new TransportAddress(localAddress, getProfilePort("client")));
|
||||
assertGreenClusterState(transportClient);
|
||||
|
@ -174,7 +181,9 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
"/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"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"));
|
||||
builder.putList("xpack.security.transport.ssl.supported_protocols", getProtocols());
|
||||
try (TransportClient transportClient = createTransportClient(builder.build())) {
|
||||
transportClient.addTransportAddress(new TransportAddress(localAddress,
|
||||
getProfilePort("no_client_auth")));
|
||||
|
@ -195,7 +204,8 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
"/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"));
|
||||
Arrays.asList("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt",
|
||||
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt"));
|
||||
try (TransportClient transportClient = createTransportClient(builder.build())) {
|
||||
TransportAddress transportAddress = randomFrom(internalCluster().getInstance(Transport.class).boundAddress().boundAddresses());
|
||||
transportClient.addTransportAddress(transportAddress);
|
||||
|
@ -273,8 +283,10 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
.put(SecurityField.USER_SETTING.getKey(), TEST_USER_NAME + ":" + TEST_PASSWORD)
|
||||
.put("cluster.name", internalCluster().getClusterName())
|
||||
.put("xpack.security.transport.ssl.enabled", true)
|
||||
.put("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.putList("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt").toString(),
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt").toString())
|
||||
.putList("xpack.security.transport.ssl.supported_protocols", getProtocols())
|
||||
.build();
|
||||
try (TransportClient transportClient = new TestXPackTransportClient(settings,
|
||||
Collections.singletonList(LocalStateSecurity.class))) {
|
||||
|
@ -294,8 +306,10 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
.put("cluster.name", internalCluster().getClusterName())
|
||||
.put("xpack.security.transport.ssl.enabled", true)
|
||||
.put("xpack.security.transport.ssl.client_authentication", SSLClientAuth.REQUIRED)
|
||||
.put("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.putList("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt").toString(),
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt").toString())
|
||||
.putList("xpack.security.transport.ssl.supported_protocols", getProtocols())
|
||||
.build();
|
||||
try (TransportClient transportClient = new TestXPackTransportClient(settings,
|
||||
Collections.singletonList(LocalStateSecurity.class))) {
|
||||
|
@ -318,8 +332,10 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
.put("cluster.name", internalCluster().getClusterName())
|
||||
.put("xpack.security.transport.ssl.enabled", true)
|
||||
.put("xpack.security.transport.ssl.client_authentication", SSLClientAuth.REQUIRED)
|
||||
.put("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
|
||||
.putList("xpack.security.transport.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt").toString(),
|
||||
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt").toString())
|
||||
.putList("xpack.security.transport.ssl.supported_protocols", getProtocols())
|
||||
.build();
|
||||
try (TransportClient transportClient = new TestXPackTransportClient(settings,
|
||||
Collections.singletonList(LocalStateSecurity.class))) {
|
||||
|
@ -409,4 +425,21 @@ public class SslMultiPortTests extends SecurityIntegTestCase {
|
|||
throw new IllegalStateException("failed to find transport address equal to [" + NetworkAddress.format(localAddress) + "] " +
|
||||
" in the following bound addresses " + Arrays.toString(transportAddresses));
|
||||
}
|
||||
|
||||
/**
|
||||
* TLSv1.3 when running in a JDK prior to 11.0.3 has a race condition when multiple simultaneous connections are established. See
|
||||
* JDK-8213202. This issue is not triggered when using client authentication, which we do by default for transport connections.
|
||||
* However if client authentication is turned off and TLSv1.3 is used on the affected JVMs then we will hit this issue.
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("11.0.3")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.apache.http.ssl.SSLContexts;
|
|||
import org.apache.http.util.EntityUtils;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
@ -23,6 +24,7 @@ import org.elasticsearch.common.transport.TransportAddress;
|
|||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
import org.elasticsearch.xpack.core.TestXPackTransportClient;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.security.SecurityField;
|
||||
import org.elasticsearch.xpack.core.ssl.CertParsingUtils;
|
||||
import org.elasticsearch.xpack.core.ssl.PemUtils;
|
||||
|
@ -38,11 +40,14 @@ import java.io.InputStream;
|
|||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertPathBuilderException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -101,7 +106,7 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void testThatHttpFailsWithoutSslClientAuth() throws IOException {
|
||||
public void testThatHttpFailsWithoutSslClientAuth() {
|
||||
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(SSLContexts.createDefault(), NoopHostnameVerifier.INSTANCE);
|
||||
try (RestClient restClient = createRestClient(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy), "https")) {
|
||||
restClient.performRequest(new Request("GET", "/"));
|
||||
|
@ -130,11 +135,12 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testThatTransportWorksWithoutSslClientAuth() throws IOException {
|
||||
public void testThatTransportWorksWithoutSslClientAuth() {
|
||||
// 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");
|
||||
Path nodeECCertPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.crt");
|
||||
|
||||
if (Files.notExists(keyPath) || Files.notExists(certPath)) {
|
||||
throw new ElasticsearchException("key or certificate path doesn't exist");
|
||||
|
@ -147,7 +153,8 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
.put("xpack.security.transport.ssl.client_authentication", SSLClientAuth.NONE)
|
||||
.put("xpack.security.transport.ssl.key", keyPath)
|
||||
.put("xpack.security.transport.ssl.certificate", certPath)
|
||||
.put("xpack.security.transport.ssl.certificate_authorities", nodeCertPath)
|
||||
.putList("xpack.security.transport.ssl.supported_protocols", getProtocols())
|
||||
.putList("xpack.security.transport.ssl.certificate_authorities", nodeCertPath.toString(), nodeECCertPath.toString())
|
||||
.setSecureSettings(secureSettings)
|
||||
.put("cluster.name", internalCluster().getClusterName())
|
||||
.put(SecurityField.USER_SETTING.getKey(), transportClientUsername() + ":" + new String(transportClientPassword().getChars()))
|
||||
|
@ -165,12 +172,19 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
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 nodeEcCertPath = "/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_ec.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))));
|
||||
(certPath), getDataPath(nodeCertPath), getDataPath(nodeEcCertPath))));
|
||||
KeyManager km = CertParsingUtils.keyManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
|
||||
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), "testclient"::toCharArray), "testclient".toCharArray());
|
||||
SSLContext context = SSLContext.getInstance("TLSv1.2");
|
||||
|
||||
final SSLContext context;
|
||||
if (XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS.contains("TLSv1.3")) {
|
||||
context = SSLContext.getInstance(randomBoolean() ? "TLSv1.3" : "TLSv1.2");
|
||||
} else {
|
||||
context = SSLContext.getInstance("TLSv1.2");
|
||||
}
|
||||
context.init(new KeyManager[] { km }, new TrustManager[] { tm }, new SecureRandom());
|
||||
return context;
|
||||
} catch (Exception e) {
|
||||
|
@ -188,4 +202,21 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* TLSv1.3 when running in a JDK prior to 11.0.3 has a race condition when multiple simultaneous connections are established. See
|
||||
* JDK-8213202. This issue is not triggered when using client authentication, which we do by default for transport connections.
|
||||
* However if client authentication is turned off and TLSv1.3 is used on the affected JVMs then we will hit this issue.
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("11.0.3")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@ public class SSLReloadIntegTests extends SecurityIntegTestCase {
|
|||
try (SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(address.getAddress(), address.getPort())) {
|
||||
assertThat(socket.isConnected(), is(true));
|
||||
socket.startHandshake();
|
||||
if (socket.getSession().getProtocol().equals("TLSv1.3")) {
|
||||
// blocking read for TLSv1.3 to see if the other side closed the connection
|
||||
socket.getInputStream().read();
|
||||
}
|
||||
fail("handshake should not have been successful!");
|
||||
} catch (SSLException | SocketException expected) {
|
||||
logger.trace("expected exception", expected);
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.net.ssl.SSLSocket;
|
|||
import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.file.AtomicMoveNotSupportedException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -165,7 +166,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
public void testCertificateWithTrustedNameIsAccepted() throws Exception {
|
||||
writeRestrictions("*.trusted");
|
||||
try {
|
||||
tryConnect(trustedCert);
|
||||
tryConnect(trustedCert, false);
|
||||
} catch (SSLException | SocketException ex) {
|
||||
logger.warn(new ParameterizedMessage("unexpected handshake failure with certificate [{}] [{}]",
|
||||
trustedCert.certificate.getSubjectDN(), trustedCert.certificate.getSubjectAlternativeNames()), ex);
|
||||
|
@ -176,7 +177,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
public void testCertificateWithUntrustedNameFails() throws Exception {
|
||||
writeRestrictions("*.trusted");
|
||||
try {
|
||||
tryConnect(untrustedCert);
|
||||
tryConnect(untrustedCert, true);
|
||||
fail("handshake should have failed, but was successful");
|
||||
} catch (SSLException | SocketException ex) {
|
||||
// expected
|
||||
|
@ -187,7 +188,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
writeRestrictions("*");
|
||||
assertBusy(() -> {
|
||||
try {
|
||||
tryConnect(untrustedCert);
|
||||
tryConnect(untrustedCert, false);
|
||||
} catch (SSLException | SocketException ex) {
|
||||
fail("handshake should have been successful, but failed with " + ex);
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
writeRestrictions("*.trusted");
|
||||
assertBusy(() -> {
|
||||
try {
|
||||
tryConnect(untrustedCert);
|
||||
tryConnect(untrustedCert, true);
|
||||
fail("handshake should have failed, but was successful");
|
||||
} catch (SSLException | SocketException ex) {
|
||||
// expected
|
||||
|
@ -221,7 +222,7 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private void tryConnect(CertificateInfo certificate) throws Exception {
|
||||
private void tryConnect(CertificateInfo certificate, boolean shouldFail) throws Exception {
|
||||
Settings settings = Settings.builder()
|
||||
.put("path.home", createTempDir())
|
||||
.put("xpack.security.transport.ssl.key", certificate.getKeyPath())
|
||||
|
@ -239,6 +240,16 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
|
|||
assertThat(socket.isConnected(), is(true));
|
||||
// The test simply relies on this (synchronously) connecting (or not), so we don't need a handshake handler
|
||||
socket.startHandshake();
|
||||
|
||||
// blocking read for TLSv1.3 to see if the other side closed the connection
|
||||
if (socket.getSession().getProtocol().equals("TLSv1.3")) {
|
||||
if (shouldFail) {
|
||||
socket.getInputStream().read();
|
||||
} else {
|
||||
socket.setSoTimeout(1000); // 1 second timeout
|
||||
expectThrows(SocketTimeoutException.class, () -> socket.getInputStream().read());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,3 +34,116 @@ keytool -importkeystore -destkeystore <NAME>.jks -srckeystore <NAME>.p12 -srcsto
|
|||
|
||||
The keystore is now created and has the private/public key pair. You can import additional trusted certificates using
|
||||
`keytool -importcert`. When doing so make sure to specify an alias so that others can recreate the keystore if necessary.
|
||||
|
||||
=== Changes and additions for removing Bouncy Castle Dependency
|
||||
|
||||
`testnode-unprotected.pem` is simply the decrypted `testnode.pem`
|
||||
------
|
||||
openssl rsa -in testnode.pem -out testnode-unprotected.pem
|
||||
------
|
||||
|
||||
`rsa_key_pkcs8_plain.pem` is the same plaintext key encoded in `PKCS#8`
|
||||
------
|
||||
openssl pkcs8 -topk8 -inform PEM -outform PEM -in testnode-unprotected.pem -out rsa_key_pkcs8_plain.pem -nocrypt
|
||||
------
|
||||
|
||||
`testnode-aes{128,192,256}.pem` is the testnode.pem private key, encrypted with `AES-128`, `AES-192` and `AES-256`
|
||||
respectively, encoded in `PKCS#1`
|
||||
[source,shell]
|
||||
------
|
||||
openssl rsa -aes128 -in testnode-unprotected.pem -out testnode-aes128.pem
|
||||
------
|
||||
[source,shell]
|
||||
------
|
||||
openssl rsa -aes192 -in testnode-unprotected.pem -out testnode-aes192.pem
|
||||
------
|
||||
[source,shell]
|
||||
------
|
||||
openssl rsa -aes256 -in testnode-unprotected.pem -out testnode-aes256.pem
|
||||
------
|
||||
|
||||
Adding `DSA` and `EC` Keys to the Keystore
|
||||
|
||||
[source,shell]
|
||||
------
|
||||
keytool -genkeypair -keyalg DSA -alias testnode_dsa -keystore testnode.jks -storepass testnode \
|
||||
-keypass testnode -validity 10000 -keysize 1024 -dname "CN=Elasticsearch Test Node" \
|
||||
-ext SAN=dns:localhost,dns:localhost.localdomain,dns:localhost4,dns:localhost4.localdomain4,dns:localhost6,dns:localhost6.localdomain6,ip:127.0.0.1,ip:0:0:0:0:0:0:0:1
|
||||
------
|
||||
[source,shell]
|
||||
------
|
||||
keytool -genkeypair -keyalg EC -alias testnode_ec -keystore testnode.jks -storepass testnode \
|
||||
-keypass testnode -validity 10000 -keysize 256 -dname "CN=Elasticsearch Test Node" \
|
||||
-ext SAN=dns:localhost,dns:localhost.localdomain,dns:localhost4,dns:localhost4.localdomain4,dns:localhost6,dns:localhost6.localdomain6,ip:127.0.0.1,ip:0:0:0:0:0:0:0:1
|
||||
------
|
||||
|
||||
Exporting the `DSA` and `EC` private keys from the keystore
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
keytool -importkeystore -srckeystore testnode.jks -destkeystore dsa.p12 -deststoretype PKCS12 \
|
||||
-srcalias testnode_dsa -deststorepass testnode -destkeypass testnode
|
||||
----
|
||||
[source,shell]
|
||||
----
|
||||
openssl pkcs12 -in dsa.p12 -nodes -nocerts | openssl pkcs8 -topk8 -nocrypt -outform pem \
|
||||
-out dsa_key_pkcs8_plain.pem
|
||||
----
|
||||
[source,shell]
|
||||
----
|
||||
keytool -importkeystore -srckeystore testnode.jks -destkeystore ec.p12 -deststoretype PKCS12 \
|
||||
-srcalias testnode_ec -deststorepass testnode -destkeypass testnode
|
||||
----
|
||||
[source,shell]
|
||||
----
|
||||
openssl pkcs12 -in ec.p12 -nodes -nocerts | openssl pkcs8 -topk8 -nocrypt -outform pem \
|
||||
-out ec_key_pkcs8_plain.pem
|
||||
----
|
||||
|
||||
|
||||
|
||||
Create `PKCS#8` encrypted key from the encrypted `PKCS#1` encoded `testnode.pem`
|
||||
[source,shell]
|
||||
-----
|
||||
openssl pkcs8 -topk8 -inform PEM -outform PEM -in testnode.pem -out key_pkcs8_encrypted.pem
|
||||
-----
|
||||
[source,shell]
|
||||
-----
|
||||
ssh-keygen -t ed25519 -f key_unsupported.pem
|
||||
-----
|
||||
|
||||
|
||||
Convert `prime256v1-key-noparam.pem` to `PKCS#8` format
|
||||
-----
|
||||
openssl pkcs8 -topk8 -in prime256v1-key-noparam.pem -nocrypt -out prime256v1-key-noparam-pkcs8.pem
|
||||
-----
|
||||
|
||||
Generate the keys and self-signed certificates in `nodes/self/` :
|
||||
|
||||
------
|
||||
openssl req -newkey rsa:2048 -keyout n1.c1.key -x509 -days 3650 -subj "/CN=n1.c1" -reqexts SAN \
|
||||
-extensions SAN -config <(cat /etc/ssl/openssl.cnf \
|
||||
<(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node1.cluster1")) -out n1.c1.crt
|
||||
------
|
||||
|
||||
|
||||
Create a `CA` keypair for testing
|
||||
[source,shell]
|
||||
-----
|
||||
openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -subj "/CN=certAuth" -days 10000 -out ca.crt
|
||||
-----
|
||||
|
||||
Generate Certificates signed with our CA for testing
|
||||
[source,shell]
|
||||
------
|
||||
openssl req -new -newkey rsa:2048 -keyout n2.c2.key -reqexts SAN -extensions SAN \
|
||||
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node2.cluster2"))\
|
||||
-out n2.c2.csr
|
||||
------
|
||||
|
||||
[source,shell]
|
||||
------
|
||||
openssl x509 -req -in n2.c2.csr -extensions SAN -CA ca.crt -CAkey ca.key -CAcreateserial \
|
||||
-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node2.cluster2"))\
|
||||
-out n2.c2.crt -days 10000
|
||||
------
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIB7zCCAZOgAwIBAgIEcmggOzAMBggqhkjOPQQDAgUAMCIxIDAeBgNVBAMTF0Vs
|
||||
YXN0aWNzZWFyY2ggVGVzdCBOb2RlMB4XDTE4MDUxNzA5MzYxMFoXDTQ1MTAwMjA5
|
||||
MzYxMFowIjEgMB4GA1UEAxMXRWxhc3RpY3NlYXJjaCBUZXN0IE5vZGUwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAATuZRlXGn/ROcO7yFJJ50b20YvgV3U+FpRx0nx/
|
||||
yigWj6xiEMKnWbbUnM0mKF8c3GHGk5g8OXPnbK96uj6tpMB5o4G0MIGxMB0GA1Ud
|
||||
DgQWBBRNAGO77mUhG6SQvIXQTbpcFwlf2TCBjwYDVR0RBIGHMIGEgglsb2NhbGhv
|
||||
c3SCFWxvY2FsaG9zdC5sb2NhbGRvbWFpboIKbG9jYWxob3N0NIIXbG9jYWxob3N0
|
||||
NC5sb2NhbGRvbWFpbjSCCmxvY2FsaG9zdDaCF2xvY2FsaG9zdDYubG9jYWxkb21h
|
||||
aW42hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMAwGCCqGSM49BAMCBQADSAAwRQIg
|
||||
Z3IvdmY5LFdbxoVSs6pV2tJ5+U833Chu0+ZzPo77IVUCIQDRx1FVitVuzBpqwhSW
|
||||
+Zprt2RLPllC4s4BCApGDh8i1g==
|
||||
-----END CERTIFICATE-----
|
|
@ -5,12 +5,15 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.watcher.actions.webhook;
|
||||
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.test.http.MockResponse;
|
||||
import org.elasticsearch.test.http.MockWebServer;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.ssl.TestsSSLService;
|
||||
import org.elasticsearch.xpack.core.watcher.history.WatchRecord;
|
||||
import org.elasticsearch.xpack.core.watcher.support.xcontent.XContentSource;
|
||||
|
@ -26,6 +29,10 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
|
@ -51,6 +58,7 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
|
|||
.put("xpack.http.ssl.key", keyPath)
|
||||
.put("xpack.http.ssl.certificate", certPath)
|
||||
.put("xpack.http.ssl.keystore.password", "testnode")
|
||||
.putList("xpack.http.ssl.supported_protocols", getProtocols())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -131,4 +139,23 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
|
|||
assertThat(webServer.requests().get(0).getBody(), equalTo("{key=value}"));
|
||||
assertThat(webServer.requests().get(0).getHeader("Authorization"), equalTo("Basic X3VzZXJuYW1lOl9wYXNzd29yZA=="));
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
} else if (JavaVersion.current().compareTo(JavaVersion.parse("12")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
} else {
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("12.0.1")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.elasticsearch.xpack.watcher.common.http;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
|
@ -13,6 +14,7 @@ import org.apache.logging.log4j.message.ParameterizedMessage;
|
|||
import org.apache.logging.log4j.util.Supplier;
|
||||
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
|
@ -28,6 +30,7 @@ import org.elasticsearch.test.ESTestCase;
|
|||
import org.elasticsearch.test.http.MockResponse;
|
||||
import org.elasticsearch.test.http.MockWebServer;
|
||||
import org.elasticsearch.test.junit.annotations.Network;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
import org.elasticsearch.xpack.core.ssl.SSLService;
|
||||
import org.elasticsearch.xpack.core.ssl.TestsSSLService;
|
||||
import org.elasticsearch.xpack.core.ssl.VerificationMode;
|
||||
|
@ -44,9 +47,12 @@ import java.net.Socket;
|
|||
import java.net.SocketTimeoutException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
@ -190,6 +196,7 @@ public class HttpClientTests extends ESTestCase {
|
|||
Settings settings2 = Settings.builder()
|
||||
.put("xpack.security.http.ssl.key", keyPath)
|
||||
.put("xpack.security.http.ssl.certificate", certPath)
|
||||
.putList("xpack.security.http.ssl.supported_protocols", getProtocols())
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
|
||||
|
@ -218,6 +225,7 @@ public class HttpClientTests extends ESTestCase {
|
|||
Settings settings2 = Settings.builder()
|
||||
.put("xpack.security.http.ssl.key", keyPath)
|
||||
.put("xpack.security.http.ssl.certificate", certPath)
|
||||
.putList("xpack.security.http.ssl.supported_protocols", getProtocols())
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
|
||||
|
@ -234,6 +242,7 @@ public class HttpClientTests extends ESTestCase {
|
|||
Settings settings = Settings.builder()
|
||||
.put("xpack.http.ssl.key", keyPath)
|
||||
.put("xpack.http.ssl.certificate", certPath)
|
||||
.putList("xpack.http.ssl.supported_protocols", getProtocols())
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
|
||||
|
@ -370,6 +379,7 @@ public class HttpClientTests extends ESTestCase {
|
|||
Settings serverSettings = Settings.builder()
|
||||
.put("xpack.http.ssl.key", keyPath)
|
||||
.put("xpack.http.ssl.certificate", certPath)
|
||||
.putList("xpack.http.ssl.supported_protocols", getProtocols())
|
||||
.setSecureSettings(serverSecureSettings)
|
||||
.build();
|
||||
TestsSSLService sslService = new TestsSSLService(serverSettings, environment);
|
||||
|
@ -383,6 +393,7 @@ public class HttpClientTests extends ESTestCase {
|
|||
.put(HttpSettings.PROXY_PORT.getKey(), proxyServer.getPort())
|
||||
.put(HttpSettings.PROXY_SCHEME.getKey(), "https")
|
||||
.put("xpack.http.ssl.certificate_authorities", trustedCertPath)
|
||||
.putList("xpack.http.ssl.supported_protocols", getProtocols())
|
||||
.build();
|
||||
|
||||
HttpRequest.Builder requestBuilder = HttpRequest.builder("localhost", webServer.getPort())
|
||||
|
@ -737,4 +748,23 @@ public class HttpClientTests extends ESTestCase {
|
|||
private String getWebserverUri() {
|
||||
return String.format(Locale.ROOT, "http://%s:%s", webServer.getHostName(), webServer.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link HttpsServer} in the JDK has issues with TLSv1.3 when running in a JDK prior to
|
||||
* 12.0.1 so we pin to TLSv1.2 when running on an earlier JDK
|
||||
*/
|
||||
private static List<String> getProtocols() {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
} else if (JavaVersion.current().compareTo(JavaVersion.parse("12")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
} else {
|
||||
JavaVersion full =
|
||||
AccessController.doPrivileged((PrivilegedAction<JavaVersion>) () -> JavaVersion.parse(System.getProperty("java.version")));
|
||||
if (full.compareTo(JavaVersion.parse("12.0.1")) < 0) {
|
||||
return Collections.singletonList("TLSv1.2");
|
||||
}
|
||||
}
|
||||
return XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,12 @@ integTestCluster {
|
|||
setting 'xpack.security.http.ssl.key_passphrase', 'http-password'
|
||||
setting 'reindex.ssl.truststore.path', 'ca.p12'
|
||||
setting 'reindex.ssl.truststore.password', 'password'
|
||||
|
||||
// Workaround for JDK-8212885
|
||||
if (project.ext.runtimeJavaVersion.isJava12Compatible() == false) {
|
||||
setting 'reindex.ssl.supported_protocols', 'TLSv1.2'
|
||||
}
|
||||
|
||||
extraConfigFile 'roles.yml', 'roles.yml'
|
||||
[
|
||||
test_admin: 'superuser',
|
||||
|
|
Loading…
Reference in New Issue