From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 2D91C9195D for ; Thu, 15 Feb 2024 16:20:19 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 43D521672A for ; Thu, 15 Feb 2024 16:20:18 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 15 Feb 2024 16:20:16 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id B1E5B48420 for ; Thu, 15 Feb 2024 16:20:15 +0100 (CET) From: Stefan Sterz To: pbs-devel@lists.proxmox.com Date: Thu, 15 Feb 2024 16:20:01 +0100 Message-Id: <20240215152001.269490-13-s.sterz@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240215152001.269490-1-s.sterz@proxmox.com> References: <20240215152001.269490-1-s.sterz@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.082 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH proxmox-backup 12/12] auth: us ec keys as auth keys X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Feb 2024 15:20:19 -0000 this commit moves new installations from our default rsa keys toward smaller and more efficient ec keys. this uses the `PrivateKey` and `PublicKey` structs from proxmox-auth-api to handle generating the keys. this means we can move aways from using openssl directly in the auth_helpers and instead rely on the implementation in `proxmox-auth-api`. thus, further unifying key handling in `proxmox-auth-api`. this should make it easier to switch keys in the future if necessary. Signed-off-by: Stefan Sterz --- note that this breaks the following scenario: - a user installs pbs from a version after this patch was packaged - proxmox-backup then creates a new ed25519 authkey - the user manually forces a downgrade proxmox-backup-api and proxmox-backup-proxy will now fail to start as they cannot read the, from their perspective, malformed authkey. src/auth.rs | 4 ++-- src/auth_helpers.rs | 53 ++++++++++++++------------------------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 3379577f..20d2e39f 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -262,9 +262,9 @@ pub(crate) fn authenticate_user<'a>( } static PRIVATE_KEYRING: Lazy = - Lazy::new(|| Keyring::with_private_key(crate::auth_helpers::private_auth_key().clone().into())); + Lazy::new(|| Keyring::with_private_key(crate::auth_helpers::private_auth_key().clone())); static PUBLIC_KEYRING: Lazy = - Lazy::new(|| Keyring::with_public_key(crate::auth_helpers::public_auth_key().clone().into())); + Lazy::new(|| Keyring::with_public_key(crate::auth_helpers::public_auth_key().clone())); static AUTH_CONTEXT: OnceCell = OnceCell::new(); pub fn setup_auth_context(use_private_key: bool) { diff --git a/src/auth_helpers.rs b/src/auth_helpers.rs index 375ce190..f518c2ee 100644 --- a/src/auth_helpers.rs +++ b/src/auth_helpers.rs @@ -3,12 +3,9 @@ use std::path::PathBuf; use std::sync::OnceLock; use anyhow::{format_err, Error}; -use lazy_static::lazy_static; -use openssl::pkey::{PKey, Private, Public}; -use openssl::rsa::Rsa; use pbs_config::BackupLockGuard; -use proxmox_auth_api::HMACKey; +use proxmox_auth_api::{HMACKey, PrivateKey, PublicKey}; use proxmox_sys::fs::{file_get_contents, replace_file, CreateOptions}; use pbs_buildcfg::configdir; @@ -87,26 +84,22 @@ pub fn generate_auth_key() -> Result<(), Error> { return Ok(()); } - let rsa = Rsa::generate(4096).unwrap(); - - let priv_pem = rsa.private_key_to_pem()?; + let key = proxmox_auth_api::PrivateKey::generate_ec()?; use nix::sys::stat::Mode; replace_file( &priv_path, - &priv_pem, + &key.private_key_to_pem()?, CreateOptions::new().perm(Mode::from_bits_truncate(0o0600)), true, )?; - let public_pem = rsa.public_key_to_pem()?; - let backup_user = pbs_config::backup_user()?; replace_file( &public_path, - &public_pem, + &key.public_key_to_pem()?, CreateOptions::new() .perm(Mode::from_bits_truncate(0o0640)) .owner(nix::unistd::ROOT) @@ -134,36 +127,22 @@ pub fn csrf_secret() -> &'static HMACKey { }) } -fn load_public_auth_key() -> Result, Error> { - let pem = file_get_contents(configdir!("/authkey.pub"))?; - let rsa = Rsa::public_key_from_pem(&pem)?; - let key = PKey::from_rsa(rsa)?; - - Ok(key) -} - -pub fn public_auth_key() -> &'static PKey { - lazy_static! { - static ref KEY: PKey = load_public_auth_key().unwrap(); - } - - &KEY -} - -fn load_private_auth_key() -> Result, Error> { - let pem = file_get_contents(configdir!("/authkey.key"))?; - let rsa = Rsa::private_key_from_pem(&pem)?; - let key = PKey::from_rsa(rsa)?; +pub fn public_auth_key() -> &'static PublicKey { + static KEY: OnceLock = OnceLock::new(); - Ok(key) + KEY.get_or_init(|| { + let pem = file_get_contents(configdir!("/authkey.pub")).unwrap(); + PublicKey::from_pem(&pem).unwrap() + }) } -pub fn private_auth_key() -> &'static PKey { - lazy_static! { - static ref KEY: PKey = load_private_auth_key().unwrap(); - } +pub fn private_auth_key() -> &'static PrivateKey { + static KEY: OnceLock = OnceLock::new(); - &KEY + KEY.get_or_init(|| { + let pem = file_get_contents(configdir!("/authkey.key")).unwrap(); + PrivateKey::from_pem(&pem).unwrap() + }) } const LDAP_PASSWORDS_FILENAME: &str = configdir!("/ldap_passwords.json"); -- 2.39.2