Skip to content

Commit

Permalink
Update to RSA 0.7.0-rc version
Browse files Browse the repository at this point in the history
Update the RSA crate to the 0.7.0-rc version

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
  • Loading branch information
lumag committed Oct 18, 2022
1 parent 2a3cdcd commit 6ea108a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 44 deletions.
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ digest = "^0.10"
generic-array = "^0.14"
hex = "^0.4"
log = "0.4.6"
md-5 = "^0.10"
md-5 = { version = "^0.10.5", features = ["oid"] }
nom = "^4.2"
num-derive = "0.3.0"
num-traits = "0.2.6"
rand = "0.8"
ripemd = "^0.1"
rsa = "^0.6.0"
sha1 = "^0.10"
sha2 = "^0.10"
sha3 = "0.10"
ripemd = { version = "^0.1.3", features = ["oid"] }
rsa = { version = "^0.7.0", features = ["hazmat"] }
sha1 = { version = "^0.10.5", features = ["oid"] }
sha2 = { version = "^0.10.6", features = ["oid"] }
sha3 = { version = "^0.10.5", features = ["oid"] }
signature = "1.3.0"
smallvec = "1.6.1"
thiserror = "1.0.9"
Expand Down
25 changes: 1 addition & 24 deletions src/crypto/hash.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use std::boxed::Box;
use std::convert::TryInto;

use rsa::Hash;

use digest::Digest;
use md5::Md5;
use ripemd::Ripemd160;
use sha1::Sha1;

use crate::errors::{Error, Result};
use crate::errors::Result;

/// Available hash algorithms.
/// Ref: https://tools.ietf.org/html/rfc4880.html#section-9.4
Expand Down Expand Up @@ -38,26 +35,6 @@ impl Default for HashAlgorithm {
}
}

impl TryInto<Hash> for HashAlgorithm {
type Error = Error;

fn try_into(self) -> Result<Hash> {
match self {
HashAlgorithm::None => Err(format_err!("none")),
HashAlgorithm::MD5 => Ok(Hash::MD5),
HashAlgorithm::SHA1 => Ok(Hash::SHA1),
HashAlgorithm::RIPEMD160 => Ok(Hash::RIPEMD160),
HashAlgorithm::SHA2_256 => Ok(Hash::SHA2_256),
HashAlgorithm::SHA2_384 => Ok(Hash::SHA2_384),
HashAlgorithm::SHA2_512 => Ok(Hash::SHA2_512),
HashAlgorithm::SHA2_224 => Ok(Hash::SHA2_224),
HashAlgorithm::SHA3_256 => Ok(Hash::SHA3_256),
HashAlgorithm::SHA3_512 => Ok(Hash::SHA3_512),
HashAlgorithm::Private10 => unsupported_err!("Private10 should not be used"),
}
}
}

/// Trait to work around the fact that the `Digest` trait from rustcrypto can not
/// be used as `Box<Digest>`.
pub trait Hasher: std::io::Write {
Expand Down
79 changes: 69 additions & 10 deletions src/crypto/rsa.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
use std::convert::TryInto;

use num_bigint::traits::ModInverse;
use num_bigint::BigUint;
use rand::{CryptoRng, Rng};
use rsa::padding::PaddingScheme;
use rsa::pkcs1v15::{Signature as RsaSignature, SigningKey, VerifyingKey};
use rsa::{PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey};

use crate::crypto::HashAlgorithm;
use crate::errors::Result;
use crate::types::{Mpi, PlainSecretParams, PublicParams};

use digest::{const_oid::AssociatedOid, Digest};
use md5::Md5;
use ripemd::Ripemd160;
use sha1::Sha1;
use sha2::{Sha224, Sha256, Sha384, Sha512};
use sha3::{Sha3_256, Sha3_512};
use signature::hazmat::{PrehashSigner, PrehashVerifier};
use signature::Signature;

const MAX_KEY_SIZE: usize = 16384;

/// RSA decryption using PKCS1v15 padding.
pub fn decrypt(priv_key: &RsaPrivateKey, mpis: &[Mpi], _fingerprint: &[u8]) -> Result<Vec<u8>> {
// rsa consist of exactly one mpi
Expand All @@ -28,7 +38,11 @@ pub fn encrypt<R: CryptoRng + Rng>(
e: &[u8],
plaintext: &[u8],
) -> Result<Vec<Vec<u8>>> {
let key = RsaPublicKey::new(BigUint::from_bytes_be(n), BigUint::from_bytes_be(e))?;
let key = RsaPublicKey::new_with_max_size(
BigUint::from_bytes_be(n),
BigUint::from_bytes_be(e),
MAX_KEY_SIZE,
)?;
let data = key.encrypt(rng, PaddingScheme::new_pkcs1v15_encrypt(), plaintext)?;

Ok(vec![data])
Expand Down Expand Up @@ -64,19 +78,64 @@ pub fn generate_key<R: Rng + CryptoRng>(
))
}

fn verify_int<D>(key: RsaPublicKey, hashed: &[u8], signature: &RsaSignature) -> Result<()>
where
D: Digest + AssociatedOid,
{
VerifyingKey::<D>::new_with_prefix(key)
.verify_prehash(hashed, &signature)
.map_err(Into::into)
}

fn sign_int<D>(key: RsaPrivateKey, digest: &[u8]) -> Result<RsaSignature>
where
D: Digest + AssociatedOid,
{
SigningKey::<D>::new_with_prefix(key)
.sign_prehash(digest)
.map_err(Into::into)
}

/// Verify a RSA, PKCS1v15 padded signature.
pub fn verify(n: &[u8], e: &[u8], hash: HashAlgorithm, hashed: &[u8], sig: &[u8]) -> Result<()> {
let key = RsaPublicKey::new(BigUint::from_bytes_be(n), BigUint::from_bytes_be(e))?;
let rsa_hash: Option<rsa::Hash> = hash.try_into().ok();
let signature = Signature::from_bytes(sig)?;
let key = RsaPublicKey::new_with_max_size(
BigUint::from_bytes_be(n),
BigUint::from_bytes_be(e),
MAX_KEY_SIZE,
)?;

key.verify(PaddingScheme::new_pkcs1v15_sign(rsa_hash), hashed, sig)
.map_err(Into::into)
match hash {
HashAlgorithm::None => Err(format_err!("none")),
HashAlgorithm::MD5 => verify_int::<Md5>(key, hashed, &signature),
HashAlgorithm::RIPEMD160 => verify_int::<Ripemd160>(key, hashed, &signature),
HashAlgorithm::SHA1 => verify_int::<Sha1>(key, hashed, &signature),
HashAlgorithm::SHA2_224 => verify_int::<Sha224>(key, hashed, &signature),
HashAlgorithm::SHA2_256 => verify_int::<Sha256>(key, hashed, &signature),
HashAlgorithm::SHA2_384 => verify_int::<Sha384>(key, hashed, &signature),
HashAlgorithm::SHA2_512 => verify_int::<Sha512>(key, hashed, &signature),
HashAlgorithm::SHA3_256 => verify_int::<Sha3_256>(key, hashed, &signature),
HashAlgorithm::SHA3_512 => verify_int::<Sha3_512>(key, hashed, &signature),
HashAlgorithm::Private10 => unsupported_err!("Private10 should not be used"),
}
.map_err(Into::into)
}

/// Sign using RSA, with PKCS1v15 padding.
pub fn sign(key: &RsaPrivateKey, hash: HashAlgorithm, digest: &[u8]) -> Result<Vec<Vec<u8>>> {
let rsa_hash: Option<rsa::Hash> = hash.try_into().ok();
let sig = key.sign(PaddingScheme::new_pkcs1v15_sign(rsa_hash), digest)?;
let sig = match hash {
HashAlgorithm::None => return Err(format_err!("none")),
HashAlgorithm::MD5 => sign_int::<Md5>(key.clone(), digest),
HashAlgorithm::RIPEMD160 => sign_int::<Ripemd160>(key.clone(), digest),
HashAlgorithm::SHA1 => sign_int::<Sha1>(key.clone(), digest),
HashAlgorithm::SHA2_224 => sign_int::<Sha224>(key.clone(), digest),
HashAlgorithm::SHA2_256 => sign_int::<Sha256>(key.clone(), digest),
HashAlgorithm::SHA2_384 => sign_int::<Sha384>(key.clone(), digest),
HashAlgorithm::SHA2_512 => sign_int::<Sha512>(key.clone(), digest),
HashAlgorithm::SHA3_256 => sign_int::<Sha3_256>(key.clone(), digest),
HashAlgorithm::SHA3_512 => sign_int::<Sha3_512>(key.clone(), digest),
HashAlgorithm::Private10 => unsupported_err!("Private10 should not be used"),
}?;

Ok(vec![sig])
Ok(vec![sig.to_vec()])
}
6 changes: 3 additions & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ pub enum Error {
ParseIntError(#[from] std::num::ParseIntError),
#[error("Invalid Packet Content {0:?}")]
InvalidPacketContent(Box<Error>),
#[error("Ed25519 {0:?}")]
Ed25519SignatureError(#[from] SignatureError),
#[error("Signature {0:?}")]
SignatureError(#[from] SignatureError),
#[error("Modification Detection Code error")]
MdcError,
}
Expand Down Expand Up @@ -95,7 +95,7 @@ impl Error {
Error::Utf8Error(_) => 23,
Error::ParseIntError(_) => 24,
Error::InvalidPacketContent(_) => 25,
Error::Ed25519SignatureError(_) => 26,
Error::SignatureError(_) => 26,
Error::MdcError => 27,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/params/plain_secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl<'a> PlainSecretParamsRef<'a> {
e.into(),
d.into(),
vec![p.into(), q.into()],
);
)?;
secret_key.validate()?;
Ok(SecretKeyRepr::RSA(secret_key))
}
Expand Down

0 comments on commit 6ea108a

Please sign in to comment.