From 51c404d5a0b2276a601105517d8bb4480abd105c Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Mon, 20 Apr 2020 14:36:43 +0800 Subject: [PATCH] Migrate to vanilla Bouncycastle Fixes #1870. Per - Remove stock Bouncycastle provider bundled with Android - Register updated Bouncycastle provider as first crypto provider available - Remove proguard config related to Spongycastle - Update code to obtain crypto provider directly without prefix --- app/build.gradle | 5 ++-- app/proguard.cfg | 26 ------------------- .../asynchronous/services/ftp/FtpService.java | 2 +- .../filesystem/ssh/CustomSshJConfig.java | 4 +-- .../filemanager/utils/files/CryptUtil.java | 10 +++---- .../filesystem/ssh/test/TestKeyProvider.java | 2 +- .../filemanager/test/ShadowCryptUtil.java | 6 ++--- gradle.properties | 4 +++ 8 files changed, 18 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 692cf4802e..bce59421c6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,6 +88,7 @@ ext { glideVersion = '4.9.0' sshjVersion = '0.26.0' fabSpeedDialVersion = '3.1.1' + bouncyCastleVersion = '1.65' } dependencies { @@ -172,8 +173,8 @@ dependencies { //SFTP implementation "com.hierynomus:sshj:$sshjVersion" - implementation 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0' - implementation 'com.madgag.spongycastle:prov:1.58.0.0' + implementation "org.bouncycastle:bcpkix-jdk15on:$bouncyCastleVersion" + implementation "org.bouncycastle:bcprov-jdk15on:$bouncyCastleVersion" //Glide: loads icons seemlessly implementation "com.github.bumptech.glide:glide:$glideVersion" diff --git a/app/proguard.cfg b/app/proguard.cfg index 63e8f7fb91..c7b39a6cce 100644 --- a/app/proguard.cfg +++ b/app/proguard.cfg @@ -72,32 +72,6 @@ #From here CloudRail -keep class com.cloudrail.** { *; } -#From here SpongyCastle (https://github.com/signalapp/Signal-Android/blob/master/proguard-spongycastle.pro) --keep class org.spongycastle.crypto.* {*;} --keep class org.spongycastle.crypto.agreement.** {*;} --keep class org.spongycastle.crypto.digests.* {*;} --keep class org.spongycastle.crypto.ec.* {*;} --keep class org.spongycastle.crypto.encodings.* {*;} --keep class org.spongycastle.crypto.engines.* {*;} --keep class org.spongycastle.crypto.macs.* {*;} --keep class org.spongycastle.crypto.modes.* {*;} --keep class org.spongycastle.crypto.paddings.* {*;} --keep class org.spongycastle.crypto.params.* {*;} --keep class org.spongycastle.crypto.prng.* {*;} --keep class org.spongycastle.crypto.signers.* {*;} - --keep class org.spongycastle.jcajce.provider.asymmetric.* {*;} --keep class org.spongycastle.jcajce.provider.asymmetric.util.* {*;} --keep class org.spongycastle.jcajce.provider.asymmetric.dh.* {*;} --keep class org.spongycastle.jcajce.provider.asymmetric.ec.* {*;} --keep class org.spongycastle.jcajce.provider.asymmetric.rsa.* {*;} - --keep class org.spongycastle.jcajce.provider.digest.** {*;} --keep class org.spongycastle.jcajce.provider.keystore.** {*;} --keep class org.spongycastle.jcajce.provider.symmetric.** {*;} --keep class org.spongycastle.jcajce.spec.* {*;} --keep class org.spongycastle.jce.** {*;} - #From here BouncyCastle -keep class org.bouncycastle.crypto.* {*;} -keep class org.bouncycastle.crypto.agreement.** {*;} diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/services/ftp/FtpService.java b/app/src/main/java/com/amaze/filemanager/asynchronous/services/ftp/FtpService.java index 3ba34445b3..b596cca1e5 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/services/ftp/FtpService.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/services/ftp/FtpService.java @@ -199,7 +199,7 @@ public void run() { if (preferences.getBoolean(KEY_PREFERENCE_SECURE, DEFAULT_SECURE)) { try { - KeyStore keyStore = KeyStore.getInstance("BKS", "BC"); + KeyStore keyStore = KeyStore.getInstance("BKS"); keyStore.load(getResources().openRawResource(R.raw.key), KEYSTORE_PASSWORD); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java index b0034be6b5..1aa9eafc48 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java @@ -43,10 +43,8 @@ public class CustomSshJConfig extends DefaultConfig // BouncyCastle before registering SpongyCastle's provider public static void init() { Security.removeProvider("BC"); - Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), - Security.getProviders().length+1); Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), - Security.getProviders().length+1); + 0); } // don't add ECDSA diff --git a/app/src/main/java/com/amaze/filemanager/utils/files/CryptUtil.java b/app/src/main/java/com/amaze/filemanager/utils/files/CryptUtil.java index 05e734b655..0870ba7659 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/files/CryptUtil.java +++ b/app/src/main/java/com/amaze/filemanager/utils/files/CryptUtil.java @@ -384,7 +384,7 @@ private static Key getSecretKey() throws GeneralSecurityException, IOException { private void rsaEncrypt(Context context, BufferedInputStream inputStream, BufferedOutputStream outputStream) throws GeneralSecurityException, IOException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); RSAKeygen keygen = new RSAKeygen(context); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes()); @@ -414,7 +414,7 @@ private void rsaEncrypt(Context context, BufferedInputStream inputStream, Buffer private void rsaDecrypt(Context context, BufferedInputStream inputStream, BufferedOutputStream outputStream) throws GeneralSecurityException, IOException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); RSAKeygen keygen = new RSAKeygen(context); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes()); @@ -443,7 +443,7 @@ private void rsaDecrypt(Context context, BufferedInputStream inputStream, @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private static String rsaEncryptPassword(Context context, String password) throws GeneralSecurityException, IOException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); RSAKeygen keygen = new RSAKeygen(context); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes()); @@ -455,7 +455,7 @@ private static String rsaEncryptPassword(Context context, String password) throw @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private static String rsaDecryptPassword(Context context, String cipherText) throws GeneralSecurityException, IOException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); RSAKeygen keygen = new RSAKeygen(context); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes()); cipher.init(Cipher.DECRYPT_MODE, keygen.getSecretKey(), ivParameterSpec); @@ -498,7 +498,7 @@ public static Cipher initCipher(Context context) throws GeneralSecurityException GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), gcmParameterSpec); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - cipher = Cipher.getInstance(ALGO_AES, "BC"); + cipher = Cipher.getInstance(ALGO_AES); RSAKeygen keygen = new RSAKeygen(context); cipher.init(Cipher.ENCRYPT_MODE, keygen.getSecretKey()); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/test/TestKeyProvider.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/test/TestKeyProvider.java index f68a224fb1..82e9778b0d 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/test/TestKeyProvider.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/test/TestKeyProvider.java @@ -12,7 +12,7 @@ public class TestKeyProvider implements KeyPairProvider { private KeyPair keyPair; public TestKeyProvider() throws Exception { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC"); + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024, new SecureRandom()); keyPair = keyPairGenerator.generateKeyPair(); } diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtil.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtil.java index 453ec29762..c0b8ff3e5d 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtil.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtil.java @@ -26,7 +26,7 @@ public class ShadowCryptUtil { static { try { - KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC"); + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(128); secretKey = keyGen.generateKey(); } catch (GeneralSecurityException e) { @@ -56,7 +56,7 @@ public static String decryptPassword(Context context, String cipherText) throws private static String aesEncryptPassword(String plainTextPassword) throws GeneralSecurityException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec); byte[] encodedBytes = cipher.doFinal(plainTextPassword.getBytes()); @@ -69,7 +69,7 @@ private static String aesEncryptPassword(String plainTextPassword) */ private static String aesDecryptPassword(String cipherPassword) throws GeneralSecurityException { - Cipher cipher = Cipher.getInstance(ALGO_AES, "BC"); + Cipher cipher = Cipher.getInstance(ALGO_AES); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV.getBytes()); cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); byte[] decryptedBytes = cipher.doFinal(Base64.decode(cipherPassword, Base64.DEFAULT)); diff --git a/gradle.properties b/gradle.properties index 3496d4a18e..fea8ad8eed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,6 +11,10 @@ # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true android.useAndroidX=true +# Workaround for Android Gradle Plugin before 3.6.0. +# See https://github.com/robolectric/robolectric/issues/5299#issuecomment-543125381 +# and https://issuetracker.google.com/issues/142580430 +android.jetifier.blacklist=.*bcprov.* org.gradle.jvmargs=-Xmx4608M # When configured, Gradle will run in incubating parallel mode.