From 5079ff6a3cb21abf3e1ba28e9ef08d790ab7931d Mon Sep 17 00:00:00 2001 From: Maximiliano Sandoval Date: Tue, 23 Apr 2024 13:19:53 +0200 Subject: [PATCH] tfa: webauthn: serialize OriginUrl following RFC6454 We serialize `OriginUrl` using the ASCII serialization mentioned at [RFC6454] section 6.2 or [1]. Note that the unicode serialization is not used widely adopted [2]. Note that `url::Url` serialize with a trailign slash, e.g. https://foo.bar serializes as https://foo.bar/ which is not the origin for this domain. [RFC6454] https://www.rfc-editor.org/rfc/rfc6454 [1] https://html.spec.whatwg.org/multipage/browsers.html#ascii-serialisation-of-an-origin [2] https://html.spec.whatwg.org/multipage/browsers.html#unicode-serialisation-of-an-origin Signed-off-by: Maximiliano Sandoval --- proxmox-tfa/src/api/webauthn.rs | 35 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/proxmox-tfa/src/api/webauthn.rs b/proxmox-tfa/src/api/webauthn.rs index 0f908229..4c854011 100644 --- a/proxmox-tfa/src/api/webauthn.rs +++ b/proxmox-tfa/src/api/webauthn.rs @@ -10,10 +10,19 @@ use proxmox_schema::{api, Updater, UpdaterType}; use super::IsExpired; -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Deserialize)] /// Origin URL for WebauthnConfig pub struct OriginUrl(Url); +impl serde::Serialize for OriginUrl { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + #[cfg(feature = "api-types")] impl UpdaterType for OriginUrl { type Updater = Option; @@ -27,23 +36,15 @@ impl std::str::FromStr for OriginUrl { } } -impl std::ops::Deref for OriginUrl { - type Target = Url; - - fn deref(&self) -> &Url { - &self.0 - } -} - -impl std::ops::DerefMut for OriginUrl { - fn deref_mut(&mut self) -> &mut Url { - &mut self.0 - } -} - impl From for String { fn from(url: OriginUrl) -> String { - url.0.into() + url.to_string() + } +} + +impl OriginUrl { + fn to_string(&self) -> String { + self.0.origin().ascii_serialization() } } @@ -90,7 +91,7 @@ impl WebauthnConfig { pub fn digest(&self) -> [u8; 32] { let mut data = format!("rp={:?}\nid={:?}\n", self.rp, self.id,); if let Some(origin) = &self.origin { - data.push_str(&format!("origin={:?}\n", origin.as_str())); + data.push_str(&format!("origin={}\n", origin.to_string())); } openssl::sha::sha256(data.as_bytes()) }