//! Traits for the key containers use std::{ borrow::Cow, error, convert::Infallible, }; use openssl::{ pkey::{ HasPublic, HasPrivate, PKey, }, rsa::{ Rsa, }, }; /// A trait for containers that contain public keys pub trait PublicKey { /// The type of the key type KeyType: HasPublic; /// Error that can happen from the conversion type Error: error::Error; /// Get or create a `PKey` that contains the public key fn get_pkey_pub(&self) -> Result>, Self::Error>; /// Get or create an `Rsa` from this public key if possible #[inline] fn get_rsa_pub(&self) -> Result>>, Self::Error> { Ok(self.get_pkey_pub()?.rsa().ok().map(|x| Cow::Owned(x))) } } /// A trait for containers that contain private and public keys pub trait PrivateKey: PublicKey where ::KeyType: HasPrivate { /// Get or create a `PKey` that contains the private key #[inline] fn get_pkey_priv(&self) -> Result::KeyType>>, ::Error> { self.get_pkey_pub() } /// Get or create an `Rsa` from this private key if possible #[inline] fn get_rsa_priv(&self) -> Result>>, Self::Error> { self.get_rsa_pub() } } impl PublicKey for PKey where T: HasPublic { type KeyType = T; type Error = Infallible; fn get_pkey_pub(&self) -> Result>, Self::Error> { Ok(Cow::Borrowed(self)) } } impl PrivateKey for PKey where T: HasPrivate { fn get_pkey_priv(&self) -> Result::KeyType>>, ::Error> { Ok(Cow::Borrowed(self)) } } impl PublicKey for Rsa where T: HasPublic { type KeyType = T; type Error = openssl::error::ErrorStack; fn get_pkey_pub(&self) -> Result>, Self::Error> { Ok(Cow::Owned(PKey::from_rsa(self.clone())?)) } #[inline] fn get_rsa_pub(&self) -> Result>>, Self::Error> { Ok(Some(Cow::Borrowed(self))) } } impl PrivateKey for Rsa where T: HasPrivate { fn get_pkey_priv(&self) -> Result::KeyType>>, ::Error> { Ok(Cow::Owned(PKey::from_rsa(self.clone())?)) } #[inline] fn get_rsa_priv(&self) -> Result>>, Self::Error> { Ok(Some(Cow::Borrowed(self))) } }