]> git.proxmox.com Git - proxmox-offline-mirror.git/blobdiff - src/helpers/verifier.rs
weak crypto: fix RSA config option
[proxmox-offline-mirror.git] / src / helpers / verifier.rs
index 4e556c3b4d77a08866b8d8ba1b7c40ebda5c634f..17d36eb650feb2eee6c8e37f78eea610fe9ffc13 100644 (file)
@@ -3,16 +3,19 @@ use anyhow::{bail, Error};
 use sequoia_openpgp::{
     parse::{
         stream::{
-            DetachedVerifierBuilder, MessageLayer, MessageStructure, VerificationHelper,
-            VerifierBuilder,
+            DetachedVerifierBuilder, MessageLayer, MessageStructure, VerificationError,
+            VerificationHelper, VerifierBuilder,
         },
         Parse,
     },
     policy::StandardPolicy,
+    types::HashAlgorithm,
     Cert, KeyHandle,
 };
 use std::io;
 
+use crate::config::WeakCryptoConfig;
+
 struct Helper<'a> {
     cert: &'a Cert,
 }
@@ -53,21 +56,63 @@ 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());
+            }
+
+            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
+                };
             }
-            Err(anyhow::anyhow!("encountered {} error(s)", errors.len()))
+            eprintln!();
+            Err(anyhow::anyhow!("No valid signature found."))
         }
     }
 }
+
+/// Verifies GPG-signed `msg` was signed by `key`, returning the verified data without signature.
 pub(crate) fn verify_signature<'msg>(
     msg: &'msg [u8],
     key: &[u8],
     detached_sig: Option<&[u8]>,
+    weak_crypto: &WeakCryptoConfig,
 ) -> Result<Vec<u8>, Error> {
     let cert = Cert::from_bytes(key)?;
 
-    let policy = StandardPolicy::new();
+    let mut policy = StandardPolicy::new();
+    if weak_crypto.allow_sha1 {
+        policy.accept_hash(HashAlgorithm::SHA1);
+    }
+    if let Some(min_dsa) = weak_crypto.min_dsa_key_size {
+        if min_dsa <= 1024 {
+            policy.accept_asymmetric_algo(sequoia_openpgp::policy::AsymmetricAlgorithm::DSA1024);
+        }
+    }
+    if let Some(min_rsa) = weak_crypto.min_rsa_key_size {
+        if min_rsa <= 1024 {
+            policy.accept_asymmetric_algo(sequoia_openpgp::policy::AsymmetricAlgorithm::RSA1024);
+        }
+    }
+
     let helper = Helper { cert: &cert };
 
     let verified = if let Some(sig) = detached_sig {