wireguard_conf/utils/
keys.rs1use core::fmt;
2
3use base64::prelude::*;
4use x25519_dalek::{PublicKey as XPublicKey, StaticSecret};
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use crate::WireguardError;
8
9#[derive(Clone, Zeroize, ZeroizeOnDrop)]
39pub struct PrivateKey(StaticSecret);
40
41impl PrivateKey {
42 #[must_use]
44 pub fn random() -> PrivateKey {
45 Self(StaticSecret::random())
46 }
47}
48
49impl PrivateKey {
50 #[inline]
52 #[must_use]
53 pub fn as_bytes(&self) -> &[u8; 32] {
54 self.0.as_bytes()
55 }
56
57 #[inline]
59 #[must_use]
60 pub fn to_bytes(&self) -> [u8; 32] {
61 self.0.to_bytes()
62 }
63}
64
65impl fmt::Debug for PrivateKey {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_tuple("PrivateKey")
68 .field(&self.to_string())
69 .finish()
70 }
71}
72
73impl fmt::Display for PrivateKey {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
77 }
78}
79
80impl PartialEq for PrivateKey {
81 fn eq(&self, other: &Self) -> bool {
82 self.as_bytes() == other.as_bytes()
83 }
84}
85
86impl TryFrom<&str> for PrivateKey {
87 type Error = WireguardError;
88
89 fn try_from(value: &str) -> Result<Self, Self::Error> {
90 let bytes: [u8; 32] = BASE64_STANDARD
91 .decode(value)
92 .map_err(|_| WireguardError::InvalidPrivateKey)?
93 .try_into()
94 .map_err(|_| WireguardError::InvalidPrivateKey)?;
95
96 Ok(Self(StaticSecret::from(bytes)))
97 }
98}
99
100impl TryFrom<String> for PrivateKey {
101 type Error = WireguardError;
102
103 fn try_from(value: String) -> Result<Self, Self::Error> {
104 Self::try_from(value.as_str())
105 }
106}
107
108#[derive(Clone, PartialEq, Zeroize, ZeroizeOnDrop)]
140pub struct PublicKey(XPublicKey);
141
142impl PublicKey {
143 #[inline]
145 #[must_use]
146 pub fn to_bytes(&self) -> [u8; 32] {
147 self.0.to_bytes()
148 }
149
150 #[inline]
152 #[must_use]
153 pub fn as_bytes(&self) -> &[u8; 32] {
154 self.0.as_bytes()
155 }
156}
157
158impl fmt::Debug for PublicKey {
159 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160 f.debug_tuple("PublicKey").field(&self.to_string()).finish()
161 }
162}
163
164impl fmt::Display for PublicKey {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
168 }
169}
170
171impl TryFrom<&str> for PublicKey {
172 type Error = WireguardError;
173
174 fn try_from(value: &str) -> Result<Self, Self::Error> {
175 let bytes: [u8; 32] = BASE64_STANDARD
176 .decode(value)
177 .map_err(|_| WireguardError::InvalidPublicKey)?
178 .try_into()
179 .map_err(|_| WireguardError::InvalidPublicKey)?;
180
181 Ok(Self(XPublicKey::from(bytes)))
182 }
183}
184
185impl TryFrom<String> for PublicKey {
186 type Error = WireguardError;
187
188 fn try_from(value: String) -> Result<Self, Self::Error> {
189 Self::try_from(value.as_str())
190 }
191}
192
193impl From<&PrivateKey> for PublicKey {
194 fn from(value: &PrivateKey) -> Self {
195 Self(XPublicKey::from(&value.0))
196 }
197}