use async_trait::async_trait;
use zeroize::Zeroizing;
use crate::{
CryptoAlgorithm, InterfaceResult, KeyMetadata, KeyType, encryption_oracle::EncryptedContent,
};
pub enum HsmKeyAlgorithm {
AES,
}
pub enum HsmKeypairAlgorithm {
RSA,
}
pub enum HsmObjectFilter {
Any,
AesKey,
RsaKey,
RsaPrivateKey,
RsaPublicKey,
}
#[derive(Debug)]
pub struct RsaPrivateKeyMaterial {
pub modulus: Vec<u8>,
pub public_exponent: Vec<u8>,
pub private_exponent: Zeroizing<Vec<u8>>,
pub prime_1: Zeroizing<Vec<u8>>,
pub prime_2: Zeroizing<Vec<u8>>,
pub exponent_1: Zeroizing<Vec<u8>>,
pub exponent_2: Zeroizing<Vec<u8>>,
pub coefficient: Zeroizing<Vec<u8>>,
}
#[derive(Debug)]
pub struct RsaPublicKeyMaterial {
pub modulus: Vec<u8>,
pub public_exponent: Vec<u8>,
}
#[derive(Debug)]
pub enum KeyMaterial {
AesKey(Zeroizing<Vec<u8>>),
RsaPrivateKey(RsaPrivateKeyMaterial),
RsaPublicKey(RsaPublicKeyMaterial),
}
#[derive(Debug)]
pub struct HsmObject {
key_material: KeyMaterial,
id: String,
}
impl HsmObject {
pub fn new(key_material: KeyMaterial, label: String) -> Self {
HsmObject {
key_material,
id: label,
}
}
pub fn key_material(&self) -> &KeyMaterial {
&self.key_material
}
pub fn id(&self) -> &str {
&self.id
}
}
#[async_trait]
pub trait HSM: Send + Sync {
async fn create_key(
&self,
slot_id: usize,
id: &[u8],
algorithm: HsmKeyAlgorithm,
key_length_in_bits: usize,
sensitive: bool,
) -> InterfaceResult<()>;
async fn create_keypair(
&self,
slot_id: usize,
sk_id: &[u8],
pk_is: &[u8],
algorithm: HsmKeypairAlgorithm,
key_length_in_bits: usize,
sensitive: bool,
) -> InterfaceResult<()>;
async fn export(&self, slot_id: usize, object_id: &[u8]) -> InterfaceResult<Option<HsmObject>>;
async fn delete(&self, slot_id: usize, object_id: &[u8]) -> InterfaceResult<()>;
async fn find(
&self,
slot_id: usize,
object_filter: HsmObjectFilter,
) -> InterfaceResult<Vec<Vec<u8>>>;
async fn encrypt(
&self,
slot_id: usize,
key_id: &[u8],
algorithm: CryptoAlgorithm,
data: &[u8],
) -> InterfaceResult<EncryptedContent>;
async fn decrypt(
&self,
slot_id: usize,
key_id: &[u8],
algorithm: CryptoAlgorithm,
data: &[u8],
) -> InterfaceResult<Zeroizing<Vec<u8>>>;
async fn get_key_type(&self, slot_id: usize, key_id: &[u8])
-> InterfaceResult<Option<KeyType>>;
async fn get_key_metadata(
&self,
slot_id: usize,
key_id: &[u8],
) -> InterfaceResult<Option<KeyMetadata>>;
}