Skip to content

Commit 091d425

Browse files
committed
Test adjustments for FIPS 140
This change aims to fix our setup in CI so that we can run 7.x in FIPS 140 mode. The major issue that we have in 7.x and did not have in master is that we can't use the diagnostic trust manager in FIPS mode in Java 8 with SunJSSE in FIPS approved mode as it explicitly disallows the wrapping of X509TrustManager. Previous attempts like elastic#56427 and elastic#52211 focused on disabling the setting in all of our tests when creating a Settings object or on setting fips_mode.enabled accordingly (which implicitly disables the diagnostic trust manager). The attempts weren't future proof though as nothing would forbid someone to add new tests without setting the necessary setting and forcing this would be very inconvenient for any other case ( see elastic#56427 (comment) for the full argumentation). This change introduces a system property that effectively bypasses the configuration value of xpack.security.ssl.diagnose.trust and disables the diagnostic trust manager. We will then set this system property in our periodic CI jobs for Java 8.
1 parent c29bc87 commit 091d425

File tree

8 files changed

+80
-26
lines changed

8 files changed

+80
-26
lines changed

libs/ssl-config/src/test/java/org/elasticsearch/common/ssl/PemUtilsTests.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import java.io.InputStream;
2525
import java.nio.file.Files;
2626
import java.nio.file.Path;
27+
import java.security.AlgorithmParameters;
2728
import java.security.Key;
2829
import java.security.KeyStore;
2930
import java.security.PrivateKey;
3031
import java.security.interfaces.ECPrivateKey;
32+
import java.security.spec.ECGenParameterSpec;
3133
import java.security.spec.ECParameterSpec;
3234
import java.util.function.Supplier;
3335

@@ -72,8 +74,10 @@ public void testReadEcKeyCurves() throws Exception {
7274
PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/private_" + curve + ".pem"), ""::toCharArray);
7375
assertThat(privateKey, instanceOf(ECPrivateKey.class));
7476
ECParameterSpec parameterSpec = ((ECPrivateKey) privateKey).getParams();
75-
// This is brittle but we can't access sun.security.util.NamedCurve
76-
assertThat(parameterSpec.toString(), containsString(curve));
77+
ECGenParameterSpec algorithmParameterSpec = new ECGenParameterSpec(curve);
78+
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
79+
algoParameters.init(algorithmParameterSpec);
80+
assertThat(parameterSpec, equalTo(algoParameters.getParameterSpec(ECParameterSpec.class)));
7781
}
7882

7983
public void testReadPKCS8EcKey() throws Exception {

plugins/discovery-ec2/build.gradle

+33-7
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,34 @@ task writeTestJavaPolicy {
6464
throw new GradleException("failed to create temporary directory [${tmp}]")
6565
}
6666
final File javaPolicy = file("${tmp}/java.policy")
67-
javaPolicy.write(
68-
[
69-
"grant {",
70-
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
71-
"};"
72-
].join("\n"))
67+
if (BuildParams.inFipsJvm) {
68+
javaPolicy.write(
69+
[
70+
"grant {",
71+
"permission java.security.SecurityPermission \"putProviderProperty.BCFIPS\";",
72+
"permission java.security.SecurityPermission \"putProviderProperty.BCJSSE\";",
73+
"permission java.lang.RuntimePermission \"getProtectionDomain\";",
74+
"permission java.util.PropertyPermission \"java.runtime.name\", \"read\";",
75+
"permission org.bouncycastle.crypto.CryptoServicesPermission \"tlsAlgorithmsEnabled\";",
76+
"permission java.lang.RuntimePermission \"accessClassInPackage.sun.security.internal.spec\";",
77+
"permission java.lang.RuntimePermission \"accessDeclaredMembers\";",
78+
"permission java.util.PropertyPermission \"intellij.debug.agent\", \"read\";",
79+
"permission java.util.PropertyPermission \"intellij.debug.agent\", \"write\";",
80+
"permission org.bouncycastle.crypto.CryptoServicesPermission \"exportSecretKey\";",
81+
"permission org.bouncycastle.crypto.CryptoServicesPermission \"exportPrivateKey\";",
82+
"permission java.io.FilePermission \"\${javax.net.ssl.trustStore}\", \"read\";",
83+
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
84+
"};"
85+
].join("\n")
86+
)
87+
} else {
88+
javaPolicy.write(
89+
[
90+
"grant {",
91+
" permission java.util.PropertyPermission \"com.amazonaws.sdk.ec2MetadataServiceEndpointOverride\", \"write\";",
92+
"};"
93+
].join("\n"))
94+
}
7395
}
7496
}
7597

@@ -80,7 +102,11 @@ test {
80102

81103
// this is needed to manipulate com.amazonaws.sdk.ec2MetadataServiceEndpointOverride system property
82104
// it is better rather disable security manager at all with `systemProperty 'tests.security.manager', 'false'`
83-
systemProperty 'java.security.policy', "file://${buildDir}/tmp/java.policy"
105+
if (BuildParams.inFipsJvm){
106+
systemProperty 'java.security.policy', "=file://${buildDir}/tmp/java.policy"
107+
} else {
108+
systemProperty 'java.security.policy', "file://${buildDir}/tmp/java.policy"
109+
}
84110
}
85111

86112
check {

plugins/ingest-attachment/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,6 @@ if (BuildParams.inFipsJvm) {
103103
// rather than provide a long list of exclusions, disable the check on FIPS.
104104
jarHell.enabled = false
105105
test.enabled = false
106-
integTest.enabled = false;
107-
testingConventions.enabled = false;
106+
integTest.enabled = false
107+
testingConventions.enabled = false
108108
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,12 @@ private static String sslContextAlgorithm(List<String> supportedProtocols) {
829829
}
830830

831831
private boolean shouldEnableDiagnoseTrust() {
832-
if (XPackSettings.FIPS_MODE_ENABLED.get(settings) && DIAGNOSE_TRUST_EXCEPTIONS_SETTING.exists(settings) == false ) {
832+
// We disable the DiagnosticTrustManager in tests in Java 8 in FIPS 140 mode, as we're not allowed to wrap X509TrustManager
833+
final boolean explicitlyDisable = Boolean.parseBoolean(System.getProperty("es.disable.diagnostic.trust.manager", "false"));
834+
if (explicitlyDisable) {
835+
logger.info("diagnostic messages for SSL/TLS trust failures are explicitly disabled.");
836+
return false;
837+
} else if (XPackSettings.FIPS_MODE_ENABLED.get(settings) && DIAGNOSE_TRUST_EXCEPTIONS_SETTING.exists(settings) == false) {
833838
logger.info("diagnostic messages for SSL/TLS trust failures are not enabled in FIPS 140 mode by default.");
834839
return false;
835840
} else {

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/transport/ProfileConfigurationsTests.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ public void testGetInsecureTransportProfileConfigurations() {
5858
}
5959

6060
private Settings.Builder getBaseSettings() {
61-
final Path keystore = randomBoolean()
62-
? getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks")
63-
: getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
64-
61+
final Path keystore = inFipsJvm()
62+
? getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12")
63+
: getDataPath(randomFrom("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks",
64+
"/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12"));
6565
MockSecureSettings secureSettings = new MockSecureSettings();
6666
secureSettings.setString("xpack.security.transport.ssl.keystore.secure_password", "testnode");
6767

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/PemUtilsTests.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
import java.io.InputStream;
1212
import java.nio.file.Files;
1313
import java.nio.file.Path;
14+
import java.security.AlgorithmParameters;
1415
import java.security.Key;
1516
import java.security.KeyStore;
1617
import java.security.PrivateKey;
1718
import java.security.interfaces.ECPrivateKey;
19+
import java.security.spec.ECGenParameterSpec;
1820
import java.security.spec.ECParameterSpec;
1921

2022
import static org.hamcrest.Matchers.equalTo;
@@ -70,8 +72,10 @@ public void testReadEcKeyCurves() throws Exception {
7072
("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/private_" + curve + ".pem"), ""::toCharArray);
7173
assertThat(privateKey, instanceOf(ECPrivateKey.class));
7274
ECParameterSpec parameterSpec = ((ECPrivateKey) privateKey).getParams();
73-
// This is brittle but we can't access sun.security.util.NamedCurve
74-
assertThat(parameterSpec.toString(), containsString(curve));
75+
ECGenParameterSpec algorithmParameterSpec = new ECGenParameterSpec(curve);
76+
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
77+
algoParameters.init(algorithmParameterSpec);
78+
assertThat(parameterSpec, equalTo(algoParameters.getParameterSpec(ECParameterSpec.class)));
7579
}
7680

7781
public void testReadEncryptedPKCS8Key() throws Exception {

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLServiceTests.java

+17-8
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,19 @@ public class SSLServiceTests extends ESTestCase {
9090

9191
@Before
9292
public void setup() throws Exception {
93-
// Randomise the keystore type (jks/PKCS#12)
94-
if (randomBoolean()) {
95-
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
96-
// The default is to use JKS. Randomly test with explicit and with the default value.
97-
testnodeStoreType = "jks";
98-
} else {
93+
// Randomise the keystore type (jks/PKCS#12) when possible
94+
if (inFipsJvm()) {
9995
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
10096
testnodeStoreType = randomBoolean() ? "PKCS12" : null;
97+
} else {
98+
if (randomBoolean()) {
99+
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks");
100+
// The default is to use JKS. Randomly test with explicit and with the default value.
101+
testnodeStoreType = "jks";
102+
} else {
103+
testnodeStore = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.p12");
104+
testnodeStoreType = randomBoolean() ? "PKCS12" : null;
105+
}
101106
}
102107
logger.info("Using [{}] key/truststore [{}]", testnodeStoreType, testnodeStore);
103108
testnodeCert = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt");
@@ -820,6 +825,8 @@ public void testThatSSLIOSessionStrategyTrustsJDKTrustedCAs() throws Exception {
820825
}
821826

822827
public void testWrapTrustManagerWhenDiagnosticsEnabled() {
828+
assumeFalse("We override the setting with a sysprop",
829+
Boolean.parseBoolean(System.getProperty("es.disable.diagnostic.trust.manager", "false")));
823830
final Settings.Builder builder = Settings.builder();
824831
if (randomBoolean()) { // randomly select between default, and explicit enabled
825832
builder.put("xpack.security.ssl.diagnose.trust", true);
@@ -841,7 +848,7 @@ public void testDontWrapTrustManagerWhenDiagnosticsDisabled() {
841848
assertThat(sslService.wrapWithDiagnostics(baseTrustManager, sslConfiguration), sameInstance(baseTrustManager));
842849
}
843850

844-
public void testDontWrapTrustManagerByDefaultWhenInFips(){
851+
public void testDontWrapTrustManagerByDefaultWhenInFips() {
845852
final Settings.Builder builder = Settings.builder();
846853
builder.put("xpack.security.fips_mode.enabled", true);
847854
final SSLService sslService = new SSLService(builder.build(), env);
@@ -850,7 +857,9 @@ public void testDontWrapTrustManagerByDefaultWhenInFips(){
850857
assertThat(sslService.wrapWithDiagnostics(baseTrustManager, sslConfiguration), sameInstance(baseTrustManager));
851858
}
852859

853-
public void testWrapTrustManagerWhenInFipsAndExplicitlyConfigured(){
860+
public void testWrapTrustManagerWhenInFipsAndExplicitlyConfigured() {
861+
assumeFalse("We override the setting with a sysprop",
862+
Boolean.parseBoolean(System.getProperty("es.disable.diagnostic.trust.manager", "false")));
854863
final Settings.Builder builder = Settings.builder();
855864
builder.put("xpack.security.fips_mode.enabled", true);
856865
builder.put("xpack.security.ssl.diagnose.trust", true);

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLReloadDuringStartupIntegTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
1414
import org.elasticsearch.test.InternalTestCluster.RestartCallback;
1515
import org.elasticsearch.test.SecurityIntegTestCase;
16+
import org.junit.BeforeClass;
1617

1718
import java.io.IOException;
1819
import java.io.UncheckedIOException;
@@ -28,6 +29,11 @@
2829
@ClusterScope(transportClientRatio = 0)
2930
public class SSLReloadDuringStartupIntegTests extends SecurityIntegTestCase {
3031

32+
@BeforeClass
33+
public static void skipInFips() {
34+
assumeFalse("Can't use JKS keystores in FIPS JVM", inFipsJvm());
35+
}
36+
3137
@Override
3238
public Settings nodeSettings(int nodeOrdinal) {
3339
Settings settings = super.nodeSettings(nodeOrdinal);

0 commit comments

Comments
 (0)