11use alloc:: vec;
22use alloc:: vec:: Vec ;
3+ use core:: fmt:: { Debug , Display , Formatter , LowerHex , UpperHex } ;
34use rand_core:: { CryptoRng , RngCore } ;
5+ use signature:: { RandomizedSigner , Signature as SignSignature , Signer , Verifier } ;
46use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
57use zeroize:: Zeroizing ;
68
9+ use crate :: dummy_rng:: DummyRng ;
710use crate :: errors:: { Error , Result } ;
811use crate :: hash:: Hash ;
912use crate :: key:: { self , PrivateKey , PublicKey } ;
13+ use crate :: { RsaPrivateKey , RsaPublicKey } ;
14+
15+ #[ derive( Clone ) ]
16+ pub struct Signature {
17+ bytes : Vec < u8 > ,
18+ }
19+
20+ impl signature:: Signature for Signature {
21+ fn from_bytes ( bytes : & [ u8 ] ) -> signature:: Result < Self > {
22+ Ok ( Signature {
23+ bytes : bytes. into ( ) ,
24+ } )
25+ }
26+
27+ fn as_bytes ( & self ) -> & [ u8 ] {
28+ & self . bytes . as_slice ( )
29+ }
30+ }
31+
32+ impl From < Vec < u8 > > for Signature {
33+ fn from ( bytes : Vec < u8 > ) -> Self {
34+ Self { bytes }
35+ }
36+ }
37+
38+ impl PartialEq for Signature {
39+ fn eq ( & self , other : & Self ) -> bool {
40+ self . as_bytes ( ) == other. as_bytes ( )
41+ }
42+ }
43+
44+ impl Eq for Signature { }
45+
46+ impl Debug for Signature {
47+ fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> core:: result:: Result < ( ) , core:: fmt:: Error > {
48+ fmt. debug_list ( ) . entries ( self . as_bytes ( ) . iter ( ) ) . finish ( )
49+ }
50+ }
51+
52+ impl AsRef < [ u8 ] > for Signature {
53+ fn as_ref ( & self ) -> & [ u8 ] {
54+ & self . as_bytes ( )
55+ }
56+ }
57+
58+ impl LowerHex for Signature {
59+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
60+ for byte in self . as_bytes ( ) {
61+ write ! ( f, "{:02x}" , byte) ?;
62+ }
63+ Ok ( ( ) )
64+ }
65+ }
66+
67+ impl UpperHex for Signature {
68+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
69+ for byte in self . as_bytes ( ) {
70+ write ! ( f, "{:02X}" , byte) ?;
71+ }
72+ Ok ( ( ) )
73+ }
74+ }
75+
76+ impl Display for Signature {
77+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
78+ write ! ( f, "{:X}" , self )
79+ }
80+ }
1081
1182// Encrypts the given message with RSA and the padding
1283// scheme from PKCS#1 v1.5. The message must be no longer than the
1384// length of the public modulus minus 11 bytes.
1485#[ inline]
15- pub fn encrypt < R : RngCore + CryptoRng , PK : PublicKey > (
86+ pub ( crate ) fn encrypt < R : RngCore + CryptoRng , PK : PublicKey > (
1687 rng : & mut R ,
1788 pub_key : & PK ,
1889 msg : & [ u8 ] ,
@@ -43,7 +114,7 @@ pub fn encrypt<R: RngCore + CryptoRng, PK: PublicKey>(
43114// forge signatures as if they had the private key. See
44115// `decrypt_session_key` for a way of solving this problem.
45116#[ inline]
46- pub fn decrypt < R : RngCore + CryptoRng , SK : PrivateKey > (
117+ pub ( crate ) fn decrypt < R : RngCore + CryptoRng , SK : PrivateKey > (
47118 rng : Option < & mut R > ,
48119 priv_key : & SK ,
49120 ciphertext : & [ u8 ] ,
@@ -72,7 +143,7 @@ pub fn decrypt<R: RngCore + CryptoRng, SK: PrivateKey>(
72143// messages to signatures and identify the signed messages. As ever,
73144// signatures provide authenticity, not confidentiality.
74145#[ inline]
75- pub fn sign < R : RngCore + CryptoRng , SK : PrivateKey > (
146+ pub ( crate ) fn sign < R : RngCore + CryptoRng , SK : PrivateKey > (
76147 rng : Option < & mut R > ,
77148 priv_key : & SK ,
78149 hash : Option < & Hash > ,
@@ -99,7 +170,7 @@ pub fn sign<R: RngCore + CryptoRng, SK: PrivateKey>(
99170
100171/// Verifies an RSA PKCS#1 v1.5 signature.
101172#[ inline]
102- pub fn verify < PK : PublicKey > (
173+ pub ( crate ) fn verify < PK : PublicKey > (
103174 pub_key : & PK ,
104175 hash : Option < & Hash > ,
105176 hashed : & [ u8 ] ,
@@ -214,6 +285,100 @@ fn non_zero_random_bytes<R: RngCore + CryptoRng>(rng: &mut R, data: &mut [u8]) {
214285 }
215286}
216287
288+ pub struct SigningKey {
289+ inner : RsaPrivateKey ,
290+ hash : Option < Hash > ,
291+ }
292+
293+ impl SigningKey {
294+ pub ( crate ) fn key ( & self ) -> & RsaPrivateKey {
295+ & self . inner
296+ }
297+
298+ pub ( crate ) fn hash ( & self ) -> Option < Hash > {
299+ self . hash
300+ }
301+
302+ pub fn new ( key : RsaPrivateKey ) -> Self {
303+ Self {
304+ inner : key,
305+ hash : None ,
306+ }
307+ }
308+
309+ pub fn new_with_hash ( key : RsaPrivateKey , hash : Hash ) -> Self {
310+ Self {
311+ inner : key,
312+ hash : Some ( hash) ,
313+ }
314+ }
315+ }
316+
317+ impl Signer < Signature > for SigningKey {
318+ fn try_sign ( & self , digest : & [ u8 ] ) -> signature:: Result < Signature > {
319+ sign :: < DummyRng , _ > ( None , & self . inner , self . hash . as_ref ( ) , digest)
320+ . map ( |v| v. into ( ) )
321+ . map_err ( |e| e. into ( ) )
322+ }
323+ }
324+
325+ impl RandomizedSigner < Signature > for SigningKey {
326+ fn try_sign_with_rng (
327+ & self ,
328+ mut rng : impl CryptoRng + RngCore ,
329+ digest : & [ u8 ] ,
330+ ) -> signature:: Result < Signature > {
331+ sign ( Some ( & mut rng) , & self . inner , self . hash . as_ref ( ) , digest)
332+ . map ( |v| v. into ( ) )
333+ . map_err ( |e| e. into ( ) )
334+ }
335+ }
336+
337+ pub struct VerifyingKey {
338+ inner : RsaPublicKey ,
339+ hash : Option < Hash > ,
340+ }
341+
342+ impl VerifyingKey {
343+ pub fn new ( key : RsaPublicKey ) -> Self {
344+ Self {
345+ inner : key,
346+ hash : None ,
347+ }
348+ }
349+
350+ pub fn new_with_hash ( key : RsaPublicKey , hash : Hash ) -> Self {
351+ Self {
352+ inner : key,
353+ hash : Some ( hash) ,
354+ }
355+ }
356+ }
357+
358+ impl From < SigningKey > for VerifyingKey {
359+ fn from ( key : SigningKey ) -> Self {
360+ Self {
361+ inner : key. key ( ) . into ( ) ,
362+ hash : key. hash ( ) ,
363+ }
364+ }
365+ }
366+
367+ impl From < & SigningKey > for VerifyingKey {
368+ fn from ( key : & SigningKey ) -> Self {
369+ Self {
370+ inner : key. key ( ) . into ( ) ,
371+ hash : key. hash ( ) ,
372+ }
373+ }
374+ }
375+
376+ impl Verifier < Signature > for VerifyingKey {
377+ fn verify ( & self , msg : & [ u8 ] , signature : & Signature ) -> signature:: Result < ( ) > {
378+ verify ( & self . inner , self . hash . as_ref ( ) , msg, signature. as_ref ( ) ) . map_err ( |e| e. into ( ) )
379+ }
380+ }
381+
217382#[ cfg( test) ]
218383mod tests {
219384 use super :: * ;
@@ -224,6 +389,7 @@ mod tests {
224389 use num_traits:: Num ;
225390 use rand_chacha:: { rand_core:: SeedableRng , ChaCha8Rng } ;
226391 use sha1:: { Digest , Sha1 } ;
392+ use signature:: { RandomizedSigner , Signature , Signer , Verifier } ;
227393
228394 use crate :: { Hash , PaddingScheme , PublicKey , PublicKeyParts , RsaPrivateKey , RsaPublicKey } ;
229395
@@ -348,6 +514,33 @@ mod tests {
348514 }
349515 }
350516
517+ #[ test]
518+ fn test_sign_pkcs1v15_signer ( ) {
519+ let priv_key = get_private_key ( ) ;
520+
521+ let tests = [ (
522+ "Test.\n " ,
523+ hex ! (
524+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
525+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
526+ ) ,
527+ ) ] ;
528+
529+ let signing_key = SigningKey :: new_with_hash ( priv_key, Hash :: SHA1 ) ;
530+
531+ for ( text, expected) in & tests {
532+ let digest = Sha1 :: digest ( text. as_bytes ( ) ) . to_vec ( ) ;
533+
534+ let out = signing_key. sign ( & digest) ;
535+ assert_ne ! ( out. as_ref( ) , digest) ;
536+ assert_eq ! ( out. as_ref( ) , expected) ;
537+
538+ let mut rng = ChaCha8Rng :: from_seed ( [ 42 ; 32 ] ) ;
539+ let out2 = signing_key. sign_with_rng ( & mut rng, & digest) ;
540+ assert_eq ! ( out2. as_ref( ) , expected) ;
541+ }
542+ }
543+
351544 #[ test]
352545 fn test_verify_pkcs1v15 ( ) {
353546 let priv_key = get_private_key ( ) ;
@@ -390,6 +583,45 @@ mod tests {
390583 }
391584 }
392585
586+ #[ test]
587+ fn test_verify_pkcs1v15_signer ( ) {
588+ let priv_key = get_private_key ( ) ;
589+
590+ let tests = [
591+ (
592+ "Test.\n " ,
593+ hex ! (
594+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
595+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
596+ ) ,
597+ true ,
598+ ) ,
599+ (
600+ "Test.\n " ,
601+ hex ! (
602+ "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
603+ "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
604+ ) ,
605+ false ,
606+ ) ,
607+ ] ;
608+ let pub_key: RsaPublicKey = priv_key. into ( ) ;
609+ let verifying_key = VerifyingKey :: new_with_hash ( pub_key, Hash :: SHA1 ) ;
610+
611+ for ( text, sig, expected) in & tests {
612+ let digest = Sha1 :: digest ( text. as_bytes ( ) ) . to_vec ( ) ;
613+
614+ let result = verifying_key. verify ( & digest, & Signature :: from_bytes ( sig) . unwrap ( ) ) ;
615+ match expected {
616+ true => result. expect ( "failed to verify" ) ,
617+ false => {
618+ result. expect_err ( "expected verifying error" ) ;
619+ ( )
620+ }
621+ }
622+ }
623+ }
624+
393625 #[ test]
394626 fn test_unpadded_signature ( ) {
395627 let msg = b"Thu Dec 19 18:06:16 EST 2013\n " ;
@@ -406,4 +638,26 @@ mod tests {
406638 . verify ( PaddingScheme :: new_pkcs1v15_sign ( None ) , msg, & sig)
407639 . expect ( "failed to verify" ) ;
408640 }
641+
642+ #[ test]
643+ fn test_unpadded_signature_signer ( ) {
644+ let msg = b"Thu Dec 19 18:06:16 EST 2013\n " ;
645+ let expected_sig = Base64 :: decode_vec ( "pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==" ) . unwrap ( ) ;
646+ let priv_key = get_private_key ( ) ;
647+
648+ let signing_key = SigningKey :: new ( priv_key) ;
649+ let sig = signing_key. sign ( msg) ;
650+ assert_eq ! ( sig. as_ref( ) , expected_sig) ;
651+
652+ let verifying_key: VerifyingKey = ( & signing_key) . into ( ) ;
653+ verifying_key
654+ . verify ( msg, & Signature :: from_bytes ( & expected_sig) . unwrap ( ) )
655+ . expect ( "failed to verify" ) ;
656+
657+ let mut rng = ChaCha8Rng :: from_seed ( [ 42 ; 32 ] ) ;
658+ let sig = signing_key. sign_with_rng ( & mut rng, msg) ;
659+ assert_eq ! ( sig. as_ref( ) , expected_sig) ;
660+
661+ verifying_key. verify ( msg, & sig) . expect ( "failed to verify" ) ;
662+ }
409663}
0 commit comments