android-password-store/Android-Password-Store

[BUG] DecryptActivity "error reading input data" (I edited my PGP key)

o-alquimista opened this issue · 10 comments

Describe the bug

I have been using an RSA-4096 gnupg signing/encryption key, but recently I revoked the encryption subkey and generated an ECC subkey to replace it. On the computer (gnupg on Linux) everything is working as expected, but on APS it is not.

08-17 13:46:12.053  3531  3531 E APS/BasePgpActivity: onError getErrorId: 0
08-17 13:46:12.054  3531  3531 E DecryptActivity$decryptAndVerify: onError getMessage: Encontrado um erro ao ler os dados de entrada!

However, passwords inserted/generated by APS can be decrypted successfully, but any pre-existing passwords result in an error when you try to open them.

See the full debug log:
android-password-store-logcat.txt

Steps to reproduce

Steps to reproduce the behavior:

  1. Generate an RSA-4096 key for signing and encryption, and use it to initialize a new password store.
  2. Edit the key, revoke its encryption subordinate key, and generate an ECC key for encryption - and set it as primary.
  3. Open APS, click on one of your existing passwords. At this point it should call OpenKeychain, but instead it opens a blank view and triggers a little toast notification at the bottom of the screen with the (translated) message OpenKeyChain error: error found when reading input data!

Expected behavior

It works on the desktop, so my best guess is that this is an edge case that APS did not cover.

Screenshots

No response

Device information

  • Device: Nokia 5.4 (arm64)
  • OS: Android 12
  • App version: 1.13.5

Additional context

No response

I just tested the latest snapshot 2.0, and although the feedback is different, the issue can be reproduced just as well.

Instead of failing and showing an error message, APS 2.0 simply says my PGP passphrase is incorrect. But if now you insert one new password into the store and attempt to decrypt it with the same passphrase, it will succeed.

OpenKeychain is in maintenance mode and effectively deprecated so I can't do anything about issues involving that, if you can capture a log of the bug with the 2.0 snapshot I can try to take a look over the weekend.

Here's the logcat for v2:
https://gist.github.com/o-alquimista/08133a5d35076a404428fef2b934db12

I exported it from Android Studio Preview, it seems to be in JSON. Is that ok?

That works, just needed minor jq wrangling. The failure is due to your new key using AEAD, which remains unsupported in v2.0's PGP implementation. Ideally APS should've caught this when you were adding the PGP key but clearly something went wrong. Your only solution for now is to disable AEAD from the key's settings, and if you can create a fresh disposable key with AEAD that APS doesn't warn you about I can try to analyze it and figure why it didn't trip our checks.

Logcat
org.pgpainless.decryption_verification.OpenPgpMessageInputStream: Symmetrically Encrypted Data Packet at depth 0 encountered
org.pgpainless.decryption_verification.OpenPgpMessageInputStream: Symmetrically Encrypted Data Packet is not integrity-protected.
org.pgpainless.exception.MessageNotIntegrityProtectedException: Message is encrypted using a 'Symmetrically Encrypted Data' (SED) packet, which enables certain types of attacks. A 'Symmetrically Encrypted Integrity Protected' (SEIP) packet should be used instead.
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.processEncryptedData(OpenPgpMessageInputStream.java:413)
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.consumePackets(OpenPgpMessageInputStream.java:305)
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.<init>(OpenPgpMessageInputStream.java:226)
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.create(OpenPgpMessageInputStream.java:153)
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.create(OpenPgpMessageInputStream.java:135)
	at org.pgpainless.decryption_verification.OpenPgpMessageInputStream.create(OpenPgpMessageInputStream.java:115)
	at org.pgpainless.decryption_verification.DecryptionBuilder$DecryptWithImpl.withOptions(DecryptionBuilder.java:39)
	at app.passwordstore.crypto.PGPainlessCryptoHandler.decrypt(PGPainlessCryptoHandler.kt:60)
	at app.passwordstore.data.crypto.CryptoRepository.decryptPgp(CryptoRepository.kt:62) 
	at app.passwordstore.data.crypto.CryptoRepository.access$decryptPgp(CryptoRepository.kt:26) 
	at app.passwordstore.data.crypto.CryptoRepository$decrypt$2.invokeSuspend(CryptoRepository.kt:46) 
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) 
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115) 
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684) 

I removed the AEAD feature through --edit-key and setpref, saved it, transferred it to my phone and imported it into password store, but it doesn't seem to have any effect, it's failing to decrypt in the exact same way.

showpref

[ultimate] (1). Douglas Silva <removed@mail.org>
     Cipher: AES256, AES192, AES, 3DES
-    AEAD: OCB
+    AEAD:
     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
-    Features: MDC, AEAD, Keyserver no-modify
+    Features: MDC, Keyserver no-modify

Same error:

Caused by: org.pgpainless.exception.MessageNotIntegrityProtectedException: Message is encrypted using a 'Symmetrically Encrypted Data' (SED) packet, which enables certain types of attacks. A 'Symmetrically Encrypted Integrity Protected' (SEIP) packet should be used instead.

Full debug log:
https://gist.github.com/o-alquimista/053d0bb9a801a512bfed33814e4b17af

I removed the AEAD feature through --edit-key and setpref, saved it, transferred it to my phone and imported it into password store, but it doesn't seem to have any effect, it's failing to decrypt in the exact same way.

The password entry needs to be encrypted again with the key after AEAD is removed. pass init <key-id> with the Linux CLI should be able to do that for your entire store easily.

I removed the AEAD feature through --edit-key and setpref, saved it, transferred it to my phone and imported it into password store, but it doesn't seem to have any effect, it's failing to decrypt in the exact same way.

The password entry needs to be encrypted again with the key after AEAD is removed. pass init <key-id> with the Linux CLI should be able to do that for your entire store easily.

I imagined that would be necessary, and I did it, but it still doesn't work.

I think I'll generate a new key and test it in a container later.

Output of pass init <encryption-subkey-fingerprint>:

Password store initialized for <keyid>

This command is supposed to take a long time, right? But it's not, it's not doing anything, it's just changing the .gpg-id and committing it. Is there another way to force it to re-encrypt all passwords?

Output of pass init <encryption-subkey-fingerprint>:

Password store initialized for <keyid>

This command is supposed to take a long time, right? But it's not, it's not doing anything, it's just changing the .gpg-id and committing it. Is there another way to force it to re-encrypt all passwords?

The CLI always calls the reencrypt_path function when pass init is invoked so it shouldn't have broken down like that 😕

Ok, I got it.

To get pass to re-encrypt the whole password store I generated a throwaway key and ran pass init with it. Once that is done, I run pass init with my existing key, and voilá!

Finally I have access to my passwords on the phone :) thanks.