Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand DownExpand Up@@ -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() {
Expand All@@ -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 {
Expand DownExpand Up@@ -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()
}
}
}
Original file line numberDiff line numberDiff line change
@@ -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)
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand All@@ -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
Expand DownExpand Up@@ -150,25 +150,35 @@ 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)
Comment thread
DenBond7 marked this conversation as resolved.

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")
assertThrows(KeyIntegrityException::class.java) {
PgpKey.checkSecretKeyIntegrity(encryptedKeyText, passphrase)
}
} finally {
PGPainless.getInstance().algorithmPolicy.enableKeyParameterValidation = false
PGPainless.setInstance(originalPgpainless)
}
}

Expand Down
Loading