wireguard_conf/utils/
keys.rs1use core::fmt;
2
3use base64::prelude::*;
4use rand::RngCore;
5use x25519_dalek::{PublicKey as XPublicKey, StaticSecret};
6use zeroize::{Zeroize, ZeroizeOnDrop};
7
8use crate::WireguardError;
9
10#[derive(Clone, Zeroize, ZeroizeOnDrop)]
40pub struct PrivateKey(StaticSecret);
41
42impl PrivateKey {
43 #[must_use]
45 pub fn random() -> PrivateKey {
46 Self(StaticSecret::random())
47 }
48}
49
50impl PrivateKey {
51 #[inline]
53 #[must_use]
54 pub fn as_bytes(&self) -> &[u8; 32] {
55 self.0.as_bytes()
56 }
57
58 #[inline]
60 #[must_use]
61 pub fn to_bytes(&self) -> [u8; 32] {
62 self.0.to_bytes()
63 }
64}
65
66impl fmt::Debug for PrivateKey {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 f.debug_tuple("PrivateKey")
69 .field(&self.to_string())
70 .finish()
71 }
72}
73
74impl fmt::Display for PrivateKey {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
78 }
79}
80
81impl PartialEq for PrivateKey {
82 fn eq(&self, other: &Self) -> bool {
83 self.as_bytes() == other.as_bytes()
84 }
85}
86
87impl TryFrom<&str> for PrivateKey {
88 type Error = WireguardError;
89
90 fn try_from(value: &str) -> Result<Self, Self::Error> {
91 let bytes: [u8; 32] = BASE64_STANDARD
92 .decode(value)
93 .map_err(|_| WireguardError::InvalidPrivateKey)?
94 .try_into()
95 .map_err(|_| WireguardError::InvalidPrivateKey)?;
96
97 Ok(Self(StaticSecret::from(bytes)))
98 }
99}
100
101impl TryFrom<String> for PrivateKey {
102 type Error = WireguardError;
103
104 fn try_from(value: String) -> Result<Self, Self::Error> {
105 Self::try_from(value.as_str())
106 }
107}
108
109impl From<[u8; 32]> for PrivateKey {
110 fn from(value: [u8; 32]) -> Self {
111 Self(StaticSecret::from(value))
112 }
113}
114
115#[derive(Clone, PartialEq, Zeroize, ZeroizeOnDrop)]
147pub struct PublicKey(XPublicKey);
148
149impl PublicKey {
150 #[inline]
152 #[must_use]
153 pub fn to_bytes(&self) -> [u8; 32] {
154 self.0.to_bytes()
155 }
156
157 #[inline]
159 #[must_use]
160 pub fn as_bytes(&self) -> &[u8; 32] {
161 self.0.as_bytes()
162 }
163}
164
165impl fmt::Debug for PublicKey {
166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 f.debug_tuple("PublicKey").field(&self.to_string()).finish()
168 }
169}
170
171impl fmt::Display for PublicKey {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
175 }
176}
177
178impl TryFrom<&str> for PublicKey {
179 type Error = WireguardError;
180
181 fn try_from(value: &str) -> Result<Self, Self::Error> {
182 let bytes: [u8; 32] = BASE64_STANDARD
183 .decode(value)
184 .map_err(|_| WireguardError::InvalidPublicKey)?
185 .try_into()
186 .map_err(|_| WireguardError::InvalidPublicKey)?;
187
188 Ok(Self(XPublicKey::from(bytes)))
189 }
190}
191
192impl TryFrom<String> for PublicKey {
193 type Error = WireguardError;
194
195 fn try_from(value: String) -> Result<Self, Self::Error> {
196 Self::try_from(value.as_str())
197 }
198}
199
200impl From<[u8; 32]> for PublicKey {
201 fn from(value: [u8; 32]) -> Self {
202 Self(XPublicKey::from(value))
203 }
204}
205
206impl From<&PrivateKey> for PublicKey {
207 fn from(value: &PrivateKey) -> Self {
208 Self(XPublicKey::from(&value.0))
209 }
210}
211
212#[derive(Clone, PartialEq, Zeroize, ZeroizeOnDrop)]
242pub struct PresharedKey([u8; 32]);
243
244impl PresharedKey {
245 #[must_use]
247 pub fn random() -> Self {
248 let mut key = [0u8; 32];
249 rand::rng().fill_bytes(&mut key);
250 Self(key)
251 }
252}
253
254impl PresharedKey {
255 #[inline]
257 #[must_use]
258 pub fn to_bytes(&self) -> [u8; 32] {
259 self.0
260 }
261
262 #[inline]
264 #[must_use]
265 pub fn as_bytes(&self) -> &[u8; 32] {
266 &self.0
267 }
268}
269
270impl fmt::Debug for PresharedKey {
271 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 f.debug_tuple("PresharedKey")
273 .field(&self.to_string())
274 .finish()
275 }
276}
277
278impl fmt::Display for PresharedKey {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
282 }
283}
284
285impl From<[u8; 32]> for PresharedKey {
286 fn from(value: [u8; 32]) -> Self {
287 Self(value)
288 }
289}
290
291impl TryFrom<&str> for PresharedKey {
292 type Error = WireguardError;
293
294 fn try_from(value: &str) -> Result<Self, Self::Error> {
295 let bytes: [u8; 32] = BASE64_STANDARD
296 .decode(value)
297 .map_err(|_| WireguardError::InvalidPresharedKey)?
298 .try_into()
299 .map_err(|_| WireguardError::InvalidPresharedKey)?;
300
301 Ok(Self(bytes))
302 }
303}
304
305impl TryFrom<String> for PresharedKey {
306 type Error = WireguardError;
307
308 fn try_from(value: String) -> Result<Self, Self::Error> {
309 Self::try_from(value.as_str())
310 }
311}