1use super::{Ed25519PublicKey, SkEd25519};
4use crate::{
5 checked::CheckedSum, decode::Decode, encode::Encode, reader::Reader, writer::Writer, Algorithm,
6 Error, Result,
7};
8
9#[cfg(feature = "alloc")]
10use super::{DsaPublicKey, RsaPublicKey};
11
12#[cfg(feature = "ecdsa")]
13use super::{EcdsaPublicKey, SkEcdsaSha2NistP256};
14
15#[cfg(feature = "fingerprint")]
16use crate::{Fingerprint, HashAlg};
17
18#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
20#[non_exhaustive]
21pub enum KeyData {
22 #[cfg(feature = "alloc")]
24 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
25 Dsa(DsaPublicKey),
26
27 #[cfg(feature = "ecdsa")]
29 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
30 Ecdsa(EcdsaPublicKey),
31
32 Ed25519(Ed25519PublicKey),
34
35 #[cfg(feature = "alloc")]
37 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
38 Rsa(RsaPublicKey),
39
40 #[cfg(feature = "ecdsa")]
44 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
45 SkEcdsaSha2NistP256(SkEcdsaSha2NistP256),
46
47 SkEd25519(SkEd25519),
51}
52
53impl KeyData {
54 pub fn algorithm(&self) -> Algorithm {
56 match self {
57 #[cfg(feature = "alloc")]
58 Self::Dsa(_) => Algorithm::Dsa,
59 #[cfg(feature = "ecdsa")]
60 Self::Ecdsa(key) => key.algorithm(),
61 Self::Ed25519(_) => Algorithm::Ed25519,
62 #[cfg(feature = "alloc")]
63 Self::Rsa(_) => Algorithm::Rsa { hash: None },
64 #[cfg(feature = "ecdsa")]
65 Self::SkEcdsaSha2NistP256(_) => Algorithm::SkEcdsaSha2NistP256,
66 Self::SkEd25519(_) => Algorithm::SkEd25519,
67 }
68 }
69
70 #[cfg(feature = "alloc")]
72 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
73 pub fn dsa(&self) -> Option<&DsaPublicKey> {
74 match self {
75 Self::Dsa(key) => Some(key),
76 _ => None,
77 }
78 }
79
80 #[cfg(feature = "ecdsa")]
82 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
83 pub fn ecdsa(&self) -> Option<&EcdsaPublicKey> {
84 match self {
85 Self::Ecdsa(key) => Some(key),
86 _ => None,
87 }
88 }
89
90 pub fn ed25519(&self) -> Option<&Ed25519PublicKey> {
92 match self {
93 Self::Ed25519(key) => Some(key),
94 #[allow(unreachable_patterns)]
95 _ => None,
96 }
97 }
98
99 #[cfg(feature = "fingerprint")]
103 #[cfg_attr(docsrs, doc(cfg(feature = "fingerprint")))]
104 pub fn fingerprint(&self, hash_alg: HashAlg) -> Fingerprint {
105 Fingerprint::new(hash_alg, self)
106 }
107
108 #[cfg(feature = "alloc")]
110 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
111 pub fn rsa(&self) -> Option<&RsaPublicKey> {
112 match self {
113 Self::Rsa(key) => Some(key),
114 _ => None,
115 }
116 }
117
118 #[cfg(feature = "ecdsa")]
120 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
121 pub fn sk_ecdsa_p256(&self) -> Option<&SkEcdsaSha2NistP256> {
122 match self {
123 Self::SkEcdsaSha2NistP256(sk) => Some(sk),
124 _ => None,
125 }
126 }
127
128 pub fn sk_ed25519(&self) -> Option<&SkEd25519> {
130 match self {
131 Self::SkEd25519(sk) => Some(sk),
132 _ => None,
133 }
134 }
135
136 #[cfg(feature = "alloc")]
138 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
139 pub fn is_dsa(&self) -> bool {
140 matches!(self, Self::Dsa(_))
141 }
142
143 #[cfg(feature = "ecdsa")]
145 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
146 pub fn is_ecdsa(&self) -> bool {
147 matches!(self, Self::Ecdsa(_))
148 }
149
150 pub fn is_ed25519(&self) -> bool {
152 matches!(self, Self::Ed25519(_))
153 }
154
155 #[cfg(feature = "alloc")]
157 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
158 pub fn is_rsa(&self) -> bool {
159 matches!(self, Self::Rsa(_))
160 }
161
162 #[cfg(feature = "ecdsa")]
164 #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
165 pub fn is_sk_ecdsa_p256(&self) -> bool {
166 matches!(self, Self::SkEcdsaSha2NistP256(_))
167 }
168
169 pub fn is_sk_ed25519(&self) -> bool {
171 matches!(self, Self::SkEd25519(_))
172 }
173
174 pub(crate) fn decode_as(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
176 match algorithm {
177 #[cfg(feature = "alloc")]
178 Algorithm::Dsa => DsaPublicKey::decode(reader).map(Self::Dsa),
179 #[cfg(feature = "ecdsa")]
180 Algorithm::Ecdsa { curve } => match EcdsaPublicKey::decode(reader)? {
181 key if key.curve() == curve => Ok(Self::Ecdsa(key)),
182 _ => Err(Error::Algorithm),
183 },
184 Algorithm::Ed25519 => Ed25519PublicKey::decode(reader).map(Self::Ed25519),
185 #[cfg(feature = "alloc")]
186 Algorithm::Rsa { .. } => RsaPublicKey::decode(reader).map(Self::Rsa),
187 #[cfg(feature = "ecdsa")]
188 Algorithm::SkEcdsaSha2NistP256 => {
189 SkEcdsaSha2NistP256::decode(reader).map(Self::SkEcdsaSha2NistP256)
190 }
191 Algorithm::SkEd25519 => SkEd25519::decode(reader).map(Self::SkEd25519),
192 #[allow(unreachable_patterns)]
193 _ => Err(Error::Algorithm),
194 }
195 }
196
197 pub(crate) fn encoded_key_data_len(&self) -> Result<usize> {
200 match self {
201 #[cfg(feature = "alloc")]
202 Self::Dsa(key) => key.encoded_len(),
203 #[cfg(feature = "ecdsa")]
204 Self::Ecdsa(key) => key.encoded_len(),
205 Self::Ed25519(key) => key.encoded_len(),
206 #[cfg(feature = "alloc")]
207 Self::Rsa(key) => key.encoded_len(),
208 #[cfg(feature = "ecdsa")]
209 Self::SkEcdsaSha2NistP256(sk) => sk.encoded_len(),
210 Self::SkEd25519(sk) => sk.encoded_len(),
211 }
212 }
213
214 pub(crate) fn encode_key_data(&self, writer: &mut impl Writer) -> Result<()> {
216 match self {
217 #[cfg(feature = "alloc")]
218 Self::Dsa(key) => key.encode(writer),
219 #[cfg(feature = "ecdsa")]
220 Self::Ecdsa(key) => key.encode(writer),
221 Self::Ed25519(key) => key.encode(writer),
222 #[cfg(feature = "alloc")]
223 Self::Rsa(key) => key.encode(writer),
224 #[cfg(feature = "ecdsa")]
225 Self::SkEcdsaSha2NistP256(sk) => sk.encode(writer),
226 Self::SkEd25519(sk) => sk.encode(writer),
227 }
228 }
229}
230
231impl Decode for KeyData {
232 fn decode(reader: &mut impl Reader) -> Result<Self> {
233 let algorithm = Algorithm::decode(reader)?;
234 Self::decode_as(reader, algorithm)
235 }
236}
237
238impl Encode for KeyData {
239 fn encoded_len(&self) -> Result<usize> {
240 [
241 self.algorithm().encoded_len()?,
242 self.encoded_key_data_len()?,
243 ]
244 .checked_sum()
245 }
246
247 fn encode(&self, writer: &mut impl Writer) -> Result<()> {
248 self.algorithm().encode(writer)?;
249 self.encode_key_data(writer)
250 }
251}
252
253#[cfg(feature = "alloc")]
254#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
255impl From<DsaPublicKey> for KeyData {
256 fn from(public_key: DsaPublicKey) -> KeyData {
257 Self::Dsa(public_key)
258 }
259}
260
261#[cfg(feature = "ecdsa")]
262#[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
263impl From<EcdsaPublicKey> for KeyData {
264 fn from(public_key: EcdsaPublicKey) -> KeyData {
265 Self::Ecdsa(public_key)
266 }
267}
268
269impl From<Ed25519PublicKey> for KeyData {
270 fn from(public_key: Ed25519PublicKey) -> KeyData {
271 Self::Ed25519(public_key)
272 }
273}
274
275#[cfg(feature = "alloc")]
276#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
277impl From<RsaPublicKey> for KeyData {
278 fn from(public_key: RsaPublicKey) -> KeyData {
279 Self::Rsa(public_key)
280 }
281}
282
283#[cfg(feature = "ecdsa")]
284#[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))]
285impl From<SkEcdsaSha2NistP256> for KeyData {
286 fn from(public_key: SkEcdsaSha2NistP256) -> KeyData {
287 Self::SkEcdsaSha2NistP256(public_key)
288 }
289}
290
291impl From<SkEd25519> for KeyData {
292 fn from(public_key: SkEd25519) -> KeyData {
293 Self::SkEd25519(public_key)
294 }
295}