mod decrypting_key;
mod encrypting_key;
mod signature;
mod signing_key;
mod verifying_key;
pub use self::{
decrypting_key::DecryptingKey, encrypting_key::EncryptingKey, signature::Signature,
signing_key::SigningKey, verifying_key::VerifyingKey,
};
use alloc::{boxed::Box, vec::Vec};
use const_oid::AssociatedOid;
use core::fmt::Debug;
use digest::Digest;
use rand_core::TryCryptoRng;
use crate::algorithms::pad::{i2osp, i2osp_zeroizing, os2ip, os2ip_zeroizing};
use crate::algorithms::pkcs1v15::*;
use crate::algorithms::rsa::{rsa_decrypt_and_check, rsa_encrypt};
use crate::errors::{Error, Result};
use crate::traits::{PaddingScheme, PrivateKeyParts, PublicKeyParts, SignatureScheme};
use crate::{RsaPrivateKey, RsaPublicKey, public_key};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Pkcs1v15Encrypt;
impl PaddingScheme for Pkcs1v15Encrypt {
fn decrypt<Rng: TryCryptoRng + ?Sized>(
self,
rng: Option<&mut Rng>,
priv_key: &RsaPrivateKey,
ciphertext: &[u8],
) -> Result<Vec<u8>> {
decrypt(rng, priv_key, ciphertext)
}
fn encrypt<Rng: TryCryptoRng + ?Sized>(
self,
rng: &mut Rng,
pub_key: &RsaPublicKey,
msg: &[u8],
) -> Result<Vec<u8>> {
encrypt(rng, pub_key, msg)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Pkcs1v15Sign {
pub hash_len: Option<usize>,
pub prefix: Box<[u8]>,
}
impl Pkcs1v15Sign {
#[must_use]
pub fn new<D>() -> Self
where
D: Digest + AssociatedOid,
{
Self {
hash_len: Some(<D as Digest>::output_size()),
prefix: pkcs1v15_generate_prefix::<D>().into_boxed_slice(),
}
}
#[must_use]
pub fn new_unprefixed() -> Self {
Self {
hash_len: None,
prefix: Box::new([]),
}
}
}
impl SignatureScheme for Pkcs1v15Sign {
fn sign<Rng: TryCryptoRng + ?Sized>(
self,
rng: Option<&mut Rng>,
priv_key: &RsaPrivateKey,
hashed: &[u8],
) -> Result<Vec<u8>> {
if let Some(hash_len) = self.hash_len {
if hashed.len() != hash_len {
return Err(Error::InputNotHashed);
}
}
sign(rng, priv_key, &self.prefix, hashed)
}
fn verify(self, pub_key: &RsaPublicKey, hashed: &[u8], sig: &[u8]) -> Result<()> {
if let Some(hash_len) = self.hash_len {
if hashed.len() != hash_len {
return Err(Error::InputNotHashed);
}
}
verify(pub_key, self.prefix.as_ref(), hashed, sig)
}
}
#[inline]
fn encrypt<R: TryCryptoRng + ?Sized>(
rng: &mut R,
pub_key: &RsaPublicKey,
msg: &[u8],
) -> Result<Vec<u8>> {
public_key::check_public(pub_key)?;
let em = pkcs1v15_encrypt_pad(rng, msg, pub_key.size())?;
let int = os2ip_zeroizing(em, pub_key.n_bits_precision())?;
Ok(i2osp(rsa_encrypt(pub_key, &int)?, pub_key.size()))
}
#[inline]
fn decrypt<R: TryCryptoRng + ?Sized>(
rng: Option<&mut R>,
priv_key: &RsaPrivateKey,
ciphertext: &[u8],
) -> Result<Vec<u8>> {
public_key::check_public(priv_key)?;
let k = priv_key.size();
if k < 11 || ciphertext.len() != k {
return Err(Error::Decryption);
}
if k > 8191 {
return Err(Error::Decryption);
}
let c = os2ip(ciphertext, priv_key.n_bits_precision())?;
let m = rsa_decrypt_and_check(priv_key, rng, &c)?;
let mut em = i2osp_zeroizing(m, k);
let kdk = implicit_rejection::KeyDerivationKey::derive(priv_key.d(), k, ciphertext)?;
let (am, al) = kdk.alternative_message(k)?;
let (check, l) = eme_pkcs1v15_decode(&em, k);
let length = select_message(&mut em, &am, al, l, check) as usize;
Ok(em[k - length..].to_vec())
}
fn sign_with_default_rng(
priv_key: &RsaPrivateKey,
prefix: &[u8],
hashed: &[u8],
) -> Result<Vec<u8>> {
#[cfg(feature = "getrandom")]
{
sign(
Some(&mut crypto_common::getrandom::SysRng),
priv_key,
prefix,
hashed,
)
}
#[cfg(not(feature = "getrandom"))]
{
sign::<crate::dummy_rng::DummyRng>(None, priv_key, prefix, hashed)
}
}
#[inline]
fn sign<R: TryCryptoRng + ?Sized>(
rng: Option<&mut R>,
priv_key: &RsaPrivateKey,
prefix: &[u8],
hashed: &[u8],
) -> Result<Vec<u8>> {
let em = pkcs1v15_sign_pad(prefix, hashed, priv_key.size())?;
let em = os2ip(&em, priv_key.n_bits_precision())?;
Ok(i2osp(
rsa_decrypt_and_check(priv_key, rng, &em)?,
priv_key.size(),
))
}
#[inline]
fn verify(pub_key: &RsaPublicKey, prefix: &[u8], hashed: &[u8], sig: &[u8]) -> Result<()> {
if sig.len() != pub_key.size() {
return Err(Error::Verification);
}
let s = os2ip(sig, pub_key.n_bits_precision()).map_err(|_| Error::Verification)?;
if s >= *pub_key.n().as_ref() {
return Err(Error::Verification);
}
let em = i2osp(rsa_encrypt(pub_key, &s)?, pub_key.size());
pkcs1v15_sign_unpad(prefix, hashed, &em, pub_key.size())
}
mod oid {
use const_oid::ObjectIdentifier;
pub trait RsaSignatureAssociatedOid {
const OID: ObjectIdentifier;
}
#[cfg(feature = "sha1")]
impl RsaSignatureAssociatedOid for sha1::Sha1 {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.5");
}
impl RsaSignatureAssociatedOid for sha2::Sha224 {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.14");
}
impl RsaSignatureAssociatedOid for sha2::Sha256 {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11");
}
impl RsaSignatureAssociatedOid for sha2::Sha384 {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.12");
}
impl RsaSignatureAssociatedOid for sha2::Sha512 {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.13");
}
}
pub use oid::RsaSignatureAssociatedOid;
#[cfg(test)]
mod tests {
use super::*;
use ::signature::{
DigestSigner, DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner,
SignatureEncoding, Signer, Verifier,
hazmat::{PrehashSigner, PrehashVerifier},
};
use base64ct::{Base64, Encoding};
use crypto_bigint::BoxedUint;
use hex_literal::hex;
use rand::rngs::ChaCha8Rng;
use rand_core::{Rng, SeedableRng};
use rstest::rstest;
use sha1::{Digest, Sha1};
use sha2::Sha256;
use sha3::Sha3_256;
use crate::traits::{
Decryptor, EncryptingKeypair, PublicKeyParts, RandomizedDecryptor, RandomizedEncryptor,
};
use crate::{RsaPrivateKey, RsaPublicKey};
fn get_private_key() -> RsaPrivateKey {
RsaPrivateKey::from_components(
BoxedUint::from_be_hex("B2990F49C47DFA8CD400AE6A4D1B8A3B6A13642B23F28B003BFB97790ADE9A4CC82B8B2A81747DDEC08B6296E53A08C331687EF25C4BF4936BA1C0E6041E9D15", 512).unwrap(),
BoxedUint::from(65_537u64),
BoxedUint::from_be_hex("8ABD6A69F4D1A4B487F0AB8D7AAEFD38609405C999984E30F567E1E8AEEFF44E8B18BDB1EC78DFA31A55E32A48D7FB131F5AF1F44D7D6B2CED2A9DF5E5AE4535", 512).unwrap(),
vec![
BoxedUint::from_be_hex("DAB2F18048BAA68DE7DF04D2D35D5D80E60E2DFA42D50A9B04219032715E46B3", 256).unwrap(),
BoxedUint::from_be_hex("D10F2E66B1D0C13F10EF9927BF5324A379CA218146CBF9CAFC795221F16A3117", 256).unwrap()
],
).unwrap()
}
#[rstest]
#[case(
"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
"x"
)]
#[case(
"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
"testing."
)]
#[case(
"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
"testing.\n"
)]
#[case(
"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
"01234567890123456789012345678901234567890123456789012"
)]
fn test_decrypt_pkcs1v15(#[case] ciphertext: &str, #[case] plaintext: &str) {
let priv_key = get_private_key();
let out = priv_key
.decrypt(Pkcs1v15Encrypt, &Base64::decode_vec(ciphertext).unwrap())
.unwrap();
assert_eq!(out, plaintext.as_bytes());
}
#[test]
fn test_encrypt_decrypt_pkcs1v15() {
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let priv_key = get_private_key();
let k = priv_key.size();
for i in 1..100 {
let mut input = vec![0u8; i * 8];
rng.fill_bytes(&mut input);
if input.len() > k - 11 {
input = input[0..k - 11].to_vec();
}
let pub_key: RsaPublicKey = priv_key.clone().into();
let ciphertext = encrypt(&mut rng, &pub_key, &input).unwrap();
assert_ne!(input, ciphertext);
let blind: bool = rng.next_u32() < (1u32 << 31);
let blinder = if blind { Some(&mut rng) } else { None };
let plaintext = decrypt(blinder, &priv_key, &ciphertext).unwrap();
assert_eq!(input, plaintext);
}
}
#[rstest]
#[case(
"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
"x"
)]
#[case(
"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
"testing."
)]
#[case(
"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
"testing.\n"
)]
#[case(
"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
"01234567890123456789012345678901234567890123456789012"
)]
fn test_decrypt_pkcs1v15_traits(#[case] ciphertext: &str, #[case] plaintext: &str) {
let priv_key = get_private_key();
let decrypting_key = DecryptingKey::new(priv_key);
let out = decrypting_key
.decrypt(&Base64::decode_vec(ciphertext).unwrap())
.unwrap();
assert_eq!(out, plaintext.as_bytes());
}
#[test]
fn test_decrypt_pkcs1v15_rejects_wrong_length() {
let priv_key = get_private_key();
let ct = hex!(
"00a40774c6e201e41714d1ab89c245116ff8f0baada675f22a50c7b6c1210e"
"3d2c3b7c595462aa8cb9447c43ef7d50ebcf544789b19ca5c2a26daea72cf9dbde"
);
assert_eq!(priv_key.decrypt(Pkcs1v15Encrypt, &ct).unwrap(), b"x");
assert_eq!(
priv_key.decrypt(Pkcs1v15Encrypt, &ct[1..]),
Err(Error::Decryption)
);
let mut long = vec![0u8];
long.extend_from_slice(&ct);
assert_eq!(
priv_key.decrypt(Pkcs1v15Encrypt, &long),
Err(Error::Decryption)
);
}
#[test]
fn implicit_rejection_preserves_public_errors() {
let tiny_key = RsaPrivateKey::from_components(
BoxedUint::from(3233u64),
BoxedUint::from(17u64),
BoxedUint::from(413u64),
vec![BoxedUint::from(61u64), BoxedUint::from(53u64)],
)
.unwrap();
assert_eq!(
tiny_key.decrypt(Pkcs1v15Encrypt, &[0; 2]),
Err(Error::Decryption)
);
let key = get_private_key();
let typed = DecryptingKey::new(key.clone());
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let k = key.size();
for ciphertext in [
vec![],
vec![0; k - 1],
vec![0; k + 1],
i2osp(key.n().as_ref().clone(), k),
vec![0xff; k],
] {
assert_eq!(
key.decrypt(Pkcs1v15Encrypt, &ciphertext),
Err(Error::Decryption)
);
assert_eq!(
key.decrypt_blinded(&mut rng, Pkcs1v15Encrypt, &ciphertext),
Err(Error::Decryption)
);
assert_eq!(typed.decrypt(&ciphertext), Err(Error::Decryption));
assert_eq!(
typed.decrypt_with_rng(&mut rng, &ciphertext),
Err(Error::Decryption)
);
}
let ciphertext = vec![0; k];
let expected = key.decrypt(Pkcs1v15Encrypt, &ciphertext).unwrap();
assert!(expected.len() <= k - 11);
assert_eq!(
typed.decrypt_with_rng(&mut rng, &ciphertext).unwrap(),
expected
);
assert_eq!(typed.decrypt(&ciphertext).unwrap(), expected);
}
#[test]
fn implicit_rejection_preserves_rng_errors() {
struct FailingRng;
impl rand_core::TryRng for FailingRng {
type Error = Error;
fn try_next_u32(&mut self) -> Result<u32> {
Err(Error::Rng)
}
fn try_next_u64(&mut self) -> Result<u64> {
Err(Error::Rng)
}
fn try_fill_bytes(&mut self, _: &mut [u8]) -> Result<()> {
Err(Error::Rng)
}
}
impl TryCryptoRng for FailingRng {}
let key = get_private_key();
let ciphertext = vec![0; key.size()];
assert_eq!(
Pkcs1v15Encrypt.decrypt(Some(&mut FailingRng), &key, &ciphertext),
Err(Error::Rng)
);
}
#[test]
fn test_encrypt_decrypt_pkcs1v15_traits() {
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let priv_key = get_private_key();
let k = priv_key.size();
let decrypting_key = DecryptingKey::new(priv_key);
for i in 1..100 {
let mut input = vec![0u8; i * 8];
rng.fill_bytes(&mut input);
if input.len() > k - 11 {
input = input[0..k - 11].to_vec();
}
let encrypting_key = decrypting_key.encrypting_key();
let ciphertext = encrypting_key.encrypt_with_rng(&mut rng, &input).unwrap();
assert_ne!(input, ciphertext);
let blind: bool = rng.next_u32() < (1u32 << 31);
let plaintext = if blind {
decrypting_key
.decrypt_with_rng(&mut rng, &ciphertext)
.unwrap()
} else {
decrypting_key.decrypt(&ciphertext).unwrap()
};
assert_eq!(input, plaintext);
}
}
#[rstest]
#[case("Test.\n", hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"))
]
fn test_sign_pkcs1v15(#[case] text: &str, #[case] expected: [u8; 64]) {
let priv_key = get_private_key();
let digest = Sha1::digest(text.as_bytes()).to_vec();
let out = priv_key.sign(Pkcs1v15Sign::new::<Sha1>(), &digest).unwrap();
assert_ne!(out, digest);
assert_eq!(out, expected);
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let out2 = priv_key
.sign_with_rng(&mut rng, Pkcs1v15Sign::new::<Sha1>(), &digest)
.unwrap();
assert_eq!(out2, expected);
}
#[rstest]
#[case("Test.\n", hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"))
]
fn test_sign_pkcs1v15_signer(#[case] text: &str, #[case] expected: [u8; 64]) {
let priv_key = get_private_key();
let signing_key = SigningKey::<Sha1>::new(priv_key);
let out = signing_key.sign(text.as_bytes()).to_bytes();
assert_ne!(out.as_ref(), text.as_bytes());
assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
assert_eq!(out.as_ref(), expected);
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let out2 = signing_key
.sign_with_rng(&mut rng, text.as_bytes())
.to_bytes();
assert_eq!(out2.as_ref(), expected);
}
#[rstest]
#[case("Test.\n", hex!(
"2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea"
"02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b"))
]
fn test_sign_pkcs1v15_signer_sha2_256(#[case] text: &str, #[case] expected: [u8; 64]) {
let priv_key = get_private_key();
let signing_key = SigningKey::<Sha256>::new(priv_key);
let out = signing_key.sign(text.as_bytes()).to_bytes();
assert_ne!(out.as_ref(), text.as_bytes());
assert_eq!(out.as_ref(), expected);
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let out2 = signing_key
.sign_with_rng(&mut rng, text.as_bytes())
.to_bytes();
assert_eq!(out2.as_ref(), expected);
}
#[rstest]
#[case("Test.\n", hex!(
"55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7"
"2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9"))
]
fn test_sign_pkcs1v15_signer_sha3_256(#[case] text: &str, #[case] expected: [u8; 64]) {
let priv_key = get_private_key();
let signing_key = SigningKey::<Sha3_256>::new(priv_key);
let out = signing_key.sign(text.as_bytes()).to_bytes();
assert_ne!(out.as_ref(), text.as_bytes());
assert_eq!(out.as_ref(), expected);
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let out2 = signing_key
.sign_with_rng(&mut rng, text.as_bytes())
.to_bytes();
assert_eq!(out2.as_ref(), expected);
}
#[rstest]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
)
)]
fn test_sign_pkcs1v15_digest_signer(#[case] text: &str, #[case] expected: [u8; 64]) {
let priv_key = get_private_key();
let signing_key = SigningKey::new(priv_key);
let mut digest = Sha1::new();
digest.update(text.as_bytes());
let out = signing_key
.sign_digest(|digest: &mut Sha1| digest.update(text.as_bytes()))
.to_bytes();
assert_ne!(out.as_ref(), text.as_bytes());
assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
assert_eq!(out.as_ref(), expected);
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let out2 = signing_key
.sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(text.as_bytes()))
.to_bytes();
assert_eq!(out2.as_ref(), expected);
}
#[rstest]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
),
true
)]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
),
false
)]
fn test_verify_pkcs1v15(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) {
let priv_key = get_private_key();
let pub_key: RsaPublicKey = priv_key.into();
let digest = Sha1::digest(text.as_bytes()).to_vec();
let result = pub_key.verify(Pkcs1v15Sign::new::<Sha1>(), &digest, &sig);
match expected {
true => result.expect("failed to verify"),
false => {
result.expect_err("expected verifying error");
}
}
}
#[rstest]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
),
true
)]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
),
false
)]
fn test_verify_pkcs1v15_signer(
#[case] text: &str,
#[case] sig: [u8; 64],
#[case] expected: bool,
) {
let priv_key = get_private_key();
let pub_key: RsaPublicKey = priv_key.into();
let verifying_key = VerifyingKey::<Sha1>::new(pub_key);
let result = verifying_key.verify(
text.as_bytes(),
&Signature::try_from(sig.as_slice()).unwrap(),
);
match expected {
true => result.expect("failed to verify"),
false => {
result.expect_err("expected verifying error");
}
}
}
#[rstest]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
),
true
)]
#[case(
"Test.\n",
hex!(
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
),
false
)]
fn test_verify_pkcs1v15_digest_signer(
#[case] text: &str,
#[case] sig: [u8; 64],
#[case] expected: bool,
) {
let priv_key = get_private_key();
let pub_key: RsaPublicKey = priv_key.into();
let verifying_key = VerifyingKey::new(pub_key);
let result = verifying_key.verify_digest(
|digest: &mut Sha1| {
digest.update(text.as_bytes());
Ok(())
},
&Signature::try_from(sig.as_slice()).unwrap(),
);
match expected {
true => result.expect("failed to verify"),
false => {
result.expect_err("expected verifying error");
}
}
}
#[test]
fn test_unpadded_signature() {
let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
let priv_key = get_private_key();
let sig = priv_key.sign(Pkcs1v15Sign::new_unprefixed(), msg).unwrap();
assert_eq!(expected_sig, sig);
let pub_key: RsaPublicKey = priv_key.into();
pub_key
.verify(Pkcs1v15Sign::new_unprefixed(), msg, &sig)
.expect("failed to verify");
}
#[test]
fn test_unpadded_signature_hazmat() {
let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
let priv_key = get_private_key();
let signing_key = SigningKey::<Sha1>::new_unprefixed(priv_key);
let sig = signing_key
.sign_prehash(msg)
.expect("Failure during sign")
.to_bytes();
assert_eq!(sig.as_ref(), expected_sig);
let verifying_key = signing_key.verifying_key();
verifying_key
.verify_prehash(msg, &Signature::try_from(expected_sig.as_slice()).unwrap())
.expect("failed to verify");
}
}