From 5726353c8e894434f6d0c232f89bc5e9a6981f2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:08:05 +0000 Subject: [PATCH 1/9] Bump org.pgpainless:pgpainless-core from 1.6.7 to 1.7.2 Bumps [org.pgpainless:pgpainless-core](https://github.com/pgpainless/pgpainless) from 1.6.7 to 1.7.2. - [Changelog](https://github.com/pgpainless/pgpainless/blob/main/CHANGELOG.md) - [Commits](https://github.com/pgpainless/pgpainless/compare/1.6.7...1.7.2) --- updated-dependencies: - dependency-name: org.pgpainless:pgpainless-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- FlowCrypt/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlowCrypt/build.gradle.kts b/FlowCrypt/build.gradle.kts index fbc8158315..cc1470b9ce 100644 --- a/FlowCrypt/build.gradle.kts +++ b/FlowCrypt/build.gradle.kts @@ -468,7 +468,7 @@ dependencies { implementation("org.bitbucket.b_c:jose4j:0.9.6") implementation("org.jsoup:jsoup:1.18.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") - implementation("org.pgpainless:pgpainless-core:1.6.7") + implementation("org.pgpainless:pgpainless-core:1.7.2") implementation("org.eclipse.angus:angus-mail:2.0.3") implementation("org.eclipse.angus:gimap:2.0.3") implementation("commons-io:commons-io:2.17.0") From 48978d4fcb847e80b2f851002df605fdac5c8290 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 16 Dec 2024 18:06:46 +0200 Subject: [PATCH 2/9] Fixed compilation issues --- FlowCrypt/build.gradle.kts | 3 ++- .../java/com/flowcrypt/email/FlowCryptApplication.kt | 6 +++--- .../org/bouncycastle/openpgp/PGPKeyRingExt.kt | 12 +++--------- .../extensions/org/pgpainless/util/PassphraseExt.kt | 4 ++-- .../jetpack/viewmodel/CheckPrivateKeysViewModel.kt | 4 ++-- .../jetpack/viewmodel/EditPrivateKeyViewModel.kt | 2 +- .../email/jetpack/viewmodel/PrivateKeysViewModel.kt | 6 ++---- .../com/flowcrypt/email/security/KeysStorageImpl.kt | 12 ++++++------ .../email/security/pgp/PgpEncryptAndOrSign.kt | 10 +++++----- .../java/com/flowcrypt/email/security/pgp/PgpKey.kt | 4 ++-- .../java/com/flowcrypt/email/security/pgp/PgpMsg.kt | 11 +++++------ .../com/flowcrypt/email/security/pgp/PgpSignature.kt | 4 ++-- .../com/flowcrypt/email/security/pgp/PgpKeyTest.kt | 6 +++--- 13 files changed, 38 insertions(+), 46 deletions(-) diff --git a/FlowCrypt/build.gradle.kts b/FlowCrypt/build.gradle.kts index 444ffaa8bf..9643f417a5 100644 --- a/FlowCrypt/build.gradle.kts +++ b/FlowCrypt/build.gradle.kts @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ @@ -209,6 +209,7 @@ android { "META-INF/*.DSA", "META-INF/*.RSA", "META-INF/javamail.providers", + "META-INF/versions/9/OSGI-INF/MANIFEST.MF", ) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt index 7cb690d966..d2e57f93d8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email @@ -79,7 +79,7 @@ class FlowCryptApplication : Application(), Configuration.Provider { enableDeprecatedSHA1ForPGPainlessPolicy() //https://github.com/FlowCrypt/flowcrypt-android/issues/2111 - PGPainless.getPolicy().isEnableKeyParameterValidation = true + PGPainless.getPolicy().enableKeyParameterValidation = true } private fun setupGlobalSettingsForJavaMail() { @@ -101,7 +101,7 @@ class FlowCryptApplication : Application(), Configuration.Provider { private fun enableDeprecatedSHA1ForPGPainlessPolicy() { @Suppress("KotlinConstantConditions") if (BuildConfig.FLAVOR != Constants.FLAVOR_NAME_ENTERPRISE) { - PGPainless.getPolicy().signatureHashAlgorithmPolicy = HashAlgorithmPolicy( + PGPainless.getPolicy().dataSignatureHashAlgorithmPolicy = HashAlgorithmPolicy( HashAlgorithm.SHA512, listOf( HashAlgorithm.SHA512, HashAlgorithm.SHA384, diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt index 083dd1af2f..200835c0de 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: ivan + * Contributors: denbond7 */ package com.flowcrypt.email.extensions.org.bouncycastle.openpgp @@ -14,10 +14,8 @@ import com.flowcrypt.email.security.model.KeyId import com.flowcrypt.email.security.model.PgpKeyRingDetails import org.bouncycastle.openpgp.PGPKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing -import org.pgpainless.algorithm.PublicKeyAlgorithm +import org.pgpainless.bouncycastle.extensions.getCurveName import org.pgpainless.key.OpenPgpV4Fingerprint -import org.pgpainless.key.generation.type.eddsa.EdDSACurve -import org.pgpainless.key.info.KeyInfo import org.pgpainless.key.info.KeyRingInfo import java.io.IOException import java.time.Instant @@ -40,11 +38,7 @@ fun PGPKeyRing.toPgpKeyRingDetails(hideArmorMeta: Boolean = false): PgpKeyRingDe algorithm = keyRingInfo.algorithm.name, algorithmId = keyRingInfo.algorithm.algorithmId, bits = if (keyRingInfo.publicKey.bitStrength != -1) keyRingInfo.publicKey.bitStrength else 0, - curve = when (keyRingInfo.algorithm) { - PublicKeyAlgorithm.ECDSA, PublicKeyAlgorithm.ECDH -> KeyInfo.getCurveName(publicKey) - PublicKeyAlgorithm.EDDSA -> EdDSACurve._Ed25519.getName() // for EDDSA KeyInfo.getCurveName(publicKey) return null - else -> null - } + curve = runCatching { publicKey.getCurveName() }.getOrNull() ) val keyIdList = publicKeys.iterator().asSequence().toList() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/pgpainless/util/PassphraseExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/pgpainless/util/PassphraseExt.kt index da5dc321d2..6298bb550f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/pgpainless/util/PassphraseExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/pgpainless/util/PassphraseExt.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.extensions.org.pgpainless.util @@ -12,5 +12,5 @@ import org.pgpainless.util.Passphrase */ val Passphrase.asString: String? get() { - return chars?.let { String(it) } + return runCatching { getChars() }.getOrNull()?.let { String(it) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/CheckPrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/CheckPrivateKeysViewModel.kt index aa54a72ed4..1f94dccd2e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/CheckPrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/CheckPrivateKeysViewModel.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.jetpack.viewmodel @@ -150,7 +150,7 @@ class CheckPrivateKeysViewModel( resultList.add( CheckResult( pgpKeyRingDetails = copy, - passphrase = passphrase.chars ?: throw IllegalArgumentException(), + passphrase = passphrase.getChars() ?: throw IllegalArgumentException(), e = e ) ) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/EditPrivateKeyViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/EditPrivateKeyViewModel.kt index 26450f3ea9..6bccff091d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/EditPrivateKeyViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/EditPrivateKeyViewModel.kt @@ -66,7 +66,7 @@ class EditPrivateKeyViewModel(val fingerprint: String, application: Application) roomDatabase.keysDao().updateSuspend(entity.copy(privateKey = encryptedPrvKey)) //update contacts and pub keys - val email = userId.email.lowercase() + val email = userId.email?.lowercase() ?: "" var cachedRecipientWithPubKeys = roomDatabase.recipientDao() .getRecipientWithPubKeysByEmailSuspend(email) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index d5e4c8f11f..3aa5223798 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -1,8 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: - * DenBond7 - * Ivan Pizhenko + * Contributors: denbond7 */ package com.flowcrypt.email.jetpack.viewmodel @@ -498,7 +496,7 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat protectPrivateKeysLiveData.value = Result.success(PgpKey.parsePrivateKeys(encryptedKeysSource).map { key -> key.copy( - tempPassphrase = passphrase.chars, + tempPassphrase = passphrase.getChars(), importInfo = (key.importInfo ?: PgpKeyRingDetails.ImportInfo()).copy( importSourceType = sourceTypeInfo[key.fingerprint] ) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/KeysStorageImpl.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/KeysStorageImpl.kt index 1025ac7717..7447a97409 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/KeysStorageImpl.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/KeysStorageImpl.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.security @@ -111,7 +111,7 @@ class KeysStorageImpl private constructor(context: Context) : KeysStorage { return rings.map { val pgpKeyRingDetails = it.toPgpKeyRingDetails() val passphrase = getPassphraseByFingerprint(pgpKeyRingDetails.fingerprint) - pgpKeyRingDetails.copy(tempPassphrase = passphrase?.chars) + pgpKeyRingDetails.copy(tempPassphrase = passphrase?.getChars()) } } @@ -161,12 +161,12 @@ class KeysStorageImpl private constructor(context: Context) : KeysStorage { override fun getSecretKeyRingProtector(): SecretKeyRingProtector { val availablePGPSecretKeyRings = getPGPSecretKeyRings() val passphraseProvider = object : SecretKeyPassphraseProvider { - override fun getPassphraseFor(keyId: Long): Passphrase? { - return doGetPassphrase(keyId, true) + override fun getPassphraseFor(keyId: Long?): Passphrase? { + return keyId?.let { doGetPassphrase(keyId, true) } } - override fun hasPassphrase(keyId: Long): Boolean { - return doGetPassphrase(keyId, false) != null + override fun hasPassphrase(keyId: Long?): Boolean { + return keyId != null && doGetPassphrase(keyId, false) != null } private fun doGetPassphrase(keyId: Long, throwException: Boolean): Passphrase? { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpEncryptAndOrSign.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpEncryptAndOrSign.kt index b1783c47e1..9858263f61 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpEncryptAndOrSign.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpEncryptAndOrSign.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.security.pgp @@ -172,7 +172,7 @@ object PgpEncryptAndOrSign { generateDetachedSignatures: Boolean = false, ): EncryptionStream { val encOpt = EncryptionOptions().apply { - passphrase?.let { addPassphrase(passphrase) } + passphrase?.let { addMessagePassphrase(passphrase) } pgpPublicKeyRingCollection?.forEach { addRecipient(it) } @@ -207,10 +207,10 @@ object PgpEncryptAndOrSign { ProducerOptions.encrypt(encOpt) } - producerOptions.isAsciiArmor = doArmor - producerOptions.isHideArmorHeaders = doArmor && hideArmorMeta + producerOptions.setAsciiArmor(doArmor) + producerOptions.setHideArmorHeaders(doArmor && hideArmorMeta) - fileName?.let { producerOptions.fileName = it } + fileName?.let { producerOptions.setFileName(it) } return PGPainless.encryptAndOrSign() .onOutputStream(destOutputStream) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpKey.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpKey.kt index ebb79c8926..76bbb83940 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpKey.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpKey.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: Ivan Pizhenko + * Contributors: denbond7 */ package com.flowcrypt.email.security.pgp @@ -187,7 +187,7 @@ object PgpKey { private fun encryptKey(key: PGPSecretKeyRing, passphrase: Passphrase): PGPSecretKeyRing { return PGPainless.modifyKeyRing(key) - .changePassphraseFromOldPassphrase(null) + .changePassphraseFromOldPassphrase(Passphrase.emptyPassphrase()) .withSecureDefaultSettings() .toNewPassphrase(passphrase) .done() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt index 9db852d94d..1f4d6a9d51 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt @@ -1,7 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: Ivan Pizhenko, - * DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.security.pgp @@ -831,15 +830,15 @@ object PgpMsg { keyIdOfSigningKeys.addAll(invalidSignatureFailures.filter { it.validationException.message?.matches("Missing verification key.?".toRegex()) == true - }.mapNotNull { it.signatureVerification.signature.keyID }) + }.map { it.signature.keyID }) } if (verifiedSignatures.isEmpty()) { verifiedSignatures.addAll(messageMetadata.verifiedSignatures) } else { - val keyIdsOfAllVerifiedSignatures = verifiedSignatures.map { it.signingKey?.keyId } + val keyIdsOfAllVerifiedSignatures = verifiedSignatures.map { it.signingKey.keyId } val keyIdsOfCurrentVerifiedSignatures = messageMetadata.verifiedSignatures.map { - it.signingKey?.keyId + it.signingKey.keyId } if (keyIdsOfAllVerifiedSignatures != keyIdsOfCurrentVerifiedSignatures) { hasMixedSignatures = true @@ -1342,7 +1341,7 @@ object PgpMsg { private fun moveElementsOutOfAnchorTag(element: Element, parent: Element) { if (element.tag().normalName() == "a" && element.hasAttr(FC_INNER_TEXT_TYPE_ATTR)) { - val children = element.children().map { it as Node }.toTypedArray() + val children = element.children().map { it }.toTypedArray() val n = element.childrenSize() var index = 0 while (index < n && parent.child(index) !== element) ++index diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpSignature.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpSignature.kt index 12adbeb29f..ebe760e6c7 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpSignature.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpSignature.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.security.pgp @@ -34,7 +34,7 @@ object PgpSignature { srcStream, multiPassStrategy.messageOutputStream ) - String(multiPassStrategy.bytes) + String(multiPassStrategy.getBytes()) } catch (e: Exception) { if (isSilent) { e.printStackTrace() 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 d621c9b303..eb3ccd1c27 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 @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: Ivan Pizhenko + * Contributors: denbond7 */ package com.flowcrypt.email.security.pgp @@ -146,14 +146,14 @@ class PgpKeyTest { @Test fun testReadCorruptedPrivateKey() { try { - PGPainless.getPolicy().isEnableKeyParameterValidation = true + PGPainless.getPolicy().enableKeyParameterValidation = true val encryptedKeyText = loadResourceAsString("keys/issue-1669-corrupted.private.gpg-key") val passphrase = Passphrase.fromPassword("123") assertThrows(KeyIntegrityException::class.java) { PgpKey.checkSecretKeyIntegrity(encryptedKeyText, passphrase) } } finally { - PGPainless.getPolicy().isEnableKeyParameterValidation = false + PGPainless.getPolicy().enableKeyParameterValidation = false } } From 826f6fa2f2715d87feda436c40220ad9fa991694 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 17 Dec 2024 12:33:55 +0200 Subject: [PATCH 3/9] Added PgpKeyTest.testRejectingSHA1KeysForDefaultPGPainlessPolicy() and PgpKeyTest.testAcceptingSHA1KeysForModifiedPGPainlessPolicy() --- .../email/security/pgp/PgpKeyTest.kt | 33 +++++++++++++++++++ .../keys/sha1@flowcrypt.test_pub.asc | 24 ++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 FlowCrypt/src/test/resources/PgpKeyTest/keys/sha1@flowcrypt.test_pub.asc 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 eb3ccd1c27..625bd7069c 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 @@ -16,9 +16,11 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertThrows import org.junit.Test import org.pgpainless.PGPainless +import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.KeyFlag import org.pgpainless.exception.KeyIntegrityException import org.pgpainless.key.OpenPgpV4Fingerprint +import org.pgpainless.policy.Policy.HashAlgorithmPolicy import org.pgpainless.util.Passphrase import java.nio.charset.Charset import java.nio.charset.StandardCharsets @@ -157,6 +159,37 @@ class PgpKeyTest { } } + @Test + fun testRejectingSHA1KeysForDefaultPGPainlessPolicy() { + val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") + assertThrows(NoSuchElementException::class.java) { + //PGPainless.readKeyRing().keyRingCollection(keyWithSHA1Algo, false) + PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList + } + } + + @Test + fun testAcceptingSHA1KeysForModifiedPGPainlessPolicy() { + val originalSignatureHashAlgorithmPolicy = PGPainless.getPolicy().signatureHashAlgorithmPolicy + try { + val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") + PGPainless.getPolicy().signatureHashAlgorithmPolicy = HashAlgorithmPolicy( + HashAlgorithm.SHA512, listOf( + HashAlgorithm.SHA512, + HashAlgorithm.SHA384, + HashAlgorithm.SHA256, + HashAlgorithm.SHA224, + HashAlgorithm.SHA1 + ) + ) + val parseKeyResult = PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList + assertEquals(1, parseKeyResult.size) + assertEquals("5DE92AB364B3100D89FBF460241512660BDDC426", parseKeyResult.first().fingerprint) + } finally { + PGPainless.getPolicy().signatureHashAlgorithmPolicy = originalSignatureHashAlgorithmPolicy + } + } + fun replaceVersionInKey(key: String?): String { val regex = "^Version: FlowCrypt Email Encryption \\d*.\\d*.\\d*(_.*)?\$".toRegex(RegexOption.MULTILINE) diff --git a/FlowCrypt/src/test/resources/PgpKeyTest/keys/sha1@flowcrypt.test_pub.asc b/FlowCrypt/src/test/resources/PgpKeyTest/keys/sha1@flowcrypt.test_pub.asc new file mode 100644 index 0000000000..ded9cd4456 --- /dev/null +++ b/FlowCrypt/src/test/resources/PgpKeyTest/keys/sha1@flowcrypt.test_pub.asc @@ -0,0 +1,24 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: PGPainless + +mQGNBGElEfUBDACxoQswgPVv4bHZSpl0o2cNk1pkJKDfdsD992CZcLOTeO73KyT4 +9SmBPz/85bUt2RhpTHG6+gFaoDW08zRn8W4kL2O6GWeQpreNS+nNi10DeN/H1ciw +BtEJvfNkofQIANBspMSWE0hJhlHyYcUuiQFp7CL2nErInIk63uBVllWwwLdj+FLH +TuT8qxqEBCEaTDlZUHAPlbRrRYOikmh13AfqO6I42I50cf8gLRXFaf6jECkw3Ik5 +URGl9RIWT7gnN9WAaKq65qNUrFrjVySe4AvyZG39RzN0gkmqJ3qR91K97nw8E4lM +r8rqfLdQK8yzsFS4O6xl+YbN8dF+LtXsCOxp8Bg3Y4Ux2zurpf4PZ41ld7rGzMAp +6MikhTXCa2Sdci4Vp9T8Q7OztNia48GRsngZXXjVut2tLQA25XA1kK8OQwNLUM2k +Py2i5AS2Ezj03ExHplwcIhxfSxsyUM//IWdAoeTFMuvfbQ+ihwQu8nuhFB8RnTOI +DNE6zWEbsn7o7AkAEQEAAbQTc2hhMUBmbG93Y3J5cHQudGVzdIkBugQTAQIAJAUC +YSUR9QIbBwUWAgMBAAcLCQgHAwIBBhUIAgkKCwIeAQIZAQAKCRAkFRJmC93EJnoL +DACC88oZKQCKEbNI9cot5O04FQeENE7CUGHjvch4mjiPTO7qQZy23JW0nKba0lLl +mj4Oh/2eIT+2Ox2kM4wBtF1UambCx0i/6MDMIO7ridyYfDdMpjlb5OzZPceHYC4x +/Lo6LDqTF3IRNKHU1EHcxLL0h1KZlLCLNbgWvbWFb0ga7FKn9oLukmTy4vYX3A3H +W+ZQOfUDE8Lei9A0E4TP4/YzuVSYljA2G50QSC9T7KvG+PzBmoUVVWqO/rcczIyp +IjItJV8NC9NALQ9rbGdCc+WyUfSEU96whu6CWNlFTLHQ7YkU4iBMauyInenKG+CE +IEkFc2SP1zTSSSZs1gqFGTDm+v4I72kiODsRrLsnBVkrB6ZPhUE5/wLWjJIuFRkn +Gu/u0uPuQ1xoDDD7W9G63S4/1i/pnNdDr31RCazCFcFwG2H0xr6ZFeCwoxjB3dc2 +CcT6NFwTD0QvKPNQU4yUAV0kGM87fT9mP0xiz+22FvwS2p1UmXwpMoY1VAKKuUy7 +PrY= +=/FZC +-----END PGP PUBLIC KEY BLOCK----- From 7713a68245bfac6ca0de6fca586cb3844d1546f1 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 17 Dec 2024 17:05:51 +0200 Subject: [PATCH 4/9] wip --- .../com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt index d7578cd355..f93c047e5a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt @@ -1,6 +1,6 @@ /* * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 + * Contributors: denbond7 */ package com.flowcrypt.email.ui @@ -30,6 +30,7 @@ import com.flowcrypt.email.ui.adapter.RecipientChipRecyclerViewAdapter import com.flowcrypt.email.ui.base.BaseComposeScreenTest import com.flowcrypt.email.util.TestGeneralUtil import org.hamcrest.Matchers.allOf +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.RuleChain @@ -42,6 +43,7 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) @EnterpriseTest +@Ignore("Temporary disabled") class ComposeScreenEnterpriseFlowTest : BaseComposeScreenTest() { @get:Rule From c54e5a9050c0fecfa5f990638df0bfece31a75ec Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 17 Dec 2024 17:06:32 +0200 Subject: [PATCH 5/9] wip --- .../com/flowcrypt/email/security/pgp/PgpKeyTest.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) 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 625bd7069c..967e7e33af 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 @@ -16,11 +16,9 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertThrows import org.junit.Test import org.pgpainless.PGPainless -import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.KeyFlag import org.pgpainless.exception.KeyIntegrityException import org.pgpainless.key.OpenPgpV4Fingerprint -import org.pgpainless.policy.Policy.HashAlgorithmPolicy import org.pgpainless.util.Passphrase import java.nio.charset.Charset import java.nio.charset.StandardCharsets @@ -161,15 +159,21 @@ class PgpKeyTest { @Test fun testRejectingSHA1KeysForDefaultPGPainlessPolicy() { + /* + WIP + val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") assertThrows(NoSuchElementException::class.java) { //PGPainless.readKeyRing().keyRingCollection(keyWithSHA1Algo, false) PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList - } + }*/ } @Test fun testAcceptingSHA1KeysForModifiedPGPainlessPolicy() { + /* + WIP + val originalSignatureHashAlgorithmPolicy = PGPainless.getPolicy().signatureHashAlgorithmPolicy try { val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") @@ -187,7 +191,7 @@ class PgpKeyTest { assertEquals("5DE92AB364B3100D89FBF460241512660BDDC426", parseKeyResult.first().fingerprint) } finally { PGPainless.getPolicy().signatureHashAlgorithmPolicy = originalSignatureHashAlgorithmPolicy - } + }*/ } fun replaceVersionInKey(key: String?): String { From fff9f5f9777d763f9c402784cf1b3cd82a6f029c Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 17 Dec 2024 17:43:31 +0200 Subject: [PATCH 6/9] wip --- .../incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt index 55f312e531..ad49d1ce9b 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt @@ -49,6 +49,7 @@ import org.junit.runner.RunWith */ @MediumTest @RunWith(AndroidJUnit4::class) +@Ignore("Temporary disabled") class ParseAndSavePubKeysFragmentInIsolationTest : BaseTest() { private val existingPgpKeyDetails = From 07d8db2bfee83a117966a621c100e90be1faa6f0 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 23 Dec 2024 14:34:53 +0200 Subject: [PATCH 7/9] wip --- .../ui/ComposeScreenEnterpriseFlowTest.kt | 2 - .../flowcrypt/email/FlowCryptApplication.kt | 23 ++++++----- .../org/bouncycastle/openpgp/PGPKeyRingExt.kt | 35 ++++++++++++++++ .../email/security/pgp/PgpKeyTest.kt | 41 +++++++++---------- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt index f93c047e5a..40b2203e96 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/ComposeScreenEnterpriseFlowTest.kt @@ -30,7 +30,6 @@ import com.flowcrypt.email.ui.adapter.RecipientChipRecyclerViewAdapter import com.flowcrypt.email.ui.base.BaseComposeScreenTest import com.flowcrypt.email.util.TestGeneralUtil import org.hamcrest.Matchers.allOf -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.RuleChain @@ -43,7 +42,6 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) @EnterpriseTest -@Ignore("Temporary disabled") class ComposeScreenEnterpriseFlowTest : BaseComposeScreenTest() { @get:Rule diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt index d2e57f93d8..268e2b13da 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt @@ -38,7 +38,6 @@ import org.acra.data.StringFormat import org.acra.ktx.initAcra import org.acra.sender.HttpSender import org.pgpainless.PGPainless -import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.policy.Policy.HashAlgorithmPolicy import java.util.Calendar import java.util.concurrent.TimeUnit @@ -100,16 +99,18 @@ class FlowCryptApplication : Application(), Configuration.Provider { */ private fun enableDeprecatedSHA1ForPGPainlessPolicy() { @Suppress("KotlinConstantConditions") - if (BuildConfig.FLAVOR != Constants.FLAVOR_NAME_ENTERPRISE) { - PGPainless.getPolicy().dataSignatureHashAlgorithmPolicy = HashAlgorithmPolicy( - HashAlgorithm.SHA512, listOf( - HashAlgorithm.SHA512, - HashAlgorithm.SHA384, - HashAlgorithm.SHA256, - HashAlgorithm.SHA224, - HashAlgorithm.SHA1 - ) - ) + if (BuildConfig.FLAVOR == Constants.FLAVOR_NAME_ENTERPRISE) { + PGPainless.getPolicy().dataSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022SignatureHashAlgorithmPolicy() + + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022SignatureHashAlgorithmPolicy() + } else { + PGPainless.getPolicy().dataSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022RevocationSignatureHashAlgorithmPolicy() + + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022RevocationSignatureHashAlgorithmPolicy() } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt index 200835c0de..83d7fe0dc2 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt @@ -12,9 +12,15 @@ import com.flowcrypt.email.security.SecurityUtils import com.flowcrypt.email.security.model.Algo import com.flowcrypt.email.security.model.KeyId import com.flowcrypt.email.security.model.PgpKeyRingDetails +import org.bouncycastle.bcpg.HashAlgorithmTags +import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing +import org.bouncycastle.openpgp.PGPSignature +import org.pgpainless.PGPainless +import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.bouncycastle.extensions.getCurveName +import org.pgpainless.bouncycastle.extensions.issuerKeyId import org.pgpainless.key.OpenPgpV4Fingerprint import org.pgpainless.key.info.KeyRingInfo import java.io.IOException @@ -50,6 +56,13 @@ fun PGPKeyRing.toPgpKeyRingDetails(hideArmorMeta: Boolean = false): PgpKeyRingDe throw IllegalArgumentException("There are no fingerprints") } + if (containsHashAlgorithmWithSHA1()) { + val sigHashAlgoPolicy = PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy + if (!sigHashAlgoPolicy.isAcceptable(HashAlgorithm.SHA1)) { + throw PGPException("Unsupported signature(HashAlgorithm = SHA1)") + } + } + val privateKey = if (keyRingInfo.isSecretKey) armor(hideArmorMeta = hideArmorMeta) else null val publicKey = if (keyRingInfo.isSecretKey) { (this as PGPSecretKeyRing).toPublicKeyRing().armor(hideArmorMeta = hideArmorMeta) @@ -94,3 +107,25 @@ val PGPKeyRing.expiration: Instant? Instant.ofEpochMilli(publicKey.creationTime.time + publicKey.validSeconds * 1000) } } + +/** + * https://github.com/pgpainless/pgpainless/issues/461 + */ +fun PGPKeyRing.containsHashAlgorithmWithSHA1(): Boolean { + val hasSha1DirectKeySelfSignatures = publicKey.getSignaturesOfType(PGPSignature.DIRECT_KEY) + .asSequence() + .any { signature -> + signature.issuerKeyId == publicKey.keyID + && signature.hashAlgorithm == HashAlgorithmTags.SHA1 + } + + return hasSha1DirectKeySelfSignatures || publicKey.userIDs.asSequence().any { uid -> + publicKey.getSignaturesForID(uid) + .asSequence() + .any { signature -> + signature.isCertification + && signature.issuerKeyId == publicKey.keyID + && signature.hashAlgorithm == HashAlgorithmTags.SHA1 + } + } +} 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 967e7e33af..6ab45b3a75 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 @@ -10,15 +10,20 @@ import com.flowcrypt.email.security.model.Algo import com.flowcrypt.email.security.model.KeyId import com.flowcrypt.email.security.model.PgpKeyRingDetails import com.flowcrypt.email.util.TestUtil +import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Assert.assertThrows +import org.junit.Assert.assertTrue import org.junit.Test import org.pgpainless.PGPainless +import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.KeyFlag import org.pgpainless.exception.KeyIntegrityException import org.pgpainless.key.OpenPgpV4Fingerprint +import org.pgpainless.policy.Policy.HashAlgorithmPolicy import org.pgpainless.util.Passphrase import java.nio.charset.Charset import java.nio.charset.StandardCharsets @@ -159,39 +164,33 @@ class PgpKeyTest { @Test fun testRejectingSHA1KeysForDefaultPGPainlessPolicy() { - /* - WIP - val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") - assertThrows(NoSuchElementException::class.java) { - //PGPainless.readKeyRing().keyRingCollection(keyWithSHA1Algo, false) + val policy = PGPainless.getPolicy() + val certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy = + policy.certificationSignatureHashAlgorithmPolicy + assertFalse(certificationSignatureHashAlgorithmPolicy.isAcceptable(HashAlgorithm.SHA1)) + assertThrows(PGPException::class.java) { PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList - }*/ + } } @Test fun testAcceptingSHA1KeysForModifiedPGPainlessPolicy() { - /* - WIP - - val originalSignatureHashAlgorithmPolicy = PGPainless.getPolicy().signatureHashAlgorithmPolicy + val policy = PGPainless.getPolicy() + val originalSignatureHashAlgorithmPolicy = policy.certificationSignatureHashAlgorithmPolicy try { + assertFalse(policy.certificationSignatureHashAlgorithmPolicy.isAcceptable(HashAlgorithm.SHA1)) val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") - PGPainless.getPolicy().signatureHashAlgorithmPolicy = HashAlgorithmPolicy( - HashAlgorithm.SHA512, listOf( - HashAlgorithm.SHA512, - HashAlgorithm.SHA384, - HashAlgorithm.SHA256, - HashAlgorithm.SHA224, - HashAlgorithm.SHA1 - ) - ) + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022RevocationSignatureHashAlgorithmPolicy() + assertTrue(policy.certificationSignatureHashAlgorithmPolicy.isAcceptable(HashAlgorithm.SHA1)) val parseKeyResult = PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList assertEquals(1, parseKeyResult.size) assertEquals("5DE92AB364B3100D89FBF460241512660BDDC426", parseKeyResult.first().fingerprint) } finally { - PGPainless.getPolicy().signatureHashAlgorithmPolicy = originalSignatureHashAlgorithmPolicy - }*/ + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + originalSignatureHashAlgorithmPolicy + } } fun replaceVersionInKey(key: String?): String { From 52c7c0d3f1a8485bfacabdebeaaf0a83d8ffd0a6 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 23 Dec 2024 14:40:01 +0200 Subject: [PATCH 8/9] wip --- .../email/security/pgp/PgpKeyTest.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) 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 6ab45b3a75..c27c825da6 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 @@ -163,14 +163,20 @@ class PgpKeyTest { } @Test - fun testRejectingSHA1KeysForDefaultPGPainlessPolicy() { - val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") + fun testRejectingSHA1KeysForModifiedPGPainlessPolicy() { val policy = PGPainless.getPolicy() - val certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy = - policy.certificationSignatureHashAlgorithmPolicy - assertFalse(certificationSignatureHashAlgorithmPolicy.isAcceptable(HashAlgorithm.SHA1)) - assertThrows(PGPException::class.java) { - PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList + val originalSignatureHashAlgorithmPolicy = policy.certificationSignatureHashAlgorithmPolicy + try { + val keyWithSHA1Algo = loadResourceAsString("keys/sha1@flowcrypt.test_pub.asc") + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + HashAlgorithmPolicy.static2022SignatureHashAlgorithmPolicy() + assertFalse(policy.certificationSignatureHashAlgorithmPolicy.isAcceptable(HashAlgorithm.SHA1)) + assertThrows(PGPException::class.java) { + PgpKey.parseKeys(source = keyWithSHA1Algo).pgpKeyDetailsList + } + } finally { + PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy = + originalSignatureHashAlgorithmPolicy } } From f1ab3b69ec69fe1a2c80da607158282b330a7de7 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 23 Dec 2024 14:50:17 +0200 Subject: [PATCH 9/9] wip --- .../ParseAndSavePubKeysFragmentInIsolationTest.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt index ad49d1ce9b..9e643b2f32 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/fragment/isolation/incontainer/ParseAndSavePubKeysFragmentInIsolationTest.kt @@ -36,8 +36,7 @@ import com.flowcrypt.email.ui.activity.fragment.ParseAndSavePubKeysFragmentArgs import com.flowcrypt.email.util.PrivateKeysManager import com.flowcrypt.email.util.TestGeneralUtil import com.flowcrypt.email.viewaction.ClickOnViewInRecyclerViewItem -import org.hamcrest.Matchers.not -import org.junit.Ignore +import org.hamcrest.Matchers.allOf import org.junit.Rule import org.junit.Test import org.junit.rules.RuleChain @@ -49,7 +48,6 @@ import org.junit.runner.RunWith */ @MediumTest @RunWith(AndroidJUnit4::class) -@Ignore("Temporary disabled") class ParseAndSavePubKeysFragmentInIsolationTest : BaseTest() { private val existingPgpKeyDetails = @@ -87,14 +85,17 @@ class ParseAndSavePubKeysFragmentInIsolationTest : BaseTest() { ) onView(withId(R.id.rVPubKeys)) - .check(matches(withRecyclerViewItemCount(5))) + .check(matches(withRecyclerViewItemCount(6))) onView(withId(R.id.rVPubKeys)) .check( matches( - not( - hasItem( - withChild( + hasItem( + withChild( + allOf( + hasSibling( + withText(getResString(R.string.cannot_be_used_for_encryption)) + ), hasSibling( withText( getResString(