pub mod oaep;
pub mod pkcs1;
use super::key::{generate_rsa_key, is_rsa_key};
use super::{encoding, KeySize};
use crate::encoding::{AsDer, Pkcs8V1Der, PublicKeyX509Der};
use crate::error::{KeyRejected, Unspecified};
use crate::pkcs8::Version;
use crate::ptr::LcPtr;
use crate::wolfcrypt_rs::{EVP_PKEY, EVP_PKEY_RSA};
use core::fmt::Debug;
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum EncryptionAlgorithmId {
OaepSha1Mgf1sha1,
OaepSha256Mgf1sha256,
OaepSha384Mgf1sha384,
OaepSha512Mgf1sha512,
}
pub struct PrivateDecryptingKey(LcPtr<EVP_PKEY>);
impl PrivateDecryptingKey {
fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
Self::validate_key(&evp_pkey)?;
Ok(Self(evp_pkey))
}
fn validate_key(key: &LcPtr<EVP_PKEY>) -> Result<(), Unspecified> {
if !is_rsa_key(key) {
return Err(Unspecified);
}
match key.as_const().key_size_bits() {
2048..=8192 => Ok(()),
_ => Err(Unspecified),
}
}
pub fn generate(size: KeySize) -> Result<Self, Unspecified> {
let key = generate_rsa_key(size.bits())?;
Self::new(key)
}
#[cfg(feature = "fips")]
#[deprecated]
pub fn generate_fips(size: KeySize) -> Result<Self, Unspecified> {
Self::generate(size)
}
pub fn from_pkcs8(pkcs8: &[u8]) -> Result<Self, KeyRejected> {
let key = LcPtr::<EVP_PKEY>::parse_rfc5208_private_key(pkcs8, EVP_PKEY_RSA)?;
Ok(Self::new(key)?)
}
#[cfg(feature = "fips")]
#[must_use]
pub fn is_valid_fips_key(&self) -> bool {
super::key::is_valid_fips_key(&self.0)
}
#[must_use]
pub fn key_size_bytes(&self) -> usize {
self.0.as_const().key_size_bytes()
}
#[must_use]
pub fn key_size_bits(&self) -> usize {
self.0.as_const().key_size_bits()
}
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn public_key(&self) -> PublicEncryptingKey {
PublicEncryptingKey::new(self.0.clone()).expect(
"PublicEncryptingKey key size to be supported by PrivateDecryptingKey key sizes",
)
}
}
impl Debug for PrivateDecryptingKey {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("PrivateDecryptingKey").finish()
}
}
impl AsDer<Pkcs8V1Der<'static>> for PrivateDecryptingKey {
fn as_der(&self) -> Result<Pkcs8V1Der<'static>, Unspecified> {
Ok(Pkcs8V1Der::new(
self.0.as_const().marshal_rfc5208_private_key(Version::V1)?,
))
}
}
impl Clone for PrivateDecryptingKey {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
pub struct PublicEncryptingKey(LcPtr<EVP_PKEY>);
impl PublicEncryptingKey {
pub(crate) fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
Self::validate_key(&evp_pkey)?;
Ok(Self(evp_pkey))
}
fn validate_key(key: &LcPtr<EVP_PKEY>) -> Result<(), Unspecified> {
if !is_rsa_key(key) {
return Err(Unspecified);
}
match key.as_const().key_size_bits() {
2048..=8192 => Ok(()),
_ => Err(Unspecified),
}
}
pub fn from_der(value: &[u8]) -> Result<Self, KeyRejected> {
Ok(Self(encoding::rfc5280::decode_public_key_der(value)?))
}
#[must_use]
pub fn key_size_bytes(&self) -> usize {
self.0.as_const().key_size_bytes()
}
#[must_use]
pub fn key_size_bits(&self) -> usize {
self.0.as_const().key_size_bits()
}
}
impl Debug for PublicEncryptingKey {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("PublicEncryptingKey").finish()
}
}
impl Clone for PublicEncryptingKey {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl AsDer<PublicKeyX509Der<'static>> for PublicEncryptingKey {
fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
encoding::rfc5280::encode_public_key_der(&self.0)
}
}