public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Shannon Sterz <s.sterz@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [PATCH datacenter-manager 08/17] cli/api-types: move Fingerprint to common api type crate
Date: Thu, 11 Jun 2026 14:03:18 +0200	[thread overview]
Message-ID: <20260611120327.257523-9-s.sterz@proxmox.com> (raw)
In-Reply-To: <20260611120327.257523-1-s.sterz@proxmox.com>

this type is more generally useful when working with certificates, so
move it to the common pdm api types.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 cli/client/src/env/fingerprint_cache.rs | 77 +-----------------------
 cli/client/src/env/mod.rs               |  2 +-
 lib/pdm-api-types/Cargo.toml            |  1 +
 lib/pdm-api-types/src/fingerprint.rs    | 78 +++++++++++++++++++++++++
 lib/pdm-api-types/src/lib.rs            |  3 +
 5 files changed, 84 insertions(+), 77 deletions(-)
 create mode 100644 lib/pdm-api-types/src/fingerprint.rs

diff --git a/cli/client/src/env/fingerprint_cache.rs b/cli/client/src/env/fingerprint_cache.rs
index a4766ae9..2040b2cf 100644
--- a/cli/client/src/env/fingerprint_cache.rs
+++ b/cli/client/src/env/fingerprint_cache.rs
@@ -6,82 +6,7 @@ use anyhow::{Error, bail, format_err};
 use openssl::hash::MessageDigest;
 use openssl::x509::X509StoreContextRef;
 
-/// A sha256 fingerprint.
-// NOTE: The difference to ConfigDigest is that this also allows colons between bytes when parsing.
-// Also the API type's description is different.
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Fingerprint([u8; 32]);
-serde_plain::derive_deserialize_from_fromstr!(Fingerprint, "valid sha256 fingerprint");
-serde_plain::derive_serialize_from_display!(Fingerprint);
-
-impl From<[u8; 32]> for Fingerprint {
-    #[inline]
-    fn from(fp: [u8; 32]) -> Self {
-        Self(fp)
-    }
-}
-
-impl From<Fingerprint> for [u8; 32] {
-    #[inline]
-    fn from(fp: Fingerprint) -> Self {
-        fp.0
-    }
-}
-
-impl TryFrom<&[u8]> for Fingerprint {
-    type Error = std::array::TryFromSliceError;
-
-    fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
-        Ok(Self(slice.try_into()?))
-    }
-}
-
-impl AsRef<[u8]> for Fingerprint {
-    fn as_ref(&self) -> &[u8] {
-        &self.0
-    }
-}
-
-impl AsRef<[u8; 32]> for Fingerprint {
-    fn as_ref(&self) -> &[u8; 32] {
-        &self.0
-    }
-}
-
-impl std::ops::Deref for Fingerprint {
-    type Target = [u8; 32];
-
-    fn deref(&self) -> &[u8; 32] {
-        &self.0
-    }
-}
-
-impl std::ops::DerefMut for Fingerprint {
-    fn deref_mut(&mut self) -> &mut [u8; 32] {
-        &mut self.0
-    }
-}
-
-impl std::fmt::Display for Fingerprint {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:02x}", self[0])?;
-        for b in &self[1..] {
-            write!(f, ":{b:02x}")?;
-        }
-        Ok(())
-    }
-}
-
-impl std::str::FromStr for Fingerprint {
-    type Err = Error;
-
-    fn from_str(s: &str) -> Result<Self, Error> {
-        let s = s.replace(':', "");
-        let mut fp = [0u8; 32];
-        hex::decode_to_slice(s, &mut fp)?;
-        Ok(Fingerprint(fp))
-    }
-}
+use pdm_api_types::Fingerprint;
 
 pub struct FingerprintCache {
     pub interactive: bool,
diff --git a/cli/client/src/env/mod.rs b/cli/client/src/env/mod.rs
index 7c35e2a2..4c46e513 100644
--- a/cli/client/src/env/mod.rs
+++ b/cli/client/src/env/mod.rs
@@ -11,6 +11,7 @@ use http::Uri;
 use openssl::x509;
 use serde::{Deserialize, Serialize};
 
+pub use pdm_api_types::Fingerprint;
 use proxmox_auth_api::types::Userid;
 use proxmox_client::TfaChallenge;
 use proxmox_schema::api;
@@ -19,7 +20,6 @@ use crate::XDG;
 use crate::config::{FormatArgs, PdmConnectArgs};
 
 mod fingerprint_cache;
-pub use fingerprint_cache::Fingerprint;
 use fingerprint_cache::FingerprintCache;
 
 macro_rules! xdg_path {
diff --git a/lib/pdm-api-types/Cargo.toml b/lib/pdm-api-types/Cargo.toml
index f9e3d07e..e3a40934 100644
--- a/lib/pdm-api-types/Cargo.toml
+++ b/lib/pdm-api-types/Cargo.toml
@@ -8,6 +8,7 @@ description = "general API type helpers for PDM"
 [dependencies]
 anyhow.workspace = true
 const_format.workspace = true
+hex.workspace = true
 http.workspace = true
 regex.workspace = true
 serde.workspace = true
diff --git a/lib/pdm-api-types/src/fingerprint.rs b/lib/pdm-api-types/src/fingerprint.rs
new file mode 100644
index 00000000..ee7f9229
--- /dev/null
+++ b/lib/pdm-api-types/src/fingerprint.rs
@@ -0,0 +1,78 @@
+use anyhow::Error;
+
+/// A sha256 fingerprint.
+// NOTE: The difference to ConfigDigest is that this also allows colons between bytes when parsing.
+// Also the API type's description is different.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Fingerprint([u8; 32]);
+serde_plain::derive_deserialize_from_fromstr!(Fingerprint, "valid sha256 fingerprint");
+serde_plain::derive_serialize_from_display!(Fingerprint);
+
+impl From<[u8; 32]> for Fingerprint {
+    #[inline]
+    fn from(fp: [u8; 32]) -> Self {
+        Self(fp)
+    }
+}
+
+impl From<Fingerprint> for [u8; 32] {
+    #[inline]
+    fn from(fp: Fingerprint) -> Self {
+        fp.0
+    }
+}
+
+impl TryFrom<&[u8]> for Fingerprint {
+    type Error = std::array::TryFromSliceError;
+
+    fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
+        Ok(Self(slice.try_into()?))
+    }
+}
+
+impl AsRef<[u8]> for Fingerprint {
+    fn as_ref(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+impl AsRef<[u8; 32]> for Fingerprint {
+    fn as_ref(&self) -> &[u8; 32] {
+        &self.0
+    }
+}
+
+impl std::ops::Deref for Fingerprint {
+    type Target = [u8; 32];
+
+    fn deref(&self) -> &[u8; 32] {
+        &self.0
+    }
+}
+
+impl std::ops::DerefMut for Fingerprint {
+    fn deref_mut(&mut self) -> &mut [u8; 32] {
+        &mut self.0
+    }
+}
+
+impl std::fmt::Display for Fingerprint {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:02x}", self[0])?;
+        for b in &self[1..] {
+            write!(f, ":{b:02x}")?;
+        }
+        Ok(())
+    }
+}
+
+impl std::str::FromStr for Fingerprint {
+    type Err = Error;
+
+    fn from_str(s: &str) -> Result<Self, Error> {
+        let s = s.replace(':', "");
+        let mut fp = [0u8; 32];
+        hex::decode_to_slice(s, &mut fp)?;
+        Ok(Fingerprint(fp))
+    }
+}
diff --git a/lib/pdm-api-types/src/lib.rs b/lib/pdm-api-types/src/lib.rs
index b9cc3234..5c86cb29 100644
--- a/lib/pdm-api-types/src/lib.rs
+++ b/lib/pdm-api-types/src/lib.rs
@@ -106,6 +106,9 @@ pub mod ceph;
 
 pub mod firewall;
 
+mod fingerprint;
+pub use fingerprint::Fingerprint;
+
 pub mod remotes;
 
 pub mod remote_updates;
-- 
2.47.3





  parent reply	other threads:[~2026-06-11 12:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11 12:03 [RFC cluster/datacenter-manager/manager/proxmox 00/17] TLS Certificate Staging Shannon Sterz
2026-06-11 12:03 ` [PATCH cluster 01/17] setup: allow caller to provide the certificate filename Shannon Sterz
2026-06-11 12:03 ` [PATCH manager 02/17] bin/api: add a new staged certificate when renewing self-signed cert Shannon Sterz
2026-06-11 12:03 ` [PATCH manager 03/17] api: certificates: if node parameter is 'localhost' return local certs Shannon Sterz
2026-06-11 12:03 ` [PATCH proxmox 04/17] client: ignore certificate trust store validation result on fp option Shannon Sterz
2026-06-11 12:03 ` [PATCH proxmox 05/17] pve-api-types: expose certificates info endpoint Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 06/17] client: don't short-circuit on valid certificate when tls fp exists Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 07/17] client: allow users to update a changed fingerprint interactively Shannon Sterz
2026-06-11 12:03 ` Shannon Sterz [this message]
2026-06-11 12:03 ` [PATCH datacenter-manager 09/17] server: connection: report mismatching fingerprint as untrusted on probe Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 10/17] ui: wizzard: add context if a provided fingerprint did not match remote Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 11/17] ui: wizzard: nodes page: always update fingerprints on user confirmation Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 12/17] pdm-api-types: implement ApiType for Fingerprint Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 13/17] pdm-api-types: add staged_fingerprints field to NodeUrl Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 14/17] server: remotes: lock remotes config when updating it Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 15/17] server: connection: rotate in staged fingerprints when encountering them Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 16/17] server: api: tasks: move `spawn_aborted_on_shutdown()` to super module Shannon Sterz
2026-06-11 12:03 ` [PATCH datacenter-manager 17/17] server: bin: api: tasks: add task to discover new staged certificates Shannon Sterz

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=20260611120327.257523-9-s.sterz@proxmox.com \
    --to=s.sterz@proxmox.com \
    --cc=pdm-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal