diff options
author | Zipeng WU <zipeng.wu@sonarsource.com> | 2021-02-11 18:25:14 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-02-17 20:07:15 +0000 |
commit | 122edd4683e3019c8035c40c53c8813e855372f0 (patch) | |
tree | f69986d0d45f2ef08ffff760b223fff28b63f1dc /server/sonar-process/src/main/java/org/sonar/process | |
parent | d90fced6c38073a22b76ef7b3c6b834ca21c7418 (diff) | |
download | sonarqube-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')
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) { |