Skip to content

Commit 3de9156

Browse files
committed
Adjustments for FIPS 140 testing (elastic#49319)
- Don't install ingest-attachment and don't run the related docs tests, since ingest-attachment is not supported in FIPS 140 JVMs - Move copying extra jars and extra config files earlier on in the node configuration so that elasticsearch-keystore and elasticsearch-plugin that run before the node starts have all files (policy, properties, jars) available. - BCJSSE needs a certificate to be explicitly added in a keystore as a trustedcerty entry, it's not enough for it to be in privatekeyentry for it to be trusted - Set the value for BuildParams.inFipsJvm configuration time
1 parent 1d7867d commit 3de9156

File tree

23 files changed

+295
-90
lines changed

23 files changed

+295
-90
lines changed

buildSrc/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ if (project != rootProject) {
171171
forbiddenApisTest.enabled = false
172172
jarHell.enabled = false
173173
thirdPartyAudit.enabled = false
174+
if (Boolean.parseBoolean(System.getProperty("tests.fips.enabled"))){
175+
test.enabled = false
176+
}
174177

175178
configurations {
176179
distribution

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
*/
1919
package org.elasticsearch.gradle
2020

21-
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
2221
import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin
2322
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension
2423
import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin
@@ -27,6 +26,8 @@ import groovy.transform.CompileStatic
2726
import org.apache.commons.io.IOUtils
2827
import org.elasticsearch.gradle.info.BuildParams
2928
import org.elasticsearch.gradle.info.GlobalBuildInfoPlugin
29+
import org.elasticsearch.gradle.info.GlobalInfoExtension
30+
import org.elasticsearch.gradle.info.JavaHome
3031
import org.elasticsearch.gradle.precommit.DependencyLicensesTask
3132
import org.elasticsearch.gradle.precommit.PrecommitTasks
3233
import org.elasticsearch.gradle.test.ErrorReportingTestListener
@@ -144,44 +145,60 @@ class BuildPlugin implements Plugin<Project> {
144145
static void configureFips140(Project project) {
145146
// Common config when running with a FIPS-140 runtime JVM
146147
if (inFipsJvm()) {
147-
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') as ExportElasticsearchBuildResourcesTask
148-
File securityProperties = buildResources.copy("fips_java.security")
149-
File securityPolicy = buildResources.copy("fips_java.policy")
150-
File bcfksKeystore = buildResources.copy("cacerts.bcfks")
151148
// This configuration can be removed once system modules are available
152149
Boilerplate.maybeCreate(project.configurations, 'extraJars') {
153150
project.dependencies.add('extraJars', "org.bouncycastle:bc-fips:1.0.1")
154151
project.dependencies.add('extraJars', "org.bouncycastle:bctls-fips:1.0.9")
155152
}
153+
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') as ExportElasticsearchBuildResourcesTask
154+
File securityProperties = buildResources.copy("fips_java.security")
155+
File security8Properties = buildResources.copy("fips_java8.security")
156+
File securityPolicy = buildResources.copy("fips_java.policy")
157+
File security8Policy = buildResources.copy("fips_java8.policy")
158+
File bcfksKeystore = buildResources.copy("cacerts.bcfks")
159+
GlobalInfoExtension globalInfo = project.rootProject.extensions.getByType(GlobalInfoExtension)
156160
project.pluginManager.withPlugin("elasticsearch.testclusters") {
157161
NamedDomainObjectContainer<ElasticsearchCluster> testClusters = project.extensions.findByName(TestClustersPlugin.EXTENSION_NAME) as NamedDomainObjectContainer<ElasticsearchCluster>
158162
testClusters.all { ElasticsearchCluster cluster ->
159-
for (File dep : project.getConfigurations().getByName("extraJars").getFiles()){
160-
cluster.extraJarFile(dep)
163+
globalInfo.ready {
164+
for (File dep : project.getConfigurations().getByName("extraJars").getFiles()) {
165+
cluster.extraJarFile(dep)
166+
}
167+
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_1_8) {
168+
cluster.extraConfigFile("fips_java.security", securityProperties)
169+
cluster.extraConfigFile("fips_java.policy", securityPolicy)
170+
} else {
171+
cluster.extraConfigFile("fips_java.security", security8Properties)
172+
cluster.extraConfigFile("fips_java.policy", security8Policy)
173+
}
174+
cluster.extraConfigFile("cacerts.bcfks", bcfksKeystore)
175+
cluster.systemProperty('java.security.properties', '=${ES_PATH_CONF}/fips_java.security')
176+
cluster.systemProperty('java.security.policy', '=${ES_PATH_CONF}/fips_java.policy')
177+
cluster.systemProperty('javax.net.ssl.trustStore', '${ES_PATH_CONF}/cacerts.bcfks')
178+
cluster.systemProperty('javax.net.ssl.trustStorePassword', 'password')
179+
cluster.systemProperty('javax.net.ssl.keyStorePassword', 'password')
180+
cluster.systemProperty('javax.net.ssl.keyStoreType', 'BCFKS')
161181
}
162-
cluster.extraConfigFile("fips_java.security", securityProperties)
163-
cluster.extraConfigFile("fips_java.policy", securityPolicy)
164-
cluster.extraConfigFile("cacerts.bcfks", bcfksKeystore)
165-
cluster.systemProperty('java.security.properties', '=${ES_PATH_CONF}/fips_java.security')
166-
cluster.systemProperty('java.security.policy', '=${ES_PATH_CONF}/fips_java.policy')
167-
cluster.systemProperty('javax.net.ssl.trustStore', '${ES_PATH_CONF}/cacerts.bcfks')
168-
cluster.systemProperty('javax.net.ssl.trustStorePassword', 'password')
169-
cluster.systemProperty('javax.net.ssl.keyStorePassword', 'password')
170-
cluster.systemProperty('javax.net.ssl.keyStoreType', 'BCFKS')
171182
}
172183
}
173184
project.tasks.withType(Test).configureEach { Test task ->
174185
task.dependsOn(buildResources)
175-
task.systemProperty('javax.net.ssl.trustStorePassword', 'password')
176-
task.systemProperty('javax.net.ssl.keyStorePassword', 'password')
177-
task.systemProperty('javax.net.ssl.trustStoreType', 'BCFKS')
178-
// Using the key==value format to override default JVM security settings and policy
179-
// see also: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html
180-
task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", securityProperties.toString()))
181-
task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", securityPolicy.toString()))
182-
task.systemProperty('javax.net.ssl.trustStore', bcfksKeystore.toString())
186+
globalInfo.ready {
187+
task.systemProperty('javax.net.ssl.trustStorePassword', 'password')
188+
task.systemProperty('javax.net.ssl.keyStorePassword', 'password')
189+
task.systemProperty('javax.net.ssl.trustStoreType', 'BCFKS')
190+
// Using the key==value format to override default JVM security settings and policy
191+
// see also: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html
192+
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_1_8) {
193+
task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", securityProperties.toString()))
194+
task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", securityPolicy.toString()))
195+
} else {
196+
task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", security8Properties.toString()))
197+
task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", security8Policy.toString()))
198+
}
199+
task.systemProperty('javax.net.ssl.trustStore', bcfksKeystore.toString())
200+
}
183201
}
184-
185202
}
186203
}
187204

buildSrc/src/main/java/org/elasticsearch/gradle/info/GenerateGlobalBuildInfoTask.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
4141
private final RegularFileProperty outputFile;
4242
private final RegularFileProperty compilerVersionFile;
4343
private final RegularFileProperty runtimeVersionFile;
44-
private final RegularFileProperty fipsJvmFile;
4544

4645
@Inject
4746
public GenerateGlobalBuildInfoTask(ObjectFactory objectFactory) {
4847
this.outputFile = objectFactory.fileProperty();
4948
this.compilerVersionFile = objectFactory.fileProperty();
5049
this.runtimeVersionFile = objectFactory.fileProperty();
51-
this.fipsJvmFile = objectFactory.fileProperty();
5250
}
5351

5452
@Input
@@ -113,11 +111,6 @@ public RegularFileProperty getRuntimeVersionFile() {
113111
return runtimeVersionFile;
114112
}
115113

116-
@OutputFile
117-
public RegularFileProperty getFipsJvmFile() {
118-
return fipsJvmFile;
119-
}
120-
121114
@TaskAction
122115
public void generate() {
123116
String javaVendorVersion = System.getProperty("java.vendor.version", System.getProperty("java.vendor"));
@@ -130,7 +123,6 @@ public void generate() {
130123
String runtimeJavaVersionDetails = gradleJavaVersionDetails;
131124
JavaVersion runtimeJavaVersionEnum = JavaVersion.current();
132125
File gradleJavaHome = Jvm.current().getJavaHome();
133-
boolean inFipsJvm = false;
134126

135127
try {
136128
if (Files.isSameFile(compilerJavaHome.toPath(), gradleJavaHome.toPath()) == false) {
@@ -146,8 +138,6 @@ public void generate() {
146138
if (runtimeJavaHome.exists()) {
147139
runtimeJavaVersionDetails = findJavaVersionDetails(runtimeJavaHome);
148140
runtimeJavaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(runtimeJavaHome));
149-
150-
inFipsJvm = Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
151141
} else {
152142
throw new RuntimeException("Runtime Java home path of '" + compilerJavaHome + "' does not exist");
153143
}
@@ -213,7 +203,6 @@ public void generate() {
213203

214204
writeToFile(compilerVersionFile.getAsFile().get(), compilerJavaVersionEnum.name());
215205
writeToFile(runtimeVersionFile.getAsFile().get(), runtimeJavaVersionEnum.name());
216-
writeToFile(fipsJvmFile.getAsFile().get(), Boolean.toString(inFipsJvm));
217206
}
218207

219208
private void writeToFile(File file, String content) {

buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,12 @@ public void apply(Project project) {
7676
task.getOutputFile().set(new File(project.getBuildDir(), "global-build-info"));
7777
task.getCompilerVersionFile().set(new File(project.getBuildDir(), "java-compiler-version"));
7878
task.getRuntimeVersionFile().set(new File(project.getBuildDir(), "java-runtime-version"));
79-
task.getFipsJvmFile().set(new File(project.getBuildDir(), "in-fips-jvm"));
8079
});
8180

8281
PrintGlobalBuildInfoTask printTask = project.getTasks().create("printGlobalBuildInfo", PrintGlobalBuildInfoTask.class, task -> {
8382
task.getBuildInfoFile().set(generateTask.getOutputFile());
8483
task.getCompilerVersionFile().set(generateTask.getCompilerVersionFile());
8584
task.getRuntimeVersionFile().set(generateTask.getRuntimeVersionFile());
86-
task.getFipsJvmFile().set(generateTask.getFipsJvmFile());
8785
task.setGlobalInfoListeners(extension.listeners);
8886
});
8987

@@ -103,6 +101,7 @@ public void apply(Project project) {
103101
params.setIsCi(System.getenv("JENKINS_URL") != null);
104102
params.setIsInternal(GlobalBuildInfoPlugin.class.getResource("/buildSrc.marker") != null);
105103
params.setDefaultParallel(findDefaultParallel(project));
104+
params.setInFipsJvm(isInFipsJvm());
106105
});
107106

108107
project.allprojects(p -> {
@@ -153,6 +152,10 @@ private static String getJavaHomeEnvVarName(String version) {
153152
return "JAVA" + version + "_HOME";
154153
}
155154

155+
private static boolean isInFipsJvm() {
156+
return Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
157+
}
158+
156159
private static String getResourceContents(String resourcePath) {
157160
try (BufferedReader reader = new BufferedReader(
158161
new InputStreamReader(GlobalBuildInfoPlugin.class.getResourceAsStream(resourcePath))

buildSrc/src/main/java/org/elasticsearch/gradle/info/PrintGlobalBuildInfoTask.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
1616
private final RegularFileProperty buildInfoFile;
1717
private final RegularFileProperty compilerVersionFile;
1818
private final RegularFileProperty runtimeVersionFile;
19-
private final RegularFileProperty fipsJvmFile;
2019
private List<Runnable> globalInfoListeners = new ArrayList<>();
2120

2221
@Inject
2322
public PrintGlobalBuildInfoTask(ObjectFactory objectFactory) {
2423
this.buildInfoFile = objectFactory.fileProperty();
2524
this.compilerVersionFile = objectFactory.fileProperty();
2625
this.runtimeVersionFile = objectFactory.fileProperty();
27-
this.fipsJvmFile = objectFactory.fileProperty();
2826
}
2927

3028
@InputFile
@@ -42,11 +40,6 @@ public RegularFileProperty getRuntimeVersionFile() {
4240
return runtimeVersionFile;
4341
}
4442

45-
@InputFile
46-
public RegularFileProperty getFipsJvmFile() {
47-
return fipsJvmFile;
48-
}
49-
5043
public void setGlobalInfoListeners(List<Runnable> globalInfoListeners) {
5144
this.globalInfoListeners = globalInfoListeners;
5245
}
@@ -57,6 +50,7 @@ public void print() {
5750
getLogger().quiet("Elasticsearch Build Hamster says Hello!");
5851
getLogger().quiet(getFileText(getBuildInfoFile()).asString());
5952
getLogger().quiet(" Random Testing Seed : " + BuildParams.getTestSeed());
53+
getLogger().quiet(" In FIPS 140 mode : " + BuildParams.isInFipsJvm());
6054
getLogger().quiet("=======================================");
6155

6256
setGlobalProperties();
@@ -76,7 +70,6 @@ private void setGlobalProperties() {
7670
BuildParams.init(params -> {
7771
params.setCompilerJavaVersion(JavaVersion.valueOf(getFileText(getCompilerVersionFile()).asString()));
7872
params.setRuntimeJavaVersion(JavaVersion.valueOf(getFileText(getRuntimeVersionFile()).asString()));
79-
params.setInFipsJvm(Boolean.parseBoolean(getFileText(getFipsJvmFile()).asString()));
8073
});
8174
}
8275
}

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,11 @@ public synchronized void start() {
415415
} catch (IOException e) {
416416
throw new UncheckedIOException("Failed to create working directory for " + this, e);
417417
}
418+
419+
copyExtraJars();
420+
421+
copyExtraConfigFiles();
422+
418423
createConfiguration();
419424

420425
if (plugins.isEmpty() == false) {
@@ -438,7 +443,7 @@ public synchronized void start() {
438443
runElaticsearchBinScript("elasticsearch-keystore", "create");
439444

440445
keystoreSettings.forEach((key, value) ->
441-
runElaticsearchBinScriptWithInput(value.toString(), "elasticsearch-keystore", "add", "-x", key)
446+
runElasticsearchBinScriptWithInput(value.toString(), "elasticsearch-keystore", "add", "-x", key)
442447
);
443448

444449
for (Map.Entry<String, File> entry : keystoreFiles.entrySet()) {
@@ -453,10 +458,6 @@ public synchronized void start() {
453458

454459
installModules();
455460

456-
copyExtraConfigFiles();
457-
458-
copyExtraJars();
459-
460461
if (isSettingTrue("xpack.security.enabled")) {
461462
if (credentials.isEmpty()) {
462463
user(Collections.emptyMap());
@@ -622,7 +623,7 @@ public void user(Map<String, String> userSpec) {
622623
credentials.add(cred);
623624
}
624625

625-
private void runElaticsearchBinScriptWithInput(String input, String tool, String... args) {
626+
private void runElasticsearchBinScriptWithInput(String input, String tool, String... args) {
626627
if (
627628
Files.exists(getDistroDir().resolve("bin").resolve(tool)) == false &&
628629
Files.exists(getDistroDir().resolve("bin").resolve(tool + ".bat")) == false
@@ -663,7 +664,7 @@ private void runElaticsearchBinScriptWithInput(String input, String tool, String
663664
}
664665

665666
private void runElaticsearchBinScript(String tool, String... args) {
666-
runElaticsearchBinScriptWithInput("", tool, args);
667+
runElasticsearchBinScriptWithInput("", tool, args);
667668
}
668669

669670
private Map<String, String> getESEnvironment() {
@@ -676,6 +677,10 @@ private Map<String, String> getESEnvironment() {
676677
if (systemProperties.isEmpty() == false) {
677678
systemPropertiesString = " " + systemProperties.entrySet().stream()
678679
.map(entry -> "-D" + entry.getKey() + "=" + entry.getValue())
680+
// ES_PATH_CONF is also set as an environment variable and for a reference to ${ES_PATH_CONF}
681+
// to work ES_JAVA_OPTS, we need to make sure that ES_PATH_CONF before ES_JAVA_OPTS. Instead,
682+
// we replace the reference with the actual value in other environment variables
683+
.map(p -> p.replace("${ES_PATH_CONF}", configFile.getParent().toString()))
679684
.collect(Collectors.joining(" "));
680685
}
681686
String jvmArgsString = "";
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
grant codeBase "file:${java.home}/lib/ext/localedata.jar" {
2+
// Allow resource bundles to be loaded for non root locales. See
3+
// https://github.com/elastic/elasticsearch/issues/39981
4+
permission java.lang.RuntimePermission "accessClassInPackage.sun.util.*";
5+
};
6+
grant {
7+
permission org.bouncycastle.crypto.CryptoServicesPermission "exportPrivateKey";
8+
permission org.bouncycastle.crypto.CryptoServicesPermission "exportSecretKey";
9+
permission java.lang.RuntimePermission "getProtectionDomain";
10+
permission java.util.PropertyPermission "java.runtime.name", "read";
11+
permission org.bouncycastle.crypto.CryptoServicesPermission "tlsAlgorithmsEnabled";
12+
//io.netty.handler.codec.DecoderException
13+
permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
14+
//java.security.InvalidAlgorithmParameterException: Cannot process GCMParameterSpec
15+
permission java.lang.RuntimePermission "accessDeclaredMembers";
16+
};

0 commit comments

Comments
 (0)