wireguard_conf/keys/
private.rs1use core::fmt;
2
3use base64::prelude::*;
4use x25519_dalek::StaticSecret;
5use zeroize::ZeroizeOnDrop;
6
7use crate::WireguardError;
8
9#[derive(Clone, ZeroizeOnDrop)]
39pub struct PrivateKey(pub(crate) 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
108impl From<[u8; 32]> for PrivateKey {
109 fn from(value: [u8; 32]) -> Self {
110 Self(StaticSecret::from(value))
111 }
112}
113
114#[cfg(feature = "serde")]
115mod serde_impl {
116 use super::PrivateKey;
117 use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
118
119 impl Serialize for PrivateKey {
120 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
121 where
122 S: Serializer,
123 {
124 if serializer.is_human_readable() {
125 serializer.serialize_str(&self.to_string())
126 } else {
127 serializer.serialize_bytes(self.as_bytes())
128 }
129 }
130 }
131
132 impl<'de> Deserialize<'de> for PrivateKey {
133 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
134 where
135 D: Deserializer<'de>,
136 {
137 if deserializer.is_human_readable() {
138 let data = String::deserialize(deserializer)?;
139
140 PrivateKey::try_from(data.as_str()).map_err(|_| {
141 de::Error::invalid_value(de::Unexpected::Str(&data), &"a private key")
142 })
143 } else {
144 let bytes = <[u8; 32]>::deserialize(deserializer)?;
145
146 Ok(PrivateKey::from(bytes))
147 }
148 }
149 }
150}