1414#[ cfg( feature = "ecdsa" ) ]
1515use super :: { EcdsaPublicKey , SkEcdsaSha2NistP256 } ;
1616
17+ #[ cfg( feature = "mldsa" ) ]
18+ use super :: MlDsaPublicKey ;
19+
1720/// Public key data.
1821#[ derive( Clone , Debug , Eq , Hash , PartialEq , PartialOrd , Ord ) ]
1922#[ non_exhaustive]
@@ -33,6 +36,10 @@ pub enum KeyData {
3336 #[ cfg( feature = "alloc" ) ]
3437 Rsa ( RsaPublicKey ) ,
3538
39+ /// ML-DSA public key data.
40+ #[ cfg( feature = "mldsa" ) ]
41+ MlDsa ( MlDsaPublicKey ) ,
42+
3643 /// Security Key (FIDO/U2F) using ECDSA/NIST P-256 as specified in [PROTOCOL.u2f].
3744 ///
3845 /// [PROTOCOL.u2f]: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.u2f?annotate=HEAD
@@ -69,6 +76,8 @@ impl KeyData {
6976 Self :: Ed25519 ( _) => Algorithm :: Ed25519 ,
7077 #[ cfg( feature = "alloc" ) ]
7178 Self :: Rsa ( _) => Algorithm :: Rsa { hash : None } ,
79+ #[ cfg( feature = "mldsa" ) ]
80+ Self :: MlDsa ( key) => key. algorithm ( ) ,
7281 #[ cfg( feature = "ecdsa" ) ]
7382 Self :: SkEcdsaSha2NistP256 ( _) => Algorithm :: SkEcdsaSha2NistP256 ,
7483 Self :: SkEd25519 ( _) => Algorithm :: SkEd25519 ,
@@ -127,6 +136,16 @@ impl KeyData {
127136 }
128137 }
129138
139+ /// Get ML-DSA public key if this key is the correct type.
140+ #[ cfg( feature = "mldsa" ) ]
141+ #[ must_use]
142+ pub fn mldsa ( & self ) -> Option < & MlDsaPublicKey > {
143+ match self {
144+ Self :: MlDsa ( key) => Some ( key) ,
145+ _ => None ,
146+ }
147+ }
148+
130149 /// Get FIDO/U2F ECDSA/NIST P-256 public key if this key is the correct type.
131150 #[ cfg( feature = "ecdsa" ) ]
132151 #[ must_use]
@@ -203,6 +222,13 @@ impl KeyData {
203222 matches ! ( self , Self :: Rsa ( _) )
204223 }
205224
225+ /// Is this key an ML-DSA key?
226+ #[ cfg( feature = "mldsa" ) ]
227+ #[ must_use]
228+ pub fn is_mldsa ( & self ) -> bool {
229+ matches ! ( self , Self :: MlDsa ( _) )
230+ }
231+
206232 /// Is this key a FIDO/U2F ECDSA/NIST P-256 key?
207233 #[ cfg( feature = "ecdsa" ) ]
208234 #[ must_use]
@@ -248,6 +274,10 @@ impl KeyData {
248274 Algorithm :: Ed25519 => Ed25519PublicKey :: decode ( reader) . map ( Self :: Ed25519 ) ,
249275 #[ cfg( feature = "alloc" ) ]
250276 Algorithm :: Rsa { .. } => RsaPublicKey :: decode ( reader) . map ( Self :: Rsa ) ,
277+ #[ cfg( feature = "mldsa" ) ]
278+ Algorithm :: MlDsa { params } => {
279+ MlDsaPublicKey :: decode_as ( reader, params) . map ( Self :: MlDsa )
280+ }
251281 #[ cfg( feature = "ecdsa" ) ]
252282 Algorithm :: SkEcdsaSha2NistP256 => {
253283 SkEcdsaSha2NistP256 :: decode ( reader) . map ( Self :: SkEcdsaSha2NistP256 )
@@ -280,6 +310,8 @@ impl KeyData {
280310 Self :: Ed25519 ( key) => key. encoded_len ( ) ,
281311 #[ cfg( feature = "alloc" ) ]
282312 Self :: Rsa ( key) => key. encoded_len ( ) ,
313+ #[ cfg( feature = "mldsa" ) ]
314+ Self :: MlDsa ( key) => key. encoded_len ( ) ,
283315 #[ cfg( feature = "ecdsa" ) ]
284316 Self :: SkEcdsaSha2NistP256 ( sk) => sk. encoded_len ( ) ,
285317 Self :: SkEd25519 ( sk) => sk. encoded_len ( ) ,
@@ -300,6 +332,8 @@ impl KeyData {
300332 Self :: Ed25519 ( key) => key. encode ( writer) ,
301333 #[ cfg( feature = "alloc" ) ]
302334 Self :: Rsa ( key) => key. encode ( writer) ,
335+ #[ cfg( feature = "mldsa" ) ]
336+ Self :: MlDsa ( key) => key. encode ( writer) ,
303337 #[ cfg( feature = "ecdsa" ) ]
304338 Self :: SkEcdsaSha2NistP256 ( sk) => sk. encode ( writer) ,
305339 Self :: SkEd25519 ( sk) => sk. encode ( writer) ,
@@ -380,6 +414,13 @@ impl From<RsaPublicKey> for KeyData {
380414 }
381415}
382416
417+ #[ cfg( feature = "mldsa" ) ]
418+ impl From < MlDsaPublicKey > for KeyData {
419+ fn from ( public_key : MlDsaPublicKey ) -> KeyData {
420+ Self :: MlDsa ( public_key)
421+ }
422+ }
423+
383424#[ cfg( feature = "ecdsa" ) ]
384425impl From < SkEcdsaSha2NistP256 > for KeyData {
385426 fn from ( public_key : SkEcdsaSha2NistP256 ) -> KeyData {
0 commit comments