wireguard_conf/keys/
public.rs1use core::fmt;
2
3use base64::prelude::*;
4use x25519_dalek::PublicKey as XPublicKey;
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use crate::WireguardError;
8
9use super::PrivateKey;
10
11#[derive(Clone, PartialEq, Zeroize, ZeroizeOnDrop)]
43pub struct PublicKey(XPublicKey);
44
45impl PublicKey {
46 #[inline]
48 #[must_use]
49 pub fn to_bytes(&self) -> [u8; 32] {
50 self.0.to_bytes()
51 }
52
53 #[inline]
55 #[must_use]
56 pub fn as_bytes(&self) -> &[u8; 32] {
57 self.0.as_bytes()
58 }
59}
60
61impl fmt::Debug for PublicKey {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 f.debug_tuple("PublicKey").field(&self.to_string()).finish()
64 }
65}
66
67impl fmt::Display for PublicKey {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(f, "{}", BASE64_STANDARD.encode(self.as_bytes()))
71 }
72}
73
74impl TryFrom<&str> for PublicKey {
75 type Error = WireguardError;
76
77 fn try_from(value: &str) -> Result<Self, Self::Error> {
78 let bytes: [u8; 32] = BASE64_STANDARD
79 .decode(value)
80 .map_err(|_| WireguardError::InvalidPublicKey)?
81 .try_into()
82 .map_err(|_| WireguardError::InvalidPublicKey)?;
83
84 Ok(Self(XPublicKey::from(bytes)))
85 }
86}
87
88impl TryFrom<String> for PublicKey {
89 type Error = WireguardError;
90
91 fn try_from(value: String) -> Result<Self, Self::Error> {
92 Self::try_from(value.as_str())
93 }
94}
95
96impl From<[u8; 32]> for PublicKey {
97 fn from(value: [u8; 32]) -> Self {
98 Self(XPublicKey::from(value))
99 }
100}
101
102impl From<&PrivateKey> for PublicKey {
103 fn from(value: &PrivateKey) -> Self {
104 Self(XPublicKey::from(&value.0))
105 }
106}
107
108#[cfg(feature = "serde")]
109mod serde_impl {
110 use super::PublicKey;
111 use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
112
113 impl Serialize for PublicKey {
114 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115 where
116 S: Serializer,
117 {
118 if serializer.is_human_readable() {
119 serializer.serialize_str(&self.to_string())
120 } else {
121 serializer.serialize_bytes(self.as_bytes())
122 }
123 }
124 }
125
126 impl<'de> Deserialize<'de> for PublicKey {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: Deserializer<'de>,
130 {
131 if deserializer.is_human_readable() {
132 let data = String::deserialize(deserializer)?;
133
134 PublicKey::try_from(data.as_str()).map_err(|_| {
135 de::Error::invalid_value(de::Unexpected::Str(&data), &"a public key")
136 })
137 } else {
138 let bytes = <[u8; 32]>::deserialize(deserializer)?;
139
140 Ok(PublicKey::from(bytes))
141 }
142 }
143 }
144}