summaryrefslogtreecommitdiff
path: root/src/vapid/ser.rs
blob: f5372c8873801a4ff5fa526a2fc706c3c847ca31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
pub mod key {
    use base64::{Engine as _, engine::general_purpose::URL_SAFE};
    use p256::ecdsa::VerifyingKey;
    use serde::Serialize as _;

    // 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
    // section 3.2:
    //
    // > The "k" parameter includes an ECDSA public key [FIPS186] in uncompressed form [X9.62] that
    // > is encoded using base64url encoding [RFC7515].
    //
    // <https://datatracker.ietf.org/doc/html/rfc8292#section-3.2>
    //
    // I believe this is also supported by MDN's explanation:
    //
    // > `applicationServerKey`
    // >
    // > A Base64-encoded string or ArrayBuffer containing an ECDSA P-256 public key that the push
    // > server will use to authenticate your application server. If specified, all messages from
    // > your application server must use the VAPID authentication scheme, and include a JWT signed
    // > with the corresponding private key. This key IS NOT the same ECDH key that you use to
    // > encrypt the data. For more information, see "Using VAPID with WebPush".
    //
    // <https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#applicationserverkey>

    pub fn serialize<S>(key: &VerifyingKey, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let key = key.to_sec1_bytes();
        let key = URL_SAFE.encode(key);
        key.serialize(serializer)
    }
}