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

Test adjustments for FIPS 140 #56427

Closed
wants to merge 3 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ class BuildPlugin implements Plugin<Project> {
cluster.systemProperty('javax.net.ssl.trustStorePassword', 'password')
cluster.systemProperty('javax.net.ssl.keyStorePassword', 'password')
cluster.systemProperty('javax.net.ssl.keyStoreType', 'BCFKS')
// Can't use our DiagnosticTrustManager with SunJSSE in FIPS mode
cluster.setting 'xpack.security.ssl.diagnose.trust', 'false'
cluster.setting 'xpack.security.fips_mode.enabled', 'true'
cluster.setting 'xpack.security.authc.password_hashing.algorithm', 'PBKDF2'
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.function.Supplier;

Expand Down Expand Up @@ -72,8 +74,11 @@ public void testReadEcKeyCurves() throws Exception {
PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/private_" + curve + ".pem"), ""::toCharArray);
assertThat(privateKey, instanceOf(ECPrivateKey.class));
ECParameterSpec parameterSpec = ((ECPrivateKey) privateKey).getParams();
// This is brittle but we can't access sun.security.util.NamedCurve
assertThat(parameterSpec.toString(), containsString(curve));

ECGenParameterSpec algorithmParameterSpec = new ECGenParameterSpec(curve);
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(algorithmParameterSpec);
assertThat(parameterSpec, equalTo(algoParameters.getParameterSpec(ECParameterSpec.class)));
}

public void testReadPKCS8EcKey() throws Exception {
Expand Down
40 changes: 33 additions & 7 deletions plugins/discovery-ec2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,34 @@ task writeTestJavaPolicy {
throw new GradleException("failed to create temporary directory [${tmp}]")
}
final File javaPolicy = file("${tmp}/java.policy")
javaPolicy.write(
[
"grant {",
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
"};"
].join("\n"))
if (BuildParams.inFipsJvm) {
javaPolicy.write(
[
"grant {",
"permission java.security.SecurityPermission \"putProviderProperty.BCFIPS\";",
"permission java.security.SecurityPermission \"putProviderProperty.BCJSSE\";",
"permission java.lang.RuntimePermission \"getProtectionDomain\";",
"permission java.util.PropertyPermission \"java.runtime.name\", \"read\";",
"permission org.bouncycastle.crypto.CryptoServicesPermission \"tlsAlgorithmsEnabled\";",
"permission java.lang.RuntimePermission \"accessClassInPackage.sun.security.internal.spec\";",
"permission java.lang.RuntimePermission \"accessDeclaredMembers\";",
"permission java.util.PropertyPermission \"intellij.debug.agent\", \"read\";",
"permission java.util.PropertyPermission \"intellij.debug.agent\", \"write\";",
"permission org.bouncycastle.crypto.CryptoServicesPermission \"exportSecretKey\";",
"permission org.bouncycastle.crypto.CryptoServicesPermission \"exportPrivateKey\";",
"permission java.io.FilePermission \"\${javax.net.ssl.trustStore}\", \"read\";",
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
"};"
].join("\n")
)
} else {
javaPolicy.write(
[
"grant {",
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
"};"
].join("\n"))
}
}
}

Expand All @@ -80,7 +102,11 @@ test {

// this is needed to manipulate com.amazonaws.sdk.ec2MetadataServiceEndpointOverride system property
// it is better rather disable security manager at all with `systemProperty 'tests.security.manager', 'false'`
systemProperty 'java.security.policy', "file://${buildDir}/tmp/java.policy"
if (BuildParams.inFipsJvm){
systemProperty 'java.security.policy', "=file://${buildDir}/tmp/java.policy"
} else {
systemProperty 'java.security.policy', "file://${buildDir}/tmp/java.policy"
}
}

check {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.junit.BeforeClass;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
Expand All @@ -52,6 +53,17 @@
*/
public class CustomAuthorizationEngineIT extends ESIntegTestCase {

private static Hasher passwordHashingAlgorighm;

@BeforeClass
public static void setup() {
if (inFipsJvm()) {
passwordHashingAlgorighm = Hasher.PBKDF2;
} else {
passwordHashingAlgorighm = Hasher.BCRYPT;
}
}

@Override
protected Settings externalClusterClientSettings() {
final String token = "Basic " +
Expand All @@ -69,7 +81,8 @@ protected Collection<Class<? extends Plugin>> transportClientPlugins() {

public void testClusterAction() throws IOException {
SecurityClient securityClient = new SecurityClient(client());
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get();
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "custom_superuser")
.get();

{
RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
Expand All @@ -82,7 +95,8 @@ public void testClusterAction() throws IOException {
}

{
securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "not_superuser").get();
securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "not_superuser")
.get();
RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
basicAuthHeaderValue("custom_user2", new SecureString("x-pack-test-password".toCharArray())));
Expand All @@ -95,7 +109,8 @@ public void testClusterAction() throws IOException {

public void testIndexAction() throws IOException {
SecurityClient securityClient = new SecurityClient(client());
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get();
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "custom_superuser")
.get();

{
RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
Expand All @@ -121,9 +136,12 @@ public void testIndexAction() throws IOException {

public void testRunAs() throws IOException {
SecurityClient securityClient = new SecurityClient(client());
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get();
securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get();
securityClient.preparePutUser("custom_user3", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "not_superuser").get();
securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "custom_superuser")
.get();
securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "custom_superuser")
.get();
securityClient.preparePutUser("custom_user3", "x-pack-test-password".toCharArray(), passwordHashingAlgorighm, "not_superuser")
.get();

{
RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1344,11 +1344,15 @@ protected static long spinForAtLeastNMilliseconds(final long ms) {
return elapsed;
}

public static boolean inFipsSunJsseJvm() {
return inFipsJvm() && JavaVersion.current().getVersion().get(0) == 8;
}

/**
* Creates an TestAnalysis with all the default analyzers configured.
*/
public static TestAnalysis createTestAnalysis(Index index, Settings settings, AnalysisPlugin... analysisPlugins)
throws IOException {
throws IOException {
Settings nodeSettings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), createTempDir()).build();
return createTestAnalysis(index, nodeSettings, settings, analysisPlugins);
}
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ integTest.runner {
// private key, these tests are blacklisted in non-snapshot test runs
blacklist.addAll(['xpack/15_basic/*', 'license/20_put_license/*', 'license/30_enterprise_license/*'])
}
if (BuildParams.inFipsJvm) {
// We cannot install GOLD licenses or older 1.x license types on FIPS mode, as FIPS is allowed only in platinum
blacklist.add('license/20_put_license/*')
}
systemProperty 'tests.rest.blacklist', blacklist.join(',')
dependsOn copyKeyCerts
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;
import static org.elasticsearch.test.ESTestCase.inFipsJvm;

public class LocalStateCompositeXPackPlugin extends XPackPlugin implements ScriptPlugin, ActionPlugin, IngestPlugin, NetworkPlugin,
ClusterPlugin, DiscoveryPlugin, MapperPlugin, AnalysisPlugin, PersistentTaskPlugin, EnginePlugin {
Expand Down Expand Up @@ -257,8 +258,12 @@ public Settings additionalSettings() {
Settings.Builder builder = Settings.builder();
builder.put(super.additionalSettings());
filterPlugins(Plugin.class).stream().forEach(p ->
builder.put(p.additionalSettings())
builder.put(p.additionalSettings())
);
if (inFipsJvm()) {
builder.put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true);
builder.put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(), "PBKDF2_1000");
}
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void close() {
private static Settings possiblyDisableTlsDiagnostic(Settings settings) {
Settings.Builder builder = Settings.builder().put(settings);
if (inFipsJvm()) {
builder.put(XPackSettings.DIAGNOSE_TRUST_EXCEPTIONS_SETTING.getKey(), false);
builder.put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true);
}
return builder.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.TestEnvironment;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.ssl.SSLConfiguration;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.core.ssl.VerificationMode;
Expand Down Expand Up @@ -58,17 +59,22 @@ public void testGetInsecureTransportProfileConfigurations() {
}

private Settings.Builder getBaseSettings() {
final Path keystore = randomBoolean()
? getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks")
: getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
final Path keystore = inFipsJvm()
? getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12")
: getDataPath(randomFrom("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks",
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12"));

MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.keystore.secure_password", "testnode");

return Settings.builder()
Settings.Builder builder = Settings.builder()
.setSecureSettings(secureSettings)
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.keystore.path", keystore.toString());
if (inFipsJvm()) {
builder.put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true);
}
return builder;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;

import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -70,8 +72,11 @@ public void testReadEcKeyCurves() throws Exception {
("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/private_" + curve + ".pem"), ""::toCharArray);
assertThat(privateKey, instanceOf(ECPrivateKey.class));
ECParameterSpec parameterSpec = ((ECPrivateKey) privateKey).getParams();
// This is brittle but we can't access sun.security.util.NamedCurve
assertThat(parameterSpec.toString(), containsString(curve));

ECGenParameterSpec algorithmParameterSpec = new ECGenParameterSpec(curve);
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(algorithmParameterSpec);
assertThat(parameterSpec, equalTo(algoParameters.getParameterSpec(ECParameterSpec.class)));
}

public void testReadEncryptedPKCS8Key() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.xpack.core.XPackSettings;
import org.junit.After;
import org.junit.Before;

Expand Down Expand Up @@ -110,7 +111,7 @@ public void testReloadingKeyStore() throws Exception {
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.jks"), updatedKeystorePath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.keystore.secure_password", "testnode");
final Settings settings = Settings.builder()
final Settings settings = getSettingsBuilder()
.put("path.home", createTempDir())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.keystore.path", keystorePath)
Expand Down Expand Up @@ -168,7 +169,7 @@ public void testPEMKeyConfigReloading() throws Exception {
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCertPath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.secure_key_passphrase", "testnode");
final Settings settings = Settings.builder()
final Settings settings = getSettingsBuilder()
.put("path.home", createTempDir())
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.key", keyPath)
Expand Down Expand Up @@ -327,7 +328,7 @@ public void testReloadingKeyStoreException() throws Exception {
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.keystore.secure_password", "testnode");
Settings settings = Settings.builder()
Settings settings = getSettingsBuilder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.keystore.path", keystorePath)
.setSecureSettings(secureSettings)
Expand Down Expand Up @@ -376,7 +377,7 @@ public void testReloadingPEMKeyConfigException() throws Exception {
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath);
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.security.transport.ssl.secure_key_passphrase", "testnode");
Settings settings = Settings.builder()
Settings settings = getSettingsBuilder()
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.key", keyPath)
.put("xpack.security.transport.ssl.certificate", certPath)
Expand Down Expand Up @@ -513,7 +514,7 @@ private Settings.Builder baseKeystoreSettings(Path tempDir, MockSecureSettings s
}
secureSettings.setString("xpack.security.transport.ssl.secure_key_passphrase", "testnode");

return Settings.builder()
return getSettingsBuilder()
.put("xpack.security.transport.ssl.key", keyPath.toString())
.put("xpack.security.transport.ssl.certificate", certPath.toString())
.setSecureSettings(secureSettings);
Expand Down Expand Up @@ -624,6 +625,14 @@ private static CloseableHttpClient createHttpClient(SSLContext sslContext) {
.build();
}

private Settings.Builder getSettingsBuilder() {
Settings.Builder builder = Settings.builder();
if (inFipsJvm()) {
builder.put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true);
}
return builder;
}

/**
* Creates our own HttpConnectionFactory that changes how the connection is closed to prevent issues with
* the MockWebServer going into an endless loop based on the way that HttpClient closes its connection.
Expand Down
Loading