use hmac_sha256::Hash as Sha256;
use hmac_sha512::sha384::Hash as Sha384;
use hmac_sha512::Hash as Sha512;
use std::ffi::c_int;
#[allow(unused_imports)]
use rrsa::pkcs1::{
DecodeRsaPrivateKey as _, DecodeRsaPublicKey as _, EncodeRsaPrivateKey as _,
EncodeRsaPublicKey as _,
};
#[allow(unused_imports)]
use rrsa::pkcs8::{
AssociatedOid as _, DecodePrivateKey as _, DecodePublicKey as _, EncodePrivateKey as _,
EncodePublicKey as _,
};
#[allow(unused_imports)]
use rrsa::signature::{
DigestSigner as _, DigestVerifier as _, Keypair as _, KeypairRef as _, PrehashSignature as _,
RandomizedDigestSigner as _, RandomizedSigner as _, SignatureEncoding as _, Signer as _,
SignerMut as _, Verifier as _,
};
#[allow(unused_imports)]
use rrsa::traits::{
Decryptor as _, EncryptingKeypair as _, PaddingScheme as _, PrivateKeyParts as _,
PublicKeyParts as _, RandomizedDecryptor as _, RandomizedEncryptor as _, SignatureScheme as _,
};
pub mod reexports {
pub use hmac_sha256;
pub use hmac_sha512;
pub use rand;
pub use rrsa as rsa;
}
#[allow(unused_imports)]
use rsa::*;
pub mod rsa {
use rrsa::pkcs8::EncodePrivateKey;
#[allow(unused_imports)]
use super::*;
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum RsaKey {
#[default]
None,
Public(rrsa::RsaPublicKey),
Private(rrsa::RsaPrivateKey),
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Rsa<T> {
pub rsa_key: RsaKey,
pub _marker: std::marker::PhantomData<T>,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
pub enum PaddingId {
#[default]
None,
Pkcs1,
Pkcs1Pss,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Padding {
id: PaddingId,
}
impl Padding {
pub const NONE: Padding = Padding {
id: PaddingId::None,
};
pub const PKCS1: Padding = Padding {
id: PaddingId::Pkcs1,
};
pub const PKCS1_PSS: Padding = Padding {
id: PaddingId::Pkcs1Pss,
};
}
impl Rsa<Public> {
pub fn new() -> Self {
Rsa {
rsa_key: RsaKey::None,
_marker: std::marker::PhantomData,
}
}
pub fn bits(&self) -> usize {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
rsa_key.size() * 8
}
pub fn check_key(&self) -> Result<bool, ErrorStack> {
match self.bits() {
2048 | 3072 | 4096 => Ok(true),
_ => Ok(false),
}
}
pub fn public_key_from_der(der: &[u8]) -> Result<Rsa<Public>, ErrorStack> {
let rsa_public_key = rrsa::RsaPublicKey::from_public_key_der(der)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_key = RsaKey::Public(rsa_public_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn public_key_from_der_pkcs1(der: &[u8]) -> Result<Rsa<Public>, ErrorStack> {
let rsa_public_key = rrsa::RsaPublicKey::from_pkcs1_der(der)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_key = RsaKey::Public(rsa_public_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn public_key_from_pem(pem: &[u8]) -> Result<Rsa<Public>, ErrorStack> {
let rsa_pem = std::str::from_utf8(pem).map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_public_key = rrsa::RsaPublicKey::from_public_key_pem(rsa_pem)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_key = RsaKey::Public(rsa_public_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn public_key_from_pem_pkcs1(pem: &[u8]) -> Result<Rsa<Public>, ErrorStack> {
let rsa_pem = std::str::from_utf8(pem).map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_public_key = rrsa::RsaPublicKey::from_pkcs1_pem(rsa_pem)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_key = RsaKey::Public(rsa_public_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
let rsa_public_key = rrsa::RsaPublicKey::new(n.rsa_bn, e.rsa_bn)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let rsa_key = RsaKey::Public(rsa_public_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn n(&self) -> BigNum {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.n().clone(),
}
}
pub fn e(&self) -> BigNum {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.e().clone(),
}
}
pub fn public_key_to_der(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
Ok(rsa_key
.to_public_key_der()
.map_err(|_| ErrorStack::InvalidPublicKey)?
.into_vec())
}
pub fn public_key_to_der_pkcs1(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
Ok(rsa_key
.to_pkcs1_der()
.map_err(|_| ErrorStack::InvalidPublicKey)?
.into_vec())
}
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
Ok(rsa_key
.to_public_key_pem(Default::default())
.map_err(|_| ErrorStack::InvalidPublicKey)?
.into_bytes())
}
pub fn public_key_to_pem_pkcs1(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
Ok(rsa_key
.to_pkcs1_pem(Default::default())
.map_err(|_| ErrorStack::InvalidPublicKey)?
.into_bytes())
}
pub fn public_encrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
let rsa_key = if let RsaKey::Public(x) = &self.rsa_key {
x
} else {
unreachable!();
};
let padding = match padding {
Padding::NONE => panic!("Padding not set"),
Padding::PKCS1 => rrsa::Pkcs1v15Encrypt,
Padding::PKCS1_PSS => panic!("Invalid padding for encryption"),
};
let mut rng = rand::thread_rng();
let c = rsa_key
.encrypt(&mut rng, padding, from)
.map_err(|_| ErrorStack::InvalidPublicKey)?;
let len = c.len();
to.fill(0);
to[0..len].copy_from_slice(&c);
Ok(len)
}
}
impl Rsa<Private> {
pub fn generate(bits: u32) -> Result<Rsa<Private>, ErrorStack> {
match bits {
2048 | 3072 | 4096 => {}
_ => return Err(ErrorStack::UnsupportedModulus),
};
let mut rng = rand::thread_rng();
let rsa_key = rrsa::RsaPrivateKey::new(&mut rng, bits as _)
.map_err(|_| ErrorStack::InternalError)?;
let rsa_key = RsaKey::Private(rsa_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn bits(&self) -> usize {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
rsa_key.size() * 8
}
pub fn check_key(&self) -> Result<bool, ErrorStack> {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
match self.bits() {
2048 | 3072 | 4096 => {}
_ => return Ok(false),
};
if rsa_key.validate().is_err() {
return Ok(false);
}
Ok(true)
}
pub fn public_key(&self) -> Result<Rsa<Public>, ErrorStack> {
let n = self.n();
let e = self.e();
Rsa::from_public_components(n, e)
}
pub fn private_key_from_pem(pem: &[u8]) -> Result<Rsa<Private>, ErrorStack> {
let rsa_pem = std::str::from_utf8(pem).map_err(|_| ErrorStack::InvalidPrivateKey)?;
let rsa_pem = rsa_pem.trim();
let mut rsa_key = rrsa::RsaPrivateKey::from_pkcs8_pem(rsa_pem)
.or_else(|_| rrsa::RsaPrivateKey::from_pkcs1_pem(rsa_pem))
.map_err(|_| ErrorStack::InvalidPrivateKey)?;
rsa_key
.validate()
.map_err(|_| ErrorStack::InvalidPrivateKey)?;
rsa_key
.precompute()
.map_err(|_| ErrorStack::InvalidPrivateKey)?;
let rsa_key = RsaKey::Private(rsa_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn private_key_from_der(der: &[u8]) -> Result<Rsa<Private>, ErrorStack> {
let rsa_key = rrsa::RsaPrivateKey::from_pkcs8_der(der)
.or_else(|_| rrsa::RsaPrivateKey::from_pkcs1_der(der))
.map_err(|_| ErrorStack::InvalidPrivateKey)?;
let rsa_key = RsaKey::Private(rsa_key);
Ok(Rsa {
rsa_key,
_marker: std::marker::PhantomData,
})
}
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
let bytes = rsa_key
.to_pkcs8_pem(Default::default())
.map_err(|_| ErrorStack::InvalidPrivateKey)?
.as_bytes()
.to_vec();
Ok(bytes)
}
pub fn private_key_to_der(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
let bytes = rsa_key
.to_pkcs8_der()
.map_err(|_| ErrorStack::InvalidPrivateKey)?
.as_bytes()
.to_vec();
Ok(bytes)
}
pub fn n(&self) -> BigNum {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.n().clone(),
}
}
pub fn d(&self) -> BigNum {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.d().clone(),
}
}
pub fn e(&self) -> BigNum {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.e().clone(),
}
}
pub fn p(&self) -> BigNum {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.primes()[0].clone(),
}
}
pub fn q(&self) -> BigNum {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
BigNum {
rsa_bn: rsa_key.primes()[1].clone(),
}
}
pub fn private_decrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
let rsa_key = if let RsaKey::Private(x) = &self.rsa_key {
x
} else {
unreachable!();
};
let padding = match padding {
Padding::NONE => panic!("Padding not set"),
Padding::PKCS1 => rrsa::Pkcs1v15Encrypt,
Padding::PKCS1_PSS => panic!("Invalid padding for encryption"),
};
let mut rng = rand::thread_rng();
let m = rsa_key
.decrypt_blinded(&mut rng, padding, from)
.map_err(|_| ErrorStack::InvalidPrivateKey)?;
let len = m.len();
to.fill(0);
to[0..len].copy_from_slice(&m);
Ok(len)
}
}
}
#[allow(unused_imports)]
use error::*;
pub mod error {
#[allow(unused_imports)]
use super::*;
pub enum ErrorStack {
InternalError,
InvalidPrivateKey,
InvalidPublicKey,
Overflow,
UnsupportedModulus,
}
impl std::fmt::Display for ErrorStack {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ErrorStack::InternalError => write!(f, "Internal error"),
ErrorStack::InvalidPrivateKey => write!(f, "Invalid private key"),
ErrorStack::InvalidPublicKey => write!(f, "Invalid public key"),
ErrorStack::Overflow => write!(f, "Overflow"),
ErrorStack::UnsupportedModulus => write!(f, "Unsupported modulus"),
}
}
}
impl std::fmt::Debug for ErrorStack {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Superboring error: {}", self)
}
}
impl std::error::Error for ErrorStack {}
}
#[allow(unused_imports)]
use bn::*;
pub mod bn {
#[allow(unused_imports)]
use super::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BigNum {
pub rsa_bn: rrsa::BigUint,
}
pub type BigNumRef<'a> = BigNum;
impl BigNum {
pub fn from_slice(slice: &[u8]) -> Result<Self, ErrorStack> {
let rsa_bn = rrsa::BigUint::from_bytes_be(slice);
Ok(BigNum { rsa_bn })
}
pub fn to_vec(&self) -> Vec<u8> {
self.rsa_bn.to_bytes_be()
}
pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
Ok(self.clone())
}
}
}
#[allow(unused_imports)]
use hash::*;
pub mod hash {
#[allow(unused_imports)]
use super::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MessageDigest {
Sha256,
Sha384,
Sha512,
}
impl MessageDigest {
pub fn sha256() -> MessageDigest {
MessageDigest::Sha256
}
pub fn sha384() -> MessageDigest {
MessageDigest::Sha384
}
pub fn sha512() -> MessageDigest {
MessageDigest::Sha512
}
}
}
#[allow(unused_imports)]
use pkey::*;
pub mod pkey {
#[allow(unused_imports)]
use super::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Public {}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Private {}
pub trait HasPublic {}
impl HasPublic for Public {}
pub trait HasPrivate {}
impl HasPrivate for Private {}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub enum PKey<T> {
#[default]
None,
Rsa(Rsa<T>),
}
impl<T> PKey<T> {
pub fn from_rsa(rsa: Rsa<T>) -> Result<PKey<T>, ErrorStack> {
Ok(PKey::Rsa(rsa))
}
}
}
#[allow(unused_imports)]
use sign::*;
pub mod sign {
#[allow(unused_imports)]
use super::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct RsaPssSaltlen {
pub len: c_int,
}
impl Default for RsaPssSaltlen {
fn default() -> Self {
RsaPssSaltlen { len: -1 }
}
}
impl RsaPssSaltlen {
pub fn custom(len: c_int) -> Self {
RsaPssSaltlen { len }
}
pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen { len: -1 };
pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen { len: -2 };
}
#[derive(Clone, Default)]
pub enum AnyHash {
#[default]
None,
Sha256(Sha256),
Sha384(Sha384),
Sha512(Sha512),
}
#[derive(Clone)]
pub struct Signer<'t, T> {
pub message_digest: MessageDigest,
pub pkey_ref: &'t PKey<T>,
pub padding: Padding,
pub salt_len: RsaPssSaltlen,
pub any_hash: AnyHash,
}
impl<'t, T> Signer<'t, T> {
pub fn new(type_: MessageDigest, pkey: &'t PKey<T>) -> Result<Signer<'t, T>, ErrorStack>
where
T: HasPrivate,
{
let any_hash = match type_ {
MessageDigest::Sha256 => AnyHash::Sha256(Sha256::new()),
MessageDigest::Sha384 => AnyHash::Sha384(Sha384::new()),
MessageDigest::Sha512 => AnyHash::Sha512(Sha512::new()),
};
Ok(Signer {
message_digest: type_,
pkey_ref: pkey,
padding: Padding::NONE,
salt_len: RsaPssSaltlen::default(),
any_hash,
})
}
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
self.padding = padding;
Ok(())
}
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
Ok(self.padding)
}
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
self.salt_len = len;
Ok(())
}
pub fn rsa_pss_saltlen(&self) -> Result<RsaPssSaltlen, ErrorStack> {
Ok(self.salt_len)
}
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
match &mut self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => x.update(buf),
AnyHash::Sha384(x) => x.update(buf),
AnyHash::Sha512(x) => x.update(buf),
};
Ok(())
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> Result<usize, ErrorStack> {
let rsa_key = if let PKey::Rsa(x) = self.pkey_ref {
x
} else {
unreachable!();
};
let rsa_key = if let RsaKey::Private(x) = &rsa_key.rsa_key {
x
} else {
unreachable!();
};
Ok(rsa_key.size())
}
pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
let sig = self.sign_to_vec()?;
if buf.len() < sig.len() {
return Err(ErrorStack::Overflow);
}
buf.copy_from_slice(&sig);
Ok(sig.len())
}
pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
let rsa_key = if let PKey::Rsa(x) = self.pkey_ref {
x
} else {
unreachable!();
};
let rsa_key = if let RsaKey::Private(x) = &rsa_key.rsa_key {
x
} else {
unreachable!();
};
let mut rng = rand::thread_rng();
let rsa_key = rsa_key.clone();
match self.padding {
Padding::NONE => panic!("Padding not set"),
Padding::PKCS1 => match self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => {
let signing_key = rrsa::pkcs1v15::SigningKey::<Sha256>::new(rsa_key);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
AnyHash::Sha384(x) => {
let signing_key = rrsa::pkcs1v15::SigningKey::<Sha384>::new(rsa_key);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
AnyHash::Sha512(x) => {
let signing_key = rrsa::pkcs1v15::SigningKey::<Sha512>::new(rsa_key);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
},
Padding::PKCS1_PSS => {
let hash_len = match self.message_digest {
MessageDigest::Sha256 => 32,
MessageDigest::Sha384 => 48,
MessageDigest::Sha512 => 64,
};
let salt_len = match self.salt_len.len {
-1 => hash_len,
-2 => rsa_key.size() - hash_len - 2,
x => x as _,
};
match self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => {
let signing_key =
rrsa::pss::BlindedSigningKey::<Sha256>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
AnyHash::Sha384(x) => {
let signing_key =
rrsa::pss::BlindedSigningKey::<Sha384>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
AnyHash::Sha512(x) => {
let signing_key =
rrsa::pss::BlindedSigningKey::<Sha512>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(signing_key
.sign_digest_with_rng(&mut rng, x)
.to_bytes()
.into_vec())
}
}
}
}
}
}
#[derive(Clone)]
pub struct Verifier<'t, T> {
pub message_digest: MessageDigest,
pub pkey_ref: &'t PKey<T>,
pub padding: Padding,
pub salt_len: RsaPssSaltlen,
pub any_hash: AnyHash,
}
impl<'t, T> Verifier<'t, T> {
pub fn new(type_: MessageDigest, pkey: &'t PKey<T>) -> Result<Verifier<'t, T>, ErrorStack>
where
T: HasPublic,
{
let any_hash = match type_ {
MessageDigest::Sha256 => AnyHash::Sha256(Sha256::new()),
MessageDigest::Sha384 => AnyHash::Sha384(Sha384::new()),
MessageDigest::Sha512 => AnyHash::Sha512(Sha512::new()),
};
Ok(Verifier {
message_digest: type_,
pkey_ref: pkey,
padding: Padding::NONE,
salt_len: RsaPssSaltlen::default(),
any_hash,
})
}
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
self.padding = padding;
Ok(())
}
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
Ok(self.padding)
}
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
self.salt_len = len;
Ok(())
}
pub fn rsa_pss_saltlen(&self) -> Result<RsaPssSaltlen, ErrorStack> {
Ok(self.salt_len)
}
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
match &mut self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => x.update(buf),
AnyHash::Sha384(x) => x.update(buf),
AnyHash::Sha512(x) => x.update(buf),
};
Ok(())
}
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
let rsa_key = if let PKey::Rsa(x) = self.pkey_ref {
x
} else {
unreachable!();
};
let rsa_key = if let RsaKey::Public(x) = &rsa_key.rsa_key {
x
} else {
unreachable!();
};
let rsa_key = rsa_key.clone();
match self.padding {
Padding::NONE => panic!("Padding not set"),
Padding::PKCS1 => {
let rsa_signature = match rrsa::pkcs1v15::Signature::try_from(signature) {
Ok(x) => x,
Err(_) => return Ok(false),
};
match self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => {
let verifying_key =
rrsa::pkcs1v15::VerifyingKey::<Sha256>::new(rsa_key);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
AnyHash::Sha384(x) => {
let verifying_key =
rrsa::pkcs1v15::VerifyingKey::<Sha384>::new(rsa_key);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
AnyHash::Sha512(x) => {
let verifying_key =
rrsa::pkcs1v15::VerifyingKey::<Sha512>::new(rsa_key);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
}
}
Padding::PKCS1_PSS => {
let hash_len = match self.message_digest {
MessageDigest::Sha256 => 32,
MessageDigest::Sha384 => 48,
MessageDigest::Sha512 => 64,
};
let salt_len = match self.salt_len.len {
-1 => hash_len,
-2 => rsa_key.size() - hash_len - 2,
x => x as _,
};
let rsa_signature = match rrsa::pss::Signature::try_from(signature) {
Ok(x) => x,
Err(_) => return Ok(false),
};
match self.any_hash {
AnyHash::None => unreachable!("AnyHash::None"),
AnyHash::Sha256(x) => {
let verifying_key =
rrsa::pss::VerifyingKey::<Sha256>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
AnyHash::Sha384(x) => {
let verifying_key =
rrsa::pss::VerifyingKey::<Sha384>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
AnyHash::Sha512(x) => {
let verifying_key =
rrsa::pss::VerifyingKey::<Sha512>::new_with_salt_len(
rsa_key, salt_len,
);
Ok(verifying_key.verify_digest(x, &rsa_signature).is_ok())
}
}
}
}
}
pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
self.update(buf)?;
self.verify(signature)
}
}
}
#[test]
fn test_rsa_pkcs1() {
let sk = Rsa::generate(2048).unwrap();
let pk = sk.public_key().unwrap();
let sk = PKey::from_rsa(sk).unwrap();
let pk = PKey::from_rsa(pk).unwrap();
let mut signer = Signer::new(MessageDigest::Sha256, &sk).unwrap();
let mut verifier = Verifier::new(MessageDigest::Sha256, &pk).unwrap();
signer.set_rsa_padding(Padding::PKCS1).unwrap();
verifier.set_rsa_padding(Padding::PKCS1).unwrap();
signer.update(b"hello").unwrap();
let signature = signer.sign_to_vec().unwrap();
verifier.update(b"hello").unwrap();
let res = verifier.verify(&signature).unwrap();
assert!(res);
}
#[test]
fn test_rsa_pss() {
let sk = Rsa::generate(2048).unwrap();
let pk = sk.public_key().unwrap();
let sk = PKey::from_rsa(sk).unwrap();
let pk = PKey::from_rsa(pk).unwrap();
let mut signer = Signer::new(MessageDigest::Sha384, &sk).unwrap();
let mut verifier = Verifier::new(MessageDigest::Sha384, &pk).unwrap();
signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
signer.update(b"hello").unwrap();
let signature = signer.sign_to_vec().unwrap();
verifier.update(b"hello").unwrap();
let res = verifier.verify(&signature).unwrap();
assert!(res);
}
#[test]
fn test_rsa_encrypt_decrypt() {
let sk = Rsa::generate(2048).unwrap();
let pk = sk.public_key().unwrap();
let mut ciphertext = [0u8; 256];
let mut recovered_plaintext = [0u8; 256];
let len = pk
.public_encrypt(b"hello", &mut ciphertext, Padding::PKCS1)
.unwrap();
let len2 = sk
.private_decrypt(
&ciphertext[0..len],
&mut recovered_plaintext,
Padding::PKCS1,
)
.unwrap();
assert_eq!(&recovered_plaintext[0..len2], b"hello");
}