mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
Allow ESRestTestClient to trust certificates (#66559)
ESRestTestCase rest clients could only be configured to trust the certificate authorities that were contained in a truststore. In certain cases (like in fips mode where JKS/PKCS12 keystores) cannot be used, it's beneficial to be able to trust specific certificate authorities (indicated by the CA PEM endoded certificate)
This commit is contained in:
parent
ed43be8c42
commit
abaf81e37e
3 changed files with 35 additions and 3 deletions
|
@ -62,7 +62,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
final class PemUtils {
|
public final class PemUtils {
|
||||||
|
|
||||||
private static final String PKCS1_HEADER = "-----BEGIN RSA PRIVATE KEY-----";
|
private static final String PKCS1_HEADER = "-----BEGIN RSA PRIVATE KEY-----";
|
||||||
private static final String PKCS1_FOOTER = "-----END RSA PRIVATE KEY-----";
|
private static final String PKCS1_FOOTER = "-----END RSA PRIVATE KEY-----";
|
||||||
|
@ -589,7 +589,7 @@ final class PemUtils {
|
||||||
"] is not żsupported");
|
"] is not żsupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Certificate> readCertificates(Collection<Path> certPaths) throws CertificateException, IOException {
|
public static List<Certificate> readCertificates(Collection<Path> certPaths) throws CertificateException, IOException {
|
||||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
List<Certificate> certificates = new ArrayList<>(certPaths.size());
|
List<Certificate> certificates = new ArrayList<>(certPaths.size());
|
||||||
for (Path path : certPaths) {
|
for (Path path : certPaths) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ dependencies {
|
||||||
api project(":client:rest")
|
api project(":client:rest")
|
||||||
api project(":client:sniffer")
|
api project(":client:sniffer")
|
||||||
api project(':libs:elasticsearch-nio')
|
api project(':libs:elasticsearch-nio')
|
||||||
|
api project(':libs:elasticsearch-ssl-config')
|
||||||
api project(":server")
|
api project(":server")
|
||||||
api project(":libs:elasticsearch-cli")
|
api project(":libs:elasticsearch-cli")
|
||||||
api "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
|
api "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.elasticsearch.common.CheckedRunnable;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.ssl.PemUtils;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
import org.elasticsearch.common.util.set.Sets;
|
||||||
|
@ -81,6 +82,7 @@ import java.security.KeyManagementException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -114,6 +116,7 @@ import static org.hamcrest.Matchers.notNullValue;
|
||||||
public abstract class ESRestTestCase extends ESTestCase {
|
public abstract class ESRestTestCase extends ESTestCase {
|
||||||
public static final String TRUSTSTORE_PATH = "truststore.path";
|
public static final String TRUSTSTORE_PATH = "truststore.path";
|
||||||
public static final String TRUSTSTORE_PASSWORD = "truststore.password";
|
public static final String TRUSTSTORE_PASSWORD = "truststore.password";
|
||||||
|
public static final String CERTIFICATE_AUTHORITIES = "certificate_authorities";
|
||||||
public static final String CLIENT_SOCKET_TIMEOUT = "client.socket.timeout";
|
public static final String CLIENT_SOCKET_TIMEOUT = "client.socket.timeout";
|
||||||
public static final String CLIENT_PATH_PREFIX = "client.path.prefix";
|
public static final String CLIENT_PATH_PREFIX = "client.path.prefix";
|
||||||
|
|
||||||
|
@ -1001,8 +1004,19 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void configureClient(RestClientBuilder builder, Settings settings) throws IOException {
|
protected static void configureClient(RestClientBuilder builder, Settings settings) throws IOException {
|
||||||
|
String certificateAuthorities = settings.get(CERTIFICATE_AUTHORITIES);
|
||||||
String keystorePath = settings.get(TRUSTSTORE_PATH);
|
String keystorePath = settings.get(TRUSTSTORE_PATH);
|
||||||
|
|
||||||
|
if (certificateAuthorities != null && keystorePath != null) {
|
||||||
|
throw new IllegalStateException("Cannot set both " + CERTIFICATE_AUTHORITIES + " and " + TRUSTSTORE_PATH
|
||||||
|
+ ". Please configure one of these.");
|
||||||
|
|
||||||
|
}
|
||||||
if (keystorePath != null) {
|
if (keystorePath != null) {
|
||||||
|
if (inFipsJvm()) {
|
||||||
|
throw new IllegalStateException("Keystore " + keystorePath + "cannot be used in FIPS 140 mode. Please configure "
|
||||||
|
+ CERTIFICATE_AUTHORITIES + " with a PEM encoded trusted CA/certificate instead");
|
||||||
|
}
|
||||||
final String keystorePass = settings.get(TRUSTSTORE_PASSWORD);
|
final String keystorePass = settings.get(TRUSTSTORE_PASSWORD);
|
||||||
if (keystorePass == null) {
|
if (keystorePass == null) {
|
||||||
throw new IllegalStateException(TRUSTSTORE_PATH + " is provided but not " + TRUSTSTORE_PASSWORD);
|
throw new IllegalStateException(TRUSTSTORE_PATH + " is provided but not " + TRUSTSTORE_PASSWORD);
|
||||||
|
@ -1024,6 +1038,23 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
throw new RuntimeException("Error setting up ssl", e);
|
throw new RuntimeException("Error setting up ssl", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (certificateAuthorities != null) {
|
||||||
|
Path path = PathUtils.get(certificateAuthorities);
|
||||||
|
if (!Files.exists(path)) {
|
||||||
|
throw new IllegalStateException(CERTIFICATE_AUTHORITIES + " is set but points to a non-existing file");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
|
keyStore.load(null, null);
|
||||||
|
Certificate cert = PemUtils.readCertificates(List.of(path)).get(0);
|
||||||
|
keyStore.setCertificateEntry(cert.toString(), cert);
|
||||||
|
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, null).build();
|
||||||
|
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslcontext);
|
||||||
|
builder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy));
|
||||||
|
} catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | CertificateException e) {
|
||||||
|
throw new RuntimeException("Error setting up ssl", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
Map<String, String> headers = ThreadContext.buildDefaultHeaders(settings);
|
Map<String, String> headers = ThreadContext.buildDefaultHeaders(settings);
|
||||||
Header[] defaultHeaders = new Header[headers.size()];
|
Header[] defaultHeaders = new Header[headers.size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue