From: Christian Ebner <c.ebner@proxmox.com>
To: Thomas Lamprecht <t.lamprecht@proxmox.com>,
Proxmox Backup Server development discussion
<pbs-devel@lists.proxmox.com>
Subject: Re: [pbs-devel] [PATCH proxmox v7 1/9] s3 client: add crate for AWS s3 compatible object store client
Date: Fri, 11 Jul 2025 12:52:14 +0200 [thread overview]
Message-ID: <5f1a3122-5478-4f4c-8b74-4487bab5dd9e@proxmox.com> (raw)
In-Reply-To: <38e3b3b5-a1a6-43d6-b925-1d04d8b1e22d@proxmox.com>
On 7/11/25 09:42, Thomas Lamprecht wrote:
> Am 10.07.25 um 19:06 schrieb Christian Ebner:
>> + fn verify_certificate_fingerprint(
>> + openssl_valid: bool,
>> + context: &mut X509StoreContextRef,
>> + expected_fingerprint: Option<String>,
>> + trust_openssl: Arc<Mutex<bool>>,
>> + ) -> Result<Option<String>, Error> {
>
> This method seems a bit like it might fit better into a (micro) crate specific for
> "cert stuff". FWIW, there is a verify_fingerprint function in the proxmox-client
> crate already, this one here seems to be a bit more generic, or well also include
> things like the fp_string function for doing &[u8] -> String the client has separately.
>
>
> As both use openssl, i.e. X509StoreContextRef as base, it quite probably can share
> most of the implementation.
>
> FWIW, I'd be even open for a quite specific proxmox-tls-cert-fingerprint micro
> crate, as IMO those micro crates to not produce much maintenance cost, especially
> if one assembles it after having the use case already in a few places, thus being
> pretty likely that the API will work OK that way for new future use cases too.
> Note, not promoting creation of trivial things, e.g. the famous leftpad crates,
> but TLS (fingerprint) cert verification is not really trivial and can have
> critical implications, which then can be IMO enough to justify a micro crate.
>
> Anyhow, this can be refactored out transparently at any time, so really not
> a blocker for getting this client in.
>
>> + let mut trust_openssl_valid = trust_openssl.lock().unwrap();
>> +
>> + // only rely on openssl prevalidation if was not forced earlier
>> + if openssl_valid && *trust_openssl_valid {
>> + return Ok(None);
>> + }
>> +
>> + let certificate = match context.current_cert() {
>> + Some(certificate) => certificate,
>> + None => bail!("context lacks current certificate."),
>> + };
>> +
>
>
> This below would do well with a (short) explanatory comment IMO.
>
>> + if context.error_depth() > 0 {
>> + *trust_openssl_valid = false;
>> + return Ok(None);
>> + }
>> +
>> + let certificate_digest = certificate
>> + .digest(MessageDigest::sha256())
>> + .context("failed to calculate certificate digest")?;
>> + let certificate_fingerprint = hex::encode(certificate_digest);
>> + let certificate_fingerprint = certificate_fingerprint
>> + .as_bytes()
>> + .chunks(2)
>> + .map(|v| std::str::from_utf8(v).unwrap())
>> + .collect::<Vec<&str>>()
>> + .join(":");
>
> I really have nothing against iterator chains, but here unrolling that seems a
> bit more readable, e.g. the aforementioned fp_string fn from proxmox-client does:
>
> let mut cert_fingerprint_str = String::new();
> for b in fp {
> if !cert_fingerprint_str.is_empty() {
> out.push(':');
> }
> let _ = write!(cert_fingerprint_str, "{b:02x}");
> }
>
> Or at least avoid the upfront hex::encode and to that on the fly, e.g. like:
>
> let certificate_fingerprint = certificate_digest
> .iter()
> .map(|byte| format!("{byte:02x}"))
> .collect::<Vec<String>>()
> .join(":");
>
>
> That variant would also be fine, IMO even nicer as the yours and the one from
> proxmox-client (and shorter as both!), but as disclaimer I only quicktested it in
> the rust playground:
>
> https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f575fdf9da37aa3ebefc28a66a93be2b
>
>> +
>> + if let Some(expected_fingerprint) = expected_fingerprint {
>> + let expected_fingerprint = expected_fingerprint.to_lowercase();
>
> The to_lowercase would not be required if we control the format and use a lower
> case x in the {byte:02x} fmt.
So actually this needs some more checking. After all the
expected_fingerprint is provided to the client via the S3ClientOptions,
which have this as optional String parameter. There is no guarantee that
this will stem from a config, where it is checked a-priori.
So instead of doing a to_lowercase() here, during client instantiation
there should happen some check along the lines of (untested):
```rust
@@ -105,7 +107,17 @@ impl S3Client {
/// Creates a new S3 client instance, connecting to the provided
endpoint using https given the
/// provided options.
pub fn new(options: S3ClientOptions) -> Result<Self, Error> {
- let expected_fingerprint = options.fingerprint.clone();
+ let expected_fingerprint = if let Some(ref fingerprint) =
options.fingerprint {
+ match CERT_FINGERPRINT_SHA256_SCHEMA {
+ Schema::String(ref schema) => schema
+ .check_constraints(fingerprint)
+ .context("invalid fingerprint provided")?,
+ _ => unreachable!(),
+ }
+ Some(fingerprint.to_lowercase())
+ } else {
+ None
+ };
let verified_fingerprint = Arc::new(Mutex::new(None));
let trust_openssl_valid = Arc::new(Mutex::new(true));
let mut ssl_connector_builder =
SslConnector::builder(SslMethod::tls())?;
```
That should make this more robust.
>
>> + if expected_fingerprint == certificate_fingerprint {
>> + return Ok(Some(certificate_fingerprint));
>> + }
>> + }
>> +
>> + Err(format_err!(
>> + "unexpected certificate fingerprint {certificate_fingerprint}"
>> + ))
>> + }
>
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2025-07-11 10:52 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-10 17:06 [pbs-devel] [PATCH proxmox{, -backup} v7 00/47] fix #2943: S3 storage backend for datastores Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 1/9] s3 client: add crate for AWS s3 compatible object store client Christian Ebner
2025-07-11 7:42 ` Thomas Lamprecht
2025-07-11 8:17 ` Christian Ebner
2025-07-11 8:22 ` Thomas Lamprecht
2025-07-11 10:52 ` Christian Ebner [this message]
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 2/9] s3 client: implement AWS signature v4 request authentication Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 3/9] s3 client: add dedicated type for s3 object keys Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 4/9] s3 client: add type for last modified timestamp in responses Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 5/9] s3 client: add helper to parse http date headers Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 6/9] s3 client: implement methods to operate on s3 objects in bucket Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 7/9] s3 client: add example usage for basic operations Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 8/9] pbs-api-types: extend datastore config by backend config enum Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox v7 9/9] pbs-api-types: maintenance: add new maintenance mode S3 refresh Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 01/38] datastore: add helpers for path/digest to s3 object key conversion Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 02/38] config: introduce s3 object store client configuration Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 03/38] api: config: implement endpoints to manipulate and list s3 configs Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 04/38] api: datastore: check s3 backend bucket access on datastore create Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 05/38] api/cli: add endpoint and command to check s3 client connection Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 06/38] datastore: allow to get the backend for a datastore Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 07/38] api: backup: store datastore backend in runtime environment Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 08/38] api: backup: conditionally upload chunks to s3 object store backend Christian Ebner
2025-07-10 17:06 ` [pbs-devel] [PATCH proxmox-backup v7 09/38] api: backup: conditionally upload blobs " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 10/38] api: backup: conditionally upload indices " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 11/38] api: backup: conditionally upload manifest " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 12/38] api: datastore: conditionally upload client log to s3 backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 13/38] sync: pull: conditionally upload content " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 14/38] api: reader: fetch chunks based on datastore backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 15/38] datastore: local chunk reader: read chunks based on backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 16/38] verify worker: add datastore backed to verify worker Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 17/38] verify: implement chunk verification for stores with s3 backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 18/38] datastore: create namespace marker in " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 19/38] datastore: create/delete protected marker file on s3 storage backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 20/38] datastore: prune groups/snapshots from s3 object store backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 21/38] datastore: get and set owner for s3 " Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 22/38] datastore: implement garbage collection for s3 backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 23/38] ui: add datastore type selector and reorganize component layout Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 24/38] ui: add s3 client edit window for configuration create/edit Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 25/38] ui: add s3 client view for configuration Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 26/38] ui: expose the s3 client view in the navigation tree Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 27/38] ui: add s3 client selector and bucket field for s3 backend setup Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 28/38] tools: lru cache: add removed callback for evicted cache nodes Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 29/38] tools: async lru cache: implement insert, remove and contains methods Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 30/38] datastore: add local datastore cache for network attached storages Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 31/38] api: backup: use local datastore cache on s3 backend chunk upload Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 32/38] api: reader: use local datastore cache on s3 backend chunk fetching Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 33/38] datastore: local chunk reader: get cached chunk from local cache store Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 34/38] api: backup: add no-cache flag to bypass local datastore cache Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 35/38] api/datastore: implement refresh endpoint for stores with s3 backend Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 36/38] cli: add dedicated subcommand for datastore s3 refresh Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 37/38] ui: render s3 refresh as valid maintenance type and task description Christian Ebner
2025-07-10 17:07 ` [pbs-devel] [PATCH proxmox-backup v7 38/38] ui: expose s3 refresh button for datastores backed by object store Christian Ebner
2025-07-14 14:33 ` [pbs-devel] [PATCH proxmox{, -backup} v7 00/47] fix #2943: S3 storage backend for datastores Lukas Wagner
2025-07-14 15:40 ` Christian Ebner
2025-07-15 7:21 ` Lukas Wagner
2025-07-15 7:32 ` Christian Ebner
2025-07-15 12:55 ` [pbs-devel] superseded: " Christian Ebner
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=5f1a3122-5478-4f4c-8b74-4487bab5dd9e@proxmox.com \
--to=c.ebner@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
--cc=t.lamprecht@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox