1use alloc::vec::Vec;
10use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
11use core::marker::PhantomData;
12use core::ops::Deref;
13use digest::Digest;
14use pkcs8::{AssociatedOid, Document, EncodePrivateKey, EncodePublicKey, SecretDocument};
15use rand_core::{CryptoRng, RngCore};
16#[cfg(feature = "hazmat")]
17use signature::hazmat::{PrehashSigner, PrehashVerifier};
18use signature::{
19 DigestSigner, DigestVerifier, RandomizedDigestSigner, RandomizedSigner,
20 Signature as SignSignature, Signer, Verifier,
21};
22use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
23use zeroize::Zeroizing;
24
25use crate::dummy_rng::DummyRng;
26use crate::errors::{Error, Result};
27use crate::key::{self, PrivateKey, PublicKey};
28use crate::{RsaPrivateKey, RsaPublicKey};
29
30#[derive(Clone)]
34pub struct Signature {
35 bytes: Vec<u8>,
36}
37
38impl signature::Signature for Signature {
39 fn from_bytes(bytes: &[u8]) -> signature::Result<Self> {
40 Ok(Signature {
41 bytes: bytes.into(),
42 })
43 }
44
45 fn as_bytes(&self) -> &[u8] {
46 self.bytes.as_slice()
47 }
48}
49
50impl From<Vec<u8>> for Signature {
51 fn from(bytes: Vec<u8>) -> Self {
52 Self { bytes }
53 }
54}
55
56impl Deref for Signature {
57 type Target = [u8];
58
59 fn deref(&self) -> &Self::Target {
60 self.as_bytes()
61 }
62}
63
64impl PartialEq for Signature {
65 fn eq(&self, other: &Self) -> bool {
66 self.as_bytes() == other.as_bytes()
67 }
68}
69
70impl Eq for Signature {}
71
72impl Debug for Signature {
73 fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
74 fmt.debug_list().entries(self.as_bytes().iter()).finish()
75 }
76}
77
78impl AsRef<[u8]> for Signature {
79 fn as_ref(&self) -> &[u8] {
80 self.as_bytes()
81 }
82}
83
84impl LowerHex for Signature {
85 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
86 for byte in self.as_bytes() {
87 write!(f, "{:02x}", byte)?;
88 }
89 Ok(())
90 }
91}
92
93impl UpperHex for Signature {
94 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
95 for byte in self.as_bytes() {
96 write!(f, "{:02X}", byte)?;
97 }
98 Ok(())
99 }
100}
101
102impl Display for Signature {
103 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
104 write!(f, "{:X}", self)
105 }
106}
107
108#[inline]
112pub(crate) fn encrypt<R: RngCore + CryptoRng, PK: PublicKey>(
113 rng: &mut R,
114 pub_key: &PK,
115 msg: &[u8],
116) -> Result<Vec<u8>> {
117 key::check_public(pub_key)?;
118
119 let k = pub_key.size();
120 if msg.len() > k - 11 {
121 return Err(Error::MessageTooLong);
122 }
123
124 let mut em = Zeroizing::new(vec![0u8; k]);
126 em[1] = 2;
127 non_zero_random_bytes(rng, &mut em[2..k - msg.len() - 1]);
128 em[k - msg.len() - 1] = 0;
129 em[k - msg.len()..].copy_from_slice(msg);
130
131 pub_key.raw_encryption_primitive(&em, pub_key.size())
132}
133
134#[inline]
144pub(crate) fn decrypt<R: RngCore + CryptoRng, SK: PrivateKey>(
145 rng: Option<&mut R>,
146 priv_key: &SK,
147 ciphertext: &[u8],
148) -> Result<Vec<u8>> {
149 key::check_public(priv_key)?;
150
151 let (valid, out, index) = decrypt_inner(rng, priv_key, ciphertext)?;
152 if valid == 0 {
153 return Err(Error::Decryption);
154 }
155
156 Ok(out[index as usize..].to_vec())
157}
158
159#[inline]
173pub(crate) fn sign<R: RngCore + CryptoRng, SK: PrivateKey>(
174 rng: Option<&mut R>,
175 priv_key: &SK,
176 prefix: &[u8],
177 hashed: &[u8],
178) -> Result<Vec<u8>> {
179 let hash_len = hashed.len();
180 let t_len = prefix.len() + hashed.len();
181 let k = priv_key.size();
182 if k < t_len + 11 {
183 return Err(Error::MessageTooLong);
184 }
185
186 let mut em = vec![0xff; k];
188 em[0] = 0;
189 em[1] = 1;
190 em[k - t_len - 1] = 0;
191 em[k - t_len..k - hash_len].copy_from_slice(prefix);
192 em[k - hash_len..k].copy_from_slice(hashed);
193
194 priv_key.raw_decryption_primitive(rng, &em, priv_key.size())
195}
196
197#[inline]
199pub(crate) fn verify<PK: PublicKey>(
200 pub_key: &PK,
201 prefix: &[u8],
202 hashed: &[u8],
203 sig: &[u8],
204) -> Result<()> {
205 let hash_len = hashed.len();
206 let t_len = prefix.len() + hashed.len();
207 let k = pub_key.size();
208 if k < t_len + 11 {
209 return Err(Error::Verification);
210 }
211
212 let em = pub_key.raw_encryption_primitive(sig, pub_key.size())?;
213
214 let mut ok = em[0].ct_eq(&0u8);
216 ok &= em[1].ct_eq(&1u8);
217 ok &= em[k - hash_len..k].ct_eq(hashed);
218 ok &= em[k - t_len..k - hash_len].ct_eq(prefix);
219 ok &= em[k - t_len - 1].ct_eq(&0u8);
220
221 for el in em.iter().skip(2).take(k - t_len - 3) {
222 ok &= el.ct_eq(&0xff)
223 }
224
225 if ok.unwrap_u8() != 1 {
226 return Err(Error::Verification);
227 }
228
229 Ok(())
230}
231
232#[inline]
234pub(crate) fn generate_prefix<D>() -> Vec<u8>
235where
236 D: Digest + AssociatedOid,
237{
238 let oid = D::OID.as_bytes();
239 let oid_len = oid.len() as u8;
240 let digest_len = <D as Digest>::output_size() as u8;
241 let mut v = vec![
242 0x30,
243 oid_len + 8 + digest_len,
244 0x30,
245 oid_len + 4,
246 0x6,
247 oid_len,
248 ];
249 v.extend_from_slice(oid);
250 v.extend_from_slice(&[0x05, 0x00, 0x04, digest_len]);
251 v
252}
253
254#[inline]
261fn decrypt_inner<R: RngCore + CryptoRng, SK: PrivateKey>(
262 rng: Option<&mut R>,
263 priv_key: &SK,
264 ciphertext: &[u8],
265) -> Result<(u8, Vec<u8>, u32)> {
266 let k = priv_key.size();
267 if k < 11 {
268 return Err(Error::Decryption);
269 }
270
271 let em = priv_key.raw_decryption_primitive(rng, ciphertext, priv_key.size())?;
272
273 let first_byte_is_zero = em[0].ct_eq(&0u8);
274 let second_byte_is_two = em[1].ct_eq(&2u8);
275
276 let mut looking_for_index = 1u8;
281 let mut index = 0u32;
282
283 for (i, el) in em.iter().enumerate().skip(2) {
284 let equals0 = el.ct_eq(&0u8);
285 index.conditional_assign(&(i as u32), Choice::from(looking_for_index) & equals0);
286 looking_for_index.conditional_assign(&0u8, equals0);
287 }
288
289 let valid_ps = Choice::from((((2i32 + 8i32 - index as i32 - 1i32) >> 31) & 1) as u8);
296 let valid =
297 first_byte_is_zero & second_byte_is_two & Choice::from(!looking_for_index & 1) & valid_ps;
298 index = u32::conditional_select(&0, &(index + 1), valid);
299
300 Ok((valid.unwrap_u8(), em, index))
301}
302
303#[inline]
306fn non_zero_random_bytes<R: RngCore + CryptoRng>(rng: &mut R, data: &mut [u8]) {
307 rng.fill_bytes(data);
308
309 for el in data {
310 if *el == 0u8 {
311 while *el == 0u8 {
313 rng.fill_bytes(core::slice::from_mut(el));
314 }
315 }
316 }
317}
318
319#[derive(Debug, Clone)]
323pub struct SigningKey<D>
324where
325 D: Digest,
326{
327 inner: RsaPrivateKey,
328 prefix: Vec<u8>,
329 phantom: PhantomData<D>,
330}
331
332impl<D> SigningKey<D>
333where
334 D: Digest,
335{
336 pub fn new(key: RsaPrivateKey) -> Self {
338 Self {
339 inner: key,
340 prefix: Vec::new(),
341 phantom: Default::default(),
342 }
343 }
344
345 pub(crate) fn key(&self) -> &RsaPrivateKey {
346 &self.inner
347 }
348
349 pub(crate) fn prefix(&self) -> Vec<u8> {
350 self.prefix.clone()
351 }
352}
353
354impl<D> From<RsaPrivateKey> for SigningKey<D>
355where
356 D: Digest,
357{
358 fn from(key: RsaPrivateKey) -> Self {
359 Self::new(key)
360 }
361}
362
363impl<D> From<SigningKey<D>> for RsaPrivateKey
364where
365 D: Digest,
366{
367 fn from(key: SigningKey<D>) -> Self {
368 key.inner
369 }
370}
371
372impl<D> SigningKey<D>
373where
374 D: Digest + AssociatedOid,
375{
376 pub fn new_with_prefix(key: RsaPrivateKey) -> Self {
378 Self {
379 inner: key,
380 prefix: generate_prefix::<D>(),
381 phantom: Default::default(),
382 }
383 }
384}
385
386impl<D> AsRef<RsaPrivateKey> for SigningKey<D>
387where
388 D: Digest,
389{
390 fn as_ref(&self) -> &RsaPrivateKey {
391 &self.inner
392 }
393}
394
395impl<D> EncodePrivateKey for SigningKey<D>
396where
397 D: Digest,
398{
399 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
400 self.inner.to_pkcs8_der()
401 }
402}
403
404impl<D> Signer<Signature> for SigningKey<D>
405where
406 D: Digest,
407{
408 fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
409 sign::<DummyRng, _>(None, &self.inner, &self.prefix, &D::digest(msg))
410 .map(|v| v.into())
411 .map_err(|e| e.into())
412 }
413}
414
415impl<D> RandomizedSigner<Signature> for SigningKey<D>
416where
417 D: Digest,
418{
419 fn try_sign_with_rng(
420 &self,
421 mut rng: impl CryptoRng + RngCore,
422 msg: &[u8],
423 ) -> signature::Result<Signature> {
424 sign(Some(&mut rng), &self.inner, &self.prefix, &D::digest(msg))
425 .map(|v| v.into())
426 .map_err(|e| e.into())
427 }
428}
429
430impl<D> DigestSigner<D, Signature> for SigningKey<D>
431where
432 D: Digest,
433{
434 fn try_sign_digest(&self, digest: D) -> signature::Result<Signature> {
435 sign::<DummyRng, _>(None, &self.inner, &self.prefix, &digest.finalize())
436 .map(|v| v.into())
437 .map_err(|e| e.into())
438 }
439}
440
441impl<D> RandomizedDigestSigner<D, Signature> for SigningKey<D>
442where
443 D: Digest,
444{
445 fn try_sign_digest_with_rng(
446 &self,
447 mut rng: impl CryptoRng + RngCore,
448 digest: D,
449 ) -> signature::Result<Signature> {
450 sign(
451 Some(&mut rng),
452 &self.inner,
453 &self.prefix,
454 &digest.finalize(),
455 )
456 .map(|v| v.into())
457 .map_err(|e| e.into())
458 }
459}
460
461#[cfg(feature = "hazmat")]
462impl<D> PrehashSigner<Signature> for SigningKey<D>
463where
464 D: Digest,
465{
466 fn sign_prehash(&self, prehash: &[u8]) -> signature::Result<Signature> {
467 sign::<DummyRng, _>(None, &self.inner, &self.prefix, prehash)
468 .map(|v| v.into())
469 .map_err(|e| e.into())
470 }
471}
472
473#[derive(Debug, Clone)]
477pub struct VerifyingKey<D>
478where
479 D: Digest,
480{
481 inner: RsaPublicKey,
482 prefix: Vec<u8>,
483 phantom: PhantomData<D>,
484}
485
486impl<D> VerifyingKey<D>
487where
488 D: Digest,
489{
490 pub fn new(key: RsaPublicKey) -> Self {
492 Self {
493 inner: key,
494 prefix: Vec::new(),
495 phantom: Default::default(),
496 }
497 }
498}
499
500impl<D> From<RsaPublicKey> for VerifyingKey<D>
501where
502 D: Digest,
503{
504 fn from(key: RsaPublicKey) -> Self {
505 Self::new(key)
506 }
507}
508
509impl<D> From<VerifyingKey<D>> for RsaPublicKey
510where
511 D: Digest,
512{
513 fn from(key: VerifyingKey<D>) -> Self {
514 key.inner
515 }
516}
517
518impl<D> VerifyingKey<D>
519where
520 D: Digest + AssociatedOid,
521{
522 pub fn new_with_prefix(key: RsaPublicKey) -> Self {
524 Self {
525 inner: key,
526 prefix: generate_prefix::<D>(),
527 phantom: Default::default(),
528 }
529 }
530}
531
532impl<D> AsRef<RsaPublicKey> for VerifyingKey<D>
533where
534 D: Digest,
535{
536 fn as_ref(&self) -> &RsaPublicKey {
537 &self.inner
538 }
539}
540
541impl<D> From<SigningKey<D>> for VerifyingKey<D>
542where
543 D: Digest,
544{
545 fn from(key: SigningKey<D>) -> Self {
546 Self {
547 inner: key.key().into(),
548 prefix: key.prefix(),
549 phantom: Default::default(),
550 }
551 }
552}
553
554impl<D> From<&SigningKey<D>> for VerifyingKey<D>
555where
556 D: Digest,
557{
558 fn from(key: &SigningKey<D>) -> Self {
559 Self {
560 inner: key.key().into(),
561 prefix: key.prefix(),
562 phantom: Default::default(),
563 }
564 }
565}
566
567impl<D> Verifier<Signature> for VerifyingKey<D>
568where
569 D: Digest,
570{
571 fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
572 verify(
573 &self.inner,
574 &self.prefix,
575 &D::digest(msg),
576 signature.as_ref(),
577 )
578 .map_err(|e| e.into())
579 }
580}
581
582impl<D> DigestVerifier<D, Signature> for VerifyingKey<D>
583where
584 D: Digest,
585{
586 fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> {
587 verify(
588 &self.inner,
589 &self.prefix,
590 &digest.finalize(),
591 signature.as_ref(),
592 )
593 .map_err(|e| e.into())
594 }
595}
596
597#[cfg(feature = "hazmat")]
598impl<D> PrehashVerifier<Signature> for VerifyingKey<D>
599where
600 D: Digest,
601{
602 fn verify_prehash(&self, prehash: &[u8], signature: &Signature) -> signature::Result<()> {
603 verify(&self.inner, &self.prefix, prehash, signature.as_ref()).map_err(|e| e.into())
604 }
605}
606
607impl<D> EncodePublicKey for VerifyingKey<D>
608where
609 D: Digest,
610{
611 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
612 self.inner.to_public_key_der()
613 }
614}
615
616#[cfg(test)]
617mod tests {
618 use super::*;
619 use base64ct::{Base64, Encoding};
620 use hex_literal::hex;
621 use num_bigint::BigUint;
622 use num_traits::FromPrimitive;
623 use num_traits::Num;
624 use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
625 use sha1::{Digest, Sha1};
626 use sha2::Sha256;
627 use sha3::Sha3_256;
628 use signature::{RandomizedSigner, Signature, Signer, Verifier};
629
630 use crate::{PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey};
631
632 #[test]
633 fn test_non_zero_bytes() {
634 for _ in 0..10 {
635 let mut rng = ChaCha8Rng::from_seed([42; 32]);
636 let mut b = vec![0u8; 512];
637 non_zero_random_bytes(&mut rng, &mut b);
638 for el in &b {
639 assert_ne!(*el, 0u8);
640 }
641 }
642 }
643
644 fn get_private_key() -> RsaPrivateKey {
645 RsaPrivateKey::from_components(
657 BigUint::from_str_radix("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077", 10).unwrap(),
658 BigUint::from_u64(65537).unwrap(),
659 BigUint::from_str_radix("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861", 10).unwrap(),
660 vec![
661 BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
662 BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
663 ],
664 ).unwrap()
665 }
666
667 #[test]
668 fn test_decrypt_pkcs1v15() {
669 let priv_key = get_private_key();
670
671 let tests = [[
672 "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
673 "x",
674 ], [
675 "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
676 "testing.",
677 ], [
678 "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
679 "testing.\n",
680 ], [
681 "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
682 "01234567890123456789012345678901234567890123456789012",
683 ]];
684
685 for test in &tests {
686 let out = priv_key
687 .decrypt(
688 PaddingScheme::new_pkcs1v15_encrypt(),
689 &Base64::decode_vec(test[0]).unwrap(),
690 )
691 .unwrap();
692 assert_eq!(out, test[1].as_bytes());
693 }
694 }
695
696 #[test]
697 fn test_encrypt_decrypt_pkcs1v15() {
698 let mut rng = ChaCha8Rng::from_seed([42; 32]);
699 let priv_key = get_private_key();
700 let k = priv_key.size();
701
702 for i in 1..100 {
703 let mut input = vec![0u8; i * 8];
704 rng.fill_bytes(&mut input);
705 if input.len() > k - 11 {
706 input = input[0..k - 11].to_vec();
707 }
708
709 let pub_key: RsaPublicKey = priv_key.clone().into();
710 let ciphertext = encrypt(&mut rng, &pub_key, &input).unwrap();
711 assert_ne!(input, ciphertext);
712
713 let blind: bool = rng.next_u32() < (1u32 << 31);
714 let blinder = if blind { Some(&mut rng) } else { None };
715 let plaintext = decrypt(blinder, &priv_key, &ciphertext).unwrap();
716 assert_eq!(input, plaintext);
717 }
718 }
719
720 #[test]
721 fn test_sign_pkcs1v15() {
722 let priv_key = get_private_key();
723
724 let tests = [(
725 "Test.\n",
726 hex!(
727 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
728 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
729 ),
730 )];
731
732 for (text, expected) in &tests {
733 let digest = Sha1::digest(text.as_bytes()).to_vec();
734
735 let out = priv_key
736 .sign(PaddingScheme::new_pkcs1v15_sign::<Sha1>(), &digest)
737 .unwrap();
738 assert_ne!(out, digest);
739 assert_eq!(out, expected);
740
741 let mut rng = ChaCha8Rng::from_seed([42; 32]);
742 let out2 = priv_key
743 .sign_blinded(
744 &mut rng,
745 PaddingScheme::new_pkcs1v15_sign::<Sha1>(),
746 &digest,
747 )
748 .unwrap();
749 assert_eq!(out2, expected);
750 }
751 }
752
753 #[test]
754 fn test_sign_pkcs1v15_signer() {
755 let priv_key = get_private_key();
756
757 let tests = [(
758 "Test.\n",
759 hex!(
760 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
761 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
762 ),
763 )];
764
765 let signing_key = SigningKey::<Sha1>::new_with_prefix(priv_key);
766
767 for (text, expected) in &tests {
768 let out = signing_key.sign(text.as_bytes());
769 assert_ne!(out.as_ref(), text.as_bytes());
770 assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
771 assert_eq!(out.as_ref(), expected);
772
773 let mut rng = ChaCha8Rng::from_seed([42; 32]);
774 let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
775 assert_eq!(out2.as_ref(), expected);
776 }
777 }
778
779 #[test]
780 fn test_sign_pkcs1v15_signer_sha2_256() {
781 let priv_key = get_private_key();
782
783 let tests = [(
784 "Test.\n",
785 hex!(
786 "2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea"
787 "02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b"
788 ),
789 )];
790
791 let signing_key = SigningKey::<Sha256>::new_with_prefix(priv_key);
792
793 for (text, expected) in &tests {
794 let out = signing_key.sign(text.as_bytes());
795 assert_ne!(out.as_ref(), text.as_bytes());
796 assert_eq!(out.as_ref(), expected);
797
798 let mut rng = ChaCha8Rng::from_seed([42; 32]);
799 let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
800 assert_eq!(out2.as_ref(), expected);
801 }
802 }
803
804 #[test]
805 fn test_sign_pkcs1v15_signer_sha3_256() {
806 let priv_key = get_private_key();
807
808 let tests = [(
809 "Test.\n",
810 hex!(
811 "55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7"
812 "2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9"
813 ),
814 )];
815
816 let signing_key = SigningKey::<Sha3_256>::new_with_prefix(priv_key);
817
818 for (text, expected) in &tests {
819 let out = signing_key.sign(text.as_bytes());
820 assert_ne!(out.as_ref(), text.as_bytes());
821 assert_eq!(out.as_ref(), expected);
822
823 let mut rng = ChaCha8Rng::from_seed([42; 32]);
824 let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
825 assert_eq!(out2.as_ref(), expected);
826 }
827 }
828
829 #[test]
830 fn test_sign_pkcs1v15_digest_signer() {
831 let priv_key = get_private_key();
832
833 let tests = [(
834 "Test.\n",
835 hex!(
836 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
837 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
838 ),
839 )];
840
841 let signing_key = SigningKey::new_with_prefix(priv_key);
842
843 for (text, expected) in &tests {
844 let mut digest = Sha1::new();
845 digest.update(text.as_bytes());
846 let out = signing_key.sign_digest(digest);
847 assert_ne!(out.as_ref(), text.as_bytes());
848 assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
849 assert_eq!(out.as_ref(), expected);
850
851 let mut rng = ChaCha8Rng::from_seed([42; 32]);
852 let mut digest = Sha1::new();
853 digest.update(text.as_bytes());
854 let out2 = signing_key.sign_digest_with_rng(&mut rng, digest);
855 assert_eq!(out2.as_ref(), expected);
856 }
857 }
858
859 #[test]
860 fn test_verify_pkcs1v15() {
861 let priv_key = get_private_key();
862
863 let tests = [
864 (
865 "Test.\n",
866 hex!(
867 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
868 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
869 ),
870 true,
871 ),
872 (
873 "Test.\n",
874 hex!(
875 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
876 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
877 ),
878 false,
879 ),
880 ];
881 let pub_key: RsaPublicKey = priv_key.into();
882
883 for (text, sig, expected) in &tests {
884 let digest = Sha1::digest(text.as_bytes()).to_vec();
885
886 let result = pub_key.verify(PaddingScheme::new_pkcs1v15_sign::<Sha1>(), &digest, sig);
887 match expected {
888 true => result.expect("failed to verify"),
889 false => {
890 result.expect_err("expected verifying error");
891 }
892 }
893 }
894 }
895
896 #[test]
897 fn test_verify_pkcs1v15_signer() {
898 let priv_key = get_private_key();
899
900 let tests = [
901 (
902 "Test.\n",
903 hex!(
904 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
905 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
906 ),
907 true,
908 ),
909 (
910 "Test.\n",
911 hex!(
912 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
913 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
914 ),
915 false,
916 ),
917 ];
918 let pub_key: RsaPublicKey = priv_key.into();
919 let verifying_key = VerifyingKey::<Sha1>::new_with_prefix(pub_key);
920
921 for (text, sig, expected) in &tests {
922 let result =
923 verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap());
924 match expected {
925 true => result.expect("failed to verify"),
926 false => {
927 result.expect_err("expected verifying error");
928 }
929 }
930 }
931 }
932
933 #[test]
934 fn test_verify_pkcs1v15_digest_signer() {
935 let priv_key = get_private_key();
936
937 let tests = [
938 (
939 "Test.\n",
940 hex!(
941 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
942 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
943 ),
944 true,
945 ),
946 (
947 "Test.\n",
948 hex!(
949 "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
950 "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
951 ),
952 false,
953 ),
954 ];
955 let pub_key: RsaPublicKey = priv_key.into();
956 let verifying_key = VerifyingKey::new_with_prefix(pub_key);
957
958 for (text, sig, expected) in &tests {
959 let mut digest = Sha1::new();
960 digest.update(text.as_bytes());
961 let result = verifying_key.verify_digest(digest, &Signature::from_bytes(sig).unwrap());
962 match expected {
963 true => result.expect("failed to verify"),
964 false => {
965 result.expect_err("expected verifying error");
966 }
967 }
968 }
969 }
970 #[test]
971 fn test_unpadded_signature() {
972 let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
973 let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
974 let priv_key = get_private_key();
975
976 let sig = priv_key
977 .sign(PaddingScheme::new_pkcs1v15_sign_raw(), msg)
978 .unwrap();
979 assert_eq!(expected_sig, sig);
980
981 let pub_key: RsaPublicKey = priv_key.into();
982 pub_key
983 .verify(PaddingScheme::new_pkcs1v15_sign_raw(), msg, &sig)
984 .expect("failed to verify");
985 }
986
987 #[cfg(feature = "hazmat")]
988 #[test]
989 fn test_unpadded_signature_hazmat() {
990 let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
991 let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
992 let priv_key = get_private_key();
993
994 let signing_key = SigningKey::<Sha1>::new(priv_key);
995 let sig = signing_key.sign_prehash(msg).expect("Failure during sign");
996 assert_eq!(sig.as_ref(), expected_sig);
997
998 let verifying_key: VerifyingKey<_> = (&signing_key).into();
999 verifying_key
1000 .verify_prehash(msg, &Signature::from_bytes(&expected_sig).unwrap())
1001 .expect("failed to verify");
1002 }
1003}