rsa/
pkcs1v15.rs

1//! PKCS#1 v1.5 support as described in [RFC8017 § 8.2].
2//!
3//! # Usage
4//!
5//! See [code example in the toplevel rustdoc](../index.html#pkcs1-v15-signatures).
6//!
7//! [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
8
9mod decrypting_key;
10mod encrypting_key;
11mod signature;
12mod signing_key;
13mod verifying_key;
14
15pub use self::{
16    decrypting_key::DecryptingKey, encrypting_key::EncryptingKey, signature::Signature,
17    signing_key::SigningKey, verifying_key::VerifyingKey,
18};
19
20use alloc::{boxed::Box, vec::Vec};
21use core::fmt::Debug;
22use digest::Digest;
23use num_bigint::BigUint;
24use pkcs8::AssociatedOid;
25use rand_core::CryptoRngCore;
26use zeroize::Zeroizing;
27
28use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
29use crate::algorithms::pkcs1v15::*;
30use crate::algorithms::rsa::{rsa_decrypt_and_check, rsa_encrypt};
31use crate::errors::{Error, Result};
32use crate::key::{self, RsaPrivateKey, RsaPublicKey};
33use crate::traits::{PaddingScheme, PublicKeyParts, SignatureScheme};
34
35/// Encryption using PKCS#1 v1.5 padding.
36#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
37pub struct Pkcs1v15Encrypt;
38
39impl PaddingScheme for Pkcs1v15Encrypt {
40    fn decrypt<Rng: CryptoRngCore>(
41        self,
42        rng: Option<&mut Rng>,
43        priv_key: &RsaPrivateKey,
44        ciphertext: &[u8],
45    ) -> Result<Vec<u8>> {
46        decrypt(rng, priv_key, ciphertext)
47    }
48
49    fn encrypt<Rng: CryptoRngCore>(
50        self,
51        rng: &mut Rng,
52        pub_key: &RsaPublicKey,
53        msg: &[u8],
54    ) -> Result<Vec<u8>> {
55        encrypt(rng, pub_key, msg)
56    }
57}
58
59/// `RSASSA-PKCS1-v1_5`: digital signatures using PKCS#1 v1.5 padding.
60#[derive(Clone, Debug, Eq, PartialEq)]
61pub struct Pkcs1v15Sign {
62    /// Length of hash to use.
63    pub hash_len: Option<usize>,
64
65    /// Prefix.
66    pub prefix: Box<[u8]>,
67}
68
69impl Pkcs1v15Sign {
70    /// Create new PKCS#1 v1.5 padding for the given digest.
71    ///
72    /// The digest must have an [`AssociatedOid`]. Make sure to enable the `oid`
73    /// feature of the relevant digest crate.
74    pub fn new<D>() -> Self
75    where
76        D: Digest + AssociatedOid,
77    {
78        Self {
79            hash_len: Some(<D as Digest>::output_size()),
80            prefix: pkcs1v15_generate_prefix::<D>().into_boxed_slice(),
81        }
82    }
83
84    /// Create new PKCS#1 v1.5 padding for computing an unprefixed signature.
85    ///
86    /// This sets `hash_len` to `None` and uses an empty `prefix`.
87    pub fn new_unprefixed() -> Self {
88        Self {
89            hash_len: None,
90            prefix: Box::new([]),
91        }
92    }
93
94    /// Create new PKCS#1 v1.5 padding for computing an unprefixed signature.
95    ///
96    /// This sets `hash_len` to `None` and uses an empty `prefix`.
97    #[deprecated(since = "0.9.0", note = "use Pkcs1v15Sign::new_unprefixed instead")]
98    pub fn new_raw() -> Self {
99        Self::new_unprefixed()
100    }
101}
102
103impl SignatureScheme for Pkcs1v15Sign {
104    fn sign<Rng: CryptoRngCore>(
105        self,
106        rng: Option<&mut Rng>,
107        priv_key: &RsaPrivateKey,
108        hashed: &[u8],
109    ) -> Result<Vec<u8>> {
110        if let Some(hash_len) = self.hash_len {
111            if hashed.len() != hash_len {
112                return Err(Error::InputNotHashed);
113            }
114        }
115
116        sign(rng, priv_key, &self.prefix, hashed)
117    }
118
119    fn verify(self, pub_key: &RsaPublicKey, hashed: &[u8], sig: &[u8]) -> Result<()> {
120        if let Some(hash_len) = self.hash_len {
121            if hashed.len() != hash_len {
122                return Err(Error::InputNotHashed);
123            }
124        }
125
126        verify(
127            pub_key,
128            self.prefix.as_ref(),
129            hashed,
130            &BigUint::from_bytes_be(sig),
131            sig.len(),
132        )
133    }
134}
135
136/// Encrypts the given message with RSA and the padding
137/// scheme from PKCS#1 v1.5.  The message must be no longer than the
138/// length of the public modulus minus 11 bytes.
139#[inline]
140fn encrypt<R: CryptoRngCore + ?Sized>(
141    rng: &mut R,
142    pub_key: &RsaPublicKey,
143    msg: &[u8],
144) -> Result<Vec<u8>> {
145    key::check_public(pub_key)?;
146
147    let em = pkcs1v15_encrypt_pad(rng, msg, pub_key.size())?;
148    let int = Zeroizing::new(BigUint::from_bytes_be(&em));
149    uint_to_be_pad(rsa_encrypt(pub_key, &int)?, pub_key.size())
150}
151
152/// Decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
153///
154/// If an `rng` is passed, it uses RSA blinding to avoid timing side-channel attacks.
155///
156/// Note that whether this function returns an error or not discloses secret
157/// information. If an attacker can cause this function to run repeatedly and
158/// learn whether each instance returned an error then they can decrypt and
159/// forge signatures as if they had the private key. See
160/// `decrypt_session_key` for a way of solving this problem.
161#[inline]
162fn decrypt<R: CryptoRngCore + ?Sized>(
163    rng: Option<&mut R>,
164    priv_key: &RsaPrivateKey,
165    ciphertext: &[u8],
166) -> Result<Vec<u8>> {
167    key::check_public(priv_key)?;
168
169    let em = rsa_decrypt_and_check(priv_key, rng, &BigUint::from_bytes_be(ciphertext))?;
170    let em = uint_to_zeroizing_be_pad(em, priv_key.size())?;
171
172    pkcs1v15_encrypt_unpad(em, priv_key.size())
173}
174
175/// Calculates the signature of hashed using
176/// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that `hashed` must
177/// be the result of hashing the input message using the given hash
178/// function. If hash is `None`, hashed is signed directly. This isn't
179/// advisable except for interoperability.
180///
181/// If `rng` is not `None` then RSA blinding will be used to avoid timing
182/// side-channel attacks.
183///
184/// This function is deterministic. Thus, if the set of possible
185/// messages is small, an attacker may be able to build a map from
186/// messages to signatures and identify the signed messages. As ever,
187/// signatures provide authenticity, not confidentiality.
188#[inline]
189fn sign<R: CryptoRngCore + ?Sized>(
190    rng: Option<&mut R>,
191    priv_key: &RsaPrivateKey,
192    prefix: &[u8],
193    hashed: &[u8],
194) -> Result<Vec<u8>> {
195    let em = pkcs1v15_sign_pad(prefix, hashed, priv_key.size())?;
196
197    uint_to_zeroizing_be_pad(
198        rsa_decrypt_and_check(priv_key, rng, &BigUint::from_bytes_be(&em))?,
199        priv_key.size(),
200    )
201}
202
203/// Verifies an RSA PKCS#1 v1.5 signature.
204#[inline]
205fn verify(
206    pub_key: &RsaPublicKey,
207    prefix: &[u8],
208    hashed: &[u8],
209    sig: &BigUint,
210    sig_len: usize,
211) -> Result<()> {
212    if sig >= pub_key.n() || sig_len != pub_key.size() {
213        return Err(Error::Verification);
214    }
215
216    let em = uint_to_be_pad(rsa_encrypt(pub_key, sig)?, pub_key.size())?;
217
218    pkcs1v15_sign_unpad(prefix, hashed, &em, pub_key.size())
219}
220
221mod oid {
222    use const_oid::ObjectIdentifier;
223
224    /// A trait which associates an RSA-specific OID with a type.
225    pub trait RsaSignatureAssociatedOid {
226        /// The OID associated with this type.
227        const OID: ObjectIdentifier;
228    }
229
230    #[cfg(feature = "sha1")]
231    impl RsaSignatureAssociatedOid for sha1::Sha1 {
232        const OID: ObjectIdentifier =
233            const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.5");
234    }
235
236    #[cfg(feature = "sha2")]
237    impl RsaSignatureAssociatedOid for sha2::Sha224 {
238        const OID: ObjectIdentifier =
239            const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.14");
240    }
241
242    #[cfg(feature = "sha2")]
243    impl RsaSignatureAssociatedOid for sha2::Sha256 {
244        const OID: ObjectIdentifier =
245            const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11");
246    }
247
248    #[cfg(feature = "sha2")]
249    impl RsaSignatureAssociatedOid for sha2::Sha384 {
250        const OID: ObjectIdentifier =
251            const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.12");
252    }
253
254    #[cfg(feature = "sha2")]
255    impl RsaSignatureAssociatedOid for sha2::Sha512 {
256        const OID: ObjectIdentifier =
257            const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.13");
258    }
259}
260
261pub use oid::RsaSignatureAssociatedOid;
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266    use ::signature::{
267        hazmat::{PrehashSigner, PrehashVerifier},
268        DigestSigner, DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner,
269        SignatureEncoding, Signer, Verifier,
270    };
271    use base64ct::{Base64, Encoding};
272    use hex_literal::hex;
273    use num_bigint::BigUint;
274    use num_traits::FromPrimitive;
275    use num_traits::Num;
276    use rand_chacha::{
277        rand_core::{RngCore, SeedableRng},
278        ChaCha8Rng,
279    };
280    use sha1::{Digest, Sha1};
281    use sha2::Sha256;
282    use sha3::Sha3_256;
283
284    use crate::traits::{
285        Decryptor, EncryptingKeypair, PublicKeyParts, RandomizedDecryptor, RandomizedEncryptor,
286    };
287    use crate::{RsaPrivateKey, RsaPublicKey};
288
289    fn get_private_key() -> RsaPrivateKey {
290        // In order to generate new test vectors you'll need the PEM form of this key:
291        // -----BEGIN RSA PRIVATE KEY-----
292        // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
293        // fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
294        // /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
295        // RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
296        // EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
297        // IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
298        // tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
299        // -----END RSA PRIVATE KEY-----
300
301        RsaPrivateKey::from_components(
302            BigUint::from_str_radix("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077", 10).unwrap(),
303            BigUint::from_u64(65537).unwrap(),
304            BigUint::from_str_radix("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861", 10).unwrap(),
305            vec![
306                BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
307                BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
308            ],
309        ).unwrap()
310    }
311
312    #[test]
313    fn test_decrypt_pkcs1v15() {
314        let priv_key = get_private_key();
315
316        let tests = [[
317	    "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
318	    "x",
319	], [
320	    "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
321	    "testing.",
322	], [
323	    "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
324	    "testing.\n",
325	], [
326	"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
327		"01234567890123456789012345678901234567890123456789012",
328	]];
329
330        for test in &tests {
331            let out = priv_key
332                .decrypt(Pkcs1v15Encrypt, &Base64::decode_vec(test[0]).unwrap())
333                .unwrap();
334            assert_eq!(out, test[1].as_bytes());
335        }
336    }
337
338    #[test]
339    fn test_encrypt_decrypt_pkcs1v15() {
340        let mut rng = ChaCha8Rng::from_seed([42; 32]);
341        let priv_key = get_private_key();
342        let k = priv_key.size();
343
344        for i in 1..100 {
345            let mut input = vec![0u8; i * 8];
346            rng.fill_bytes(&mut input);
347            if input.len() > k - 11 {
348                input = input[0..k - 11].to_vec();
349            }
350
351            let pub_key: RsaPublicKey = priv_key.clone().into();
352            let ciphertext = encrypt(&mut rng, &pub_key, &input).unwrap();
353            assert_ne!(input, ciphertext);
354
355            let blind: bool = rng.next_u32() < (1u32 << 31);
356            let blinder = if blind { Some(&mut rng) } else { None };
357            let plaintext = decrypt(blinder, &priv_key, &ciphertext).unwrap();
358            assert_eq!(input, plaintext);
359        }
360    }
361
362    #[test]
363    fn test_decrypt_pkcs1v15_traits() {
364        let priv_key = get_private_key();
365        let decrypting_key = DecryptingKey::new(priv_key);
366
367        let tests = [[
368	    "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
369	    "x",
370	], [
371	    "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
372	    "testing.",
373	], [
374	    "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
375	    "testing.\n",
376	], [
377	"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
378		"01234567890123456789012345678901234567890123456789012",
379	]];
380
381        for test in &tests {
382            let out = decrypting_key
383                .decrypt(&Base64::decode_vec(test[0]).unwrap())
384                .unwrap();
385            assert_eq!(out, test[1].as_bytes());
386        }
387    }
388
389    #[test]
390    fn test_encrypt_decrypt_pkcs1v15_traits() {
391        let mut rng = ChaCha8Rng::from_seed([42; 32]);
392        let priv_key = get_private_key();
393        let k = priv_key.size();
394        let decrypting_key = DecryptingKey::new(priv_key);
395
396        for i in 1..100 {
397            let mut input = vec![0u8; i * 8];
398            rng.fill_bytes(&mut input);
399            if input.len() > k - 11 {
400                input = input[0..k - 11].to_vec();
401            }
402
403            let encrypting_key = decrypting_key.encrypting_key();
404            let ciphertext = encrypting_key.encrypt_with_rng(&mut rng, &input).unwrap();
405            assert_ne!(input, ciphertext);
406
407            let blind: bool = rng.next_u32() < (1u32 << 31);
408            let plaintext = if blind {
409                decrypting_key
410                    .decrypt_with_rng(&mut rng, &ciphertext)
411                    .unwrap()
412            } else {
413                decrypting_key.decrypt(&ciphertext).unwrap()
414            };
415            assert_eq!(input, plaintext);
416        }
417    }
418
419    #[test]
420    fn test_sign_pkcs1v15() {
421        let priv_key = get_private_key();
422
423        let tests = [(
424            "Test.\n",
425            hex!(
426                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
427                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
428            ),
429        )];
430
431        for (text, expected) in &tests {
432            let digest = Sha1::digest(text.as_bytes()).to_vec();
433
434            let out = priv_key.sign(Pkcs1v15Sign::new::<Sha1>(), &digest).unwrap();
435            assert_ne!(out, digest);
436            assert_eq!(out, expected);
437
438            let mut rng = ChaCha8Rng::from_seed([42; 32]);
439            let out2 = priv_key
440                .sign_with_rng(&mut rng, Pkcs1v15Sign::new::<Sha1>(), &digest)
441                .unwrap();
442            assert_eq!(out2, expected);
443        }
444    }
445
446    #[test]
447    fn test_sign_pkcs1v15_signer() {
448        let priv_key = get_private_key();
449
450        let tests = [(
451            "Test.\n",
452            hex!(
453                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
454                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
455            ),
456        )];
457
458        let signing_key = SigningKey::<Sha1>::new(priv_key);
459
460        for (text, expected) in &tests {
461            let out = signing_key.sign(text.as_bytes()).to_bytes();
462            assert_ne!(out.as_ref(), text.as_bytes());
463            assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
464            assert_eq!(out.as_ref(), expected);
465
466            let mut rng = ChaCha8Rng::from_seed([42; 32]);
467            let out2 = signing_key
468                .sign_with_rng(&mut rng, text.as_bytes())
469                .to_bytes();
470            assert_eq!(out2.as_ref(), expected);
471        }
472    }
473
474    #[test]
475    fn test_sign_pkcs1v15_signer_sha2_256() {
476        let priv_key = get_private_key();
477
478        let tests = [(
479            "Test.\n",
480            hex!(
481                "2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea"
482                "02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b"
483            ),
484        )];
485
486        let signing_key = SigningKey::<Sha256>::new(priv_key);
487
488        for (text, expected) in &tests {
489            let out = signing_key.sign(text.as_bytes()).to_bytes();
490            assert_ne!(out.as_ref(), text.as_bytes());
491            assert_eq!(out.as_ref(), expected);
492
493            let mut rng = ChaCha8Rng::from_seed([42; 32]);
494            let out2 = signing_key
495                .sign_with_rng(&mut rng, text.as_bytes())
496                .to_bytes();
497            assert_eq!(out2.as_ref(), expected);
498        }
499    }
500
501    #[test]
502    fn test_sign_pkcs1v15_signer_sha3_256() {
503        let priv_key = get_private_key();
504
505        let tests = [(
506            "Test.\n",
507            hex!(
508                "55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7"
509                "2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9"
510            ),
511        )];
512
513        let signing_key = SigningKey::<Sha3_256>::new(priv_key);
514
515        for (text, expected) in &tests {
516            let out = signing_key.sign(text.as_bytes()).to_bytes();
517            assert_ne!(out.as_ref(), text.as_bytes());
518            assert_eq!(out.as_ref(), expected);
519
520            let mut rng = ChaCha8Rng::from_seed([42; 32]);
521            let out2 = signing_key
522                .sign_with_rng(&mut rng, text.as_bytes())
523                .to_bytes();
524            assert_eq!(out2.as_ref(), expected);
525        }
526    }
527
528    #[test]
529    fn test_sign_pkcs1v15_digest_signer() {
530        let priv_key = get_private_key();
531
532        let tests = [(
533            "Test.\n",
534            hex!(
535                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
536                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
537            ),
538        )];
539
540        let signing_key = SigningKey::new(priv_key);
541
542        for (text, expected) in &tests {
543            let mut digest = Sha1::new();
544            digest.update(text.as_bytes());
545            let out = signing_key.sign_digest(digest).to_bytes();
546            assert_ne!(out.as_ref(), text.as_bytes());
547            assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
548            assert_eq!(out.as_ref(), expected);
549
550            let mut rng = ChaCha8Rng::from_seed([42; 32]);
551            let mut digest = Sha1::new();
552            digest.update(text.as_bytes());
553            let out2 = signing_key
554                .sign_digest_with_rng(&mut rng, digest)
555                .to_bytes();
556            assert_eq!(out2.as_ref(), expected);
557        }
558    }
559
560    #[test]
561    fn test_verify_pkcs1v15() {
562        let priv_key = get_private_key();
563
564        let tests = [
565            (
566                "Test.\n",
567                hex!(
568                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
569                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
570                ),
571                true,
572            ),
573            (
574                "Test.\n",
575                hex!(
576                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
577                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
578                ),
579                false,
580            ),
581        ];
582        let pub_key: RsaPublicKey = priv_key.into();
583
584        for (text, sig, expected) in &tests {
585            let digest = Sha1::digest(text.as_bytes()).to_vec();
586
587            let result = pub_key.verify(Pkcs1v15Sign::new::<Sha1>(), &digest, sig);
588            match expected {
589                true => result.expect("failed to verify"),
590                false => {
591                    result.expect_err("expected verifying error");
592                }
593            }
594        }
595    }
596
597    #[test]
598    fn test_verify_pkcs1v15_signer() {
599        let priv_key = get_private_key();
600
601        let tests = [
602            (
603                "Test.\n",
604                hex!(
605                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
606                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
607                ),
608                true,
609            ),
610            (
611                "Test.\n",
612                hex!(
613                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
614                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
615                ),
616                false,
617            ),
618        ];
619        let pub_key: RsaPublicKey = priv_key.into();
620        let verifying_key = VerifyingKey::<Sha1>::new(pub_key);
621
622        for (text, sig, expected) in &tests {
623            let result = verifying_key.verify(
624                text.as_bytes(),
625                &Signature::try_from(sig.as_slice()).unwrap(),
626            );
627            match expected {
628                true => result.expect("failed to verify"),
629                false => {
630                    result.expect_err("expected verifying error");
631                }
632            }
633        }
634    }
635
636    #[test]
637    fn test_verify_pkcs1v15_digest_signer() {
638        let priv_key = get_private_key();
639
640        let tests = [
641            (
642                "Test.\n",
643                hex!(
644                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
645                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
646                ),
647                true,
648            ),
649            (
650                "Test.\n",
651                hex!(
652                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
653                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
654                ),
655                false,
656            ),
657        ];
658        let pub_key: RsaPublicKey = priv_key.into();
659        let verifying_key = VerifyingKey::new(pub_key);
660
661        for (text, sig, expected) in &tests {
662            let mut digest = Sha1::new();
663            digest.update(text.as_bytes());
664            let result =
665                verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap());
666            match expected {
667                true => result.expect("failed to verify"),
668                false => {
669                    result.expect_err("expected verifying error");
670                }
671            }
672        }
673    }
674
675    #[test]
676    fn test_unpadded_signature() {
677        let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
678        let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
679        let priv_key = get_private_key();
680
681        let sig = priv_key.sign(Pkcs1v15Sign::new_unprefixed(), msg).unwrap();
682        assert_eq!(expected_sig, sig);
683
684        let pub_key: RsaPublicKey = priv_key.into();
685        pub_key
686            .verify(Pkcs1v15Sign::new_unprefixed(), msg, &sig)
687            .expect("failed to verify");
688    }
689
690    #[test]
691    fn test_unpadded_signature_hazmat() {
692        let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
693        let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
694        let priv_key = get_private_key();
695
696        let signing_key = SigningKey::<Sha1>::new_unprefixed(priv_key);
697        let sig = signing_key
698            .sign_prehash(msg)
699            .expect("Failure during sign")
700            .to_bytes();
701        assert_eq!(sig.as_ref(), expected_sig);
702
703        let verifying_key = signing_key.verifying_key();
704        verifying_key
705            .verify_prehash(msg, &Signature::try_from(expected_sig.as_slice()).unwrap())
706            .expect("failed to verify");
707    }
708}