Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support certs with separate Extended Key Usage #493

Merged
merged 1 commit into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public class OpenDistroSecuritySSLPlugin extends Plugin implements ActionPlugin,
protected final boolean client;
protected final boolean httpSSLEnabled;
protected final boolean transportSSLEnabled;
protected final boolean extendedKeyUsageEnabled;
protected final Settings settings;
protected final SharedGroupFactory sharedGroupFactory;
protected final OpenDistroSecurityKeyStore odsks;
Expand All @@ -109,13 +110,14 @@ public class OpenDistroSecuritySSLPlugin extends Plugin implements ActionPlugin,
// }

protected OpenDistroSecuritySSLPlugin(final Settings settings, final Path configPath, boolean disabled) {

if(disabled) {
this.settings = null;
this.sharedGroupFactory = null;
this.client = false;
this.httpSSLEnabled = false;
this.transportSSLEnabled = false;
this.extendedKeyUsageEnabled = false;
this.odsks = null;
this.configPath = null;
openDistroSSLConfig = new OpenDistroSSLConfig(false, false);
Expand Down Expand Up @@ -200,6 +202,8 @@ public Object run() {
SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_ENABLED_DEFAULT);
transportSSLEnabled = settings.getAsBoolean(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENABLED,
SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENABLED_DEFAULT);
extendedKeyUsageEnabled = settings.getAsBoolean(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED,
SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED_DEFAULT);

if (!httpSSLEnabled && !transportSSLEnabled) {
log.error("SSL not activated for http and/or transport.");
Expand Down Expand Up @@ -329,12 +333,9 @@ public List<Setting<?>> getSettings() {
settings.add(Setting.boolSetting(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENABLED, SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENABLED_DEFAULT, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, true, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, true, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE, Property.NodeScope, Property.Filtered));
Expand All @@ -345,11 +346,36 @@ public List<Setting<?>> getSettings() {
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_CLIENT_EXTERNAL_CONTEXT_ID, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL_EXTRACTOR_CLASS, Property.NodeScope, Property.Filtered));

settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, Property.NodeScope, Property.Filtered));

settings.add(Setting.boolSetting(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED, SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED_DEFAULT, Property.NodeScope, Property.Filtered));
if(extendedKeyUsageEnabled) {
lavacat marked this conversation as resolved.
Show resolved Hide resolved
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_TRUSTSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_KEYPASSWORD, Property.NodeScope, Property.Filtered));

settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_TRUSTSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_KEYPASSWORD, Property.NodeScope, Property.Filtered));

settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_PEMCERT_FILEPATH, Property.NodeScope, Property.Filtered));
debjanibnrj marked this conversation as resolved.
Show resolved Hide resolved
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_SERVER_PEMTRUSTEDCAS_FILEPATH, Property.NodeScope, Property.Filtered));

settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_PEMCERT_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_CLIENT_PEMTRUSTEDCAS_FILEPATH, Property.NodeScope, Property.Filtered));
} else {
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTSTORE_ALIAS, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD, Property.NodeScope, Property.Filtered));

settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, Property.NodeScope, Property.Filtered));
}
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_PEMCERT_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_PEMKEY_FILEPATH, Property.NodeScope, Property.Filtered));
settings.add(Setting.simpleString(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_PEMKEY_PASSWORD, Property.NodeScope, Property.Filtered));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.amazon.opendistroforelasticsearch.security.ssl.util;


public class CertFileProps {
private final String pemCertFilePath;
private final String pemKeyFilePath;
private final String trustedCasFilePath;
private final String pemKeyPassword;

public CertFileProps(String pemCertFilePath, String pemKeyFilePath, String trustedCasFilePath, String pemKeyPassword) {
this.pemCertFilePath = pemCertFilePath;
this.pemKeyFilePath = pemKeyFilePath;
this.trustedCasFilePath = trustedCasFilePath;
this.pemKeyPassword = pemKeyPassword;
}

public String getPemCertFilePath() {
return pemCertFilePath;
}

public String getPemKeyFilePath() {
return pemKeyFilePath;
}

public String getTrustedCasFilePath() {
return trustedCasFilePath;
}

public String getPemKeyPassword() {
return pemKeyPassword;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.amazon.opendistroforelasticsearch.security.ssl.util;

import com.amazon.opendistroforelasticsearch.security.support.PemKeyReader;

import java.io.File;
import java.security.cert.X509Certificate;

public class CertFromFile {
private final CertFileProps clientCertProps;
private final CertFileProps serverCertProps;

private final File serverPemCert;
private final File serverPemKey;
private final File serverTrustedCas;

private final File clientPemCert;
private final File clientPemKey;
private final File clientTrustedCas;

private final X509Certificate[] loadedCerts;

public CertFromFile(CertFileProps clientCertProps, CertFileProps serverCertProps) throws Exception {
this.serverCertProps = serverCertProps;
this.serverPemCert = new File(serverCertProps.getPemCertFilePath());
this.serverPemKey = new File(serverCertProps.getPemKeyFilePath());
this.serverTrustedCas = nullOrFile(serverCertProps.getTrustedCasFilePath());

this.clientCertProps = clientCertProps;
this.clientPemCert = new File(clientCertProps.getPemCertFilePath());
this.clientPemKey = new File(clientCertProps.getPemKeyFilePath());
this.clientTrustedCas = nullOrFile(clientCertProps.getTrustedCasFilePath());

loadedCerts = new X509Certificate[]{PemKeyReader.loadCertificateFromFile(clientCertProps.getPemCertFilePath()),
PemKeyReader.loadCertificateFromFile(serverCertProps.getPemCertFilePath())};
}

public CertFromFile(CertFileProps certProps) throws Exception {
this.serverCertProps = certProps;
this.serverPemCert = new File(certProps.getPemCertFilePath());
this.serverPemKey = new File(certProps.getPemKeyFilePath());
this.serverTrustedCas = nullOrFile(certProps.getTrustedCasFilePath());

this.clientCertProps = serverCertProps;
this.clientPemCert = serverPemCert;
this.clientPemKey = serverPemKey;
this.clientTrustedCas = serverTrustedCas;

loadedCerts = new X509Certificate[]{PemKeyReader.loadCertificateFromFile(certProps.getPemCertFilePath())};
}

public X509Certificate[] getCerts() {
return loadedCerts;
}

public File getServerPemKey() {
return serverPemKey;
}

public File getServerPemCert() {
return serverPemCert;
}

public File getServerTrustedCas() {
return serverTrustedCas;
}

public String getServerPemKeyPassword() {
return serverCertProps.getPemKeyPassword();
}

public File getClientPemKey() {
return clientPemKey;
}

public File getClientPemCert() {
return clientPemCert;
}

public File getClientTrustedCas() {
return clientTrustedCas;
}

public String getClientPemKeyPassword() {
return clientCertProps.getPemKeyPassword();
}

private File nullOrFile(String path) {
if (path != null) {
return new File(path);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.amazon.opendistroforelasticsearch.security.ssl.util;

import org.apache.commons.lang3.ArrayUtils;
import org.elasticsearch.ElasticsearchException;

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class CertFromKeystore {

private final KeystoreProps keystoreProps;
private final String serverKeystoreAlias;
private final String clientKeystoreAlias;

private PrivateKey serverKey;
private X509Certificate[] serverCert;
private final char[] serverKeyPassword;

private PrivateKey clientKey;
private X509Certificate[] clientCert;
private final char[] clientKeyPassword;

private X509Certificate[] loadedCerts;

public CertFromKeystore(KeystoreProps keystoreProps, String keystoreAlias, String keyPassword) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, UnrecoverableKeyException {
this.keystoreProps = keystoreProps;
final KeyStore ks = keystoreProps.loadKeystore();

this.serverKeystoreAlias = keystoreAlias;
this.serverKeyPassword = Utils.toCharArray(keyPassword);
this.serverCert = SSLCertificateHelper.exportServerCertChain(ks, serverKeystoreAlias);
this.serverKey = SSLCertificateHelper.exportDecryptedKey(
ks, serverKeystoreAlias, this.serverKeyPassword);

this.clientKeystoreAlias = keystoreAlias;
this.clientKeyPassword = serverKeyPassword;
this.clientCert = serverCert;
this.clientKey = serverKey;

this.loadedCerts = serverCert;

validate();
}

public CertFromKeystore(
KeystoreProps keystoreProps,
String serverKeystoreAlias, String clientKeystoreAlias, String serverKeyPassword, String clientKeyPassword) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, UnrecoverableKeyException {
this.keystoreProps = keystoreProps;
final KeyStore ks = keystoreProps.loadKeystore();

this.serverKeystoreAlias = serverKeystoreAlias;
this.serverKeyPassword = Utils.toCharArray(serverKeyPassword);
this.serverCert = SSLCertificateHelper.exportServerCertChain(ks, serverKeystoreAlias);
this.serverKey = SSLCertificateHelper.exportDecryptedKey(
ks, serverKeystoreAlias, this.serverKeyPassword);

this.clientKeystoreAlias = clientKeystoreAlias;
this.clientKeyPassword = Utils.toCharArray(clientKeyPassword);
this.clientCert = SSLCertificateHelper.exportServerCertChain(ks, clientKeystoreAlias);
this.clientKey = SSLCertificateHelper.exportDecryptedKey(
ks, clientKeystoreAlias, this.clientKeyPassword);

this.loadedCerts = ArrayUtils.addAll(serverCert, clientCert);

validate();
}

private void validate() {
if (serverKey == null) {
throw new ElasticsearchException(
"No key found in " + keystoreProps.getFilePath() + " with alias " + serverKeystoreAlias);
}

if (serverCert == null || serverCert.length == 0) {
throw new ElasticsearchException(
"No certificates found in " + keystoreProps.getFilePath() + " with alias " + serverKeystoreAlias);
}

if (clientKey == null) {
throw new ElasticsearchException(
"No key found in " + keystoreProps.getFilePath() + " with alias " + clientKeystoreAlias);
}

if (clientCert == null || clientCert.length == 0) {
throw new ElasticsearchException(
"No certificates found in " + keystoreProps.getFilePath() + " with alias " + clientKeystoreAlias);
}
}

public X509Certificate[] getCerts() {
return loadedCerts;
}

public PrivateKey getServerKey() {
return serverKey;
}

public X509Certificate[] getServerCert() {
return serverCert;
}

public PrivateKey getClientKey() {
return clientKey;
}

public X509Certificate[] getClientCert() {
return clientCert;
}
}
Loading