-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Enable tests in FIPS 140 in JDK 11 #48378
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
Conversation
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 using 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`
Pinging @elastic/es-core-infra (:Core/Infra/Build) |
Pinging @elastic/es-security (:Security/Security) |
X509ExtendedTrustManager loadedTrustManager = Optional.ofNullable(trustConfig.createTrustManager(env)). | ||
orElse(getEmptyTrustManager()); | ||
X509ExtendedKeyManager loadedKeyManager = keyConfig.createKeyManager(env); | ||
X509ExtendedTrustManager loadedTrustManager = trustConfig.createTrustManager(env); |
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.
We'd never call getEmptyTrustManager
as none of the implementations of createTrustManager
returns null. As for an emtpyKeyManager, this could only happen for KeyConfig NONE - so I moved this there
@@ -153,15 +153,16 @@ public void testReloadingKeyStore() throws Exception { | |||
* Tests the reloading of SSLContext when a PEM key and certificate are used. | |||
*/ | |||
public void testPEMKeyConfigReloading() throws Exception { | |||
assumeFalse("This fails with BCJSSE with 'certificate does not verify with supplied key'", inFipsJvm()); |
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'll follow these up with appropriate issues once the troubleshooting is concluded
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.
Can we link them to an issue or something. I don't love having temporary assumeFalse
in tests without a way to trace it back to an action.
@@ -38,6 +38,7 @@ | |||
private final AtomicInteger openPages = new AtomicInteger(0); | |||
|
|||
public void testPingPongAndClose() throws Exception { | |||
assumeFalse("Fails in normalClose as receiveDriver.getOutboundBuffer().hasEncryptedBytesToFlush() is false", inFipsJvm()); |
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'll follow these up with appropriate issues once the troubleshooting is concluded
Fun fact: BCJSSE doesn't disallow the use of JKS keystores as SunJSSE did. SunJSSE also does not explicitly disallow |
} | ||
} | ||
|
||
private void configureNodeForFips() { |
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.
We should do this externally, you can use testclusters.all {}
to configure all clusters in a project, so combining that with allprojects {}
would allow you to configure it across the board
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 can't figure out how I can reference the file locations from within the BuildPlugin
if I do this in testclusters.all {}. Any ideas ?
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.
Locations of what files exactly?
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.
The fips_java.security, fips_java.policy and cacerts.bcfks that I copy as extra config files
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.
That's problematic indeed. getConfigDir
is public, but we don't have a way to iterate over the nodes, or configure nodes individually.
Does this needs to be an absolute path ? Would a path relative to cwd work ? e.x. conf/fips_java.policy
i think that's how this problem is solved elsewhere.
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.
These paths are passed as values to system properties, not used in ES configuration so we either need an absolute path. Maybe we have a global reference to the ES_CONF_DIR that can be resolved in a system property? I'll look into it
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.
Solution required adding ES_PATH_CONF
to the substitutions we do when parsing jvm.properties
. Can't think of a side-effect but I wanted to raise it for visibility when this is reviewed
buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
Outdated
Show resolved
Hide resolved
* Copies extra jars to the `/lib` directory. | ||
* //TODO: Remove this when system modules are available | ||
*/ | ||
private void copyExtraJars() { |
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.
We prefer not to couple testclusters with random project configuration like an extraJars
configuration.
Would be better to have extra jars work exactly as extra config files so these jars could be passed in externally.
A more generic way would be to add the possibility to add hooks right before the task starts.
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 moved this outside as suggested, similar to how extraConfigurationFiles work
@atorok I have addressed your comments, please take another look |
ci/1 failed due to #48440 @elasticmachine run elasticsearch-ci/1 |
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.
LGTM. Thanks !
@elasticmachine run elasticsearch-ci/packaging-sample-matrix |
logToProcessStdout("Setting up " + extraJarFiles.size() + " additional jar dependencies"); | ||
} | ||
extraJarFiles.forEach(from -> { | ||
Path destination = getDistroDir().resolve("lib").resolve(from.getName()); |
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 this will leave trash behind. @atorok don't we setup a link for the lib dir? This would copy into the lib dir and be left behind after the test is run?
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.
We don't set up links for directories, so this will be fine.
We create a matching directory structure, and create hard links for the files.
That does bring up a slightly different problem, if we were to replace one of the jars with this mechanism, that will be reflected for all invocations across all projects because the initial file could have changed. That would be really hard to spot and debug. We originally had code to set the links to read only so this would error out, maybe we should get that back ? It would work across the board, as opposed to just checking that the libs don't replace other libs.
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.
is this something that should be taken into consideration in the context of this PR @atorok or are we ok to merge this and address it in a follow up ?
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 ok as a follow-up
@elasticmachine run elasticsearch-ci/1 |
ping @tvernum for a look at this one. Specifically the changes around SSLService and the empty{Trust,Key}Manager |
@@ -153,15 +153,16 @@ public void testReloadingKeyStore() throws Exception { | |||
* Tests the reloading of SSLContext when a PEM key and certificate are used. | |||
*/ | |||
public void testPEMKeyConfigReloading() throws Exception { | |||
assumeFalse("This fails with BCJSSE with 'certificate does not verify with supplied key'", inFipsJvm()); |
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.
Can we link them to an issue or something. I don't love having temporary assumeFalse
in tests without a way to trace it back to an action.
@@ -239,6 +239,8 @@ public void testGroupLookupBase() throws Exception { | |||
* (one failure, one success) depending on which file content is in place. | |||
*/ | |||
public void testSslTrustIsReloaded() throws Exception { | |||
assumeFalse("NPE thrown in BCFIPS JSSE - addressed in https://github" + | |||
".com/bcgit/bc-java/commit/5aed687e17a3cd63f34373cafe92699b90076fb6#diff-8e5d8089bc0d504d93194a1e484d3950R179", inFipsJvm()); |
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.
Can we re-wrap this string so the URL is on a single line?
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
The relevant handling part has been removed in infra, FIPS 140 testing needs to be enabled in the same manner as it happened for master and 7.x in elastic#48378 and elastic#49485 resolves: elastic#51924
The relevant handling part has been removed in infra, FIPS 140 testing needs to be enabled in the same manner as it happened for master and 7.x in elastic#48378 and elastic#49485 resolves: elastic#51980
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 using the system
properties
java.security.properties
andjava.security.policy
with the
==
operator that overrides the default JVM propertiesand 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