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