]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22359 Make hashing of user UUID in telemetry FIPS-compliant
authorAlain Kermis <alain.kermis@sonarsource.com>
Thu, 6 Jun 2024 07:55:04 +0000 (09:55 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 18 Jun 2024 20:02:41 +0000 (20:02 +0000)
build.gradle
server/sonar-alm-client/build.gradle
server/sonar-server-common/build.gradle
server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java
server/sonar-server-common/src/main/java/org/sonar/server/util/DigestUtil.java [new file with mode: 0644]
server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java
server/sonar-server-common/src/test/java/org/sonar/server/util/DigestUtilTest.java [new file with mode: 0644]

index 1f0d3b42219418afd1870206d7cada3d95435900..80029d6dc8ed4dd257932bdeb824b4aefa4e6235 100644 (file)
@@ -405,6 +405,8 @@ subprojects {
       dependency 'org.apache.sshd:sshd-core:2.12.1'
       dependency 'org.assertj:assertj-core:3.25.3'
       dependency 'org.assertj:assertj-guava:3.25.3'
+      dependency 'org.bouncycastle:bcpkix-jdk18on:1.78.1'
+      dependency 'org.bouncycastle:bcprov-jdk18on:1.78.1'
       dependency('org.codehaus.sonar:sonar-channel:4.2') {
         exclude 'org.slf4j:slf4j-api'
       }
index f2a636125b84491689fc7c162f31690008af7d07..fedca969e0274793e54bc9f231b41fe80e400431 100644 (file)
@@ -10,7 +10,7 @@ dependencies {
     api 'commons-codec:commons-codec'
     api 'org.kohsuke:github-api'
     api 'com.auth0:java-jwt'
-    api 'org.bouncycastle:bcpkix-jdk18on:1.78.1'
+    api 'org.bouncycastle:bcpkix-jdk18on'
     api 'org.sonarsource.api.plugin:sonar-plugin-api'
     api project(':server:sonar-auth-github')
     api project(':server:sonar-auth-gitlab')
index f3abdbeecc0949c3f97009101e45f8fac2517acd..d019caad292ee81c15564ff05b508eac2dc811de 100644 (file)
@@ -9,13 +9,14 @@ sonar {
 dependencies {
   // please keep the list grouped by configuration and ordered by name
 
-  api 'org.apache.commons:commons-email'
   api 'commons-io:commons-io'
-  api 'org.apache.commons:commons-lang3'
   api 'com.google.guava:guava'
-  api 'org.slf4j:slf4j-api'
   api 'com.squareup.okhttp3:okhttp'
+  api 'org.apache.commons:commons-email'
+  api 'org.apache.commons:commons-lang3'
+  api 'org.bouncycastle:bcprov-jdk18on'
   api 'org.elasticsearch.client:elasticsearch-rest-high-level-client'
+  api 'org.slf4j:slf4j-api'
   api 'org.sonarsource.api.plugin:sonar-plugin-api'
   api project(':server:sonar-db-dao')
   api project(':server:sonar-db-migration')
@@ -25,7 +26,6 @@ dependencies {
   api project(':sonar-ws')
 
   compileOnlyApi 'com.google.code.findbugs:jsr305'
-
   testImplementation 'org.elasticsearch.plugin:transport-netty4-client'
   testImplementation 'ch.qos.logback:logback-core'
   testImplementation 'com.google.code.findbugs:jsr305'
@@ -47,7 +47,7 @@ dependencies {
   testImplementation testFixtures(project(':server:sonar-webserver-es'))
   testImplementation project(':sonar-plugin-api-impl')
   testImplementation project(':sonar-testing-harness')
-    
+
   testFixturesApi 'junit:junit'
   testFixturesApi testFixtures(project(':server:sonar-db-dao'))
 
index 005c200b76f87c0a14faabfb191b33cba207fd3e..393d0e87857636d0ec7edbb1a3b805c0cc5fcb1b 100644 (file)
@@ -25,11 +25,11 @@ import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.Locale;
-import org.apache.commons.codec.digest.DigestUtils;
 import org.jetbrains.annotations.NotNull;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.core.telemetry.TelemetryExtension;
+import org.sonar.server.util.DigestUtil;
 
 import static org.sonar.api.utils.DateUtils.DATETIME_FORMAT;
 
@@ -117,7 +117,7 @@ public class TelemetryDataJsonWriter {
       json.beginArray();
       telemetryData.getUserTelemetries().forEach(user -> {
         json.beginObject();
-        json.prop("userUuid", DigestUtils.sha3_224Hex(user.getUuid()));
+        json.prop("userUuid", DigestUtil.sha3_224Hex(user.getUuid()));
         json.prop("status", user.isActive() ? "active" : "inactive");
         json.prop("identityProvider", user.getExternalIdentityProvider());
 
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/util/DigestUtil.java b/server/sonar-server-common/src/main/java/org/sonar/server/util/DigestUtil.java
new file mode 100644 (file)
index 0000000..f97bffa
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.util;
+
+import java.nio.charset.StandardCharsets;
+import org.bouncycastle.jcajce.provider.digest.SHA3;
+import org.bouncycastle.util.encoders.Hex;
+
+public class DigestUtil {
+
+  private DigestUtil() {
+    // utility class
+  }
+
+  public static String sha3_224Hex(String input) {
+    SHA3.DigestSHA3 sha3Digest = new SHA3.Digest224();
+    byte[] hashBytes = sha3Digest.digest(input.getBytes(StandardCharsets.UTF_8));
+    return Hex.toHexString(hashBytes);
+  }
+
+}
index f6582601ef0ce4e00e1a0733b94d382b70ce4f8c..72987c21c9366666982148b21ecc4486bd0a7355 100644 (file)
@@ -32,7 +32,6 @@ import java.util.Random;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.commons.codec.digest.DigestUtils;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -43,6 +42,7 @@ import org.sonar.core.telemetry.TelemetryExtension;
 import org.sonar.db.project.CreationMethod;
 import org.sonar.db.user.UserTelemetryDto;
 import org.sonar.server.qualitygate.Condition;
+import org.sonar.server.util.DigestUtil;
 
 import static java.util.stream.Collectors.joining;
 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
@@ -397,7 +397,7 @@ public class TelemetryDataJsonWriterTest {
         ]
       }
       """
-      .formatted(DigestUtils.sha3_224Hex("uuid-0"), DigestUtils.sha3_224Hex("uuid-1"), DigestUtils.sha3_224Hex("uuid-2")));
+      .formatted(DigestUtil.sha3_224Hex("uuid-0"), DigestUtil.sha3_224Hex("uuid-1"), DigestUtil.sha3_224Hex("uuid-2")));
   }
 
   @Test
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/util/DigestUtilTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/util/DigestUtilTest.java
new file mode 100644 (file)
index 0000000..e7f4b99
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.util;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class DigestUtilTest {
+
+  @Test
+  void whenCalledOnTheSameInput_sha3_224Hex_returnsTheSameValueAsDigestUtils() {
+    String input = "String to be hashed";
+
+    //Apache Commons DigestUtils digest for the string "String to be hashed"
+    String apacheCommonsDigest = "57ead8c5fc5c15ed7bde0550648d06a6aed3cba443ed100a6f5e64f3";
+
+    assertEquals(apacheCommonsDigest, DigestUtil.sha3_224Hex(input));
+  }
+
+}
\ No newline at end of file