@@ -261,6 +261,60 @@ pub trait UnsignedMessage {
261261 fn register_header_contents ( & mut self , signature_input : String , signature_header : String ) ;
262262}
263263
264+ /// Trait that provides interface to generate signatures given a message and an algorithm.
265+ /// This is implemented for `Vec<u8>` and friends as a batteries-included way to generate
266+ /// signatures from raw key material, but can be implemented for any type of client-controlled
267+ /// signer as well (yubikey, cloud kms, web3 wallet, etc).
268+ pub trait GenerateSignature {
269+ /// Generate signature given the algorithm and the message to sign.
270+ fn generate_signature (
271+ & self ,
272+ algorithm : Algorithm ,
273+ msg : & [ u8 ] ,
274+ ) -> Result < Vec < u8 > , ImplementationError > ;
275+ }
276+
277+ impl GenerateSignature for [ u8 ] {
278+ fn generate_signature (
279+ & self ,
280+ algorithm : Algorithm ,
281+ msg : & [ u8 ] ,
282+ ) -> Result < Vec < u8 > , ImplementationError > {
283+ let signature = match algorithm {
284+ Algorithm :: Ed25519 => {
285+ use ed25519_dalek:: { Signer , SigningKey } ;
286+ let signing_key_dalek = SigningKey :: try_from ( self )
287+ . map_err ( |_| ImplementationError :: InvalidKeyLength ) ?;
288+
289+ signing_key_dalek. sign ( msg) . to_vec ( )
290+ }
291+ other => return Err ( ImplementationError :: UnsupportedAlgorithm ( other) ) ,
292+ } ;
293+
294+ Ok ( signature)
295+ }
296+ }
297+
298+ impl GenerateSignature for Vec < u8 > {
299+ fn generate_signature (
300+ & self ,
301+ algorithm : Algorithm ,
302+ msg : & [ u8 ] ,
303+ ) -> Result < Vec < u8 > , ImplementationError > {
304+ self . as_slice ( ) . generate_signature ( algorithm, msg)
305+ }
306+ }
307+
308+ impl GenerateSignature for [ u8 ; 32 ] {
309+ fn generate_signature (
310+ & self ,
311+ algorithm : Algorithm ,
312+ msg : & [ u8 ] ,
313+ ) -> Result < Vec < u8 > , ImplementationError > {
314+ self . as_slice ( ) . generate_signature ( algorithm, msg)
315+ }
316+ }
317+
264318/// A struct that implements signing. The struct fields here are serialized into the `Signature-Input`
265319/// header.
266320pub struct MessageSigner {
@@ -273,7 +327,7 @@ pub struct MessageSigner {
273327}
274328
275329impl MessageSigner {
276- /// Sign the provided method with `signing_key `, setting an expiration value of
330+ /// Sign the provided method with `signer `, setting an expiration value of
277331 /// length `expires` from now (the time of signing).
278332 ///
279333 /// # Errors
@@ -285,7 +339,7 @@ impl MessageSigner {
285339 message : & mut impl UnsignedMessage ,
286340 expires : Duration ,
287341 algorithm : Algorithm ,
288- signing_key : & Vec < u8 > ,
342+ signer : & ( impl GenerateSignature + ? Sized ) ,
289343 ) -> Result < ( ) , ImplementationError > {
290344 let components_to_cover = message. fetch_components_to_cover ( ) ;
291345 let mut sfv_parameters = sfv:: Parameters :: new ( ) ;
@@ -361,22 +415,13 @@ impl MessageSigner {
361415 }
362416 . into_ascii ( ) ?;
363417
364- let signature = match algorithm {
365- Algorithm :: Ed25519 => {
366- use ed25519_dalek:: { Signer , SigningKey } ;
367- let signing_key_dalek = SigningKey :: try_from ( signing_key. as_slice ( ) )
368- . map_err ( |_| ImplementationError :: InvalidKeyLength ) ?;
369-
370- sfv:: Item {
371- bare_item : sfv:: BareItem :: ByteSequence (
372- signing_key_dalek. sign ( signature_base. as_bytes ( ) ) . to_vec ( ) ,
373- ) ,
374- params : sfv:: Parameters :: new ( ) ,
375- }
376- . serialize_value ( )
377- }
378- other => return Err ( ImplementationError :: UnsupportedAlgorithm ( other) ) ,
379- } ;
418+ let signature = sfv:: Item {
419+ bare_item : sfv:: BareItem :: ByteSequence (
420+ signer. generate_signature ( algorithm, signature_base. as_bytes ( ) ) ?,
421+ ) ,
422+ params : sfv:: Parameters :: new ( ) ,
423+ }
424+ . serialize_value ( ) ;
380425
381426 message. register_header_contents ( signature_params_content, signature) ;
382427
@@ -670,7 +715,7 @@ mod tests {
670715 & mut test,
671716 Duration :: seconds( 10 ) ,
672717 Algorithm :: Ed25519 ,
673- & private_key. to_vec ( )
718+ & private_key
674719 )
675720 . is_ok( )
676721 ) ;
0 commit comments