wireguard_conf/utils/
keys.rs

1use core::fmt;
2
3use base64::prelude::*;
4use x25519_dalek::{PublicKey as XPublicKey, StaticSecret};
5
6use crate::WireguardError;
7
8/// Private key
9///
10/// Wrapper around [`x25519_dalek::StaticSecret`]. It can be formatted to Wireguard's
11/// format, and also implements [`fmt::Debug`].
12#[derive(Clone)]
13pub struct PrivateKey {
14    secret: StaticSecret,
15}
16
17impl PrivateKey {
18    #[must_use] pub fn random() -> PrivateKey {
19        Self {
20            secret: StaticSecret::random(),
21        }
22    }
23}
24
25impl fmt::Debug for PrivateKey {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.debug_struct("PrivateKey")
28            .field("secret", &self.to_string())
29            .finish()
30    }
31}
32
33impl fmt::Display for PrivateKey {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        write!(f, "{}", BASE64_STANDARD.encode(self.secret.to_bytes()))
36    }
37}
38
39impl PartialEq for PrivateKey {
40    fn eq(&self, other: &Self) -> bool {
41        self.secret.as_bytes() == other.secret.as_bytes()
42    }
43}
44
45impl TryFrom<String> for PrivateKey {
46    type Error = WireguardError;
47
48    fn try_from(value: String) -> Result<Self, Self::Error> {
49        let bytes: [u8; 32] = BASE64_STANDARD
50            .decode(value)
51            .map_err(|_| WireguardError::InvalidPrivateKey)?
52            .try_into()
53            .map_err(|_| WireguardError::InvalidPrivateKey)?;
54
55        Ok(Self {
56            secret: StaticSecret::from(bytes),
57        })
58    }
59}
60
61/// Public key.
62///
63/// Wrapper around [`x25519_dalek::PublicKey`]. It can be formatted to Wireguard's
64/// format, and also implements [`fmt::Debug`].
65#[derive(Clone, PartialEq)]
66pub struct PublicKey {
67    key: XPublicKey,
68}
69
70impl fmt::Debug for PublicKey {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        f.debug_struct("PublicKey")
73            .field("key", &self.to_string())
74            .finish()
75    }
76}
77
78impl fmt::Display for PublicKey {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        write!(f, "{}", BASE64_STANDARD.encode(self.key.to_bytes()))
81    }
82}
83
84impl TryFrom<String> for PublicKey {
85    type Error = WireguardError;
86
87    fn try_from(value: String) -> Result<Self, Self::Error> {
88        let bytes: [u8; 32] = BASE64_STANDARD
89            .decode(value)
90            .map_err(|_| WireguardError::InvalidPublicKey)?
91            .try_into()
92            .map_err(|_| WireguardError::InvalidPublicKey)?;
93
94        Ok(Self {
95            key: XPublicKey::from(bytes),
96        })
97    }
98}
99
100impl From<&PrivateKey> for PublicKey {
101    fn from(value: &PrivateKey) -> Self {
102        Self {
103            key: XPublicKey::from(&value.secret),
104        }
105    }
106}