@@ -4,7 +4,10 @@ use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
4
4
use core:: marker:: PhantomData ;
5
5
use digest:: Digest ;
6
6
use rand_core:: { CryptoRng , RngCore } ;
7
- use signature:: { RandomizedSigner , Signature as SignSignature , Signer , Verifier } ;
7
+ use signature:: {
8
+ DigestSigner , DigestVerifier , RandomizedDigestSigner , RandomizedSigner ,
9
+ Signature as SignSignature , Signer , Verifier ,
10
+ } ;
8
11
use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
9
12
use zeroize:: Zeroizing ;
10
13
@@ -356,6 +359,37 @@ where
356
359
}
357
360
}
358
361
362
+ impl < D > DigestSigner < D , Signature > for SigningKey < D >
363
+ where
364
+ D : Digest ,
365
+ {
366
+ fn try_sign_digest ( & self , digest : D ) -> signature:: Result < Signature > {
367
+ sign :: < DummyRng , _ > ( None , & self . inner , self . hash . as_ref ( ) , & digest. finalize ( ) )
368
+ . map ( |v| v. into ( ) )
369
+ . map_err ( |e| e. into ( ) )
370
+ }
371
+ }
372
+
373
+ impl < D > RandomizedDigestSigner < D , Signature > for SigningKey < D >
374
+ where
375
+ D : Digest ,
376
+ {
377
+ fn try_sign_digest_with_rng (
378
+ & self ,
379
+ mut rng : impl CryptoRng + RngCore ,
380
+ digest : D ,
381
+ ) -> signature:: Result < Signature > {
382
+ sign (
383
+ Some ( & mut rng) ,
384
+ & self . inner ,
385
+ self . hash . as_ref ( ) ,
386
+ & digest. finalize ( ) ,
387
+ )
388
+ . map ( |v| v. into ( ) )
389
+ . map_err ( |e| e. into ( ) )
390
+ }
391
+ }
392
+
359
393
pub struct VerifyingKey < D >
360
394
where
361
395
D : Digest ,
@@ -427,6 +461,21 @@ where
427
461
}
428
462
}
429
463
464
+ impl < D > DigestVerifier < D , Signature > for VerifyingKey < D >
465
+ where
466
+ D : Digest ,
467
+ {
468
+ fn verify_digest ( & self , digest : D , signature : & Signature ) -> signature:: Result < ( ) > {
469
+ verify (
470
+ & self . inner ,
471
+ self . hash . as_ref ( ) ,
472
+ & digest. finalize ( ) ,
473
+ signature. as_ref ( ) ,
474
+ )
475
+ . map_err ( |e| e. into ( ) )
476
+ }
477
+ }
478
+
430
479
#[ cfg( test) ]
431
480
mod tests {
432
481
use super :: * ;
@@ -588,6 +637,36 @@ mod tests {
588
637
}
589
638
}
590
639
640
+ #[ test]
641
+ fn test_sign_pkcs1v15_digest_signer ( ) {
642
+ let priv_key = get_private_key ( ) ;
643
+
644
+ let tests = [ (
645
+ "Test.\n " ,
646
+ hex ! (
647
+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
648
+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
649
+ ) ,
650
+ ) ] ;
651
+
652
+ let signing_key = SigningKey :: new_with_hash ( priv_key, Hash :: SHA1 ) ;
653
+
654
+ for ( text, expected) in & tests {
655
+ let mut digest = Sha1 :: new ( ) ;
656
+ digest. update ( text. as_bytes ( ) ) ;
657
+ let out = signing_key. sign_digest ( digest) ;
658
+ assert_ne ! ( out. as_ref( ) , text. as_bytes( ) ) ;
659
+ assert_ne ! ( out. as_ref( ) , & Sha1 :: digest( text. as_bytes( ) ) . to_vec( ) ) ;
660
+ assert_eq ! ( out. as_ref( ) , expected) ;
661
+
662
+ let mut rng = ChaCha8Rng :: from_seed ( [ 42 ; 32 ] ) ;
663
+ let mut digest = Sha1 :: new ( ) ;
664
+ digest. update ( text. as_bytes ( ) ) ;
665
+ let out2 = signing_key. sign_digest_with_rng ( & mut rng, digest) ;
666
+ assert_eq ! ( out2. as_ref( ) , expected) ;
667
+ }
668
+ }
669
+
591
670
#[ test]
592
671
fn test_verify_pkcs1v15 ( ) {
593
672
let priv_key = get_private_key ( ) ;
@@ -668,6 +747,44 @@ mod tests {
668
747
}
669
748
}
670
749
750
+ #[ test]
751
+ fn test_verify_pkcs1v15_digest_signer ( ) {
752
+ let priv_key = get_private_key ( ) ;
753
+
754
+ let tests = [
755
+ (
756
+ "Test.\n " ,
757
+ hex ! (
758
+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
759
+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
760
+ ) ,
761
+ true ,
762
+ ) ,
763
+ (
764
+ "Test.\n " ,
765
+ hex ! (
766
+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
767
+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
768
+ ) ,
769
+ false ,
770
+ ) ,
771
+ ] ;
772
+ let pub_key: RsaPublicKey = priv_key. into ( ) ;
773
+ let verifying_key = VerifyingKey :: new_with_hash ( pub_key, Hash :: SHA1 ) ;
774
+
775
+ for ( text, sig, expected) in & tests {
776
+ let mut digest = Sha1 :: new ( ) ;
777
+ digest. update ( text. as_bytes ( ) ) ;
778
+ let result = verifying_key. verify_digest ( digest, & Signature :: from_bytes ( sig) . unwrap ( ) ) ;
779
+ match expected {
780
+ true => result. expect ( "failed to verify" ) ,
781
+ false => {
782
+ result. expect_err ( "expected verifying error" ) ;
783
+ ( )
784
+ }
785
+ }
786
+ }
787
+ }
671
788
#[ test]
672
789
fn test_unpadded_signature ( ) {
673
790
let msg = b"Thu Dec 19 18:06:16 EST 2013\n " ;
0 commit comments