#![forbid(unsafe_code)]
use getrandom::SysRng;
use oxicrypto_core::{CryptoError, Vec};
use rand_core::UnwrapErr;
use rsa::oaep;
use rsa::pkcs1v15;
use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
use rsa::pss;
use rsa::signature::{RandomizedSigner, SignatureEncoding, Verifier as RsaVerifierTrait};
use rsa::traits::{Decryptor, RandomizedEncryptor};
use sha2::{Sha256, Sha384, Sha512};
pub struct RsaPkcs1v15Sha256Signer {
signing_key: pkcs1v15::SigningKey<Sha256>,
}
impl RsaPkcs1v15Sha256Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pkcs1v15::SigningKey::<Sha256>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA PKCS1v15-SHA256 sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPkcs1v15Sha256Verifier {
verifying_key: pkcs1v15::VerifyingKey<Sha256>,
}
impl RsaPkcs1v15Sha256Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pkcs1v15::VerifyingKey::<Sha256>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pkcs1v15::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
pub struct RsaPkcs1v15Sha384Signer {
signing_key: pkcs1v15::SigningKey<Sha384>,
}
impl RsaPkcs1v15Sha384Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pkcs1v15::SigningKey::<Sha384>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA PKCS1v15-SHA384 sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPkcs1v15Sha384Verifier {
verifying_key: pkcs1v15::VerifyingKey<Sha384>,
}
impl RsaPkcs1v15Sha384Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pkcs1v15::VerifyingKey::<Sha384>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pkcs1v15::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
pub struct RsaPkcs1v15Sha512Signer {
signing_key: pkcs1v15::SigningKey<Sha512>,
}
impl RsaPkcs1v15Sha512Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pkcs1v15::SigningKey::<Sha512>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA PKCS1v15-SHA512 sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPkcs1v15Sha512Verifier {
verifying_key: pkcs1v15::VerifyingKey<Sha512>,
}
impl RsaPkcs1v15Sha512Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pkcs1v15::VerifyingKey::<Sha512>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pkcs1v15::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
pub struct RsaPssSha256Signer {
signing_key: pss::SigningKey<Sha256>,
}
impl RsaPssSha256Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pss::SigningKey::<Sha256>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA-PSS sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPssSha256Verifier {
verifying_key: pss::VerifyingKey<Sha256>,
}
impl RsaPssSha256Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pss::VerifyingKey::<Sha256>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pss::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
pub struct RsaPssSha384Signer {
signing_key: pss::SigningKey<Sha384>,
}
impl RsaPssSha384Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pss::SigningKey::<Sha384>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA-PSS-SHA384 sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPssSha384Verifier {
verifying_key: pss::VerifyingKey<Sha384>,
}
impl RsaPssSha384Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pss::VerifyingKey::<Sha384>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pss::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
pub struct RsaPssSha512Signer {
signing_key: pss::SigningKey<Sha512>,
}
impl RsaPssSha512Signer {
pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
signing_key: pss::SigningKey::<Sha512>::new(private_key),
})
}
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
let mut rng = SysRng;
let sig = RandomizedSigner::try_sign_with_rng(&self.signing_key, &mut rng, message)
.map_err(|_| CryptoError::Internal("RSA-PSS-SHA512 sign failed"))?;
Ok(sig.to_bytes().into_vec())
}
}
pub struct RsaPssSha512Verifier {
verifying_key: pss::VerifyingKey<Sha512>,
}
impl RsaPssSha512Verifier {
pub fn from_spki_der(der: &[u8]) -> Result<Self, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(der).map_err(|_| CryptoError::InvalidKey)?;
Ok(Self {
verifying_key: pss::VerifyingKey::<Sha512>::new(public_key),
})
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
let sig = pss::Signature::try_from(signature).map_err(|_| CryptoError::InvalidTag)?;
RsaVerifierTrait::verify(&self.verifying_key, message, &sig)
.map_err(|_| CryptoError::InvalidTag)
}
}
#[must_use = "generated key pair must be used"]
pub fn rsa_generate_keypair(bit_size: usize) -> Result<(Vec<u8>, Vec<u8>), CryptoError> {
if bit_size < 2048 {
return Err(CryptoError::BadInput);
}
let mut rng = UnwrapErr(SysRng);
let private_key = rsa::RsaPrivateKey::new(&mut rng, bit_size)
.map_err(|_| CryptoError::Internal("RSA key generation failed"))?;
let public_key = private_key.to_public_key();
let sk_der = private_key
.to_pkcs8_der()
.map_err(|_| CryptoError::Internal("RSA private key DER encoding failed"))?
.as_bytes()
.to_vec();
let pk_der = public_key
.to_public_key_der()
.map_err(|_| CryptoError::Internal("RSA public key DER encoding failed"))?
.as_bytes()
.to_vec();
Ok((sk_der, pk_der))
}
#[must_use = "encryption result must be checked"]
pub fn rsa_oaep_sha256_encrypt(pk_der: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
let public_key =
rsa::RsaPublicKey::from_public_key_der(pk_der).map_err(|_| CryptoError::InvalidKey)?;
let encrypting_key = oaep::EncryptingKey::<Sha256>::new(public_key);
let mut rng = UnwrapErr(SysRng);
encrypting_key
.encrypt_with_rng(&mut rng, plaintext)
.map_err(|_| CryptoError::Internal("RSA-OAEP encrypt failed"))
}
#[must_use = "decryption result must be checked"]
pub fn rsa_oaep_sha256_decrypt(sk_der: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
let private_key =
rsa::RsaPrivateKey::from_pkcs8_der(sk_der).map_err(|_| CryptoError::InvalidKey)?;
let decrypting_key = oaep::DecryptingKey::<Sha256>::new(private_key);
decrypting_key
.decrypt(ciphertext)
.map_err(|_| CryptoError::Internal("RSA-OAEP decrypt failed"))
}