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 /sonar-plugin-api-impl/src/test/java | |
parent | d90fced6c38073a22b76ef7b3c6b834ca21c7418 (diff) | |
download | sonarqube-122edd4683e3019c8035c40c53c8813e855372f0.tar.gz sonarqube-122edd4683e3019c8035c40c53c8813e855372f0.zip |
SONAR-14426 Add support for AES-GCM encryption
Diffstat (limited to 'sonar-plugin-api-impl/src/test/java')
-rw-r--r-- | sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesECBCipherTest.java (renamed from sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesCipherTest.java) | 36 | ||||
-rw-r--r-- | sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesGCMCipherTest.java | 93 | ||||
-rw-r--r-- | sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/EncryptionTest.java | 35 |
3 files changed, 146 insertions, 18 deletions
diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesCipherTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesECBCipherTest.java index b9cfc356b34..28de7d573b0 100644 --- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesCipherTest.java +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesECBCipherTest.java @@ -33,14 +33,14 @@ import org.junit.rules.ExpectedException; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; -public class AesCipherTest { +public class AesECBCipherTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void generateRandomSecretKey() { - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); String key = cipher.generateRandomSecretKey(); @@ -50,7 +50,7 @@ public class AesCipherTest { @Test public void encrypt() throws Exception { - AesCipher cipher = new AesCipher(pathToSecretKey()); + AesECBCipher cipher = new AesECBCipher(pathToSecretKey()); String encryptedText = cipher.encrypt("this is a secret"); @@ -64,14 +64,14 @@ public class AesCipherTest { thrown.expectMessage("Invalid AES key"); URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/bad_secret_key.txt"); - AesCipher cipher = new AesCipher(new File(resource.toURI()).getCanonicalPath()); + AesECBCipher cipher = new AesECBCipher(new File(resource.toURI()).getCanonicalPath()); cipher.encrypt("this is a secret"); } @Test public void decrypt() throws Exception { - AesCipher cipher = new AesCipher(pathToSecretKey()); + AesECBCipher cipher = new AesECBCipher(pathToSecretKey()); // the following value has been encrypted with the key /org/sonar/api/config/internal/AesCipherTest/aes_secret_key.txt String clearText = cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY="); @@ -82,7 +82,7 @@ public class AesCipherTest { @Test public void decrypt_bad_key() throws Exception { URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/bad_secret_key.txt"); - AesCipher cipher = new AesCipher(new File(resource.toURI()).getCanonicalPath()); + AesECBCipher cipher = new AesECBCipher(new File(resource.toURI()).getCanonicalPath()); try { cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY="); @@ -96,7 +96,7 @@ public class AesCipherTest { @Test public void decrypt_other_key() throws Exception { URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/other_secret_key.txt"); - AesCipher cipher = new AesCipher(new File(resource.toURI()).getCanonicalPath()); + AesECBCipher cipher = new AesECBCipher(new File(resource.toURI()).getCanonicalPath()); try { // text encrypted with another key @@ -110,46 +110,46 @@ public class AesCipherTest { @Test public void encryptThenDecrypt() throws Exception { - AesCipher cipher = new AesCipher(pathToSecretKey()); + AesECBCipher cipher = new AesECBCipher(pathToSecretKey()); assertThat(cipher.decrypt(cipher.encrypt("foo"))).isEqualTo("foo"); } @Test public void testDefaultPathToSecretKey() { - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); String path = cipher.getPathToSecretKey(); assertThat(StringUtils.isNotBlank(path)).isTrue(); - assertThat(new File(path).getName()).isEqualTo("sonar-secret.txt"); + assertThat(new File(path)).hasName("sonar-secret.txt"); } @Test public void loadSecretKeyFromFile() throws Exception { - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); Key secretKey = cipher.loadSecretFileFromFile(pathToSecretKey()); assertThat(secretKey.getAlgorithm()).isEqualTo("AES"); - assertThat(secretKey.getEncoded().length).isGreaterThan(10); + assertThat(secretKey.getEncoded()).hasSizeGreaterThan(10); } @Test public void loadSecretKeyFromFile_trim_content() throws Exception { URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/non_trimmed_secret_key.txt"); String path = new File(resource.toURI()).getCanonicalPath(); - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); Key secretKey = cipher.loadSecretFileFromFile(path); assertThat(secretKey.getAlgorithm()).isEqualTo("AES"); - assertThat(secretKey.getEncoded().length).isGreaterThan(10); + assertThat(secretKey.getEncoded()).hasSizeGreaterThan(10); } @Test public void loadSecretKeyFromFile_file_does_not_exist() throws Exception { thrown.expect(IllegalStateException.class); - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); cipher.loadSecretFileFromFile("/file/does/not/exist"); } @@ -157,20 +157,20 @@ public class AesCipherTest { public void loadSecretKeyFromFile_no_property() throws Exception { thrown.expect(IllegalStateException.class); - AesCipher cipher = new AesCipher(null); + AesECBCipher cipher = new AesECBCipher(null); cipher.loadSecretFileFromFile(null); } @Test public void hasSecretKey() throws Exception { - AesCipher cipher = new AesCipher(pathToSecretKey()); + AesECBCipher cipher = new AesECBCipher(pathToSecretKey()); assertThat(cipher.hasSecretKey()).isTrue(); } @Test public void doesNotHaveSecretKey() { - AesCipher cipher = new AesCipher("/my/twitter/id/is/SimonBrandhof"); + AesECBCipher cipher = new AesECBCipher("/my/twitter/id/is/SimonBrandhof"); assertThat(cipher.hasSecretKey()).isFalse(); } diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesGCMCipherTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesGCMCipherTest.java new file mode 100644 index 00000000000..08b23b19476 --- /dev/null +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/AesGCMCipherTest.java @@ -0,0 +1,93 @@ +/* + * 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.api.config.internal; + +import java.io.File; +import java.net.URL; +import java.security.InvalidKeyException; +import javax.crypto.BadPaddingException; + +import org.apache.commons.lang.StringUtils; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class AesGCMCipherTest { + + @Test + public void encrypt_should_generate_different_value_everytime() throws Exception { + AesGCMCipher cipher = new AesGCMCipher(pathToSecretKey()); + + String encryptedText1 = cipher.encrypt("this is a secret"); + String encryptedText2 = cipher.encrypt("this is a secret"); + + assertThat(StringUtils.isNotBlank(encryptedText1)).isTrue(); + assertThat(StringUtils.isNotBlank(encryptedText2)).isTrue(); + assertThat(encryptedText1).isNotEqualTo(encryptedText2); + } + + @Test + public void encrypt_bad_key() throws Exception { + URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/bad_secret_key.txt"); + AesGCMCipher cipher = new AesGCMCipher(new File(resource.toURI()).getCanonicalPath()); + + assertThatThrownBy(() -> cipher.encrypt("this is a secret")) + .hasRootCauseInstanceOf(InvalidKeyException.class) + .hasMessageContaining("Invalid AES key"); + } + + @Test + public void decrypt() throws Exception { + AesGCMCipher cipher = new AesGCMCipher(pathToSecretKey()); + String input1 = "this is a secret"; + String input2 = "asdkfja;ksldjfowiaqueropijadfskncmnv/sdjflskjdflkjiqoeuwroiqu./qewirouasoidfhjaskldfhjkhckjnkiuoewiruoasdjkfalkufoiwueroijuqwoerjsdkjflweoiru"; + + assertThat(cipher.decrypt(cipher.encrypt(input1))).isEqualTo(input1); + assertThat(cipher.decrypt(cipher.encrypt(input1))).isEqualTo(input1); + assertThat(cipher.decrypt(cipher.encrypt(input2))).isEqualTo(input2); + assertThat(cipher.decrypt(cipher.encrypt(input2))).isEqualTo(input2); + } + + @Test + public void decrypt_bad_key() throws Exception { + URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/bad_secret_key.txt"); + AesGCMCipher cipher = new AesGCMCipher(new File(resource.toURI()).getCanonicalPath()); + + assertThatThrownBy(() -> cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY=")) + .hasRootCauseInstanceOf(InvalidKeyException.class) + .hasMessageContaining("Invalid AES key"); + } + + @Test + public void decrypt_other_key() throws Exception { + URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/other_secret_key.txt"); + AesGCMCipher originalCipher = new AesGCMCipher(pathToSecretKey()); + AesGCMCipher cipher = new AesGCMCipher(new File(resource.toURI()).getCanonicalPath()); + + assertThatThrownBy(() -> cipher.decrypt(originalCipher.encrypt("this is a secret"))) + .hasRootCauseInstanceOf(BadPaddingException.class); + } + + private String pathToSecretKey() throws Exception { + URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/aes_secret_key.txt"); + return new File(resource.toURI()).getCanonicalPath(); + } +} diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/EncryptionTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/EncryptionTest.java index 12c8d716368..63f202c2864 100644 --- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/EncryptionTest.java +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/config/internal/EncryptionTest.java @@ -19,6 +19,9 @@ */ package org.sonar.api.config.internal; +import java.io.File; +import java.net.URL; + import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -50,6 +53,33 @@ public class EncryptionTest { } @Test + public void loadSecretKey() throws Exception { + Encryption encryption = new Encryption(null); + encryption.setPathToSecretKey(pathToSecretKey()); + assertThat(encryption.hasSecretKey()).isTrue(); + } + + @Test + public void generate_secret_key() { + Encryption encryption = new Encryption(null); + String key1 = encryption.generateRandomSecretKey(); + String key2 = encryption.generateRandomSecretKey(); + assertThat(key1).isNotEqualTo(key2); + } + + @Test + public void gcm_encryption() throws Exception { + Encryption encryption = new Encryption(pathToSecretKey()); + String clearText = "this is a secrit"; + String cipherText = encryption.encrypt(clearText); + String decryptedText = encryption.decrypt(cipherText); + assertThat(cipherText) + .startsWith("{aes-gcm}") + .isNotEqualTo(clearText); + assertThat(decryptedText).isEqualTo(clearText); + } + + @Test public void decrypt_unknown_algorithm() { Encryption encryption = new Encryption(null); assertThat(encryption.decrypt("{xxx}Zm9v")).isEqualTo("{xxx}Zm9v"); @@ -60,4 +90,9 @@ public class EncryptionTest { Encryption encryption = new Encryption(null); assertThat(encryption.decrypt("foo")).isEqualTo("foo"); } + + private String pathToSecretKey() throws Exception { + URL resource = getClass().getResource("/org/sonar/api/config/internal/AesCipherTest/aes_secret_key.txt"); + return new File(resource.toURI()).getCanonicalPath(); + } } |