aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-process/src/main/java/org/sonar/process
diff options
context:
space:
mode:
authorZipeng WU <zipeng.wu@sonarsource.com>2021-02-11 18:25:14 +0100
committersonartech <sonartech@sonarsource.com>2021-02-17 20:07:15 +0000
commit122edd4683e3019c8035c40c53c8813e855372f0 (patch)
treef69986d0d45f2ef08ffff760b223fff28b63f1dc /server/sonar-process/src/main/java/org/sonar/process
parentd90fced6c38073a22b76ef7b3c6b834ca21c7418 (diff)
downloadsonarqube-122edd4683e3019c8035c40c53c8813e855372f0.tar.gz
sonarqube-122edd4683e3019c8035c40c53c8813e855372f0.zip
SONAR-14426 Add support for AES-GCM encryption
Diffstat (limited to 'server/sonar-process/src/main/java/org/sonar/process')
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/AesCipher.java112
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Encryption.java63
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Props.java6
3 files changed, 5 insertions, 176 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java b/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java
deleted file mode 100644
index 129858fad94..00000000000
--- a/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.process;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.Key;
-import javax.annotation.Nullable;
-import javax.crypto.spec.SecretKeySpec;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-final class AesCipher implements Cipher {
- private static final String CRYPTO_KEY = "AES";
-
- /**
- * Duplication from CoreProperties.ENCRYPTION_SECRET_KEY_PATH
- */
- static final String ENCRYPTION_SECRET_KEY_PATH = "sonar.secretKeyPath";
-
- private String pathToSecretKey;
-
- AesCipher(@Nullable String pathToSecretKey) {
- this.pathToSecretKey = pathToSecretKey;
- }
-
- @Override
- public String encrypt(String clearText) {
- try {
- javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY);
- cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, loadSecretFile());
- return Base64.encodeBase64String(cipher.doFinal(clearText.getBytes(UTF_8)));
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public String decrypt(String encryptedText) {
- try {
- javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY);
- cipher.init(javax.crypto.Cipher.DECRYPT_MODE, loadSecretFile());
- byte[] cipherData = cipher.doFinal(Base64.decodeBase64(StringUtils.trim(encryptedText)));
- return new String(cipherData, UTF_8);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * This method checks the existence of the file, but not the validity of the contained key.
- */
- boolean hasSecretKey() {
- String path = getPathToSecretKey();
- if (StringUtils.isNotBlank(path)) {
- File file = new File(path);
- return file.exists() && file.isFile();
- }
- return false;
- }
-
- private Key loadSecretFile() throws IOException {
- String path = getPathToSecretKey();
- return loadSecretFileFromFile(path);
- }
-
- Key loadSecretFileFromFile(String path) throws IOException {
- if (StringUtils.isBlank(path)) {
- throw new IllegalStateException("Secret key not found. Please set the property " + ENCRYPTION_SECRET_KEY_PATH);
- }
- File file = new File(path);
- if (!file.exists() || !file.isFile()) {
- throw new IllegalStateException("The property " + ENCRYPTION_SECRET_KEY_PATH + " does not link to a valid file: " + path);
- }
- String s = FileUtils.readFileToString(file, UTF_8);
- if (StringUtils.isBlank(s)) {
- throw new IllegalStateException("No secret key in the file: " + path);
- }
- return new SecretKeySpec(Base64.decodeBase64(StringUtils.trim(s)), CRYPTO_KEY);
- }
-
- String getPathToSecretKey() {
- if (StringUtils.isBlank(pathToSecretKey)) {
- pathToSecretKey = new File(System.getProperty("user.home"), ".sonar/sonar-secret.txt").getPath();
- }
- return pathToSecretKey;
- }
-}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Encryption.java b/server/sonar-process/src/main/java/org/sonar/process/Encryption.java
deleted file mode 100644
index a2763997f09..00000000000
--- a/server/sonar-process/src/main/java/org/sonar/process/Encryption.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.process;
-
-import javax.annotation.Nullable;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @since 3.0
- */
-public final class Encryption {
-
- private static final String BASE64_ALGORITHM = "b64";
-
- private static final String AES_ALGORITHM = "aes";
- private final AesCipher aesCipher;
-
- private final Map<String, Cipher> ciphers = new HashMap<>();
- private static final Pattern ENCRYPTED_PATTERN = Pattern.compile("\\{(.*?)\\}(.*)");
-
- public Encryption(@Nullable String pathToSecretKey) {
- aesCipher = new AesCipher(pathToSecretKey);
- ciphers.put(BASE64_ALGORITHM, new Base64Cipher());
- ciphers.put(AES_ALGORITHM, aesCipher);
- }
-
- public boolean isEncrypted(String value) {
- return value.indexOf('{') == 0 && value.indexOf('}') > 1;
- }
-
- public String decrypt(String encryptedText) {
- Matcher matcher = ENCRYPTED_PATTERN.matcher(encryptedText);
- if (matcher.matches()) {
- Cipher cipher = ciphers.get(matcher.group(1).toLowerCase(Locale.ENGLISH));
- if (cipher != null) {
- return cipher.decrypt(matcher.group(2));
- }
- }
- return encryptedText;
- }
-
-}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Props.java b/server/sonar-process/src/main/java/org/sonar/process/Props.java
index f5294a54812..b88cbad38b0 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/Props.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/Props.java
@@ -23,7 +23,11 @@ import java.io.File;
import java.util.Properties;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.config.internal.Encryption;
+
+import static org.sonar.api.CoreProperties.ENCRYPTION_SECRET_KEY_PATH;
public class Props {
@@ -33,7 +37,7 @@ public class Props {
public Props(Properties props) {
this.properties = new Properties();
props.forEach((k, v) -> this.properties.put(k.toString().trim(), v == null ? null : v.toString().trim()));
- this.encryption = new Encryption(props.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH));
+ this.encryption = new Encryption(props.getProperty(ENCRYPTION_SECRET_KEY_PATH));
}
public boolean contains(String key) {