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 574FA7ED60 for ; Thu, 11 Nov 2021 15:07:57 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0F9A2C66C for ; Thu, 11 Nov 2021 15:07:27 +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 id 662ADC655 for ; Thu, 11 Nov 2021 15:07:26 +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 3F20243038 for ; Thu, 11 Nov 2021 15:07:26 +0100 (CET) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pve-devel@lists.proxmox.com Date: Thu, 11 Nov 2021 15:07:09 +0100 Message-Id: <20211111140721.3288364-4-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211111140721.3288364-1-f.gruenbichler@proxmox.com> References: <20211111140721.3288364-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.276 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% 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 Subject: [pve-devel] [PATCH v2 proxmox-websocket-tunnel 3/4] add fingerprint validation X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Nov 2021 14:07:57 -0000 in case we have no explicit fingerprint, we use openssl's regular "PEER" verification. if we have a fingerprint, we ignore openssl altogether and just verify the fingerprint of the presented leaf certificate. Signed-off-by: Fabian Grünbichler --- Notes: v2: new src/main.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9753248..208c346 100644 --- a/src/main.rs +++ b/src/main.rs @@ -134,9 +134,50 @@ impl CtrlTunnel { } let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls())?; - if fingerprint.is_some() { - // FIXME actually verify fingerprint via callback! - ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE); + if let Some(expected) = fingerprint { + ssl_connector_builder.set_verify_callback( + openssl::ssl::SslVerifyMode::NONE, + move |_valid, ctx| { + let cert = match ctx.current_cert() { + Some(cert) => cert, + None => { + eprintln!("SSL context lacks current certificate."); + return false; + } + }; + + let depth = ctx.error_depth(); + if depth != 0 { + return true; + } + + let fp = match cert.digest(openssl::hash::MessageDigest::sha256()) { + Ok(fp) => fp, + Err(err) => { + // should not happen + eprintln!("failed to calculate certificate FP - {}", err); + return false; + } + }; + let fp_string = proxmox::tools::digest_to_hex(&fp); + let fp_string = fp_string + .as_bytes() + .chunks(2) + .map(|v| std::str::from_utf8(v).unwrap()) + .collect::>() + .join(":"); + + let expected = expected.to_lowercase(); + if expected == fp_string { + true + } else { + eprintln!("certificate fingerprint does not match expected fingerprint!"); + eprintln!("expected: {}", expected); + eprintln!("encountered: {}", fp_string); + false + } + }, + ); } else { ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::PEER); } -- 2.30.2