aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/pgpainless/src/test
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-02 10:09:49 +0100
committerDanilo M. <danix@danix.xyz>2026-11-02 10:09:49 +0100
commit1c4d04c2089f719e8344f6c4f5cd8488c2320e9f (patch)
treeb4d3f432f7ebf558af01186601745e0402e135e4 /crypto/pgpainless/src/test
parent9b8a56cb859f45845a620d7de344079e6a91d7c9 (diff)
downloadHardenedPass-1c4d04c2089f719e8344f6c4f5cd8488c2320e9f.tar.gz
HardenedPass-1c4d04c2089f719e8344f6c4f5cd8488c2320e9f.zip
build(deps): update Bouncy Castle to 1.86 and PGPainless to 1.7.8
Bouncy Castle 1.78.1 is affected by GHSA-574f-3g2m-x479, GHSA-9pwp-9qqc-pr26, GHSA-c3fc-8qff-9hwx and GHSA-qp49-qgx5-5m26, all fixed by 1.85. PGPainless 1.7.8 is the newest 1.x release. A root resolution rule keeps every Bouncy Castle module on the catalog version; before, bcpg 1.77 shipped next to bcprov 1.78.1. The new stack decrypts the OCB (LibrePGP) packets GnuPG 2.3+ emits by default, which the old one rejected as "non-standard AEAD". Drop the NonStandardAEAD error, its bottom sheet and strings, and replace the mislabelled aead_* fixtures (SHA-1 self-signed keys plus a message encrypted to an unrelated key) with a real GnuPG 2.5 key and OCB message that the tests now decrypt. The new fixture is a throwaway test key, so it is allowlisted in .gitleaksignore by fingerprint. Fix KeyUtils.isKeyUsable, which compared a Boolean to null and so accepted every key that parsed, including keys with no encryption subkey. A signing-only key fixture now covers the rejection path. Also: migrate the removed SelectUserId.firstMatch and deprecated addDecryptionPassphrase APIs, keep one copy of the Bouncy Castle META-INF/LICENSE.md in the APK, and move the existing InvalidPackage lint baseline entries to the bcpkix 1.86 jar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'crypto/pgpainless/src/test')
-rw-r--r--crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/KeyUtilsTest.kt2
-rw-r--r--crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt2
-rw-r--r--crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandlerTest.kt11
-rw-r--r--crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/TestUtils.kt15
-rw-r--r--crypto/pgpainless/src/test/resources/aead_encrypted_filebin354 -> 0 bytes
-rw-r--r--crypto/pgpainless/src/test/resources/aead_pub51
-rw-r--r--crypto/pgpainless/src/test/resources/aead_sec107
-rw-r--r--crypto/pgpainless/src/test/resources/gnupg_ocb_encrypted_file2
-rw-r--r--crypto/pgpainless/src/test/resources/gnupg_ocb_sec18
-rw-r--r--crypto/pgpainless/src/test/resources/sign_only_pub10
10 files changed, 46 insertions, 172 deletions
diff --git a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/KeyUtilsTest.kt b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/KeyUtilsTest.kt
index 4aa83f5f..e6e3d7d1 100644
--- a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/KeyUtilsTest.kt
+++ b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/KeyUtilsTest.kt
@@ -31,7 +31,7 @@ class KeyUtilsTest {
@Test
fun isKeyUsable() {
- val params = AllKeys.entries.map { it to (it != AllKeys.AEAD_PUB && it != AllKeys.AEAD_SEC) }
+ val params = AllKeys.entries.map { it to (it != AllKeys.SIGN_ONLY_PUB) }
params.forEach { (allKeys, isUsable) ->
val key = PGPKey(allKeys.keyMaterial)
assertEquals(isUsable, isKeyUsable(key), "${allKeys.name} failed expectation:")
diff --git a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt
index 7603cfe2..0525c28a 100644
--- a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt
+++ b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt
@@ -76,7 +76,7 @@ class PGPKeyManagerTest {
@Test
fun addKeyWithUnusableKey() =
runTest(dispatcher) {
- val error = keyManager.addKey(PGPKey(TestUtils.getAEADSecretKey())).unwrapError()
+ val error = keyManager.addKey(PGPKey(TestUtils.getSignOnlyPublicKey())).unwrapError()
assertEquals(UnusableKeyException, error)
}
diff --git a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandlerTest.kt b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandlerTest.kt
index 42677337..2bfffd61 100644
--- a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandlerTest.kt
+++ b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandlerTest.kt
@@ -9,7 +9,6 @@ package app.passwordstore.crypto
import app.passwordstore.crypto.CryptoConstants.KEY_PASSPHRASE
import app.passwordstore.crypto.CryptoConstants.PLAIN_TEXT
import app.passwordstore.crypto.errors.IncorrectPassphraseException
-import app.passwordstore.crypto.errors.NonStandardAEAD
import com.github.michaelbull.result.getError
import com.google.testing.junit.testparameterinjector.TestParameter
import com.google.testing.junit.testparameterinjector.TestParameterInjector
@@ -139,10 +138,10 @@ class PGPainlessCryptoHandlerTest {
}
@Test
- fun aeadEncryptedMaterialIsSurfacedProperly() {
- val secKey = PGPKey(TestUtils.getAEADSecretKey())
+ fun decryptsGnuPGOcbEncryptedMaterial() {
+ val secKey = PGPKey(TestUtils.getGnuPGOcbSecretKey())
val plaintextStream = ByteArrayOutputStream()
- val ciphertextStream = TestUtils.getAEADEncryptedFile().inputStream()
+ val ciphertextStream = TestUtils.getGnuPGOcbEncryptedFile().inputStream()
val res =
cryptoHandler.decrypt(
listOf(secKey),
@@ -151,8 +150,8 @@ class PGPainlessCryptoHandlerTest {
plaintextStream,
PGPDecryptOptions.Builder().build(),
)
- assertTrue(res.isErr)
- assertIs<NonStandardAEAD>(res.error, message = "${res.error.cause}")
+ assertTrue(res.isOk, "${res.component2()?.cause}")
+ assertEquals("hunter2", plaintextStream.toString(Charsets.UTF_8).trim())
}
@Test
diff --git a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/TestUtils.kt b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/TestUtils.kt
index 7170b558..001fdafd 100644
--- a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/TestUtils.kt
+++ b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/TestUtils.kt
@@ -17,19 +17,22 @@ object TestUtils {
fun getArmoredPublicKeyWithMultipleIdentities() =
this::class.java.classLoader.getResource("public_key_multiple_identities").readBytes()
- fun getAEADPublicKey() = this::class.java.classLoader.getResource("aead_pub").readBytes()
+ /** A secret key generated by GnuPG 2.5 with default settings, passphrase "Password". */
+ fun getGnuPGOcbSecretKey() = this::class.java.classLoader.getResource("gnupg_ocb_sec").readBytes()
- fun getAEADSecretKey() = this::class.java.classLoader.getResource("aead_sec").readBytes()
+ /** "hunter2" encrypted to [getGnuPGOcbSecretKey] by GnuPG using its OCB (LibrePGP) packet. */
+ fun getGnuPGOcbEncryptedFile() =
+ this::class.java.classLoader.getResource("gnupg_ocb_encrypted_file").readBytes()
- fun getAEADEncryptedFile() =
- this::class.java.classLoader.getResource("aead_encrypted_file").readBytes()
+ /** A public key with no encryption-capable subkey. */
+ fun getSignOnlyPublicKey() = this::class.java.classLoader.getResource("sign_only_pub").readBytes()
enum class AllKeys(val keyMaterial: ByteArray) {
ARMORED_SEC(getArmoredSecretKey()),
ARMORED_PUB(getArmoredPublicKey()),
MULTIPLE_IDENTITIES_SEC(getArmoredSecretKeyWithMultipleIdentities()),
MULTIPLE_IDENTITIES_PUB(getArmoredPublicKeyWithMultipleIdentities()),
- AEAD_SEC(getAEADSecretKey()),
- AEAD_PUB(getAEADPublicKey()),
+ GNUPG_OCB_SEC(getGnuPGOcbSecretKey()),
+ SIGN_ONLY_PUB(getSignOnlyPublicKey()),
}
}
diff --git a/crypto/pgpainless/src/test/resources/aead_encrypted_file b/crypto/pgpainless/src/test/resources/aead_encrypted_file
deleted file mode 100644
index d8547bdb..00000000
--- a/crypto/pgpainless/src/test/resources/aead_encrypted_file
+++ /dev/null
Binary files differ
diff --git a/crypto/pgpainless/src/test/resources/aead_pub b/crypto/pgpainless/src/test/resources/aead_pub
deleted file mode 100644
index f6ae1e82..00000000
--- a/crypto/pgpainless/src/test/resources/aead_pub
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-=lwhh
------END PGP PUBLIC KEY BLOCK-----
diff --git a/crypto/pgpainless/src/test/resources/aead_sec b/crypto/pgpainless/src/test/resources/aead_sec
deleted file mode 100644
index 8e13ac0e..00000000
--- a/crypto/pgpainless/src/test/resources/aead_sec
+++ /dev/null
@@ -1,107 +0,0 @@
------BEGIN PGP PRIVATE KEY BLOCK-----
-
-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
-iHcmZE4pREmRPz9CinzsQXCm5yqJkucSfXtqn4c=
-=m5E4
------END PGP PRIVATE KEY BLOCK-----
diff --git a/crypto/pgpainless/src/test/resources/gnupg_ocb_encrypted_file b/crypto/pgpainless/src/test/resources/gnupg_ocb_encrypted_file
new file mode 100644
index 00000000..f4d5c043
--- /dev/null
+++ b/crypto/pgpainless/src/test/resources/gnupg_ocb_encrypted_file
@@ -0,0 +1,2 @@
+„^)•%XɘÝ@ëg¹(VÑ„ìÓî º¡söòo�´—h:]Bì-,�.´%0h¢_?8»FuƒÕà R¸a32wK^šÙß2
+Hù”EâhSÅ1KJØá KŒqÔM ¢åÙ!¾ �–¯H|¢:Ž£Dš(úo§e80rãâ7ÎõãŽÒcDüæ'�97­§?@( Wìó�~eÉA:®[2Ì-¨§(þ\¡ \ No newline at end of file
diff --git a/crypto/pgpainless/src/test/resources/gnupg_ocb_sec b/crypto/pgpainless/src/test/resources/gnupg_ocb_sec
new file mode 100644
index 00000000..e91d7df0
--- /dev/null
+++ b/crypto/pgpainless/src/test/resources/gnupg_ocb_sec
@@ -0,0 +1,18 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lIYEauhQJRYJKwYBBAHaRw8BAQdAbpP/vX+rAng4A46YUZ1NMURKSkvNS0UPOZPy
+1D7avk3+BwMC9e5bxxzpzc//2zvQ0TdwE4lqi5Lbjm4LAKe3NL4qOCcuZUWk5voy
+4df6LLKRPFDVTBq/7JbIBvaOOBr8M/wjOgo6/vqnGj4XInt5975buLQfSm9obiBE
+b2UgPGpvaG4uZG9lQGV4YW1wbGUuY29tPoivBBMWCgBXFiEEetBjyKz3tBaENPNJ
+WngbP50zuXoFAmroUCUbFIAAAAAABAAObWFudTIsMi41KzEuMTIsMiwyAhsDBQsJ
+CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEFp4Gz+dM7l6DRoBAMJc0lnEHFtb
+x9bX2q3ZjuWZMRFFvCEtBXKzi/8VobvsAQD4m5c2Wl0+QCHl3Fa/JUcnbB4g8xvJ
+6qXk86fu8fTND5yLBGroUCUSCisGAQQBl1UBBQEBB0DLn1Rbk8SIqgwix4FwHkSe
+QAPixLvJYLWkS7ZddD9hUwMBCAf+BwMC+dAO/JFwC+//mzU4/YsJbF+N3cSUMJ3U
+fclSmRfaOcWbFBjSzWG2CSVQJqJkgkamYBKIJY8Iw7hF4Fj67vBi5/tJYCzk2Sn7
+M1c45TTwpoiUBBgWCgA8FiEEetBjyKz3tBaENPNJWngbP50zuXoFAmroUCUbFIAA
+AAAABAAObWFudTIsMi41KzEuMTIsMiwyAhsMAAoJEFp4Gz+dM7l6UNcA/R4HA0XJ
+1EQB2Vv2IR6zLe+vOHKK8j9LCBWmXv8eMhFrAQC11yEWH7SuXKedxRkTsVS4V6dO
+/stzkZYyq7lRWmNFCg==
+=eelL
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/crypto/pgpainless/src/test/resources/sign_only_pub b/crypto/pgpainless/src/test/resources/sign_only_pub
new file mode 100644
index 00000000..bb9715af
--- /dev/null
+++ b/crypto/pgpainless/src/test/resources/sign_only_pub
@@ -0,0 +1,10 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEauhQoBYJKwYBBAHaRw8BAQdAnDvmcpRwRiGMDwuTMaz2bN2Giz966jSfLmYw
+V1nSC460IVNpZ24gT25seSA8c2lnbi5vbmx5QGV4YW1wbGUuY29tPoivBBMWCgBX
+FiEEt2karFi4tC6Y6DdBZBOuDsoW6SIFAmroUKAbFIAAAAAABAAObWFudTIsMi41
+KzEuMTIsMiwyAhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEGQTrg7K
+Fuki9jYBALsBVZDDFsQ69KielwC/S7VOMkrauc56Y8MX2rq1J7NSAP9lLzL25+16
+qiHjATR19RC8Ha3Dt5iTFeDiIN1WsgyGCQ==
+=uU24
+-----END PGP PUBLIC KEY BLOCK-----