Skip to content

Commit

Permalink
disable UsageStats in FIPS mode
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jtnord committed Sep 12, 2023
1 parent dba716b commit e7e5154
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
9 changes: 6 additions & 3 deletions core/src/main/java/hudson/model/UsageStatistics.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import jenkins.model.Jenkins;
import jenkins.security.FIPS140;
import jenkins.util.SystemProperties;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -102,8 +103,10 @@ public UsageStatistics(String keyImage) {
* Returns true if it's time for us to check for new version.
*/
public boolean isDue() {
// user opted out. no data collection.
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false;
// user opted out. no data collection, or FIPS is requested
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED || FIPS140.useCompliantAlgorithms()) {
return false;
}

long now = System.currentTimeMillis();
if (now - lastAttempt > DAY) {
Expand Down Expand Up @@ -212,7 +215,7 @@ public Permission getRequiredGlobalConfigPagePermission() {
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
try {
// for backward compatibility reasons, this configuration is stored in Jenkins
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : true);
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") && !FIPS140.useCompliantAlgorithms() ? null : true);
return true;
} catch (IOException e) {
throw new FormException(e, "usageStatisticsCollected");
Expand Down
13 changes: 11 additions & 2 deletions core/src/main/java/jenkins/model/Jenkins.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
import jenkins.security.ClassFilterImpl;
import jenkins.security.ConfidentialKey;
import jenkins.security.ConfidentialStore;
import jenkins.security.FIPS140;
import jenkins.security.MasterToSlaveCallable;
import jenkins.security.RedactSecretJsonInErrorMessageSanitizer;
import jenkins.security.ResourceDomainConfiguration;
Expand Down Expand Up @@ -1428,16 +1429,20 @@ public UpdateCenter getUpdateCenter() {
*/
@CheckForNull
public Boolean isNoUsageStatistics() {
return noUsageStatistics;
return FIPS140.useCompliantAlgorithms() ? Boolean.FALSE : noUsageStatistics;
}

/**
* If usage statistics are being collected
*
* @return {@code true} if usage statistics should be collected.
* Defaults to {@code true} when {@link #noUsageStatistics} is not set.
* Defaults to {@code true} when {@link #noUsageStatistics} is not set and
* FIPS-140 compliance is not enabled.
*/
public boolean isUsageStatisticsCollected() {
if (FIPS140.useCompliantAlgorithms()) {
return false;
}
return noUsageStatistics == null || !noUsageStatistics;
}

Expand All @@ -1446,6 +1451,10 @@ public boolean isUsageStatisticsCollected() {
*
*/
public void setNoUsageStatistics(Boolean noUsageStatistics) throws IOException {
if (FIPS140.useCompliantAlgorithms() && Boolean.FALSE.equals(noUsageStatistics)) {
LOGGER.log(Level.WARNING, "ignoring request to enable usage Statistics in FIPS mode");
return;
}
this.noUsageStatistics = noUsageStatistics;
save();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package hudson.model.UsageStatistics

import jenkins.security.FIPS140

def f=namespace(lib.FormTagLib)

f.section(title: _("Usage Statistics")) {
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
if (FIPS140.useCompliantAlgorithms()) {
span(class: "jenkins-not-applicable", _("disabledByFips"))
} else {
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@

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

0 comments on commit e7e5154

Please sign in to comment.