Use gpg.conf's default-key when unlocker add pgp has no --keyid #167

Merged
clawbot merged 1 commits from fix/141-gpgconf-default-key into next 2026-10-15 00:31:54 +02:00
Collaborator

Fixes #141.

secret unlocker add pgp without --keyid failed for anyone with default-key in gpg.conf. The key ID was read from gpgconf --list-options gpg, which prints a string value with a leading " and percent-escapes it (gpgconf(1), the value field), and it went to gpg undecoded.

The parsing of that output moved out of getDefaultGPGKey into parseDefaultGPGKey, so a unit test can feed it a line. It drops the leading " and percent-decodes the rest with url.PathUnescape, the standard library's percent-decoder; url.QueryUnescape would have turned + into a space. With no default-key set, the first secret key is still used.

TestParseDefaultGPGKey feeds the parser a fingerprint and a user ID with an escaped comma. TestAddPGPUnlockerDefaultKey writes default-key into the test keyring's gpg.conf and adds a PGP unlocker with no --keyid. Both failed before the fix.

  • Judgement call: a default-key value that does not percent-decode is an error, so a key the user did not name is never picked in its place.
  • Beyond the plan: the end-to-end test, next to the unit test the issue asks for.
  • Rule suppressed: gosec G703 on that test's write of gpg.conf into the GNUPGHOME directory newTestGPGKey made.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/secret/issues/141. `secret unlocker add pgp` without `--keyid` failed for anyone with `default-key` in `gpg.conf`. The key ID was read from `gpgconf --list-options gpg`, which prints a string value with a leading `"` and percent-escapes it (gpgconf(1), the value field), and it went to gpg undecoded. The parsing of that output moved out of `getDefaultGPGKey` into `parseDefaultGPGKey`, so a unit test can feed it a line. It drops the leading `"` and percent-decodes the rest with `url.PathUnescape`, the standard library's percent-decoder; `url.QueryUnescape` would have turned `+` into a space. With no `default-key` set, the first secret key is still used. `TestParseDefaultGPGKey` feeds the parser a fingerprint and a user ID with an escaped comma. `TestAddPGPUnlockerDefaultKey` writes `default-key` into the test keyring's `gpg.conf` and adds a PGP unlocker with no `--keyid`. Both failed before the fix. - Judgement call: a `default-key` value that does not percent-decode is an error, so a key the user did not name is never picked in its place. - Beyond the plan: the end-to-end test, next to the unit test the issue asks for. - Rule suppressed: gosec G703 on that test's write of `gpg.conf` into the `GNUPGHOME` directory `newTestGPGKey` made. Model: opus-5-5
clawbot added the needs-review label 2026-10-14 21:26:25 +02:00
clawbot self-assigned this 2026-10-14 21:26:25 +02:00
clawbot force-pushed fix/141-gpgconf-default-key from 0e4f7fe72c to afd1335e48 2026-10-14 22:29:59 +02:00 Compare
clawbot force-pushed fix/141-gpgconf-default-key from afd1335e48 to 9ae4b74ee7 2026-10-14 22:40:55 +02:00 Compare
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot added 1 commit 2026-10-15 00:28:02 +02:00
getDefaultGPGKey took the default-key value from `gpgconf --list-options
gpg` as printed. gpgconf prints a string value with a leading `"` and
percent-escaped, so gpg rejected the key ID. The parsing moved into
parseDefaultGPGKey, which drops the `"` and percent-decodes the rest with
url.PathUnescape, which leaves `+` alone. A value that does not decode is
an error, not a fallback to the first secret key.

Rule suppressed: gosec G703 on the test's write of gpg.conf into the
GNUPGHOME directory newTestGPGKey made.

Model: opus-5-5
clawbot force-pushed fix/141-gpgconf-default-key from 9ae4b74ee7 to f40f3f4041 2026-10-15 00:28:02 +02:00 Compare
clawbot merged commit 6d95d96477 into next 2026-10-15 00:31:54 +02:00
clawbot deleted branch fix/141-gpgconf-default-key 2026-10-15 00:31:54 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#167