Skip to content

Commit

Permalink
Add an option to pass a truststore in a format of a based64 string (e…
Browse files Browse the repository at this point in the history
  • Loading branch information
M0arcin committed Sep 26, 2022
1 parent d498aa0 commit 9057432
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/src/reference/asciidoc/core/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,8 @@ added[2.1]

`es.net.ssl.truststore.location`:: trust store location (typically a URL, without a prefix it is interpreted as a classpath entry)

`es.net.ssl.truststore.base64`:: trust store encoded in base64, will be used if `es.net.ssl.truststore.location` is not passed

`es.net.ssl.truststore.pass`:: <<keystore,Securable>>. trust store password

`es.net.ssl.cert.allow.self.signed` (default false):: Whether or not to allow self signed certificates
Expand Down Expand Up @@ -724,7 +726,7 @@ Typically (and again, do note that your environment might differ significantly),
The authentication support in {eh} is of two types:

Username/Password:: Set these through `es.net.http.auth.user` and `es.net.http.auth.pass` properties.
PKI/X.509:: Use X.509 certificates to authenticate {eh} to {eh}. For this, one would need to setup the `keystore` containing the private key and certificate to the appropriate user (configured in {es}) and the `truststore` with the CA certificate used to sign the SSL/TLS certificates in the {es} cluster. That is one setup the key to authenticate {eh} and also to verify that is the right one. To do so, one should setup the `es.net.ssl.keystore.location` and `es.net.ssl.truststore.location` properties to indicate the `keystore` and `truststore` to use. It is recommended to have these secured through a password in which case `es.net.ssl.keystore.pass` and `es.net.ssl.truststore.pass` properties are required.
PKI/X.509:: Use X.509 certificates to authenticate {eh} to {eh}. For this, one would need to setup the `keystore` containing the private key and certificate to the appropriate user (configured in {es}) and the `truststore` with the CA certificate used to sign the SSL/TLS certificates in the {es} cluster. That is one setup the key to authenticate {eh} and also to verify that is the right one. To do so, one should setup the `es.net.ssl.keystore.location` and `es.net.ssl.truststore.location` properties to indicate the `keystore` and `truststore` to use. It is recommended to have these secured through a password in which case `es.net.ssl.keystore.pass` and `es.net.ssl.truststore.pass` properties are required. Instead of `es.net.ssl.truststore.location` one could use `es.net.ssl.truststore.base64`.

[float]
[[keystore]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ public interface ConfigurationOptions {
String ES_NET_SSL_KEYSTORE_TYPE_DEFAULT = "JKS"; // PKCS12 could also be used
String ES_NET_SSL_KEYSTORE_PASS = "es.net.ssl.keystore.pass";

String ES_NET_SSL_TRUST_STORE_BASE64 = "es.net.ssl.truststore.base64";
String ES_NET_SSL_TRUST_STORE_LOCATION = "es.net.ssl.truststore.location";
String ES_NET_SSL_TRUST_STORE_PASS = "es.net.ssl.truststore.pass";

Expand Down
4 changes: 4 additions & 0 deletions mr/src/main/java/org/elasticsearch/hadoop/cfg/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ public String getNetworkSSLKeyStorePass() {
return getProperty(ES_NET_SSL_KEYSTORE_PASS);
}

public String getNetworkSSLTrustStoreBase64() {
return getProperty(ES_NET_SSL_TRUST_STORE_BASE64);
}

public String getNetworkSSLTrustStoreLocation() {
return getProperty(ES_NET_SSL_TRUST_STORE_LOCATION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.elasticsearch.hadoop.rest.commonshttp;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
Expand All @@ -30,6 +31,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;

import javax.net.SocketFactory;
import javax.net.ssl.KeyManager;
Expand Down Expand Up @@ -103,6 +105,7 @@ public boolean isTrusted(X509Certificate[] chain, String authType) throws Certif
private final String keyStorePass;
private final String keyStoreType;

private final String trustStoreBase64;
private final String trustStoreLocation;
private final String trustStorePass;
private final TrustStrategy trust;
Expand All @@ -114,6 +117,7 @@ public boolean isTrusted(X509Certificate[] chain, String authType) throws Certif
keyStorePass = secureSettings.getSecureProperty(ConfigurationOptions.ES_NET_SSL_KEYSTORE_PASS);
keyStoreType = settings.getNetworkSSLKeyStoreType();

trustStoreBase64 = settings.getNetworkSSLTrustStoreBase64();
trustStoreLocation = settings.getNetworkSSLTrustStoreLocation();
trustStorePass = secureSettings.getSecureProperty(ConfigurationOptions.ES_NET_SSL_TRUST_STORE_PASS);

Expand Down Expand Up @@ -205,6 +209,17 @@ private KeyStore loadKeyStore(String location, char[] pass) throws GeneralSecuri
return keyStore;
}

private KeyStore loadKeyStoreFromBase64(String trustStoreBase64, char[] pass) throws GeneralSecurityException, IOException {
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
try(InputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(trustStoreBase64))) {
if (LOG.isDebugEnabled()) {
LOG.debug("Loading keystore from string [" + trustStoreBase64 + "]");
}
keyStore.load(in, pass);
}
return keyStore;
}

private KeyManager[] loadKeyManagers() throws GeneralSecurityException, IOException {
if (!StringUtils.hasText(keyStoreLocation)) {
LOG.debug("No keystore location specified! SSL is continuing with no keystore.");
Expand All @@ -224,8 +239,11 @@ private TrustManager[] loadTrustManagers() throws GeneralSecurityException, IOEx
if (StringUtils.hasText(trustStoreLocation)) {
char[] pass = (StringUtils.hasText(trustStorePass) ? trustStorePass.trim().toCharArray() : null);
keyStore = loadKeyStore(trustStoreLocation, pass);
} else if (StringUtils.hasText(trustStoreBase64)) {
char[] pass = (StringUtils.hasText(trustStorePass) ? trustStorePass.trim().toCharArray() : null);
keyStore = loadKeyStoreFromBase64(trustStoreBase64, pass);
} else {
LOG.debug("No truststore location specified! SSL is continuing with no truststore.");
LOG.debug("No truststore nor its specified! SSL is continuing with no truststore.");
}

TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
Expand Down Expand Up @@ -256,4 +274,4 @@ public boolean equals(Object obj) {
public int hashCode() {
return getClass().hashCode();
}
}
}

0 comments on commit 9057432

Please sign in to comment.