-
Notifications
You must be signed in to change notification settings - Fork 25k
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
[WIP] Add BouncyCastleFipsProvider as test dependency #41024
Conversation
This commit sets up a fake ivy repository to use for adding the JAR that provides the BCFIPS Security Provider as a dependency and adds it as a testRuntimeOnly dependency in all test tasks. It also disables jarHell task for many projects that either have the plain BouncyCastle provider jar as a dependency already ( plugin-cli, security-cli, etc. ) or depend on the security plugin, that in turn has a compileOnly dependency on the plain BouncyCastle provider (because of opensaml) This change was driven by the fact that the extensions mechanism (/jre/lib/ext) was removed in JDK9 and BouncyCastle does not yet offer a module for the BCFIPS provider that we could use to build an image to run our tests in a FIPS approved mode. This change enables us to run any JDK version JVM in fips approved mode.
Pinging @elastic/es-core-infra |
Pinging @elastic/es-security |
@@ -63,6 +63,7 @@ File keystore = new File(project.buildDir, 'keystore/test-node.jks') | |||
|
|||
// generate the keystore | |||
task createKey(type: LoggedExec) { | |||
onlyIf { inFipsJvm == false } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this task would fail as the JVM is setup for FIPS (BCFKS keystores, etc) but the dependency is not added when this is evaluated so the necessary classes are not available. We don't use the produced keystore eitherway as this can only work with a JKS keystore which is not available in FIPS - and this is why the integTest
task is also disabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow. If integTest is disabled, what would try to run this task in FIPS mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's because of processTestResources.dependsOn(createKey)
below. I'd be happy to explore alternatives if you have suggestions!
String inFipsJvmScript = 'print(java.security.Security.getProviders()[0].name.toLowerCase().contains("fips"));' | ||
boolean inFipsJvm = Boolean.parseBoolean(runJavaAsScript(project, runtimeJavaHome, inFipsJvmScript)) | ||
// Java home name checking is fragile, but we control the environment | ||
boolean inFipsJvm = runtimeJavaHome.contains("fips") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, the Provider was statically added as a system wide dependency ( in lib/ext
of a jdk8 JVM ) so we could evaluate the getProviders() result here. Now the preference order is still set in java.security
but the dependency is not yet available so the provider won't be loaded
} | ||
if (inFipsJvm){ | ||
// Disable jarHell in FIPS as we add the BC FIPS Provider as a dependency for the tests | ||
jarHell.enabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move this PrecommitTasks.configureJarHell()
where the JarHell
task is actually created rather than have to explicitly disable this all over the place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we fine with disabling jarHell for all projects while running tests in a FIPS JVM ? If so, I'd be more than happy to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. We have numerous other builds that will catch any issues here.
@@ -63,6 +63,7 @@ File keystore = new File(project.buildDir, 'keystore/test-node.jks') | |||
|
|||
// generate the keystore | |||
task createKey(type: LoggedExec) { | |||
onlyIf { inFipsJvm == false } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow. If integTest is disabled, what would try to run this task in FIPS mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some notes.
Maybe I missed this but it seems this won't for rest tests as the tests themselves will run on fips jvm but the cluster will not.
@@ -590,6 +589,16 @@ class BuildPlugin implements Plugin<Project> { | |||
url "https://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/${revision}" | |||
} | |||
} | |||
String compilerJavaHome = findCompilerJavaHome() | |||
String runtimeJavaHome = findRuntimeJavaHome(compilerJavaHome) | |||
if (runtimeJavaHome.contains("fips")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we take this opportunity to clean things up and have something like -Dfips.enabled=true
or -Dtests/fips=true
rather than rely on the runtime java home name ?
My understanding is that we no longer need to make modifications to that location, so it will only really act as a flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good idea ! What we would need to do is to bundle the java.policy
and java.security
(one for each jdk version) as test resources and adjust the system properties ( -Djava.security.policy
and -Djava.security.properties
IIRC) the same way we do for the keystore password. Would that be ok ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's better as it will have all the fips config contained in our build.
You'll probably want to look at the ExportElasticsearchBuildResourcesTask
tasks , there's already one created for each project.
|
||
// Java home name checking is fragile, but we control the environment | ||
if (project.runtimeJavaHome.contains("fips")){ | ||
task.enabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth to have a comment here explaining why we can't have jar hell in fips.
@@ -906,6 +915,10 @@ class BuildPlugin implements Plugin<Project> { | |||
File heapdumpDir = new File(project.buildDir, 'heapdump') | |||
|
|||
project.tasks.withType(Test) { Test test -> | |||
RepositoryHandler repos = project.repositories | |||
if (project.ext.inFipsJvm) { | |||
project.dependencies.add('testRuntimeOnly', "org.bouncycastle:bc-fips:1.0.1:jar") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we carry this classpath tot he clusters running in the rest tests, so these will probably not be running with fips enabled. We should have a smoke test to verify that fips is really enabled everywhere we think it is when we build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I missed this but it seems this won't for rest tests as the tests themselves will run on fips jvm but the cluster will not.
Good catch, thanks
How about the integTest clusters? Those are covered by the above, correct ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes internal clusters run in the same jvm as tests so would are covered.
Marking this as a [WIP], until we have some feedback for JDK11, see #37250 (comment) |
This change enables us to run our test suites in JVMs configured in FIPS 140 approved mode. It does so by: - Using BouncyCastle FIPS Cryptographic provider and BSJSSE in FIPS mode. These are used as testRuntime dependencies for unit tests and internal clusters, and copied (relevant jars) explicitly to the lib directory for testclusters used in REST tests - Configuring any given runtime Java in FIPS mode with the bundled policy and security properties files, setting the system properties java.security.properties and java.security.policy with the == operator that overrides the default JVM properties and policy. Running the tests in FIPS 140 approved mode doesn't require an additional configuration either in CI workers or locally and is controlled by specifying -Dtests.fips.enabled=true Closes: #37250 Supersedes: #41024
This change enables us to run our test suites in JVMs configured in FIPS 140 approved mode. It does so by: - Using BouncyCastle FIPS Cryptographic provider and BSJSSE in FIPS mode. These are used as testRuntime dependencies for unit tests and internal clusters, and copied (relevant jars) explicitly to the lib directory for testclusters used in REST tests - Configuring any given runtime Java in FIPS mode with the bundled policy and security properties files, setting the system properties java.security.properties and java.security.policy with the == operator that overrides the default JVM properties and policy. Running the tests in FIPS 140 approved mode doesn't require an additional configuration either in CI workers or locally and is controlled by specifying -Dtests.fips.enabled=true Closes: elastic#37250 Supersedes: elastic#41024
This commit sets up a fake ivy repository to use for adding the
JAR that provides the BCFIPS Security Provider as a
testRuntimeOnly dependency in all test tasks.
It also disables jarHell task for many projects that either have the
plain BouncyCastle provider jar as a dependency already ( plugin-cli,
security-cli, etc. ) or depend on the security plugin, that in
turn has a compileOnly dependency on the plain BouncyCastle provider
(because of opensaml)
This change was driven by the fact that the extensions mechanism
(/jre/lib/ext) was removed in JDK9 and BouncyCastle does not yet
offer a module for the BCFIPS provider that we could use to build
an image to run our tests in a FIPS approved mode. This
change enables us to run any JDK version JVM in FIPS approved
mode.