use std::fmt::Debug;
use std::sync::LazyLock;
use crate::defaults;
use crate::error::Result;
use crate::misc::copy_sized_string;
use crate::object::Object;
use crate::pkcs11::*;
use crate::token::TokenFacilities;
#[derive(Clone, Debug)]
pub struct StorageTokenInfo {
pub label: [CK_UTF8CHAR; 32usize],
pub manufacturer: [CK_UTF8CHAR; 32usize],
pub model: [CK_UTF8CHAR; 16usize],
pub serial: [CK_CHAR; 16usize],
pub flags: CK_FLAGS,
}
impl Default for StorageTokenInfo {
fn default() -> StorageTokenInfo {
let mut def = StorageTokenInfo {
label: [b' '; 32],
manufacturer: [b' '; 32],
model: [b' '; 16],
serial: [b' '; 16],
flags: 0,
};
copy_sized_string(defaults::TOKEN_LABEL.as_bytes(), &mut def.label);
copy_sized_string(
defaults::MANUFACTURER_ID.as_bytes(),
&mut def.manufacturer,
);
copy_sized_string(defaults::TOKEN_MODEL.as_bytes(), &mut def.model);
def
}
}
pub trait StorageDBInfo: Debug + Send + Sync {
fn new(&self, conf: &Option<String>) -> Result<Box<dyn Storage>>;
fn dbtype(&self) -> &str;
}
pub trait Storage: Debug + Send + Sync {
fn open(&mut self) -> Result<StorageTokenInfo>;
fn reinit(
&mut self,
facilities: &TokenFacilities,
) -> Result<StorageTokenInfo>;
fn flush(&mut self) -> Result<()>;
fn fetch(
&self,
faclities: &TokenFacilities,
handle: CK_OBJECT_HANDLE,
attributes: &[CK_ATTRIBUTE],
) -> Result<Object>;
fn store(
&mut self,
facilities: &mut TokenFacilities,
obj: Object,
) -> Result<CK_OBJECT_HANDLE>;
fn update(
&mut self,
facilities: &TokenFacilities,
handle: CK_OBJECT_HANDLE,
template: &[CK_ATTRIBUTE],
) -> Result<()>;
fn search(
&self,
facilities: &mut TokenFacilities,
template: &[CK_ATTRIBUTE],
) -> Result<Vec<CK_OBJECT_HANDLE>>;
fn remove(
&mut self,
facilities: &TokenFacilities,
handle: CK_OBJECT_HANDLE,
) -> Result<()>;
fn load_token_info(&self) -> Result<StorageTokenInfo>;
fn store_token_info(&mut self, info: &StorageTokenInfo) -> Result<()>;
fn auth_user(
&mut self,
facilities: &TokenFacilities,
user_type: CK_USER_TYPE,
pin: &[u8],
flag: &mut CK_FLAGS,
check_only: bool,
) -> Result<()>;
fn unauth_user(&mut self, user_type: CK_USER_TYPE) -> Result<()>;
fn set_user_pin(
&mut self,
facilities: &TokenFacilities,
user_type: CK_USER_TYPE,
pin: &[u8],
) -> Result<()>;
}
pub mod aci;
pub mod format;
#[cfg(any(feature = "nssdb", feature = "sqlitedb"))]
mod sqlite_common;
#[cfg(feature = "sqlitedb")]
pub mod sqlite;
#[cfg(feature = "nssdb")]
pub mod nssdb;
static STORAGE_DBS: LazyLock<Vec<&'static dyn StorageDBInfo>> =
LazyLock::new(|| {
let mut v = Vec::<&'static dyn StorageDBInfo>::with_capacity(4);
#[cfg(feature = "sqlitedb")]
v.push(&sqlite::DBINFO);
#[cfg(feature = "nssdb")]
v.push(&nssdb::DBINFO);
v
});
pub fn new_storage(
name: &str,
conf: &Option<String>,
) -> Result<Box<dyn Storage>> {
for i in 0..(*STORAGE_DBS).len() {
if name == (*STORAGE_DBS)[i].dbtype() {
return (*STORAGE_DBS)[i].new(conf);
}
}
Err(CKR_TOKEN_NOT_RECOGNIZED)?
}