2022-10-31 14:15:52 -06:00
|
|
|
//! PKCS#1 v1.5 support as described in [RFC8017 § 8.2].
|
|
|
|
//!
|
2022-11-12 18:43:30 -07:00
|
|
|
//! # Usage
|
|
|
|
//!
|
|
|
|
//! See [code example in the toplevel rustdoc](../index.html#pkcs1-v15-signatures).
|
|
|
|
//!
|
2022-10-31 14:15:52 -06:00
|
|
|
//! [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
|
|
|
|
|
2023-04-27 07:58:19 -06:00
|
|
|
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 core::fmt::Debug;
|
2022-09-07 20:47:03 +03:00
|
|
|
use digest::Digest;
|
2023-04-18 12:17:07 -06:00
|
|
|
use num_bigint::BigUint;
|
2023-04-27 07:58:19 -06:00
|
|
|
use pkcs8::AssociatedOid;
|
2022-12-05 05:03:38 +03:00
|
|
|
use rand_core::CryptoRngCore;
|
2023-04-27 07:58:19 -06:00
|
|
|
use zeroize::Zeroizing;
|
2018-07-24 01:01:44 +02:00
|
|
|
|
2023-04-24 01:53:21 +03:00
|
|
|
use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
use crate::algorithms::pkcs1v15::*;
|
2023-04-24 01:53:21 +03:00
|
|
|
use crate::algorithms::rsa::{rsa_decrypt_and_check, rsa_encrypt};
|
2019-03-18 09:29:05 -07:00
|
|
|
use crate::errors::{Error, Result};
|
2023-04-27 07:58:19 -06:00
|
|
|
use crate::key::{self, RsaPrivateKey, RsaPublicKey};
|
|
|
|
use crate::traits::{PaddingScheme, PublicKeyParts, SignatureScheme};
|
2022-08-19 20:46:40 +03:00
|
|
|
|
2023-01-10 13:59:31 -07:00
|
|
|
/// Encryption using PKCS#1 v1.5 padding.
|
|
|
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
|
|
pub struct Pkcs1v15Encrypt;
|
|
|
|
|
|
|
|
impl PaddingScheme for Pkcs1v15Encrypt {
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn decrypt<Rng: CryptoRngCore>(
|
2023-01-10 13:59:31 -07:00
|
|
|
self,
|
|
|
|
rng: Option<&mut Rng>,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
priv_key: &RsaPrivateKey,
|
2023-01-10 13:59:31 -07:00
|
|
|
ciphertext: &[u8],
|
|
|
|
) -> Result<Vec<u8>> {
|
|
|
|
decrypt(rng, priv_key, ciphertext)
|
|
|
|
}
|
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn encrypt<Rng: CryptoRngCore>(
|
2023-01-10 13:59:31 -07:00
|
|
|
self,
|
|
|
|
rng: &mut Rng,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
pub_key: &RsaPublicKey,
|
2023-01-10 13:59:31 -07:00
|
|
|
msg: &[u8],
|
|
|
|
) -> Result<Vec<u8>> {
|
|
|
|
encrypt(rng, pub_key, msg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-03 17:13:52 -06:00
|
|
|
/// `RSASSA-PKCS1-v1_5`: digital signatures using PKCS#1 v1.5 padding.
|
2023-01-10 13:59:31 -07:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub struct Pkcs1v15Sign {
|
|
|
|
/// Length of hash to use.
|
|
|
|
pub hash_len: Option<usize>,
|
|
|
|
|
|
|
|
/// Prefix.
|
|
|
|
pub prefix: Box<[u8]>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Pkcs1v15Sign {
|
|
|
|
/// Create new PKCS#1 v1.5 padding for the given digest.
|
|
|
|
///
|
|
|
|
/// The digest must have an [`AssociatedOid`]. Make sure to enable the `oid`
|
|
|
|
/// feature of the relevant digest crate.
|
|
|
|
pub fn new<D>() -> Self
|
|
|
|
where
|
|
|
|
D: Digest + AssociatedOid,
|
|
|
|
{
|
|
|
|
Self {
|
|
|
|
hash_len: Some(<D as Digest>::output_size()),
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
prefix: pkcs1v15_generate_prefix::<D>().into_boxed_slice(),
|
2023-01-10 13:59:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-17 06:40:24 -06:00
|
|
|
/// Create new PKCS#1 v1.5 padding for computing an unprefixed signature.
|
2023-01-10 13:59:31 -07:00
|
|
|
///
|
|
|
|
/// This sets `hash_len` to `None` and uses an empty `prefix`.
|
2023-04-17 06:40:24 -06:00
|
|
|
pub fn new_unprefixed() -> Self {
|
2023-01-10 13:59:31 -07:00
|
|
|
Self {
|
|
|
|
hash_len: None,
|
|
|
|
prefix: Box::new([]),
|
|
|
|
}
|
|
|
|
}
|
2023-04-17 06:40:24 -06:00
|
|
|
|
|
|
|
/// Create new PKCS#1 v1.5 padding for computing an unprefixed signature.
|
|
|
|
///
|
|
|
|
/// This sets `hash_len` to `None` and uses an empty `prefix`.
|
|
|
|
#[deprecated(since = "0.9.0", note = "use Pkcs1v15Sign::new_unprefixed instead")]
|
|
|
|
pub fn new_raw() -> Self {
|
|
|
|
Self::new_unprefixed()
|
|
|
|
}
|
2023-01-10 13:59:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SignatureScheme for Pkcs1v15Sign {
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn sign<Rng: CryptoRngCore>(
|
2023-01-10 13:59:31 -07:00
|
|
|
self,
|
|
|
|
rng: Option<&mut Rng>,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
priv_key: &RsaPrivateKey,
|
2023-01-10 13:59:31 -07:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn verify(self, pub_key: &RsaPublicKey, hashed: &[u8], sig: &[u8]) -> Result<()> {
|
2023-01-10 13:59:31 -07:00
|
|
|
if let Some(hash_len) = self.hash_len {
|
|
|
|
if hashed.len() != hash_len {
|
|
|
|
return Err(Error::InputNotHashed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-18 12:17:07 -06:00
|
|
|
verify(
|
|
|
|
pub_key,
|
|
|
|
self.prefix.as_ref(),
|
|
|
|
hashed,
|
|
|
|
&BigUint::from_bytes_be(sig),
|
2023-04-25 08:36:26 -06:00
|
|
|
sig.len(),
|
2023-04-18 12:17:07 -06:00
|
|
|
)
|
2023-01-10 13:59:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-31 14:15:52 -06:00
|
|
|
/// Encrypts the given message with RSA and the padding
|
|
|
|
/// scheme from PKCS#1 v1.5. The message must be no longer than the
|
|
|
|
/// length of the public modulus minus 11 bytes.
|
2018-07-24 14:31:06 +02:00
|
|
|
#[inline]
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn encrypt<R: CryptoRngCore + ?Sized>(
|
2022-03-13 19:50:05 +00:00
|
|
|
rng: &mut R,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
pub_key: &RsaPublicKey,
|
2022-03-13 19:50:05 +00:00
|
|
|
msg: &[u8],
|
|
|
|
) -> Result<Vec<u8>> {
|
2018-07-24 01:01:44 +02:00
|
|
|
key::check_public(pub_key)?;
|
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
let em = pkcs1v15_encrypt_pad(rng, msg, pub_key.size())?;
|
|
|
|
let int = Zeroizing::new(BigUint::from_bytes_be(&em));
|
2023-04-24 01:53:21 +03:00
|
|
|
uint_to_be_pad(rsa_encrypt(pub_key, &int)?, pub_key.size())
|
2018-07-24 01:01:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
|
2022-10-31 14:15:52 -06:00
|
|
|
///
|
|
|
|
/// If an `rng` is passed, it uses RSA blinding to avoid timing side-channel attacks.
|
|
|
|
///
|
|
|
|
/// Note that whether this function returns an error or not discloses secret
|
|
|
|
/// information. If an attacker can cause this function to run repeatedly and
|
|
|
|
/// learn whether each instance returned an error then they can decrypt and
|
|
|
|
/// forge signatures as if they had the private key. See
|
|
|
|
/// `decrypt_session_key` for a way of solving this problem.
|
2018-07-24 14:31:06 +02:00
|
|
|
#[inline]
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn decrypt<R: CryptoRngCore + ?Sized>(
|
2018-07-24 01:01:44 +02:00
|
|
|
rng: Option<&mut R>,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
priv_key: &RsaPrivateKey,
|
2018-07-24 01:01:44 +02:00
|
|
|
ciphertext: &[u8],
|
|
|
|
) -> Result<Vec<u8>> {
|
|
|
|
key::check_public(priv_key)?;
|
|
|
|
|
2023-04-24 01:53:21 +03:00
|
|
|
let em = rsa_decrypt_and_check(priv_key, rng, &BigUint::from_bytes_be(ciphertext))?;
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
let em = uint_to_zeroizing_be_pad(em, priv_key.size())?;
|
2018-07-24 01:01:44 +02:00
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
pkcs1v15_encrypt_unpad(em, priv_key.size())
|
2018-07-24 01:01:44 +02:00
|
|
|
}
|
|
|
|
|
2022-10-31 14:15:52 -06:00
|
|
|
/// Calculates the signature of hashed using
|
|
|
|
/// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that `hashed` must
|
|
|
|
/// be the result of hashing the input message using the given hash
|
|
|
|
/// function. If hash is `None`, hashed is signed directly. This isn't
|
|
|
|
/// advisable except for interoperability.
|
|
|
|
///
|
|
|
|
/// If `rng` is not `None` then RSA blinding will be used to avoid timing
|
|
|
|
/// side-channel attacks.
|
|
|
|
///
|
|
|
|
/// This function is deterministic. Thus, if the set of possible
|
|
|
|
/// messages is small, an attacker may be able to build a map from
|
|
|
|
/// messages to signatures and identify the signed messages. As ever,
|
|
|
|
/// signatures provide authenticity, not confidentiality.
|
2018-07-24 14:31:06 +02:00
|
|
|
#[inline]
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
fn sign<R: CryptoRngCore + ?Sized>(
|
2018-07-24 14:31:06 +02:00
|
|
|
rng: Option<&mut R>,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
priv_key: &RsaPrivateKey,
|
2022-09-16 20:25:05 +03:00
|
|
|
prefix: &[u8],
|
2018-07-24 14:31:06 +02:00
|
|
|
hashed: &[u8],
|
|
|
|
) -> Result<Vec<u8>> {
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
let em = pkcs1v15_sign_pad(prefix, hashed, priv_key.size())?;
|
2018-07-24 14:31:06 +02:00
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
uint_to_zeroizing_be_pad(
|
2023-04-24 01:53:21 +03:00
|
|
|
rsa_decrypt_and_check(priv_key, rng, &BigUint::from_bytes_be(&em))?,
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
priv_key.size(),
|
|
|
|
)
|
2018-07-24 14:31:06 +02:00
|
|
|
}
|
|
|
|
|
2018-07-24 22:04:41 +02:00
|
|
|
/// Verifies an RSA PKCS#1 v1.5 signature.
|
|
|
|
#[inline]
|
2023-04-25 08:36:26 -06:00
|
|
|
fn verify(
|
|
|
|
pub_key: &RsaPublicKey,
|
|
|
|
prefix: &[u8],
|
|
|
|
hashed: &[u8],
|
|
|
|
sig: &BigUint,
|
|
|
|
sig_len: usize,
|
|
|
|
) -> Result<()> {
|
|
|
|
if sig >= pub_key.n() || sig_len != pub_key.size() {
|
|
|
|
return Err(Error::Verification);
|
|
|
|
}
|
|
|
|
|
2023-04-24 01:53:21 +03:00
|
|
|
let em = uint_to_be_pad(rsa_encrypt(pub_key, sig)?, pub_key.size())?;
|
2018-07-24 01:01:44 +02:00
|
|
|
|
Remove primitive traits (#300)
The crate contains several exported traits targeting
hardware-accelerated implementations (PublicKey, PrivateKey,
EncryptionPrimitive, DecriptionPrimitive). However these traits
overcomplicate internal structure of the crate. It is not clear, which
level of API can be implemented by the hardware accelerators.
The crate is already quite complicated, implementing both
PaddingScheme-based API and Signer/Verifier/Encryptor/Decryptor API.
Remove the complication for now. The proper level of indirection can be
introduced once support for actual hardware accelerators is implemented.
Inline and drop the RsaPrivateKey::raw_decryption_primitive() function.
There is no need to zeroize argument, it is ciphertext, so it can be
assumed to be safe.
Change raw_int_decryption_primitive() and raw_int_decryption_primitive()
to output Result<BigUint> instead of Result<Vec<u8>>, because they also
take BigUint rather than Vec<u8> or &[u8].
In order to simplify adding support for RSA hardware accelerators, move
all formatting and padding functions to a separate modules, making it
theoretically possible to use that for implementing support for
low-level RSA hardware accelerators.
Also follows the pkcs1v15 change and use BigUint as a Signature's
internal implementation.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-04-19 17:51:06 +03:00
|
|
|
pkcs1v15_sign_unpad(prefix, hashed, &em, pub_key.size())
|
2018-07-24 01:01:44 +02:00
|
|
|
}
|
|
|
|
|
2023-04-05 05:12:08 +03:00
|
|
|
mod oid {
|
|
|
|
use const_oid::ObjectIdentifier;
|
|
|
|
|
|
|
|
/// A trait which associates an RSA-specific OID with a type.
|
|
|
|
pub(crate) trait RsaSignatureAssociatedOid {
|
|
|
|
/// The OID associated with this type.
|
|
|
|
const OID: ObjectIdentifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "sha1")]
|
|
|
|
impl RsaSignatureAssociatedOid for sha1::Sha1 {
|
|
|
|
const OID: ObjectIdentifier =
|
|
|
|
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.5");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "sha2")]
|
|
|
|
impl RsaSignatureAssociatedOid for sha2::Sha224 {
|
|
|
|
const OID: ObjectIdentifier =
|
|
|
|
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.14");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "sha2")]
|
|
|
|
impl RsaSignatureAssociatedOid for sha2::Sha256 {
|
|
|
|
const OID: ObjectIdentifier =
|
|
|
|
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "sha2")]
|
|
|
|
impl RsaSignatureAssociatedOid for sha2::Sha384 {
|
|
|
|
const OID: ObjectIdentifier =
|
|
|
|
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.12");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "sha2")]
|
|
|
|
impl RsaSignatureAssociatedOid for sha2::Sha512 {
|
|
|
|
const OID: ObjectIdentifier =
|
|
|
|
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.13");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-24 01:01:44 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2023-04-27 07:58:19 -06:00
|
|
|
use ::signature::{
|
|
|
|
hazmat::{PrehashSigner, PrehashVerifier},
|
|
|
|
DigestSigner, DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner,
|
|
|
|
SignatureEncoding, Signer, Verifier,
|
|
|
|
};
|
2022-03-13 19:50:05 +00:00
|
|
|
use base64ct::{Base64, Encoding};
|
|
|
|
use hex_literal::hex;
|
2020-01-02 21:51:43 -05:00
|
|
|
use num_bigint::BigUint;
|
2018-11-08 18:17:59 +01:00
|
|
|
use num_traits::FromPrimitive;
|
2018-07-24 01:01:44 +02:00
|
|
|
use num_traits::Num;
|
2022-12-05 05:03:38 +03:00
|
|
|
use rand_chacha::{
|
|
|
|
rand_core::{RngCore, SeedableRng},
|
|
|
|
ChaCha8Rng,
|
|
|
|
};
|
2018-07-24 14:31:06 +02:00
|
|
|
use sha1::{Digest, Sha1};
|
2022-09-07 20:47:03 +03:00
|
|
|
use sha2::Sha256;
|
2022-09-16 20:25:05 +03:00
|
|
|
use sha3::Sha3_256;
|
2018-07-24 14:31:06 +02:00
|
|
|
|
2023-04-27 07:58:19 -06:00
|
|
|
use crate::traits::{
|
|
|
|
Decryptor, EncryptingKeypair, PublicKeyParts, RandomizedDecryptor, RandomizedEncryptor,
|
|
|
|
};
|
|
|
|
use crate::{RsaPrivateKey, RsaPublicKey};
|
2018-07-24 01:01:44 +02:00
|
|
|
|
2021-07-26 23:25:13 +02:00
|
|
|
fn get_private_key() -> RsaPrivateKey {
|
2018-07-24 01:01:44 +02:00
|
|
|
// In order to generate new test vectors you'll need the PEM form of this key:
|
|
|
|
// -----BEGIN RSA PRIVATE KEY-----
|
|
|
|
// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
|
|
|
|
// fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
|
|
|
|
// /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
|
|
|
|
// RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
|
|
|
|
// EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
|
|
|
|
// IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
|
|
|
|
// tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
|
|
|
|
// -----END RSA PRIVATE KEY-----
|
|
|
|
|
2021-07-26 23:25:13 +02:00
|
|
|
RsaPrivateKey::from_components(
|
2018-07-24 01:01:44 +02:00
|
|
|
BigUint::from_str_radix("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077", 10).unwrap(),
|
2018-11-08 18:17:59 +01:00
|
|
|
BigUint::from_u64(65537).unwrap(),
|
2018-07-24 01:01:44 +02:00
|
|
|
BigUint::from_str_radix("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861", 10).unwrap(),
|
|
|
|
vec![
|
|
|
|
BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
|
|
|
|
BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
|
|
|
|
],
|
2022-07-25 06:35:47 -06:00
|
|
|
).unwrap()
|
2018-07-24 01:01:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_decrypt_pkcs1v15() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [[
|
|
|
|
"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
|
|
|
|
"x",
|
|
|
|
], [
|
|
|
|
"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
|
|
|
|
"testing.",
|
|
|
|
], [
|
|
|
|
"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
|
|
|
|
"testing.\n",
|
|
|
|
], [
|
|
|
|
"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
|
|
|
|
"01234567890123456789012345678901234567890123456789012",
|
|
|
|
]];
|
|
|
|
|
|
|
|
for test in &tests {
|
|
|
|
let out = priv_key
|
2023-01-10 13:59:31 -07:00
|
|
|
.decrypt(Pkcs1v15Encrypt, &Base64::decode_vec(test[0]).unwrap())
|
2018-07-24 01:01:44 +02:00
|
|
|
.unwrap();
|
|
|
|
assert_eq!(out, test[1].as_bytes());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_encrypt_decrypt_pkcs1v15() {
|
2022-03-14 14:22:48 +00:00
|
|
|
let mut rng = ChaCha8Rng::from_seed([42; 32]);
|
2018-07-24 01:01:44 +02:00
|
|
|
let priv_key = get_private_key();
|
|
|
|
let k = priv_key.size();
|
|
|
|
|
|
|
|
for i in 1..100 {
|
2022-03-13 19:50:05 +00:00
|
|
|
let mut input = vec![0u8; i * 8];
|
|
|
|
rng.fill_bytes(&mut input);
|
2018-07-24 01:01:44 +02:00
|
|
|
if input.len() > k - 11 {
|
|
|
|
input = input[0..k - 11].to_vec();
|
|
|
|
}
|
|
|
|
|
2021-07-26 23:25:13 +02:00
|
|
|
let pub_key: RsaPublicKey = priv_key.clone().into();
|
2018-07-24 01:01:44 +02:00
|
|
|
let ciphertext = encrypt(&mut rng, &pub_key, &input).unwrap();
|
|
|
|
assert_ne!(input, ciphertext);
|
2022-03-13 19:50:05 +00:00
|
|
|
|
|
|
|
let blind: bool = rng.next_u32() < (1u32 << 31);
|
2018-07-24 01:01:44 +02:00
|
|
|
let blinder = if blind { Some(&mut rng) } else { None };
|
|
|
|
let plaintext = decrypt(blinder, &priv_key, &ciphertext).unwrap();
|
|
|
|
assert_eq!(input, plaintext);
|
|
|
|
}
|
|
|
|
}
|
2018-07-24 14:31:06 +02:00
|
|
|
|
2023-02-13 18:35:20 +03:00
|
|
|
#[test]
|
|
|
|
fn test_decrypt_pkcs1v15_traits() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
let decrypting_key = DecryptingKey::new(priv_key);
|
|
|
|
|
|
|
|
let tests = [[
|
|
|
|
"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
|
|
|
|
"x",
|
|
|
|
], [
|
|
|
|
"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
|
|
|
|
"testing.",
|
|
|
|
], [
|
|
|
|
"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
|
|
|
|
"testing.\n",
|
|
|
|
], [
|
|
|
|
"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
|
|
|
|
"01234567890123456789012345678901234567890123456789012",
|
|
|
|
]];
|
|
|
|
|
|
|
|
for test in &tests {
|
|
|
|
let out = decrypting_key
|
|
|
|
.decrypt(&Base64::decode_vec(test[0]).unwrap())
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(out, test[1].as_bytes());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-24 14:31:06 +02:00
|
|
|
#[test]
|
|
|
|
fn test_sign_pkcs1v15() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
2022-03-13 19:50:05 +00:00
|
|
|
let tests = [(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
|
|
|
),
|
|
|
|
)];
|
2018-07-24 14:31:06 +02:00
|
|
|
|
2022-03-13 19:50:05 +00:00
|
|
|
for (text, expected) in &tests {
|
|
|
|
let digest = Sha1::digest(text.as_bytes()).to_vec();
|
2018-07-24 14:31:06 +02:00
|
|
|
|
2023-01-10 13:59:31 -07:00
|
|
|
let out = priv_key.sign(Pkcs1v15Sign::new::<Sha1>(), &digest).unwrap();
|
2018-07-24 14:31:06 +02:00
|
|
|
assert_ne!(out, digest);
|
|
|
|
assert_eq!(out, expected);
|
|
|
|
|
2022-03-14 14:22:48 +00:00
|
|
|
let mut rng = ChaCha8Rng::from_seed([42; 32]);
|
2018-07-24 14:31:06 +02:00
|
|
|
let out2 = priv_key
|
2023-01-10 13:59:31 -07:00
|
|
|
.sign_with_rng(&mut rng, Pkcs1v15Sign::new::<Sha1>(), &digest)
|
2018-07-24 14:31:06 +02:00
|
|
|
.unwrap();
|
|
|
|
assert_eq!(out2, expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-24 22:04:41 +02:00
|
|
|
#[test]
|
2022-08-19 20:46:40 +03:00
|
|
|
fn test_sign_pkcs1v15_signer() {
|
2018-07-24 22:04:41 +02:00
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
2022-09-16 20:25:05 +03:00
|
|
|
let tests = [(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
|
|
|
),
|
|
|
|
)];
|
|
|
|
|
2023-04-11 06:37:34 -06:00
|
|
|
let signing_key = SigningKey::<Sha1>::new(priv_key);
|
2022-09-16 20:25:05 +03:00
|
|
|
|
|
|
|
for (text, expected) in &tests {
|
2023-04-18 12:17:07 -06:00
|
|
|
let out = signing_key.sign(text.as_bytes()).to_bytes();
|
2022-09-16 20:25:05 +03:00
|
|
|
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]);
|
2023-04-18 12:17:07 -06:00
|
|
|
let out2 = signing_key
|
|
|
|
.sign_with_rng(&mut rng, text.as_bytes())
|
|
|
|
.to_bytes();
|
2022-09-16 20:25:05 +03:00
|
|
|
assert_eq!(out2.as_ref(), expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_sign_pkcs1v15_signer_sha2_256() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
2022-03-13 19:50:05 +00:00
|
|
|
let tests = [(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-07 20:47:03 +03:00
|
|
|
"2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea"
|
|
|
|
"02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b"
|
2022-03-13 19:50:05 +00:00
|
|
|
),
|
|
|
|
)];
|
2022-08-19 20:46:40 +03:00
|
|
|
|
2023-04-11 06:37:34 -06:00
|
|
|
let signing_key = SigningKey::<Sha256>::new(priv_key);
|
2022-08-19 20:46:40 +03:00
|
|
|
|
|
|
|
for (text, expected) in &tests {
|
2023-04-18 12:17:07 -06:00
|
|
|
let out = signing_key.sign(text.as_bytes()).to_bytes();
|
2022-09-07 20:47:03 +03:00
|
|
|
assert_ne!(out.as_ref(), text.as_bytes());
|
|
|
|
assert_eq!(out.as_ref(), expected);
|
2022-08-19 20:46:40 +03:00
|
|
|
|
2022-09-07 20:47:03 +03:00
|
|
|
let mut rng = ChaCha8Rng::from_seed([42; 32]);
|
2023-04-18 12:17:07 -06:00
|
|
|
let out2 = signing_key
|
|
|
|
.sign_with_rng(&mut rng, text.as_bytes())
|
|
|
|
.to_bytes();
|
2022-09-07 20:47:03 +03:00
|
|
|
assert_eq!(out2.as_ref(), expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-16 20:25:05 +03:00
|
|
|
#[test]
|
|
|
|
fn test_sign_pkcs1v15_signer_sha3_256() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
|
|
|
"55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7"
|
|
|
|
"2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9"
|
|
|
|
),
|
|
|
|
)];
|
|
|
|
|
2023-04-11 06:37:34 -06:00
|
|
|
let signing_key = SigningKey::<Sha3_256>::new(priv_key);
|
2022-09-16 20:25:05 +03:00
|
|
|
|
|
|
|
for (text, expected) in &tests {
|
2023-04-18 12:17:07 -06:00
|
|
|
let out = signing_key.sign(text.as_bytes()).to_bytes();
|
2022-09-16 20:25:05 +03:00
|
|
|
assert_ne!(out.as_ref(), text.as_bytes());
|
|
|
|
assert_eq!(out.as_ref(), expected);
|
|
|
|
|
|
|
|
let mut rng = ChaCha8Rng::from_seed([42; 32]);
|
2023-04-18 12:17:07 -06:00
|
|
|
let out2 = signing_key
|
|
|
|
.sign_with_rng(&mut rng, text.as_bytes())
|
|
|
|
.to_bytes();
|
2022-09-16 20:25:05 +03:00
|
|
|
assert_eq!(out2.as_ref(), expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-07 20:47:03 +03:00
|
|
|
#[test]
|
|
|
|
fn test_sign_pkcs1v15_digest_signer() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-16 20:25:05 +03:00
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
2022-09-07 20:47:03 +03:00
|
|
|
),
|
|
|
|
)];
|
|
|
|
|
2023-04-11 06:37:34 -06:00
|
|
|
let signing_key = SigningKey::new(priv_key);
|
2022-09-07 20:47:03 +03:00
|
|
|
|
|
|
|
for (text, expected) in &tests {
|
2022-09-16 20:25:05 +03:00
|
|
|
let mut digest = Sha1::new();
|
2022-09-07 20:47:03 +03:00
|
|
|
digest.update(text.as_bytes());
|
2023-04-18 12:17:07 -06:00
|
|
|
let out = signing_key.sign_digest(digest).to_bytes();
|
2022-09-07 20:47:03 +03:00
|
|
|
assert_ne!(out.as_ref(), text.as_bytes());
|
|
|
|
assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
|
2022-08-19 20:46:40 +03:00
|
|
|
assert_eq!(out.as_ref(), expected);
|
|
|
|
|
|
|
|
let mut rng = ChaCha8Rng::from_seed([42; 32]);
|
2022-09-16 20:25:05 +03:00
|
|
|
let mut digest = Sha1::new();
|
2022-09-07 20:47:03 +03:00
|
|
|
digest.update(text.as_bytes());
|
2023-04-18 12:17:07 -06:00
|
|
|
let out2 = signing_key
|
|
|
|
.sign_digest_with_rng(&mut rng, digest)
|
|
|
|
.to_bytes();
|
2022-08-19 20:46:40 +03:00
|
|
|
assert_eq!(out2.as_ref(), expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_verify_pkcs1v15() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
|
|
|
),
|
|
|
|
true,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
|
|
|
|
),
|
|
|
|
false,
|
|
|
|
),
|
|
|
|
];
|
2021-07-26 23:25:13 +02:00
|
|
|
let pub_key: RsaPublicKey = priv_key.into();
|
2018-07-24 22:04:41 +02:00
|
|
|
|
2022-08-19 20:46:40 +03:00
|
|
|
for (text, sig, expected) in &tests {
|
2022-03-13 19:50:05 +00:00
|
|
|
let digest = Sha1::digest(text.as_bytes()).to_vec();
|
2018-07-24 22:04:41 +02:00
|
|
|
|
2023-01-10 13:59:31 -07:00
|
|
|
let result = pub_key.verify(Pkcs1v15Sign::new::<Sha1>(), &digest, sig);
|
2022-08-19 20:46:40 +03:00
|
|
|
match expected {
|
|
|
|
true => result.expect("failed to verify"),
|
|
|
|
false => {
|
|
|
|
result.expect_err("expected verifying error");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_verify_pkcs1v15_signer() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-16 20:25:05 +03:00
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
2022-08-19 20:46:40 +03:00
|
|
|
),
|
|
|
|
true,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-16 20:25:05 +03:00
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
|
2022-08-19 20:46:40 +03:00
|
|
|
),
|
|
|
|
false,
|
|
|
|
),
|
|
|
|
];
|
|
|
|
let pub_key: RsaPublicKey = priv_key.into();
|
2023-04-11 06:37:34 -06:00
|
|
|
let verifying_key = VerifyingKey::<Sha1>::new(pub_key);
|
2022-08-19 20:46:40 +03:00
|
|
|
|
|
|
|
for (text, sig, expected) in &tests {
|
2022-12-05 05:03:38 +03:00
|
|
|
let result = verifying_key.verify(
|
|
|
|
text.as_bytes(),
|
|
|
|
&Signature::try_from(sig.as_slice()).unwrap(),
|
|
|
|
);
|
2022-08-19 20:46:40 +03:00
|
|
|
match expected {
|
|
|
|
true => result.expect("failed to verify"),
|
|
|
|
false => {
|
|
|
|
result.expect_err("expected verifying error");
|
|
|
|
}
|
|
|
|
}
|
2018-07-24 22:04:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-07 20:47:03 +03:00
|
|
|
#[test]
|
|
|
|
fn test_verify_pkcs1v15_digest_signer() {
|
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
|
|
|
let tests = [
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-16 20:25:05 +03:00
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
|
2022-09-07 20:47:03 +03:00
|
|
|
),
|
|
|
|
true,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"Test.\n",
|
|
|
|
hex!(
|
2022-09-16 20:25:05 +03:00
|
|
|
"a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
|
|
|
|
"6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
|
2022-09-07 20:47:03 +03:00
|
|
|
),
|
|
|
|
false,
|
|
|
|
),
|
|
|
|
];
|
|
|
|
let pub_key: RsaPublicKey = priv_key.into();
|
2023-04-11 06:37:34 -06:00
|
|
|
let verifying_key = VerifyingKey::new(pub_key);
|
2022-09-07 20:47:03 +03:00
|
|
|
|
|
|
|
for (text, sig, expected) in &tests {
|
2022-09-16 20:25:05 +03:00
|
|
|
let mut digest = Sha1::new();
|
2022-09-07 20:47:03 +03:00
|
|
|
digest.update(text.as_bytes());
|
2022-12-05 05:03:38 +03:00
|
|
|
let result =
|
|
|
|
verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap());
|
2022-09-07 20:47:03 +03:00
|
|
|
match expected {
|
|
|
|
true => result.expect("failed to verify"),
|
|
|
|
false => {
|
|
|
|
result.expect_err("expected verifying error");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-11 06:37:34 -06:00
|
|
|
|
2018-07-24 14:31:06 +02:00
|
|
|
#[test]
|
|
|
|
fn test_unpadded_signature() {
|
|
|
|
let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
|
2022-03-13 19:50:05 +00:00
|
|
|
let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
|
2018-07-24 14:31:06 +02:00
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
2023-04-17 06:40:24 -06:00
|
|
|
let sig = priv_key.sign(Pkcs1v15Sign::new_unprefixed(), msg).unwrap();
|
2018-07-24 14:31:06 +02:00
|
|
|
assert_eq!(expected_sig, sig);
|
|
|
|
|
2021-07-26 23:25:13 +02:00
|
|
|
let pub_key: RsaPublicKey = priv_key.into();
|
2018-07-24 22:04:41 +02:00
|
|
|
pub_key
|
2023-04-17 06:40:24 -06:00
|
|
|
.verify(Pkcs1v15Sign::new_unprefixed(), msg, &sig)
|
2018-07-24 22:04:41 +02:00
|
|
|
.expect("failed to verify");
|
2018-07-24 14:31:06 +02:00
|
|
|
}
|
2022-08-19 20:46:40 +03:00
|
|
|
|
|
|
|
#[test]
|
2022-09-22 19:03:46 +03:00
|
|
|
fn test_unpadded_signature_hazmat() {
|
2022-08-19 20:46:40 +03:00
|
|
|
let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
|
2022-09-22 19:03:46 +03:00
|
|
|
let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
|
2022-08-19 20:46:40 +03:00
|
|
|
let priv_key = get_private_key();
|
|
|
|
|
2023-04-11 06:37:34 -06:00
|
|
|
let signing_key = SigningKey::<Sha1>::new_unprefixed(priv_key);
|
2023-04-18 12:17:07 -06:00
|
|
|
let sig = signing_key
|
|
|
|
.sign_prehash(msg)
|
|
|
|
.expect("Failure during sign")
|
|
|
|
.to_bytes();
|
2022-08-19 20:46:40 +03:00
|
|
|
assert_eq!(sig.as_ref(), expected_sig);
|
|
|
|
|
2022-12-05 05:03:38 +03:00
|
|
|
let verifying_key = signing_key.verifying_key();
|
2022-08-19 20:46:40 +03:00
|
|
|
verifying_key
|
2023-04-18 12:17:07 -06:00
|
|
|
.verify_prehash(msg, &Signature::try_from(expected_sig.as_slice()).unwrap())
|
2022-08-19 20:46:40 +03:00
|
|
|
.expect("failed to verify");
|
|
|
|
}
|
2020-03-06 23:10:55 +01:00
|
|
|
}
|