1use super::{Ed25519PublicKey, SkEd25519};
4use crate::{Algorithm, Error, Fingerprint, HashAlg, Result};
5use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
6
7#[cfg(feature = "alloc")]
8use {
9 super::{DsaPublicKey, OpaquePublicKey, RsaPublicKey},
10 crate::Certificate,
11 alloc::boxed::Box,
12};
13
14#[cfg(feature = "ecdsa")]
15use super::{EcdsaPublicKey, SkEcdsaSha2NistP256};
16
17#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
19#[non_exhaustive]
20pub enum KeyData {
21 #[cfg(feature = "alloc")]
23 Dsa(DsaPublicKey),
24
25 #[cfg(feature = "ecdsa")]
27 Ecdsa(EcdsaPublicKey),
28
29 Ed25519(Ed25519PublicKey),
31
32 #[cfg(feature = "alloc")]
34 Rsa(RsaPublicKey),
35
36 #[cfg(feature = "ecdsa")]
40 SkEcdsaSha2NistP256(SkEcdsaSha2NistP256),
41
42 SkEd25519(SkEd25519),
46
47 #[cfg(feature = "alloc")]
53 Certificate(Box<Certificate>),
54
55 #[cfg(feature = "alloc")]
57 Other(OpaquePublicKey),
58}
59
60impl KeyData {
61 #[must_use]
63 pub fn algorithm(&self) -> Algorithm {
64 match self {
65 #[cfg(feature = "alloc")]
66 Self::Dsa(_) => Algorithm::Dsa,
67 #[cfg(feature = "ecdsa")]
68 Self::Ecdsa(key) => key.algorithm(),
69 Self::Ed25519(_) => Algorithm::Ed25519,
70 #[cfg(feature = "alloc")]
71 Self::Rsa(_) => Algorithm::Rsa { hash: None },
72 #[cfg(feature = "ecdsa")]
73 Self::SkEcdsaSha2NistP256(_) => Algorithm::SkEcdsaSha2NistP256,
74 Self::SkEd25519(_) => Algorithm::SkEd25519,
75 #[cfg(feature = "alloc")]
76 Self::Certificate(cert) => cert.algorithm(),
77 #[cfg(feature = "alloc")]
78 Self::Other(key) => key.algorithm(),
79 }
80 }
81
82 #[cfg(feature = "alloc")]
84 #[must_use]
85 pub fn dsa(&self) -> Option<&DsaPublicKey> {
86 match self {
87 Self::Dsa(key) => Some(key),
88 _ => None,
89 }
90 }
91
92 #[cfg(feature = "ecdsa")]
94 #[must_use]
95 pub fn ecdsa(&self) -> Option<&EcdsaPublicKey> {
96 match self {
97 Self::Ecdsa(key) => Some(key),
98 _ => None,
99 }
100 }
101
102 #[must_use]
104 pub fn ed25519(&self) -> Option<&Ed25519PublicKey> {
105 match self {
106 Self::Ed25519(key) => Some(key),
107 #[allow(unreachable_patterns)]
108 _ => None,
109 }
110 }
111
112 #[must_use]
116 pub fn fingerprint(&self, hash_alg: HashAlg) -> Fingerprint {
117 Fingerprint::new(hash_alg, self)
118 }
119
120 #[cfg(feature = "alloc")]
122 #[must_use]
123 pub fn rsa(&self) -> Option<&RsaPublicKey> {
124 match self {
125 Self::Rsa(key) => Some(key),
126 _ => None,
127 }
128 }
129
130 #[cfg(feature = "ecdsa")]
132 #[must_use]
133 pub fn sk_ecdsa_p256(&self) -> Option<&SkEcdsaSha2NistP256> {
134 match self {
135 Self::SkEcdsaSha2NistP256(sk) => Some(sk),
136 _ => None,
137 }
138 }
139
140 #[must_use]
142 pub fn sk_ed25519(&self) -> Option<&SkEd25519> {
143 match self {
144 Self::SkEd25519(sk) => Some(sk),
145 _ => None,
146 }
147 }
148
149 #[cfg(feature = "alloc")]
151 #[must_use]
152 pub fn other(&self) -> Option<&OpaquePublicKey> {
153 match self {
154 Self::Other(key) => Some(key),
155 _ => None,
156 }
157 }
158
159 #[cfg(feature = "alloc")]
161 #[must_use]
162 pub fn certificate(&self) -> Option<&Certificate> {
163 match self {
164 Self::Certificate(certificate) => Some(certificate.as_ref()),
165 _ => None,
166 }
167 }
168
169 #[cfg(feature = "alloc")]
171 #[must_use]
172 pub fn into_certificate(self) -> Option<Certificate> {
173 match self {
174 Self::Certificate(certificate) => Some(*certificate),
175 _ => None,
176 }
177 }
178
179 #[cfg(feature = "alloc")]
181 #[must_use]
182 pub fn is_dsa(&self) -> bool {
183 matches!(self, Self::Dsa(_))
184 }
185
186 #[cfg(feature = "ecdsa")]
188 #[must_use]
189 pub fn is_ecdsa(&self) -> bool {
190 matches!(self, Self::Ecdsa(_))
191 }
192
193 #[must_use]
195 pub fn is_ed25519(&self) -> bool {
196 matches!(self, Self::Ed25519(_))
197 }
198
199 #[cfg(feature = "alloc")]
201 #[must_use]
202 pub fn is_rsa(&self) -> bool {
203 matches!(self, Self::Rsa(_))
204 }
205
206 #[cfg(feature = "ecdsa")]
208 #[must_use]
209 pub fn is_sk_ecdsa_p256(&self) -> bool {
210 matches!(self, Self::SkEcdsaSha2NistP256(_))
211 }
212
213 #[must_use]
215 pub fn is_sk_ed25519(&self) -> bool {
216 matches!(self, Self::SkEd25519(_))
217 }
218
219 #[cfg(feature = "alloc")]
221 #[must_use]
222 pub fn is_other(&self) -> bool {
223 matches!(self, Self::Other(_))
224 }
225
226 #[cfg(feature = "alloc")]
228 #[must_use]
229 pub fn is_certificate(&self) -> bool {
230 matches!(self, Self::Certificate(_))
231 }
232
233 pub fn decode_as(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
240 match algorithm {
241 #[cfg(feature = "alloc")]
242 Algorithm::Dsa => DsaPublicKey::decode(reader).map(Self::Dsa),
243 #[cfg(feature = "ecdsa")]
244 Algorithm::Ecdsa { curve } => match EcdsaPublicKey::decode(reader)? {
245 key if key.curve() == curve => Ok(Self::Ecdsa(key)),
246 _ => Err(Error::AlgorithmUnknown),
247 },
248 Algorithm::Ed25519 => Ed25519PublicKey::decode(reader).map(Self::Ed25519),
249 #[cfg(feature = "alloc")]
250 Algorithm::Rsa { .. } => RsaPublicKey::decode(reader).map(Self::Rsa),
251 #[cfg(feature = "ecdsa")]
252 Algorithm::SkEcdsaSha2NistP256 => {
253 SkEcdsaSha2NistP256::decode(reader).map(Self::SkEcdsaSha2NistP256)
254 }
255 Algorithm::SkEd25519 => SkEd25519::decode(reader).map(Self::SkEd25519),
256 #[cfg(feature = "alloc")]
257 Algorithm::Other(_) => OpaquePublicKey::decode_as(reader, algorithm).map(Self::Other),
258 #[allow(unreachable_patterns)]
259 _ => Err(Error::AlgorithmUnknown),
260 }
261 }
262
263 #[cfg(feature = "alloc")]
268 pub fn decode_as_certificate(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
269 Certificate::decode_as(reader, algorithm).map(|cert| Self::Certificate(Box::new(cert)))
270 }
271
272 pub(crate) fn encoded_key_data_len(&self) -> encoding::Result<usize> {
275 match self {
276 #[cfg(feature = "alloc")]
277 Self::Dsa(key) => key.encoded_len(),
278 #[cfg(feature = "ecdsa")]
279 Self::Ecdsa(key) => key.encoded_len(),
280 Self::Ed25519(key) => key.encoded_len(),
281 #[cfg(feature = "alloc")]
282 Self::Rsa(key) => key.encoded_len(),
283 #[cfg(feature = "ecdsa")]
284 Self::SkEcdsaSha2NistP256(sk) => sk.encoded_len(),
285 Self::SkEd25519(sk) => sk.encoded_len(),
286 #[cfg(feature = "alloc")]
287 Self::Certificate(cert) => cert.encoded_len(),
288 #[cfg(feature = "alloc")]
289 Self::Other(other) => other.key.encoded_len(),
290 }
291 }
292
293 pub(crate) fn encode_key_data(&self, writer: &mut impl Writer) -> encoding::Result<()> {
295 match self {
296 #[cfg(feature = "alloc")]
297 Self::Dsa(key) => key.encode(writer),
298 #[cfg(feature = "ecdsa")]
299 Self::Ecdsa(key) => key.encode(writer),
300 Self::Ed25519(key) => key.encode(writer),
301 #[cfg(feature = "alloc")]
302 Self::Rsa(key) => key.encode(writer),
303 #[cfg(feature = "ecdsa")]
304 Self::SkEcdsaSha2NistP256(sk) => sk.encode(writer),
305 Self::SkEd25519(sk) => sk.encode(writer),
306 #[cfg(feature = "alloc")]
307 Self::Certificate(cert) => cert.encode(writer),
308 #[cfg(feature = "alloc")]
309 Self::Other(other) => other.key.encode(writer),
310 }
311 }
312}
313
314impl Decode for KeyData {
315 type Error = Error;
316
317 fn decode(reader: &mut impl Reader) -> Result<Self> {
318 let algorithm = Algorithm::decode(reader)?;
319 #[cfg(feature = "alloc")]
320 if let Algorithm::Other(name) = &algorithm {
321 if let Ok(certificate_algorithm) = Algorithm::new_certificate(name.as_str()) {
322 return Self::decode_as_certificate(reader, certificate_algorithm);
323 }
324 }
325 Self::decode_as(reader, algorithm)
326 }
327}
328
329impl Encode for KeyData {
330 fn encoded_len(&self) -> encoding::Result<usize> {
331 #[cfg(feature = "alloc")]
332 if self.is_certificate() {
333 return self.encoded_key_data_len();
335 }
336
337 [
338 self.algorithm().encoded_len()?,
339 self.encoded_key_data_len()?,
340 ]
341 .checked_sum()
342 }
343
344 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
345 #[cfg(feature = "alloc")]
346 if self.is_certificate() {
347 return self.encode_key_data(writer);
349 }
350
351 self.algorithm().encode(writer)?;
352 self.encode_key_data(writer)
353 }
354}
355
356#[cfg(feature = "alloc")]
357impl From<DsaPublicKey> for KeyData {
358 fn from(public_key: DsaPublicKey) -> KeyData {
359 Self::Dsa(public_key)
360 }
361}
362
363#[cfg(feature = "ecdsa")]
364impl From<EcdsaPublicKey> for KeyData {
365 fn from(public_key: EcdsaPublicKey) -> KeyData {
366 Self::Ecdsa(public_key)
367 }
368}
369
370impl From<Ed25519PublicKey> for KeyData {
371 fn from(public_key: Ed25519PublicKey) -> KeyData {
372 Self::Ed25519(public_key)
373 }
374}
375
376#[cfg(feature = "alloc")]
377impl From<RsaPublicKey> for KeyData {
378 fn from(public_key: RsaPublicKey) -> KeyData {
379 Self::Rsa(public_key)
380 }
381}
382
383#[cfg(feature = "ecdsa")]
384impl From<SkEcdsaSha2NistP256> for KeyData {
385 fn from(public_key: SkEcdsaSha2NistP256) -> KeyData {
386 Self::SkEcdsaSha2NistP256(public_key)
387 }
388}
389
390impl From<SkEd25519> for KeyData {
391 fn from(public_key: SkEd25519) -> KeyData {
392 Self::SkEd25519(public_key)
393 }
394}
395
396#[cfg(feature = "alloc")]
397impl From<Certificate> for KeyData {
398 fn from(certificate: Certificate) -> KeyData {
399 Self::Certificate(Box::new(certificate))
400 }
401}