diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt index d78a1bb35..4918156ca 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt @@ -8,6 +8,7 @@ package com.flowcrypt.email import android.app.Application import android.content.Context import android.util.Log +import androidx.annotation.VisibleForTesting import androidx.core.content.edit import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner @@ -85,12 +86,7 @@ class FlowCryptApplication : Application(), Configuration.Provider { } private fun setupPGPainless() { - PGPainless.setInstance( - PGPainless(algorithmPolicy = generatePGPainlessPolicy().apply { - //https://github.com/FlowCrypt/flowcrypt-android/issues/2111 - PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation = true - }) - ) + PGPainless.setInstance(createPGPainlessInstance()) } private fun setupGlobalSettingsForJavaMail() { @@ -104,27 +100,6 @@ class FlowCryptApplication : Application(), Configuration.Provider { initACRA() } - /** - * Allow sha1 for all builds except enterprise. It's a temporary solution. - * More details here https://github.com/FlowCrypt/flowcrypt-android/issues/1478 and here - * https://github.com/pgpainless/pgpainless/issues/158 - */ - @Suppress("KotlinConstantConditions") - private fun generatePGPainlessPolicy(): Policy { - val isEnterpriseBuild = BuildConfig.FLAVOR == Constants.FLAVOR_NAME_ENTERPRISE - val strongPolicySince2022 = HashAlgorithmPolicy.static2022SignatureHashAlgorithmPolicy() - val policyBefore2022Standard = - HashAlgorithmPolicy.static2022RevocationSignatureHashAlgorithmPolicy() - return Policy.Builder(PGPainless.getInstance().algorithmPolicy) - .withDataSignatureHashAlgorithmPolicy( - if (isEnterpriseBuild) strongPolicySince2022 else policyBefore2022Standard - ) - .withCertificationSignatureHashAlgorithmPolicy( - if (isEnterpriseBuild) strongPolicySince2022 else policyBefore2022Standard - ) - .build() - } - private fun setupKeysStorage() { val keysStorage = KeysStorageImpl.getInstance(this) keysStorage.secretKeyRingsLiveData.observeForever { @@ -286,4 +261,35 @@ class FlowCryptApplication : Application(), Configuration.Provider { isAppForegroundedInternal = false } } + + companion object { + @VisibleForTesting + internal fun createPGPainlessInstance(): PGPainless { + return PGPainless(algorithmPolicy = generatePGPainlessPolicy().apply { + //https://github.com/FlowCrypt/flowcrypt-android/issues/2111 + enableKeyParameterValidation = true + }) + } + + /** + * Allow sha1 for all builds except enterprise. It's a temporary solution. + * More details here https://github.com/FlowCrypt/flowcrypt-android/issues/1478 and here + * https://github.com/pgpainless/pgpainless/issues/158 + */ + @Suppress("KotlinConstantConditions") + private fun generatePGPainlessPolicy(): Policy { + val isEnterpriseBuild = BuildConfig.FLAVOR == Constants.FLAVOR_NAME_ENTERPRISE + val strongPolicySince2022 = HashAlgorithmPolicy.static2022SignatureHashAlgorithmPolicy() + val policyBefore2022Standard = + HashAlgorithmPolicy.static2022RevocationSignatureHashAlgorithmPolicy() + return Policy.Builder(PGPainless.getInstance().algorithmPolicy) + .withDataSignatureHashAlgorithmPolicy( + if (isEnterpriseBuild) strongPolicySince2022 else policyBefore2022Standard + ) + .withCertificationSignatureHashAlgorithmPolicy( + if (isEnterpriseBuild) strongPolicySince2022 else policyBefore2022Standard + ) + .build() + } + } } diff --git a/FlowCrypt/src/test/java/com/flowcrypt/email/FlowCryptApplicationTest.kt b/FlowCrypt/src/test/java/com/flowcrypt/email/FlowCryptApplicationTest.kt new file mode 100644 index 000000000..7e087d077 --- /dev/null +++ b/FlowCrypt/src/test/java/com/flowcrypt/email/FlowCryptApplicationTest.kt @@ -0,0 +1,21 @@ +/* + * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com + * Contributors: denbond7 + */ + +package com.flowcrypt.email + +import org.junit.Assert.assertTrue +import org.junit.Test + +/** + * @author Denys Bondarenko + */ +class FlowCryptApplicationTest { + @Test + fun testCreatePGPainlessInstanceEnablesKeyParameterValidation() { + val pgpainless = FlowCryptApplication.createPGPainlessInstance() + + assertTrue(pgpainless.algorithmPolicy.enableKeyParameterValidation) + } +} diff --git a/FlowCrypt/src/test/java/com/flowcrypt/email/security/pgp/PgpKeyTest.kt b/FlowCrypt/src/test/java/com/flowcrypt/email/security/pgp/PgpKeyTest.kt index 9d6e710d0..83782b302 100644 --- a/FlowCrypt/src/test/java/com/flowcrypt/email/security/pgp/PgpKeyTest.kt +++ b/FlowCrypt/src/test/java/com/flowcrypt/email/security/pgp/PgpKeyTest.kt @@ -6,6 +6,7 @@ package com.flowcrypt.email.security.pgp import com.flowcrypt.email.BuildConfig +import com.flowcrypt.email.FlowCryptApplication import com.flowcrypt.email.security.model.Algo import com.flowcrypt.email.security.model.KeyId import com.flowcrypt.email.security.model.PgpKeyRingDetails @@ -17,7 +18,6 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertThrows import org.junit.Assert.assertTrue -import org.junit.Ignore import org.junit.Test import org.pgpainless.PGPainless import org.pgpainless.algorithm.HashAlgorithm @@ -150,17 +150,27 @@ class PgpKeyTest { } @Test - @Ignore("temporary disabled due to https://github.com/pgpainless/pgpainless/issues/488") fun testPublicKey_Issue1358() { - val keyText = TestUtil.readResourceAsString("pgp/keys/issue-1358.public.gpg-key") - val actual = PgpKey.parseKeys(source = keyText) - assertEquals(1, actual.getAllKeys().size) + val originalPgpainless = PGPainless.getInstance() + try { + PGPainless.setInstance(FlowCryptApplication.createPGPainlessInstance()) + assertTrue(PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation) + + val keyText = TestUtil.readResourceAsString("pgp/keys/issue-1358.public.gpg-key") + val actual = PgpKey.parseKeys(source = keyText) + assertEquals(1, actual.getAllKeys().size) + } finally { + PGPainless.setInstance(originalPgpainless) + } } @Test fun testReadCorruptedPrivateKey() { + val originalPgpainless = PGPainless.getInstance() try { - PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation = true + PGPainless.setInstance(FlowCryptApplication.createPGPainlessInstance()) + assertTrue(PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation) + val encryptedKeyText = TestUtil.readResourceAsString("pgp/keys/issue-1669-corrupted.private.gpg-key") val passphrase = Passphrase.fromPassword("123") @@ -168,7 +178,7 @@ class PgpKeyTest { PgpKey.checkSecretKeyIntegrity(encryptedKeyText, passphrase) } } finally { - PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation = false + PGPainless.setInstance(originalPgpainless) } }