@@ -6,7 +6,7 @@ use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
66
77#[ cfg( feature = "alloc" ) ]
88use {
9- super :: { DsaPublicKey , OpaquePublicKey , RsaPublicKey } ,
9+ super :: { DsaPublicKey , MlDsaPublicKey , OpaquePublicKey , RsaPublicKey } ,
1010 crate :: Certificate ,
1111 alloc:: boxed:: Box ,
1212} ;
@@ -33,6 +33,10 @@ pub enum KeyData {
3333 #[ cfg( feature = "alloc" ) ]
3434 Rsa ( RsaPublicKey ) ,
3535
36+ /// ML-DSA public key data.
37+ #[ cfg( feature = "alloc" ) ]
38+ MlDsa ( MlDsaPublicKey ) ,
39+
3640 /// Security Key (FIDO/U2F) using ECDSA/NIST P-256 as specified in [PROTOCOL.u2f].
3741 ///
3842 /// [PROTOCOL.u2f]: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.u2f?annotate=HEAD
@@ -69,6 +73,8 @@ impl KeyData {
6973 Self :: Ed25519 ( _) => Algorithm :: Ed25519 ,
7074 #[ cfg( feature = "alloc" ) ]
7175 Self :: Rsa ( _) => Algorithm :: Rsa { hash : None } ,
76+ #[ cfg( feature = "alloc" ) ]
77+ Self :: MlDsa ( key) => key. algorithm ( ) ,
7278 #[ cfg( feature = "ecdsa" ) ]
7379 Self :: SkEcdsaSha2NistP256 ( _) => Algorithm :: SkEcdsaSha2NistP256 ,
7480 Self :: SkEd25519 ( _) => Algorithm :: SkEd25519 ,
@@ -127,6 +133,16 @@ impl KeyData {
127133 }
128134 }
129135
136+ /// Get ML-DSA public key if this key is the correct type.
137+ #[ cfg( feature = "alloc" ) ]
138+ #[ must_use]
139+ pub fn mldsa ( & self ) -> Option < & MlDsaPublicKey > {
140+ match self {
141+ Self :: MlDsa ( key) => Some ( key) ,
142+ _ => None ,
143+ }
144+ }
145+
130146 /// Get FIDO/U2F ECDSA/NIST P-256 public key if this key is the correct type.
131147 #[ cfg( feature = "ecdsa" ) ]
132148 #[ must_use]
@@ -203,6 +219,13 @@ impl KeyData {
203219 matches ! ( self , Self :: Rsa ( _) )
204220 }
205221
222+ /// Is this key an ML-DSA key?
223+ #[ cfg( feature = "alloc" ) ]
224+ #[ must_use]
225+ pub fn is_mldsa ( & self ) -> bool {
226+ matches ! ( self , Self :: MlDsa ( _) )
227+ }
228+
206229 /// Is this key a FIDO/U2F ECDSA/NIST P-256 key?
207230 #[ cfg( feature = "ecdsa" ) ]
208231 #[ must_use]
@@ -248,6 +271,10 @@ impl KeyData {
248271 Algorithm :: Ed25519 => Ed25519PublicKey :: decode ( reader) . map ( Self :: Ed25519 ) ,
249272 #[ cfg( feature = "alloc" ) ]
250273 Algorithm :: Rsa { .. } => RsaPublicKey :: decode ( reader) . map ( Self :: Rsa ) ,
274+ #[ cfg( feature = "alloc" ) ]
275+ Algorithm :: MlDsa { params } => {
276+ MlDsaPublicKey :: decode_as ( reader, params) . map ( Self :: MlDsa )
277+ }
251278 #[ cfg( feature = "ecdsa" ) ]
252279 Algorithm :: SkEcdsaSha2NistP256 => {
253280 SkEcdsaSha2NistP256 :: decode ( reader) . map ( Self :: SkEcdsaSha2NistP256 )
@@ -280,6 +307,8 @@ impl KeyData {
280307 Self :: Ed25519 ( key) => key. encoded_len ( ) ,
281308 #[ cfg( feature = "alloc" ) ]
282309 Self :: Rsa ( key) => key. encoded_len ( ) ,
310+ #[ cfg( feature = "alloc" ) ]
311+ Self :: MlDsa ( key) => key. encoded_len ( ) ,
283312 #[ cfg( feature = "ecdsa" ) ]
284313 Self :: SkEcdsaSha2NistP256 ( sk) => sk. encoded_len ( ) ,
285314 Self :: SkEd25519 ( sk) => sk. encoded_len ( ) ,
@@ -300,6 +329,8 @@ impl KeyData {
300329 Self :: Ed25519 ( key) => key. encode ( writer) ,
301330 #[ cfg( feature = "alloc" ) ]
302331 Self :: Rsa ( key) => key. encode ( writer) ,
332+ #[ cfg( feature = "alloc" ) ]
333+ Self :: MlDsa ( key) => key. encode ( writer) ,
303334 #[ cfg( feature = "ecdsa" ) ]
304335 Self :: SkEcdsaSha2NistP256 ( sk) => sk. encode ( writer) ,
305336 Self :: SkEd25519 ( sk) => sk. encode ( writer) ,
@@ -380,6 +411,13 @@ impl From<RsaPublicKey> for KeyData {
380411 }
381412}
382413
414+ #[ cfg( feature = "alloc" ) ]
415+ impl From < MlDsaPublicKey > for KeyData {
416+ fn from ( public_key : MlDsaPublicKey ) -> KeyData {
417+ Self :: MlDsa ( public_key)
418+ }
419+ }
420+
383421#[ cfg( feature = "ecdsa" ) ]
384422impl From < SkEcdsaSha2NistP256 > for KeyData {
385423 fn from ( public_key : SkEcdsaSha2NistP256 ) -> KeyData {
0 commit comments