Skip to main content

rsa/
pkcs1v15.rs

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