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