[Pkg-rust-maintainers] Bug#1104288: rust-sequoia-gpg-agent: Importing keys into gpg-agent 2.4.x is broken
Justus Winter
justus at sequoia-pgp.org
Mon Apr 28 11:14:18 BST 2025
Source: rust-sequoia-gpg-agent
Version: 0.6.0-1
Severity: important
Dear Maintainer,
importing ecc secret keys into gpg-agent 2.4.x is broken.
When importing keys, a checksum is computed over the key material.
This checksum computation (inadvertently) changed during development
shortly before gpg-agent 2.4.0 was released. sequoia-gpg-agent
contains a heuristic to deal with gpg-agent 2.4.x's new behavior, but
that heuristic is ineffective when doing a non-interactive import.
When doing a non-interactive import, the checksum is not checked at
import time, but only later when the key is used. In the following, a
patched gpg-agent is used to highlight the different behavior.
First, we do an interactive import. Observe how each (sub)key is
imported twice, with the first import failing due to a checksum
mismatch (note how the actual_csum and desired_csum differ by 8):
teythoon at europ ~ % gpg-sq --import /tmp/key.pgp
gpg: key D4BD12F1284374E0: "someone at example.org" not changed
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70ed1f25cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041d50fc8e4e2cf05cd93269317e0b799b8deb50a56e2c8f3ec599aee990db31 \
gpg-agent[3128335]: DBG: e45b4a84a2eacb4883f3a1f01e2df3947d1f16a249563980567163f403eaed87 \
gpg-agent[3128335]: DBG: bc
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00a552dba7653e8c63ff5685ae130b9c17627874ac6bb6d2bb6904c01e780bd2 \
gpg-agent[3128335]: DBG: 97
gpg-agent[3128335]: nbits original: 264
gpg-agent[3128335]: nbytes: 33
gpg-agent[3128335]: nbits rounded up: 264
gpg-agent[3128335]: *buffer: 00
gpg-agent[3128335]: nbits corrected: 264
gpg-agent[3128335]: actual_csum: 3916
gpg-agent[3128335]: desired_csum: 3908
gpg-agent[3128335]: command 'IMPORT_KEY' failed: Checksum error
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70ed1f25cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041d50fc8e4e2cf05cd93269317e0b799b8deb50a56e2c8f3ec599aee990db31 \
gpg-agent[3128335]: DBG: e45b4a84a2eacb4883f3a1f01e2df3947d1f16a249563980567163f403eaed87 \
gpg-agent[3128335]: DBG: bc
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00a552dba7653e8c63ff5685ae130b9c17627874ac6bb6d2bb6904c01e780bd2 \
gpg-agent[3128335]: DBG: 97
gpg-agent[3128335]: nbits original: 264
gpg-agent[3128335]: nbytes: 33
gpg-agent[3128335]: nbits rounded up: 264
gpg-agent[3128335]: *buffer: 00
gpg-agent[3128335]: nbits corrected: 264
gpg-agent[3128335]: actual_csum: 3916
gpg-agent[3128335]: desired_csum: 3916
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70ed1f25cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041bce6ab3fcd178b64be460682d33e0bc11cf9723e82ee8aa7efe205264288d \
gpg-agent[3128335]: DBG: d4ac69c8f1fec07e8193fcdb6685ee6e74c17b1e997b39ce272940a6e87474ff \
gpg-agent[3128335]: DBG: 8e
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00f6fdb74b4c0bff40a38af95e1e562910efd669eed74e62967718f9cd150ea4 \
gpg-agent[3128335]: DBG: 10
gpg-agent[3128335]: nbits original: 264
gpg-agent[3128335]: nbytes: 33
gpg-agent[3128335]: nbits rounded up: 264
gpg-agent[3128335]: *buffer: 00
gpg-agent[3128335]: nbits corrected: 264
gpg-agent[3128335]: actual_csum: 4138
gpg-agent[3128335]: desired_csum: 4130
gpg-agent[3128335]: command 'IMPORT_KEY' failed: Checksum error
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70ed1f25cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041bce6ab3fcd178b64be460682d33e0bc11cf9723e82ee8aa7efe205264288d \
gpg-agent[3128335]: DBG: d4ac69c8f1fec07e8193fcdb6685ee6e74c17b1e997b39ce272940a6e87474ff \
gpg-agent[3128335]: DBG: 8e
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00f6fdb74b4c0bff40a38af95e1e562910efd669eed74e62967718f9cd150ea4 \
gpg-agent[3128335]: DBG: 10
gpg-agent[3128335]: nbits original: 264
gpg-agent[3128335]: nbytes: 33
gpg-agent[3128335]: nbits rounded up: 264
gpg-agent[3128335]: *buffer: 00
gpg-agent[3128335]: nbits corrected: 264
gpg-agent[3128335]: actual_csum: 4138
gpg-agent[3128335]: desired_csum: 4138
gpg: key D4BD12F1284374E0: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
teythoon at europ ~ % gpg-sq --armor --sign --local-user F5A31D60D474FC443F82B268B0F4EC4354E6D4D6 <<< hi
-----BEGIN PGP MESSAGE-----
xA0DAAoTsPTsQ1Tm1NYBywliAAAAAABoaQrCvQQAEwoAbwWCaA9SkwkQsPTsQ1Tm
1NZHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnYlv/Jy1T
XqfUEjs/77Vhmac4/lgFwt/ARNQCtOybP60WIQT1ox1g1HT8RD+Csmiw9OxDVObU
1gAAcqoBAJsL9U768p4vNGaSsYlZkErcoIU/c2xbhlbI9ShM0Cf6AQCC626Kl4ez
c17yzTSlPlNLuB5r56YyZyHsbpTJuNlnwQ==
=nw7v
-----END PGP MESSAGE-----
Now, we do a non-interactive import:
teythoon at europ ~ % rm $GNUPGHOME/private-keys-v1.d/*
zsh: sure you want to delete all the files in /tmp/tmp.aUYEK4L0US/private-keys-v1.d [yn]? y
teythoon at europ ~ % gpg-sq --import --batch /tmp/key.pgp
gpg: key D4BD12F1284374E0: "someone at example.org" not changed
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70dd9f24cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041d50fc8e4e2cf05cd93269317e0b799b8deb50a56e2c8f3ec599aee990db31 \
gpg-agent[3128335]: DBG: e45b4a84a2eacb4883f3a1f01e2df3947d1f16a249563980567163f403eaed87 \
gpg-agent[3128335]: DBG: bc
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00a552dba7653e8c63ff5685ae130b9c17627874ac6bb6d2bb6904c01e780bd2 \
gpg-agent[3128335]: DBG: 97
DUMPING!!!!gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt 70dd9f24cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041bce6ab3fcd178b64be460682d33e0bc11cf9723e82ee8aa7efe205264288d \
gpg-agent[3128335]: DBG: d4ac69c8f1fec07e8193fcdb6685ee6e74c17b1e997b39ce272940a6e87474ff \
gpg-agent[3128335]: DBG: 8e
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00f6fdb74b4c0bff40a38af95e1e562910efd669eed74e62967718f9cd150ea4 \
gpg-agent[3128335]: DBG: 10
gpg: key D4BD12F1284374E0: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
teythoon at europ ~ % gpg-sq --armor --sign --local-user F5A31D60D474FC443F82B268B0F4EC4354E6D4D6 <<< hi
-----BEGIN PGP MESSAGE-----
gpg-agent[3128335]: DBG: XXX is v4_or_later=1
gpg-agent[3128335]: DBG: XXX pubkey_algo=18
gpg-agent[3128335]: DBG: XXX is_protected=0
gpg-agent[3128335]: DBG: XXX protect_algo=0
gpg-agent[3128335]: DBG: XXX iv
gpg-agent[3128335]: DBG: XXX ivlen=0
gpg-agent[3128335]: DBG: XXX s2k_mode=0
gpg-agent[3128335]: DBG: XXX s2k_algo=0
gpg-agent[3128335]: DBG: XXX s2k_salt a0d89f24cd7f0000
gpg-agent[3128335]: DBG: XXX s2k_count=0
gpg-agent[3128335]: DBG: XXX curve='NIST P-256'
gpg-agent[3128335]: DBG: skey(_): [520 bit]
gpg-agent[3128335]: DBG: 041bce6ab3fcd178b64be460682d33e0bc11cf9723e82ee8aa7efe205264288d \
gpg-agent[3128335]: DBG: d4ac69c8f1fec07e8193fcdb6685ee6e74c17b1e997b39ce272940a6e87474ff \
gpg-agent[3128335]: DBG: 8e
gpg-agent[3128335]: DBG: skey(_): [264 bit]
gpg-agent[3128335]: DBG: 00f6fdb74b4c0bff40a38af95e1e562910efd669eed74e62967718f9cd150ea4 \
gpg-agent[3128335]: DBG: 10
gpg-agent[3128335]: nbits original: 264
gpg-agent[3128335]: nbytes: 33
gpg-agent[3128335]: nbits rounded up: 264
gpg-agent[3128335]: *buffer: 00
gpg-agent[3128335]: nbits corrected: 264
gpg-agent[3128335]: actual_csum: 4138
gpg-agent[3128335]: desired_csum: 4130
gpg-agent[3128335]: failed to convert unprotected openpgp key: Checksum error
gpg-agent[3128335]: failed to read the secret key
gpg-agent[3128335]: command 'PKSIGN' failed: Checksum error
xA0DAAoTsPTsQ1Tm1NYBywliAAAAAABogpg: Operation failed: Checksum error <GPG Agent>
Note how the import succeeds, but the checksum mismatch is detected
when the key is used.
-- System Information:
Debian Release: trixie/sid
APT prefers testing
APT policy: (900, 'testing'), (700, 'unstable'), (500, 'testing-debug'), (500, 'stable-debug'), (500, 'proposed-updates-debug'), (400, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 6.12.19-amd64 (SMP w/20 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
More information about the Pkg-rust-maintainers
mailing list