Skip to content

Ensure CI is run in FIPS 140 approved only mode#64024

Merged
jkakavas merged 79 commits intoelastic:masterfrom
jkakavas:fips-approved-mode-tests
Dec 23, 2020
Merged

Ensure CI is run in FIPS 140 approved only mode#64024
jkakavas merged 79 commits intoelastic:masterfrom
jkakavas:fips-approved-mode-tests

Conversation

@jkakavas
Copy link
Copy Markdown
Contributor

@jkakavas jkakavas commented Oct 21, 2020

We were depending on the BouncyCastle FIPS own mechanics to set
itself in approved only mode since we run with the Security
Manager enabled. The check during startup seems to happen before we
set our restrictive SecurityManager though in
org.elasticsearch.bootstrap.Elasticsearch , and this means that
BCFIPS would not be in approved only mode, unless explicitly
configured so.

This commit sets the appropriate JVM property to explicitly set
BCFIPS in approved only mode in CI and adds tests to ensure that we
will be running with BCFIPS in approved only mode when we expect to.
It also sets xpack.security.fips_mode.enabled to true for all test clusters
used in fips mode and sets the distribution to the default one. It adds a
password to the elasticsearch keystore for all test clusters that run in fips
mode.
Moreover, it changes a few unit tests where we would use bcrypt even in
FIPS 140 mode. These would still pass since we are bundling our own
bcrypt implementation, but are now changed to use FIPS 140 approved
algorithms instead for better coverage.

It also addresses a number of tests that would fail in approved only mode
Mainly:

  • Tests that use PBKDF2 with a password less than 112 bits (14char). We
    elected to change the passwords used everywhere to be at least 14
    characters long instead of mandating
    the use of pbkdf2_stretch because both pbkdf2 and
    pbkdf2_stretch are supported and allowed in fips mode and it makes sense
    to test with both. We could possibly figure out the password algorithm used
    for each test and adjust password length accordingly only for pbkdf2 but
    there is little value in that. It's good practice to use strong passwords so if
    our docs and tests use longer passwords, then it's for the best. The approach
    is brittle as there is no guarantee that the next test that will be added won't
    use a short password, so we add some testing documentation too.
    This leaves us with a possible coverage gap since we do support passwords
    as short as 6 characters but we only test with > 14 chars but the
    validation itself was not tested even before. Tests can be added in a followup,
    outside of fips related context.

  • Tests that use a PKCS12 keystore and were not already muted.

  • Tests that depend on running test clusters with a basic license or
    using the OSS distribution as FIPS 140 support is not available in
    neither of these.

Finally, it adds some information around FIPS 140 testing in our testing
documentation reference so that developers can hopefully keep in
mind fips 140 related intricacies when writing/changing docs.

We were depending on the BouncyCastle FIPS own mechanics to set
itself in approved only mode since we run with the Security
Manager enabled. The check during startup seems to happen before we
set our restrictive SecurityManager though in
org.elasticsearch.bootstrap.Elasticsearch , and this means that
BCFIPS would not be in approved onlu mode, unless explicitly
configured so.

This commit sets the appropriate JVM property to explicitly set
BCFIPS in approved only mode and addresses a number of tests that
would fail in approved mode. Mainly:
- Tests that use PBKDF2 with a password less than 112 bits (14char)
- Tests that use a PKCS12 keystore and were not already muted.

It also changes a few unit tests where we would use bcrypt even in
FIPS 140 mode. These would still pass since we are bundling our own
bcrypt implementation, but are now changed to use FIPS 140 approved
algorithms instead for better coverage.
@jkakavas jkakavas added >test Issues or PRs that are addressing/adding tests :Security/Security Security issues without another label labels Oct 21, 2020
@jkakavas jkakavas requested review from tvernum and ywangd October 21, 2020 21:36
@elasticmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-security (:Security/Security)

@elasticmachine elasticmachine added the Team:Security Meta label for security team label Oct 21, 2020
Copy link
Copy Markdown
Member

@ywangd ywangd left a comment

Choose a reason for hiding this comment

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

I left a few comments. Woud like to have another round later. Thanks!

" - names: '*'\n" +
" privileges: [ all ]\n" +
"create_doc_role:\n" +
"create_doc_role:\n" +
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: The indentation is now inconsistent with all_indices_role. I do think the change here looks better. But I'd suggest we make the same change to all_indices_role as well.


public class Fips140ProviderVerificationTests extends ESTestCase {

public void testBcFipsProviderInUse(){
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit

Suggested change
public void testBcFipsProviderInUse(){
public void testBcFipsProviderInUse() {

break;
default:
keySize = randomFrom(1024, 2048);
keySize = randomFrom(2048);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
keySize = randomFrom(2048);
keySize = 2048;

@jkakavas jkakavas requested review from tvernum and ywangd October 22, 2020 12:38
@ywangd
Copy link
Copy Markdown
Member

ywangd commented Oct 26, 2020

I could be missing something, but is xpack.security.fips_mode.enabled set to true anywhere when -Dtests.fips.enabled=true. It seems to me that we should at least have it enabled for testClusters?

@jkakavas jkakavas marked this pull request as draft October 26, 2020 21:41
jkakavas added a commit that referenced this pull request Nov 26, 2020
In certain situations, such as when configured in FIPS 140 mode,
the Java security provider in use might throw a subclass of
java.lang.Error. We currently do not catch these and as a result
the JVM exits, shutting down elasticsearch.

This commit attempts to address this by catching subclasses of Error
that might be thrown for instance when a PBKDF2 implementation
is used from a Security Provider in FIPS 140 mode, with the password
input being less than 14 bytes (112 bits).

- In our PBKDF2 family of hashers, we catch the Error and
throw an ElasticsearchException while creating or verifying the
hash. We throw on verification instead of simply returning false
on purpose so that the message bubbles up and the cause becomes
obvious (otherwise it would be indistinguishable from a wrong
password).
- In KeyStoreWrapper, we catch the Error in order to wrap and re-throw 
a GeneralSecurityException with a helpful message. This can happen when 
using any of the keystore CLI commands, when the node starts or when we 
attempt to reload secure settings.
- In the `elasticsearch-users` tool, we catch the ElasticsearchException that
the Hasher class re-throws and throw an appropriate UserException.

Tests are missing because it's not trivial to set CI in fips approved mode
right now, and thus any tests would need to be muted. There is a parallel
effort in #64024 to enable that and tests will be added in a followup.
jkakavas added a commit to jkakavas/elasticsearch that referenced this pull request Nov 26, 2020
In certain situations, such as when configured in FIPS 140 mode,
the Java security provider in use might throw a subclass of
java.lang.Error. We currently do not catch these and as a result
the JVM exits, shutting down elasticsearch.

This commit attempts to address this by catching subclasses of Error
that might be thrown for instance when a PBKDF2 implementation
is used from a Security Provider in FIPS 140 mode, with the password
input being less than 14 bytes (112 bits).

- In our PBKDF2 family of hashers, we catch the Error and
throw an ElasticsearchException while creating or verifying the
hash. We throw on verification instead of simply returning false
on purpose so that the message bubbles up and the cause becomes
obvious (otherwise it would be indistinguishable from a wrong
password).
- In KeyStoreWrapper, we catch the Error in order to wrap and re-throw 
a GeneralSecurityException with a helpful message. This can happen when 
using any of the keystore CLI commands, when the node starts or when we 
attempt to reload secure settings.
- In the `elasticsearch-users` tool, we catch the ElasticsearchException that
the Hasher class re-throws and throw an appropriate UserException.

Tests are missing because it's not trivial to set CI in fips approved mode
right now, and thus any tests would need to be muted. There is a parallel
effort in elastic#64024 to enable that and tests will be added in a followup.
jkakavas added a commit to jkakavas/elasticsearch that referenced this pull request Nov 26, 2020
In certain situations, such as when configured in FIPS 140 mode,
the Java security provider in use might throw a subclass of
java.lang.Error. We currently do not catch these and as a result
the JVM exits, shutting down elasticsearch.

This commit attempts to address this by catching subclasses of Error
that might be thrown for instance when a PBKDF2 implementation
is used from a Security Provider in FIPS 140 mode, with the password
input being less than 14 bytes (112 bits).

- In our PBKDF2 family of hashers, we catch the Error and
throw an ElasticsearchException while creating or verifying the
hash. We throw on verification instead of simply returning false
on purpose so that the message bubbles up and the cause becomes
obvious (otherwise it would be indistinguishable from a wrong
password).
- In KeyStoreWrapper, we catch the Error in order to wrap and re-throw 
a GeneralSecurityException with a helpful message. This can happen when 
using any of the keystore CLI commands, when the node starts or when we 
attempt to reload secure settings.
- In the `elasticsearch-users` tool, we catch the ElasticsearchException that
the Hasher class re-throws and throw an appropriate UserException.

Tests are missing because it's not trivial to set CI in fips approved mode
right now, and thus any tests would need to be muted. There is a parallel
effort in elastic#64024 to enable that and tests will be added in a followup.
jkakavas added a commit that referenced this pull request Nov 26, 2020
In certain situations, such as when configured in FIPS 140 mode,
the Java security provider in use might throw a subclass of
java.lang.Error. We currently do not catch these and as a result
the JVM exits, shutting down elasticsearch.

This commit attempts to address this by catching subclasses of Error
that might be thrown for instance when a PBKDF2 implementation
is used from a Security Provider in FIPS 140 mode, with the password
input being less than 14 bytes (112 bits).

- In our PBKDF2 family of hashers, we catch the Error and
throw an ElasticsearchException while creating or verifying the
hash. We throw on verification instead of simply returning false
on purpose so that the message bubbles up and the cause becomes
obvious (otherwise it would be indistinguishable from a wrong
password).
- In KeyStoreWrapper, we catch the Error in order to wrap and re-throw 
a GeneralSecurityException with a helpful message. This can happen when 
using any of the keystore CLI commands, when the node starts or when we 
attempt to reload secure settings.
- In the `elasticsearch-users` tool, we catch the ElasticsearchException that
the Hasher class re-throws and throw an appropriate UserException.

Tests are missing because it's not trivial to set CI in fips approved mode
right now, and thus any tests would need to be muted. There is a parallel
effort in #64024 to enable that and tests will be added in a followup.
jkakavas added a commit that referenced this pull request Nov 26, 2020
In certain situations, such as when configured in FIPS 140 mode,
the Java security provider in use might throw a subclass of
java.lang.Error. We currently do not catch these and as a result
the JVM exits, shutting down elasticsearch.

This commit attempts to address this by catching subclasses of Error
that might be thrown for instance when a PBKDF2 implementation
is used from a Security Provider in FIPS 140 mode, with the password
input being less than 14 bytes (112 bits).

- In our PBKDF2 family of hashers, we catch the Error and
throw an ElasticsearchException while creating or verifying the
hash. We throw on verification instead of simply returning false
on purpose so that the message bubbles up and the cause becomes
obvious (otherwise it would be indistinguishable from a wrong
password).
- In KeyStoreWrapper, we catch the Error in order to wrap and re-throw 
a GeneralSecurityException with a helpful message. This can happen when 
using any of the keystore CLI commands, when the node starts or when we 
attempt to reload secure settings.
- In the `elasticsearch-users` tool, we catch the ElasticsearchException that
the Hasher class re-throws and throw an appropriate UserException.

Tests are missing because it's not trivial to set CI in fips approved mode
right now, and thus any tests would need to be muted. There is a parallel
effort in #64024 to enable that and tests will be added in a followup.
@jkakavas jkakavas merged commit bd87369 into elastic:master Dec 23, 2020
tvernum added a commit to tvernum/elasticsearch that referenced this pull request Dec 29, 2020
As of elastic#64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Resolves: elastic#66845
tvernum added a commit that referenced this pull request Dec 30, 2020
As of #64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Resolves: #66845
tvernum added a commit to tvernum/elasticsearch that referenced this pull request Dec 31, 2020
As of elastic#64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Backport of: elastic#66846
ywangd pushed a commit that referenced this pull request Jan 4, 2021
As of #64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Backport of: #66846
ywangd pushed a commit to ywangd/elasticsearch that referenced this pull request Jan 4, 2021
As of elastic#64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Backport of: elastic#66846
ywangd added a commit that referenced this pull request Jan 4, 2021
As of #64024 we run FIPS CI on a true, FIPS approved only mode JVM.
This mandates that any passwords that are fed into PBKDF2 must have at
least 112 bits of entropy (that is, be 14 characters long).

This commit updates our Keystore CLI tests so that tests either:
1. Use a 14+ character password when in FIPS mode, _or_
2. Are skipped on FIPS mode (because they explicitly test empty
   passwords)

Backport of: #66846

Co-authored-by: Tim Vernum <tim.vernum@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Security/Security Security issues without another label Team:Security Meta label for security team >test Issues or PRs that are addressing/adding tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants