diff --git a/core/src/main/java/jenkins/security/HMACConfidentialKey.java b/core/src/main/java/jenkins/security/HMACConfidentialKey.java index 9faf2f629f84..a6c4633ce649 100644 --- a/core/src/main/java/jenkins/security/HMACConfidentialKey.java +++ b/core/src/main/java/jenkins/security/HMACConfidentialKey.java @@ -98,6 +98,11 @@ public boolean checkMac(String message, String mac) { } private byte[] chop(byte[] mac) { + //don't shorten the mac code on FIPS mode + //if length supplied is less than original mac code length on FIPS, throw exception + if (FIPS140.useCompliantAlgorithms() && length < mac.length) { + throw new IllegalArgumentException("Supplied length can't be less than " + mac.length + " on FIPS mode"); + } if (mac.length <= length) return mac; // already too short byte[] b = new byte[length]; diff --git a/core/src/test/java/jenkins/security/HMACConfidentialKeyTest.java b/core/src/test/java/jenkins/security/HMACConfidentialKeyTest.java index 93b5244f76b1..a635ed67707e 100644 --- a/core/src/test/java/jenkins/security/HMACConfidentialKeyTest.java +++ b/core/src/test/java/jenkins/security/HMACConfidentialKeyTest.java @@ -1,5 +1,7 @@ package jenkins.security; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -38,4 +40,11 @@ public void loadingExistingKey() { } } + @Test + public void testTruncatedMacOnNonFips() { + HMACConfidentialKey key1 = new HMACConfidentialKey("test", 16); + String str = key1.mac("Hello World"); + String pattern = "[0-9A-Fa-f]{32}"; + assertThat(str, matchesPattern(pattern)); + } } diff --git a/test/src/test/java/hudson/security/HMACConfidentialKeyFIPSTest.java b/test/src/test/java/hudson/security/HMACConfidentialKeyFIPSTest.java new file mode 100644 index 000000000000..3c0f71b4e459 --- /dev/null +++ b/test/src/test/java/hudson/security/HMACConfidentialKeyFIPSTest.java @@ -0,0 +1,33 @@ +package hudson.security; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import jenkins.security.HMACConfidentialKey; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.jvnet.hudson.test.FlagRule; + +public class HMACConfidentialKeyFIPSTest { + @ClassRule + // do not use the FIPS140 class here as that initializes the field before we set the property! + public static TestRule flagRule = FlagRule.systemProperty("jenkins.security.FIPS140.COMPLIANCE", "true"); + + @Test + public void testTruncatedMacOnFips() { + HMACConfidentialKey key1 = new HMACConfidentialKey("test", 16); + IllegalArgumentException iae = assertThrows(IllegalArgumentException.class, () -> key1.mac("Hello World")); + assertEquals("Supplied length can't be less than 32 on FIPS mode", iae.getMessage()); + } + + @Test + public void testCompleteMacOnFips() { + HMACConfidentialKey key1 = new HMACConfidentialKey("test", 32); + String str = key1.mac("Hello World"); + String pattern = "[0-9A-Fa-f]{64}"; + assertThat(str, matchesPattern(pattern)); + } +}