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@europ ~ % gpg-sq --import /tmp/key.pgp gpg: key D4BD12F1284374E0: "some...@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@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@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@europ ~ % gpg-sq --import --batch /tmp/key.pgp gpg: key D4BD12F1284374E0: "some...@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@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