aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/test/java
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-03 13:57:05 +0100
committerDanilo M. <danix@danix.xyz>2026-11-03 13:57:05 +0100
commitfcbd5999f28f287507844b55f2bee82e714620c8 (patch)
treeaf26ef041aeaca0a437c52c324b6291d69e0f5a9 /app/src/test/java
parent3d8373dfff5101e58281b3b8f2e3b0ae2212678d (diff)
downloadHardenedPass-fcbd5999f28f287507844b55f2bee82e714620c8.tar.gz
HardenedPass-fcbd5999f28f287507844b55f2bee82e714620c8.zip
fix(app): harden the setup key imports
- PGP key import reads at most 1 MiB (bounded read, buffer zeroed) and refuses larger files with a new message. - SshKeyViewModel catches any Exception from import and generation (CancellationException rethrown) instead of a short list, so an unexpected provider or sshj error no longer crashes the app. - Pending PGP key bytes are zeroed in a finally block, also on cancellation during addKey after a replace, and an earlier pending pick is zeroed before a new one takes its place. - PGPKeyManager never replaces a stored secret key with a public-only key of the same ID, with or without replace (KeyDowngradeException); the setup ViewModel shows a localized message for it. Unit test added. - storeRecipients strips '#' comments and a trailing '!' as pass reads .gpg-id; tests added. - GitServerViewModel.clearStore returns the failure when the store folder cannot be emptied, so the clone does not start; the plan's Task 3 call site reports it. - readGpgId opens the file with NOFOLLOW_LINKS and reads at most 64 KiB + 1 bytes, refusing more. - SshKey.import writes the new private key to a temp file and moves it over atomically before dropping the old key's Keystore entry, public key and passphrase, so an I/O error keeps the old key. - KeyUtils.isSecretKey notes (ponytail) that GnuPG stub and smartcard keyrings count as secret. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/src/test/java')
-rw-r--r--app/src/test/java/app/passwordstore/ui/setup/SetupModelTest.kt19
1 files changed, 19 insertions, 0 deletions
diff --git a/app/src/test/java/app/passwordstore/ui/setup/SetupModelTest.kt b/app/src/test/java/app/passwordstore/ui/setup/SetupModelTest.kt
index 8d8243eb..53ea80cf 100644
--- a/app/src/test/java/app/passwordstore/ui/setup/SetupModelTest.kt
+++ b/app/src/test/java/app/passwordstore/ui/setup/SetupModelTest.kt
@@ -89,6 +89,25 @@ class SetupModelTest {
}
@Test
+ fun storeRecipientsDropCommentsAndExactSubkeyMarks() {
+ val ids =
+ storeRecipients(
+ "# store key\nF8993A789CDFB014! # laptop\n79E8208280490C77!\nalice@example.org#work\n # \n"
+ )
+ assertEquals(
+ listOf("f8993a789cdfb014", "79e8208280490c77", "alice@example.org"),
+ ids.map(PGPIdentifier::toString),
+ )
+ }
+
+ @Test
+ fun readAtMostRefusesMoreThanTheLimit() {
+ assertEquals("abc", readAtMost("abc".byteInputStream(), 3)?.decodeToString())
+ assertEquals("", readAtMost("".byteInputStream(), 3)?.decodeToString())
+ assertNull(readAtMost("abcd".byteInputStream(), 3))
+ }
+
+ @Test
fun gpgIdTextIsUppercaseKeyIdsOnePerLine() {
val ids =
listOf("f8993a789cdfb014", "0x79E8208280490C77").map {