use anyhow::Result;
use async_trait::async_trait;
pub mod software;
#[cfg(feature = "pkcs11")]
pub mod pkcs11;
#[async_trait]
pub trait CryptoProvider: Send + Sync {
async fn voprf_evaluate(&self, blinded: &[u8]) -> Result<Vec<u8>>;
async fn derive_mac_key(&self, issuer_id: &str, kid: &str, epoch: u32) -> Result<[u8; 32]>;
async fn sign_token_metadata(
&self,
token_bytes: &[u8],
kid: &str,
exp: i64,
issuer_id: &str,
) -> Result<[u8; 64]>;
fn public_key(&self) -> &[u8];
fn key_id(&self) -> &str;
fn suite_id(&self) -> &str {
"OPRF(P-256, SHA-256)-verifiable"
}
fn context(&self) -> &[u8];
}
#[derive(Debug, Clone)]
pub enum ProviderConfig {
Software {
secret_key: [u8; 32],
key_id: String,
context: Vec<u8>,
},
#[cfg(feature = "pkcs11")]
Pkcs11 {
module_path: String,
slot: u64,
pin: String,
key_label: String,
key_id: String,
context: Vec<u8>,
},
}
pub async fn create_provider(config: ProviderConfig) -> Result<Box<dyn CryptoProvider>> {
match config {
ProviderConfig::Software {
secret_key,
key_id,
context,
} => Ok(Box::new(software::SoftwareCryptoProvider::new(
secret_key, key_id, context,
)?)),
#[cfg(feature = "pkcs11")]
ProviderConfig::Pkcs11 {
module_path,
slot,
pin,
key_label,
key_id,
context,
} => Ok(Box::new(
pkcs11::Pkcs11CryptoProvider::new(
&module_path,
slot,
&pin,
&key_label,
key_id,
context,
)
.await?,
)),
}
}