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

[JENKINS-73904] [JEP-237] check algorithm used for creating oic config is fips compliant #424

Conversation

pankajy-dev
Copy link

@pankajy-dev pankajy-dev commented Oct 11, 2024

https://issues.jenkins.io/browse/JENKINS-73904
https://github.com/jenkinsci/jep/tree/master/jep/237

Testing done

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

Copy link

codecov bot commented Oct 11, 2024

Codecov Report

Attention: Patch coverage is 70.58824% with 35 lines in your changes missing coverage. Please review.

Project coverage is 71.58%. Comparing base (769f395) to head (a20ca48).
Report is 10 commits behind head on master.

Files with missing lines Patch % Lines
...va/org/jenkinsci/plugins/oic/OicSecurityRealm.java 69.23% 14 Missing and 6 partials ⚠️
...g/jenkinsci/plugins/oic/OicAlgorithmValidator.java 72.54% 9 Missing and 5 partials ⚠️
...i/plugins/oic/OicServerWellKnownConfiguration.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #424      +/-   ##
============================================
- Coverage     71.91%   71.58%   -0.34%     
- Complexity      199      233      +34     
============================================
  Files            16       17       +1     
  Lines           883     1017     +134     
  Branches        120      146      +26     
============================================
+ Hits            635      728      +93     
- Misses          185      212      +27     
- Partials         63       77      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@PereBueno PereBueno left a comment

Choose a reason for hiding this comment

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

We should be filtering existing algorithms, not launching an exception

@pankajy-dev pankajy-dev force-pushed the JENKINS-73904-check-algorithm-used-for-creating-oic-config-is-fips-compliant branch from 0e255d1 to 68edf98 Compare October 11, 2024 10:47
PereBueno

This comment was marked as outdated.

@pankajy-dev
Copy link
Author

Don't know what happened, previous comment was a change request, not a comment

Just realised I got review comments on this PR. Some of these reviews were already provided by James on the PR that I created on his Fork.

I addressed few of them.

@jtnord jtnord changed the title Jenkins 73904 check algorithm used for creating oic config is fips compliant [JENKINS-73904] [JEP-237] check algorithm used for creating oic config is fips compliant Oct 11, 2024
@pankajy-dev
Copy link
Author

Not able to add reviewers here.
@jtnord , @PereBueno , @olamy , @fcojfernandez - Please review.

Copy link
Contributor

Choose a reason for hiding this comment

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

This class is exposing methods to check FIPS-140. If those methods were private we could discuss if having a negated output is correct or not, but in a utility class like this, checking sometingNon makes the code hard to follow and maintain

Copy link
Contributor

Choose a reason for hiding this comment

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

Besides, modifying the lists received as parameter would be risky. It's better to always return an immutable list

@@ -155,7 +155,8 @@ public OIDCProviderMetadata toProviderMetadata() {
// rather we just say "I support anything, and let the check for the specific ones fail and fall through
ArrayList<JWSAlgorithm> allAlgorthms = new ArrayList<>();
allAlgorthms.addAll(JWSAlgorithm.Family.HMAC_SHA);
allAlgorthms.addAll(JWSAlgorithm.Family.SIGNATURE);
allAlgorthms.addAll(JWSAlgorithm.Family.RSA);
allAlgorthms.addAll(JWSAlgorithm.Family.EC);
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we be filtering here allAlgorithms here?

Copy link
Author

Choose a reason for hiding this comment

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

these are the compliant algorithms, thats why haven't put filter here.

Copy link
Contributor

Choose a reason for hiding this comment

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

wrong filter

@@ -509,6 +513,107 @@ private OidcConfiguration buildOidcConfiguration() {
return conf;
}

private static void filterJwsAlgorithms(OIDCProviderMetadata oidcProviderMetadata) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks dangerous, what if we're using an immutableList? All the set*JW*Algs methods are public

/**
* Checks if the Jws signing algorithm used for OIC configuration is FIPS compliant.
*/
public static boolean isJwsAlgorithmFipsNonCompliant(Algorithm algorithm) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As a rule of thumb, "positive" method (e.g.: isJwsAlgorithmCompliant) are easier to follow (those double negations make this difficult to read)

Copy link
Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

Test name is wrong, we're testing FIPS true here

Copy link
Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

Same, wrong name

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines 31 to 40
public void doCheckAlgorithmFilter() throws IOException, ParseException {
OIDCProviderMetadata oidcProviderMetadata = OicSecurityRealmNonFIPSAlgoTest.getNonCompliantMockObject();
int countIDTokenJWSAlgs = oidcProviderMetadata.getIDTokenJWSAlgs().size();
int countIDTokenJWEAlgs = oidcProviderMetadata.getIDTokenJWEAlgs().size();
OicSecurityRealm.filterNonCompliantAlgorithms(oidcProviderMetadata);
assertEquals(
countIDTokenJWSAlgs, oidcProviderMetadata.getIDTokenJWSAlgs().size());
assertEquals(
countIDTokenJWEAlgs, oidcProviderMetadata.getIDTokenJWEAlgs().size());
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Filtering isn't right, adding just the opposite check to this test fails

    @Test
    public void doCheckAlgorithmFilter() throws IOException, ParseException {
        OIDCProviderMetadata oidcProviderMetadata = OicSecurityRealmNonFIPSAlgoTest.getNonCompliantMockObject();
        int countIDTokenJWSAlgs = oidcProviderMetadata.getIDTokenJWSAlgs().size();
        int countIDTokenJWEAlgs = oidcProviderMetadata.getIDTokenJWEAlgs().size();
        OicSecurityRealm.filterNonCompliantAlgorithms(oidcProviderMetadata);
        assertEquals(
                countIDTokenJWSAlgs, oidcProviderMetadata.getIDTokenJWSAlgs().size());
        assertEquals(
                countIDTokenJWEAlgs, oidcProviderMetadata.getIDTokenJWEAlgs().size());

        // reset the mock, in FIPs mode now
        fips140Mock.reset();
        fips140Mock.when(FIPS140::useCompliantAlgorithms).thenReturn(true);
        // restart the object
        oidcProviderMetadata = OicSecurityRealmNonFIPSAlgoTest.getNonCompliantMockObject();
        // filter
        OicSecurityRealm.filterNonCompliantAlgorithms(oidcProviderMetadata);
        // We should not have the same number of algorithms as in non FIPS mode
        assertNotEquals(countIDTokenJWSAlgs, oidcProviderMetadata.getIDTokenJWSAlgs().size());
        assertNotEquals(countIDTokenJWEAlgs, oidcProviderMetadata.getIDTokenJWEAlgs().size());
    }

pankajy-dev and others added 2 commits October 11, 2024 20:40
Co-authored-by: Francisco Javier Fernandez <31063239+fcojfernandez@users.noreply.github.com>
* This class helps in validating algorithms for FIPS-140 compliance and filtering the non-compliant algorithms when in
* FIPS mode.
*/
public class OicAlgorithmValidatorFIPS140 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Class name must match file name

@@ -25,3 +25,5 @@ OicSecurityRealm.TokenRequestFailure = Token request failed: {0}"
OicSecurityRealm.TokenRefreshFailure = Unable to refresh access token
OicServerWellKnownConfiguration.DisplayName = Discovery via well-known endpoint
OicServerManualConfiguration.DisplayName = Manual entry
OicConfigNonCompliantAlgo.ErrorMessage = Algorithm ''{0}'' used for OIC configuration is not FIPS compliant.
Copy link
Contributor

Choose a reason for hiding this comment

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

unused

@@ -509,6 +513,148 @@ private OidcConfiguration buildOidcConfiguration() {
return conf;
}

private static void filterJwsAlgorithms(OIDCProviderMetadata oidcProviderMetadata) {
Copy link
Member

Choose a reason for hiding this comment

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

NIT: this class is already getting quire big and as this is static these methods could be moved to a utility class.

Copy link
Member

@jtnord jtnord left a comment

Choose a reason for hiding this comment

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

to me it looks like none of the the ECDHCryptoProviders would be compliant?

}

/**
* Checks if the Jws signing algorithm used for OIC configuration is FIPS-140 compliant.
Copy link
Member

Choose a reason for hiding this comment

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

although it doesn't.
as this returns true for something that is not compliant when not in FIPS mode.
Would it be better to just not perform the call to do any filtering if we are not in FIPS mode and then these methods would do what they are documented to do and what is expected by the function names?

@@ -509,6 +513,148 @@ private OidcConfiguration buildOidcConfiguration() {
return conf;
}

private static void filterJwsAlgorithms(OIDCProviderMetadata oidcProviderMetadata) {
// Filter Jws Algorithms
if (oidcProviderMetadata.getIDTokenJWSAlgs() != null) {
Copy link
Member

Choose a reason for hiding this comment

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

remove the null checks and make the filter handle null input?

e.g by handling the null in filterFipsNonCompliantJwsAlgorithm you can have

oidcProviderMetadate.setIdTokenJWSAlgs(OicAlgorithmValidatorFIPS140.filterFipsNonCompliantJwsAlgorithm(oidcProviderMetadata.getIDTokenJWSAlgs());

jweSupportedAlgorithms.addAll(RSACryptoProvider.SUPPORTED_ALGORITHMS);
// RSA1_5 is deprecated and not a compliant algorithm.
jweSupportedAlgorithms.remove(JWEAlgorithm.RSA1_5);
jweSupportedAlgorithms.addAll(ECDHCryptoProvider.SUPPORTED_ALGORITHMS);
Copy link
Member

Choose a reason for hiding this comment

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

seems to use its own key derivation function (ConcatKDF) and so would not be compliant?

@jtnord
Copy link
Member

jtnord commented Oct 11, 2024

Subsumed in #428

@jtnord jtnord closed this Oct 11, 2024
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.

5 participants