diff options
| author | Danilo M. <danix@danix.xyz> | 2026-11-02 10:09:49 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-11-02 10:09:49 +0100 |
| commit | 1c4d04c2089f719e8344f6c4f5cd8488c2320e9f (patch) | |
| tree | b4d3f432f7ebf558af01186601745e0402e135e4 /crypto/pgpainless/src/main | |
| parent | 9b8a56cb859f45845a620d7de344079e6a91d7c9 (diff) | |
| download | HardenedPass-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/main')
3 files changed, 5 insertions, 12 deletions
diff --git a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/KeyUtils.kt b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/KeyUtils.kt index 939fed43..f85fe92c 100644 --- a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/KeyUtils.kt +++ b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/KeyUtils.kt @@ -47,6 +47,6 @@ public object KeyUtils { val keyRing = tryParseKeyring(key) ?: return false PGPainless.inspectKeyRing(keyRing).isUsableForEncryption } - .get() != null + .get() == true } } diff --git a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt index ca411fa3..6f852af4 100644 --- a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt +++ b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt @@ -110,7 +110,9 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : val userIdMatch = keys .map { key -> key to tryParseKeyring(key) } - .firstOrNull { (_, keyRing) -> selector.firstMatch(keyRing) != null } + .firstOrNull { (_, keyRing) -> + keyRing?.publicKey?.userIDs?.asSequence()?.any(selector) == true + } userIdMatch?.first } } diff --git a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandler.kt b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandler.kt index 4a800129..a284ee0d 100644 --- a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandler.kt +++ b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPainlessCryptoHandler.kt @@ -8,7 +8,6 @@ package app.passwordstore.crypto import app.passwordstore.crypto.errors.CryptoHandlerException import app.passwordstore.crypto.errors.IncorrectPassphraseException import app.passwordstore.crypto.errors.NoKeysProvidedException -import app.passwordstore.crypto.errors.NonStandardAEAD import app.passwordstore.crypto.errors.UnknownError import com.github.michaelbull.result.Result import com.github.michaelbull.result.mapBoth @@ -26,7 +25,6 @@ import org.pgpainless.PGPainless import org.pgpainless.decryption_verification.ConsumerOptions import org.pgpainless.encryption_signing.EncryptionOptions import org.pgpainless.encryption_signing.ProducerOptions -import org.pgpainless.exception.MessageNotIntegrityProtectedException import org.pgpainless.exception.WrongPassphraseException import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.util.Passphrase @@ -63,7 +61,7 @@ public class PGPainlessCryptoHandler @Inject constructor() : .withOptions( ConsumerOptions() .addDecryptionKeys(keyringCollection, protector) - .addDecryptionPassphrase(Passphrase.fromPassword(passphrase)) + .addMessagePassphrase(Passphrase.fromPassword(passphrase)) ) decryptionStream.use { Streams.pipeAll(it, outputStream) } return@runCatching @@ -72,13 +70,6 @@ public class PGPainlessCryptoHandler @Inject constructor() : when (error) { is WrongPassphraseException -> IncorrectPassphraseException(error) is CryptoHandlerException -> error - is MessageNotIntegrityProtectedException -> { - if (error.message?.contains("Symmetrically Encrypted Data") == true) { - NonStandardAEAD(error) - } else { - UnknownError(error) - } - } else -> UnknownError(error) } } |
