all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox-offline-mirror 2/2] fix #4632: allow escape hatches for legacy repositories
Date: Tue,  4 Apr 2023 09:48:21 +0200	[thread overview]
Message-ID: <20230404074821.3765099-3-f.gruenbichler@proxmox.com> (raw)
In-Reply-To: <20230404074821.3765099-1-f.gruenbichler@proxmox.com>

there are still repositories out there that are using things like DSA/RSA-1024
and SHA1, so let's allow POM users to opt into accepting those insecure
cryptographic parameters, but keep the default settings secure.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
 src/bin/proxmox-offline-mirror.rs             |  2 +
 src/bin/proxmox_offline_mirror_cmds/config.rs |  4 ++
 src/config.rs                                 | 42 ++++++++++++++++++-
 src/helpers/verifier.rs                       | 20 ++++++++-
 src/mirror.rs                                 | 17 +++++++-
 5 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/src/bin/proxmox-offline-mirror.rs b/src/bin/proxmox-offline-mirror.rs
index 3af33bb..bec366a 100644
--- a/src/bin/proxmox-offline-mirror.rs
+++ b/src/bin/proxmox-offline-mirror.rs
@@ -423,6 +423,7 @@ fn action_add_mirror(config: &SectionConfigData) -> Result<Vec<MirrorConfig>, Er
                 use_subscription: None,
                 ignore_errors: false,
                 skip,
+                weak_crypto: None,
             });
         }
     }
@@ -438,6 +439,7 @@ fn action_add_mirror(config: &SectionConfigData) -> Result<Vec<MirrorConfig>, Er
         use_subscription,
         ignore_errors: false,
         skip,
+        weak_crypto: None,
     };
 
     configs.push(main_config);
diff --git a/src/bin/proxmox_offline_mirror_cmds/config.rs b/src/bin/proxmox_offline_mirror_cmds/config.rs
index 3ebf4ad..696da11 100644
--- a/src/bin/proxmox_offline_mirror_cmds/config.rs
+++ b/src/bin/proxmox_offline_mirror_cmds/config.rs
@@ -274,6 +274,10 @@ pub fn update_mirror(
         data.skip.skip_sections = Some(skip_sections);
     }
 
+    if let Some(weak_crypto) = update.weak_crypto {
+        data.weak_crypto = Some(weak_crypto);
+    }
+
     config.set_data(&id, "mirror", &data)?;
     proxmox_offline_mirror::config::save_config(&config_file, &config)?;
 
diff --git a/src/config.rs b/src/config.rs
index 39b1193..0e19c77 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,7 +5,7 @@ use lazy_static::lazy_static;
 use proxmox_subscription::{sign::ServerBlob, SubscriptionInfo};
 use serde::{Deserialize, Serialize};
 
-use proxmox_schema::{api, ApiType, Schema, Updater};
+use proxmox_schema::{api, ApiStringFormat, ApiType, Schema, Updater};
 use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
 use proxmox_sys::fs::{replace_file, CreateOptions};
 
@@ -46,6 +46,38 @@ pub struct SkipConfig {
     pub skip_packages: Option<Vec<String>>,
 }
 
+#[api(
+    properties: {
+        "allow-sha1": {
+            type: bool,
+            default: false,
+            optional: true,
+        },
+        "min-dsa-key-size": {
+            type: u64,
+            optional: true,
+        },
+        "min-rsa-key-size": {
+            type: u64,
+            optional: true,
+        },
+    },
+)]
+#[derive(Default, Serialize, Deserialize, Updater, Clone, Debug)]
+#[serde(rename_all = "kebab-case")]
+/// Weak Cryptography Configuration
+pub struct WeakCryptoConfig {
+    /// Whether to allow SHA-1 based signatures
+    #[serde(default)]
+    pub allow_sha1: bool,
+    /// Whether to lower the key size cutoff for DSA-based signatures
+    #[serde(default)]
+    pub min_dsa_key_size: Option<u64>,
+    /// Whether to lower the key size cutoff for RSA-based signatures
+    #[serde(default)]
+    pub min_rsa_key_size: Option<u64>,
+}
+
 #[api(
     properties: {
         id: {
@@ -81,6 +113,11 @@ pub struct SkipConfig {
         "skip": {
             type: SkipConfig,
         },
+        "weak-crypto": {
+            type: String,
+            optional: true,
+            format: &ApiStringFormat::PropertyString(&WeakCryptoConfig::API_SCHEMA),
+        },
     }
 )]
 #[derive(Clone, Debug, Serialize, Deserialize, Updater)]
@@ -111,6 +148,9 @@ pub struct MirrorConfig {
     /// Skip package files using these criteria
     #[serde(default, flatten)]
     pub skip: SkipConfig,
+    /// Whether to allow using weak cryptography algorithms or parameters, deviating from the default policy.
+    #[serde(default)]
+    pub weak_crypto: Option<String>,
 }
 
 #[api(
diff --git a/src/helpers/verifier.rs b/src/helpers/verifier.rs
index 131bccd..e38ef40 100644
--- a/src/helpers/verifier.rs
+++ b/src/helpers/verifier.rs
@@ -9,10 +9,13 @@ use sequoia_openpgp::{
         Parse,
     },
     policy::StandardPolicy,
+    types::HashAlgorithm,
     Cert, KeyHandle,
 };
 use std::io;
 
+use crate::config::WeakCryptoConfig;
+
 struct Helper<'a> {
     cert: &'a Cert,
 }
@@ -91,10 +94,25 @@ 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_dsa_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 {
diff --git a/src/mirror.rs b/src/mirror.rs
index 0dc0751..3766f23 100644
--- a/src/mirror.rs
+++ b/src/mirror.rs
@@ -10,10 +10,11 @@ use flate2::bufread::GzDecoder;
 use globset::{Glob, GlobSet, GlobSetBuilder};
 use nix::libc;
 use proxmox_http::{client::sync::Client, HttpClient, HttpOptions, ProxyConfig};
+use proxmox_schema::{ApiType, Schema};
 use proxmox_sys::fs::file_get_contents;
 
 use crate::{
-    config::{MirrorConfig, SkipConfig, SubscriptionKey},
+    config::{MirrorConfig, SkipConfig, SubscriptionKey, WeakCryptoConfig},
     convert_repo_line,
     pool::Pool,
     types::{Diff, Snapshot, SNAPSHOT_REGEX},
@@ -50,6 +51,7 @@ struct ParsedMirrorConfig {
     pub client: Client,
     pub ignore_errors: bool,
     pub skip: SkipConfig,
+    pub weak_crypto: WeakCryptoConfig,
 }
 
 impl TryInto<ParsedMirrorConfig> for MirrorConfig {
@@ -72,6 +74,15 @@ impl TryInto<ParsedMirrorConfig> for MirrorConfig {
 
         let client = Client::new(options);
 
+        let weak_crypto = match self.weak_crypto {
+            Some(property_string) => {
+                let value = (WeakCryptoConfig::API_SCHEMA as Schema)
+                    .parse_property_string(&property_string)?;
+                serde_json::from_value(value)?
+            }
+            None => WeakCryptoConfig::default(),
+        };
+
         Ok(ParsedMirrorConfig {
             repository,
             architectures: self.architectures,
@@ -83,6 +94,7 @@ impl TryInto<ParsedMirrorConfig> for MirrorConfig {
             client,
             ignore_errors: self.ignore_errors,
             skip: self.skip,
+            weak_crypto,
         })
     }
 }
@@ -208,7 +220,8 @@ fn fetch_release(
 
     println!("Verifying '{name}' signature using provided repository key..");
     let content = fetched.data_ref();
-    let verified = helpers::verify_signature(content, &config.key, sig.as_deref())?;
+    let verified =
+        helpers::verify_signature(content, &config.key, sig.as_deref(), &config.weak_crypto)?;
     println!("Success");
 
     let sha512 = Some(openssl::sha::sha512(content));
-- 
2.30.2





  parent reply	other threads:[~2023-04-04  7:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-04  7:48 [pve-devel] [PATCH proxmox-offline-mirror 0/2] improve GPG verification Fabian Grünbichler
2023-04-04  7:48 ` [pve-devel] [PATCH proxmox-offline-mirror 1/2] improve GPG error messages Fabian Grünbichler
2023-04-04  7:48 ` Fabian Grünbichler [this message]
2023-04-06 11:23   ` [pve-devel] [PATCH proxmox-offline-mirror 2/2] fix #4632: allow escape hatches for legacy repositories Thomas Lamprecht
2023-04-06 11:57     ` Fabian Grünbichler
2023-04-06 11:22 ` [pve-devel] applied: [PATCH proxmox-offline-mirror 0/2] improve GPG verification Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230404074821.3765099-3-f.gruenbichler@proxmox.com \
    --to=f.gruenbichler@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal