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

Support for FIPS compliance mode #14912

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

beanuwave
Copy link

Description

  • FIPS gradle build script is removed.
  • All BC dependencies are replaces by BCFIPS.
  • Password matcher inside Identity-Shiro that replies on BC to check if hashed passwords matches with OpenBSDBCrypt, is replaced by password4j implementation.
  • Adds support for BCFKS format (*.bks) for Key & Truststores.
  • Refactor parsing private keys with formats EC, PKCS8, PKCS1, DSA, w/wo encryption, w/wo parameters.
  • FIPS approved-only mode can be configured over opensearch.yml file.
  • java security file is added to the build.
  • java policy file is altered to grant neccessary security permissions.

This PR provides FIPS 140-2 support by replacing all BC dependencies with BCFIPS dependencies and making FIPS approved-only mode configurable at launch. Running application in approved-only mode restricts BCFIPS provoder to rely solely on FIPS certified cyphers. Due to replacement of BC libraries, BCrypt password matching and private-key loading from file were replaced by alternative implementations.

Reasons for refactoring PemUtils.java that is used by Reindex API, in case of migrating data from a remote cluster that is TLS protected:

  • PKCS#8 implementation was not supported by BCFIPS library.
  • java type security.
  • Password Based Key Derivation Functions such as PKCS#12 and OpenSSL are not supported in BCFIPS approved-only mode, because only PBKDF2 standard is approved for use in FIPS.
  • generally good idea to let ASN1 annotation parsing be done by external security libraries.

Related Issues

opensearch-project/security#3420

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Copy link
Contributor

❌ Gradle check result for 6016d5d: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@beanuwave beanuwave changed the title Draft to allow run in FIPS compliace mode Draft to allow run in FIPS compliance mode Jul 24, 2024
Copy link
Contributor

❌ Gradle check result for 8e8ed47: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Copy link
Contributor

❌ Gradle check result for 6016d5d: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@dblock
Copy link
Member

dblock commented Jul 24, 2024

Could use some help maybe from @cwperks or @peternied reviewing this, please.

@@ -1182,6 +1182,7 @@ private void createConfiguration() {
baseConfig.put("indices.breaker.total.use_real_memory", "false");
// Don't wait for state, just start up quickly. This will also allow new and old nodes in the BWC case to become the master
baseConfig.put("discovery.initial_state_timeout", "0s");
baseConfig.put("fips.approved", "true");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we proposed a similar flag previously we were encouraged not to use boolean flags to control behaviour like this opensearch-project/security#3420 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am of the opinion that this is fine, in this case, I am not sure what greater configuration would make sense. Unless you can provide different approvers or something, there is no reason for this not to be a boolean.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have missed the part of the thread where that issue came up - I'd rather see crypto.standard=FIPS-140-2 & cypto.standard=any-supported to help understand what state the server is in when viewing a configuration file. I am definately open to other ideas that clarify what state the cluster is running it, as I think it could be useful to support FIPS-140-3 seperately or other standards/restrictions as they are addopted.

This isn't a blocker - it could be circled back on when we need to support a 3rd mode, the question is if that is a potential near term issue vs later on (or never).

Copy link
Contributor

❌ Gradle check result for 7e202a2: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Copy link
Contributor

❌ Gradle check result for bbbafa9: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@beanuwave
Copy link
Author

Previously, my main focus was on running the entire test suite without the BC non-FIPS libraries, which was successfully achieved. Now, the latest changes affect FIPS compatibility by running all tests again with the additional VM parameter -Dtests.fips.enabled=true. This has resulted in several code modifications:

  • Introduced an additional test parameter: tests.fips.enabled.
  • Added support for the .bcfips keystore file format.
  • Keystores now require strict type matching.
  • Recreated some cryptographic keys, as they are no longer maintainable with newer versions of keytool and OpenSSL.
  • Keystores without a passphrase are no longer supported because BC FIPS requires passwords with at least 112 bits strength.

Currently, the AWS S3 plugin is the remaining component that needs adjustment for FIPS mode. However, applying FIPS mode to every security-relevant thread using CryptoServicesRegistrar#setApprovedOnlyMode seems unsustainable. Setting the VM parameter org.bouncycastle.fips.approved_only=true accomplishes the same goal for the entire application and eliminates the need for FIPS-specific code snippets in core classes like AbstractRunnable or ThreadContext.

Another topic to consider is how to extend the Jenkins pipeline to run tasks like gradle check in FIPS mode. Should we implement an additional downstream process that runs on every build, even if it might almost double the execution time? Or is a separate pipeline which runs at the higher stages and can be manually triggered the way to go?

@beanuwave beanuwave marked this pull request as ready for review September 26, 2024 16:10
@beanuwave
Copy link
Author

@peternied Are we moving in the right direction?

@peternied
Copy link
Member

@beanuwave Thanks for making these updates - I'll need a little time to digest them. While I do so could you please address all unresolved comment threads and look into the GitHub action failures?

Copy link
Member

@peternied peternied left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directionally this is looking solid, I've got some background questions to make sure I understand some of the tradeoffs.

@beanuwave
Copy link
Author

Directionally this is looking solid, I've got some background questions to make sure I understand some of the tradeoffs.

Definitely, can we set up a direct call? I've contacted you on slack to find a suitable timeslot.

@peternied
Copy link
Member

Directionally this is looking solid, I've got some background questions to make sure I understand some of the tradeoffs.

Definitely, can we set up a direct call? I've contacted you on slack to find a suitable timeslot.

Sorry I might have been unclear, I've put those questions in comments on this PR, I don't need to schedule a call, please review the unresolved comment threads for the open questions I have, one for example #14912 (comment)

Signed-off-by: Iwan Igonin <[email protected]>

# Conflicts:
#	server/build.gradle
Signed-off-by: Iwan Igonin <[email protected]>

# Conflicts:
#	client/rest/build.gradle
#	distribution/tools/plugin-cli/build.gradle
#	server/src/main/resources/org/opensearch/bootstrap/test-framework.policy
Signed-off-by: Iwan Igonin <[email protected]>
Copy link
Member

@peternied peternied left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking much closer

  • There are still ~7 comment threads that are open, some of these might impact the scope of this change.
  • Looks like there are failures from the gradle-check workflow.

@beanuwave are there other items that you can see need to be invested in before this is merged? Trying to get a sense of how close we are to the finish line, thanks for the hard work!

Copy link
Contributor

❌ Gradle check result for 8228037: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants