[pbs-devel] [PATCH proxmox] tfa: webauthn: serialize OriginUrl following RFC6454

Maximiliano Sandoval m.sandoval at proxmox.com
Tue Apr 23 13:19:53 CEST 2024


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 <m.sandoval at proxmox.com>
---

I tested that existing hardware keys would still unlock the user after
installing this patch.

 proxmox-tfa/src/api/webauthn.rs | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        serializer.serialize_str(&self.to_string())
+    }
+}
+
 #[cfg(feature = "api-types")]
 impl UpdaterType for OriginUrl {
     type Updater = Option<Self>;
@@ -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<OriginUrl> for String {
+    fn from(url: OriginUrl) -> String {
+        url.to_string()
     }
 }
 
-impl From<OriginUrl> for String {
-    fn from(url: OriginUrl) -> String {
-        url.0.into()
+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())
     }
-- 
2.39.2





More information about the pbs-devel mailing list