diff options
Diffstat (limited to 'src/vapid/ser.rs')
| -rw-r--r-- | src/vapid/ser.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/vapid/ser.rs b/src/vapid/ser.rs index f5372c8..02c77e1 100644 --- a/src/vapid/ser.rs +++ b/src/vapid/ser.rs @@ -1,7 +1,9 @@ pub mod key { + use std::fmt; + use base64::{Engine as _, engine::general_purpose::URL_SAFE}; use p256::ecdsa::VerifyingKey; - use serde::Serialize as _; + use serde::{Deserializer, Serialize as _, de}; // This serialization - to a URL-safe base-64-encoded string and back - is based on my best // understanding of RFC 8292 and the corresponding browser APIs. Particularly, it's based on @@ -32,4 +34,30 @@ pub mod key { let key = URL_SAFE.encode(key); key.serialize(serializer) } + + pub fn deserialize<'de, D>(deserializer: D) -> Result<VerifyingKey, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Visitor) + } + + struct Visitor; + impl de::Visitor<'_> for Visitor { + type Value = VerifyingKey; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string containing a VAPID key") + } + + fn visit_str<E>(self, key: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + let key = URL_SAFE.decode(key).map_err(E::custom)?; + let key = VerifyingKey::from_sec1_bytes(&key).map_err(E::custom)?; + + Ok(key) + } + } } |
