[pve-devel] [PATCH proxmox-offline-mirror 1/2] improve GPG error messages

Fabian Grünbichler f.gruenbichler at proxmox.com
Tue Apr 4 09:48:20 CEST 2023


e.g., when encoutering a key that is self-signed with SHA-1 (which is not that
uncommon for non-distro repositories that have an old key), instead of the
following:

----8<----
Fetching Release/Release.gpg files
-> GET 'https://download.ceph.com/debian-quincy//dists/bullseye/Release.gpg'..
-> GET 'https://download.ceph.com/debian-quincy//dists/bullseye/Release'..
Verifying 'Release(.gpg)' signature using provided repository key..
	Subkey of 08B73419AC32B4E966C1A330E84AC2C0460F3994 not bound: No binding signature at time 2022-10-17T22:41:10Z
Error: encountered 1 error(s)
---->8----

which only gives us a rought idea that something is wrong with a key signature,
we now get the following:

----8<----
Fetching Release/Release.gpg files
-> GET 'https://download.ceph.com/debian-quincy//dists/bullseye/Release.gpg'..
-> GET 'https://download.ceph.com/debian-quincy//dists/bullseye/Release'..
Verifying 'Release(.gpg)' signature using provided repository key..

Subkey of 08B73419AC32B4E966C1A330E84AC2C0460F3994 not bound: No binding signature at time 2022-10-17T22:41:10Z
Caused by:
	0: Policy rejected non-revocation signature (PositiveCertification) requiring second pre-image resistance
	1: SHA1 is not considered secure since 2023-02-01T00:00:00Z

Error: No valid signature found.
---->8----

which shows us that the key signature was rejected because it's SHA-1, and the
(default and currently only) policy doesn't allow that (anymore).

the output is also improved in case the Release file is signed multiple times
and none of the signatures are accepted.

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 src/helpers/verifier.rs | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/helpers/verifier.rs b/src/helpers/verifier.rs
index 57bfd1b..131bccd 100644
--- a/src/helpers/verifier.rs
+++ b/src/helpers/verifier.rs
@@ -3,8 +3,8 @@ use anyhow::{bail, Error};
 use sequoia_openpgp::{
     parse::{
         stream::{
-            DetachedVerifierBuilder, MessageLayer, MessageStructure, VerificationHelper,
-            VerifierBuilder,
+            DetachedVerifierBuilder, MessageLayer, MessageStructure, VerificationError,
+            VerificationHelper, VerifierBuilder,
         },
         Parse,
     },
@@ -53,10 +53,35 @@ impl<'a> VerificationHelper for Helper<'a> {
         if good {
             Ok(()) // Good signature.
         } else {
-            for err in &errors {
-                eprintln!("\t{err}");
+            if errors.len() > 1 {
+                eprintln!("\nEncountered {} errors:", errors.len());
             }
-            Err(anyhow::anyhow!("encountered {} error(s)", errors.len()))
+
+            for (n, err) in errors.iter().enumerate() {
+                if errors.len() > 1 {
+                    eprintln!("\nSignature #{n}: {err}");
+                } else {
+                    eprintln!("\n{err}");
+                }
+                match err {
+                    VerificationError::MalformedSignature { error, .. }
+                    | VerificationError::UnboundKey { error, .. }
+                    | VerificationError::BadKey { error, .. }
+                    | VerificationError::BadSignature { error, .. } => {
+                        let mut cause = error.chain();
+                        if cause.len() > 1 {
+                            cause.next(); // already included in `err` above
+                            eprintln!("Caused by:");
+                            for (n, e) in cause.enumerate() {
+                                eprintln!("\t{n}: {e}");
+                            }
+                        }
+                    }
+                    VerificationError::MissingKey { .. } => {} // doesn't contain a cause
+                };
+            }
+            eprintln!();
+            Err(anyhow::anyhow!("No valid signature found."))
         }
     }
 }
-- 
2.30.2






More information about the pve-devel mailing list