use crate::mechanism::{Mechanism, MechanismType};
use cryptoki_sys::*;
use std::{convert::TryInto, marker::PhantomData, ptr::null_mut};
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum HedgeType {
#[default]
Preferred,
Required,
DeterministicRequired,
}
impl From<HedgeType> for CK_ULONG {
fn from(hedge: HedgeType) -> CK_ULONG {
match hedge {
HedgeType::Preferred => CKH_HEDGE_PREFERRED,
HedgeType::Required => CKH_HEDGE_REQUIRED,
HedgeType::DeterministicRequired => CKH_DETERMINISTIC_REQUIRED,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct SignAdditionalContext<'a> {
inner: Option<CK_SIGN_ADDITIONAL_CONTEXT>,
_marker: PhantomData<&'a [u8]>,
}
impl SignAdditionalContext<'_> {
pub fn new(hedge: HedgeType, context: Option<&[u8]>) -> Self {
if hedge == HedgeType::Preferred && context.is_none() {
return Self {
inner: None,
_marker: PhantomData,
};
}
let (p_context, ul_context_len) = match context {
Some(c) => (
c.as_ptr() as *mut _,
c.len().try_into().expect("usize can not fit in CK_ULONG"),
),
None => (null_mut() as *mut _, 0),
};
Self {
inner: Some(CK_SIGN_ADDITIONAL_CONTEXT {
hedgeVariant: hedge.into(),
pContext: p_context,
ulContextLen: ul_context_len,
}),
_marker: PhantomData,
}
}
pub fn inner(&self) -> Option<&CK_SIGN_ADDITIONAL_CONTEXT> {
self.inner.as_ref()
}
}
#[derive(Debug, Clone, Copy)]
pub struct HashSignAdditionalContext<'a> {
inner: CK_HASH_SIGN_ADDITIONAL_CONTEXT,
_marker: PhantomData<&'a [u8]>,
}
impl HashSignAdditionalContext<'_> {
pub fn new(hedge: HedgeType, context: Option<&[u8]>, hash: MechanismType) -> Self {
let (p_context, ul_context_len) = match context {
Some(c) => (
c.as_ptr() as *mut _,
c.len().try_into().expect("usize can not fit in CK_ULONG"),
),
None => (null_mut(), 0),
};
Self {
inner: CK_HASH_SIGN_ADDITIONAL_CONTEXT {
hedgeVariant: hedge.into(),
pContext: p_context,
ulContextLen: ul_context_len,
hash: hash.into(),
},
_marker: PhantomData,
}
}
pub fn inner(&self) -> &CK_HASH_SIGN_ADDITIONAL_CONTEXT {
&self.inner
}
}
impl<'a> From<HashSignAdditionalContext<'a>> for Mechanism<'a> {
fn from(params: HashSignAdditionalContext<'a>) -> Self {
Mechanism::HashMlDsa(params)
}
}