1#[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#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
79pub struct Pkcs1v15Encrypt;
80
81impl Pkcs1v15Encrypt {
82 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#[cfg(feature = "alloc")]
109#[inline]
110#[allow(dead_code)] fn 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#[derive(Clone, Debug, Eq, PartialEq)]
193pub struct Pkcs1v15Sign {
194 pub hash_len: Option<usize>,
196
197 #[cfg(feature = "alloc")]
199 prefix: Box<[u8]>,
200 #[cfg(not(feature = "alloc"))]
201 prefix: Prefix,
202}
203
204impl Pkcs1v15Sign {
205 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 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#[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#[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#[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#[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 pub trait RsaSignatureAssociatedOid {
378 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 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}