Skip to content

Commit e7e5154

Browse files
committed
disable UsageStats in FIPS mode
UsageStatistics is so close to being FIPS-140 compliant but fails at the last hurdle. We can not encrypt with RSA but we can perform key wrap. The output does separate the key and data, by creating a new Key for encrypting the data and that key is encrypted with RSA. If only the RSA cipher was created with Cipher.WRAP_MODE (or Cipher.UNWRAP_MODE) instead of CIPHER.ENCRYPT_MODE (or CIPHER.DECRYPT_MODE) we would be fine, alas it is not and changing this would mean a change on the backend and to be able to continue to support both whilst older versions are in the wild. The goal of JEP-237 is not to fix all non compliant issues, so here we just ensure that in FIPS mode the usage statistics are disabled.
1 parent dba716b commit e7e5154

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

core/src/main/java/hudson/model/UsageStatistics.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import javax.crypto.spec.IvParameterSpec;
6565
import javax.crypto.spec.SecretKeySpec;
6666
import jenkins.model.Jenkins;
67+
import jenkins.security.FIPS140;
6768
import jenkins.util.SystemProperties;
6869
import net.sf.json.JSONObject;
6970
import org.kohsuke.stapler.StaplerRequest;
@@ -102,8 +103,10 @@ public UsageStatistics(String keyImage) {
102103
* Returns true if it's time for us to check for new version.
103104
*/
104105
public boolean isDue() {
105-
// user opted out. no data collection.
106-
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false;
106+
// user opted out. no data collection, or FIPS is requested
107+
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED || FIPS140.useCompliantAlgorithms()) {
108+
return false;
109+
}
107110

108111
long now = System.currentTimeMillis();
109112
if (now - lastAttempt > DAY) {
@@ -212,7 +215,7 @@ public Permission getRequiredGlobalConfigPagePermission() {
212215
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
213216
try {
214217
// for backward compatibility reasons, this configuration is stored in Jenkins
215-
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : true);
218+
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") && !FIPS140.useCompliantAlgorithms() ? null : true);
216219
return true;
217220
} catch (IOException e) {
218221
throw new FormException(e, "usageStatisticsCollected");

core/src/main/java/jenkins/model/Jenkins.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@
274274
import jenkins.security.ClassFilterImpl;
275275
import jenkins.security.ConfidentialKey;
276276
import jenkins.security.ConfidentialStore;
277+
import jenkins.security.FIPS140;
277278
import jenkins.security.MasterToSlaveCallable;
278279
import jenkins.security.RedactSecretJsonInErrorMessageSanitizer;
279280
import jenkins.security.ResourceDomainConfiguration;
@@ -1428,16 +1429,20 @@ public UpdateCenter getUpdateCenter() {
14281429
*/
14291430
@CheckForNull
14301431
public Boolean isNoUsageStatistics() {
1431-
return noUsageStatistics;
1432+
return FIPS140.useCompliantAlgorithms() ? Boolean.FALSE : noUsageStatistics;
14321433
}
14331434

14341435
/**
14351436
* If usage statistics are being collected
14361437
*
14371438
* @return {@code true} if usage statistics should be collected.
1438-
* Defaults to {@code true} when {@link #noUsageStatistics} is not set.
1439+
* Defaults to {@code true} when {@link #noUsageStatistics} is not set and
1440+
* FIPS-140 compliance is not enabled.
14391441
*/
14401442
public boolean isUsageStatisticsCollected() {
1443+
if (FIPS140.useCompliantAlgorithms()) {
1444+
return false;
1445+
}
14411446
return noUsageStatistics == null || !noUsageStatistics;
14421447
}
14431448

@@ -1446,6 +1451,10 @@ public boolean isUsageStatisticsCollected() {
14461451
*
14471452
*/
14481453
public void setNoUsageStatistics(Boolean noUsageStatistics) throws IOException {
1454+
if (FIPS140.useCompliantAlgorithms() && Boolean.FALSE.equals(noUsageStatistics)) {
1455+
LOGGER.log(Level.WARNING, "ignoring request to enable usage Statistics in FIPS mode");
1456+
return;
1457+
}
14491458
this.noUsageStatistics = noUsageStatistics;
14501459
save();
14511460
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package hudson.model.UsageStatistics
22

3+
import jenkins.security.FIPS140
4+
35
def f=namespace(lib.FormTagLib)
46

57
f.section(title: _("Usage Statistics")) {
6-
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
8+
if (FIPS140.useCompliantAlgorithms()) {
9+
span(class: "jenkins-not-applicable", _("disabledByFips"))
10+
} else {
11+
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
12+
}
713
}

core/src/main/resources/hudson/model/UsageStatistics/global.properties

+2
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@
2222

2323
statsBlurb=\
2424
Help make Jenkins better by sending anonymous usage statistics and crash reports to the Jenkins project
25+
disabledByFips=\
26+
The option to send anonymous usage statistics and crash reports to the Jenkins project is disabled due to running in FIPS-140 compliance mode
2527

0 commit comments

Comments
 (0)