Skip to content

Commit 5cc2d3b

Browse files
authored
Merge pull request #1720 from felixfontein/gpg
GnuPG: do not incorrectly trim fingerprint in presence of exclamation marks for specfic subkey selection
2 parents 8019097 + 9dbbc77 commit 5cc2d3b

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

README.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ the example files and pgp key provided with the repository::
188188

189189
This last step will decrypt ``example.yaml`` using the test private key.
190190

191+
Encrypting with GnuPG subkeys
192+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193+
194+
If you want to encrypt with specific GnuPG subkeys, it does not suffice to provide the
195+
exact key ID of the subkey to SOPS, since GnuPG might use *another* subkey instead
196+
to encrypt the file key with. To force GnuPG to use a specific subkey, you need to
197+
append ``!`` to the key's fingerprint.
198+
199+
.. code:: yaml
200+
201+
creation_rules:
202+
- pgp: >-
203+
85D77543B3D624B63CEA9E6DBC17301B491B3F21!,
204+
E60892BB9BD89A69F759A1A0A3D652173B763E8F!
205+
206+
Please note that this is only passed on correctly to GnuPG since SOPS 3.9.3.
191207

192208
Encrypting using age
193209
~~~~~~~~~~~~~~~~~~~~

pgp/keysource.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,13 @@ func gnuPGHome(customPath string) string {
634634
// This is mostly used for compatibility reasons, as older versions of GnuPG
635635
// do not always like long IDs.
636636
func shortenFingerprint(fingerprint string) string {
637-
if offset := len(fingerprint) - 16; offset > 0 {
637+
offset := len(fingerprint) - 16
638+
// If the fingerprint ends with '!', we must include '!' in the ID *and* the
639+
// 16 hex digits before it. See https://github.com/getsops/sops/issues/1365.
640+
if strings.HasSuffix(fingerprint, "!") {
641+
offset -= 1
642+
}
643+
if offset > 0 {
638644
fingerprint = fingerprint[offset:]
639645
}
640646
return fingerprint

pgp/keysource_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,10 +697,23 @@ func Test_gnuPGHome(t *testing.T) {
697697
}
698698

699699
func Test_shortenFingerprint(t *testing.T) {
700+
// Test with regular fingerprint
700701
shortId := shortenFingerprint(mockFingerprint)
701702
assert.Equal(t, "9732075EA221A7EA", shortId)
702703

703704
assert.Equal(t, shortId, shortenFingerprint(shortId))
705+
706+
// Test with forced subkey
707+
shortId = shortenFingerprint(mockFingerprint + "!")
708+
assert.Equal(t, "9732075EA221A7EA!", shortId)
709+
710+
assert.Equal(t, shortId, shortenFingerprint(shortId))
711+
712+
// Make sure that too short IDs are kept
713+
for _, tooShort := range []string{"012345679abcdef", "012345679abcdef!", "123", "123!"} {
714+
shortId = shortenFingerprint(tooShort)
715+
assert.Equal(t, tooShort, shortId)
716+
}
704717
}
705718

706719
// TODO(hidde): previous tests kept around for now.

0 commit comments

Comments
 (0)