use crate::attribute::{Attribute, CkAttrs};
use crate::error::Result;
use crate::object::{Object, ObjectFactories, ObjectType};
use crate::pkcs11::*;
pub const CK_ULONG_SIZE: usize = std::mem::size_of::<CK_ULONG>();
pub fn bytes_to_vec<T>(ptr: *const T, len: usize) -> Vec<u8> {
if ptr.is_null() || len == 0 {
Vec::new()
} else {
let mut v = Vec::<u8>::with_capacity(len);
unsafe {
std::ptr::copy_nonoverlapping(
ptr as *const u8,
v.as_mut_ptr(),
len,
);
v.set_len(len);
}
v
}
}
macro_rules! void_ptr {
($ptr:expr) => {
$ptr as *const _ as CK_VOID_PTR
};
}
pub(crate) use void_ptr;
macro_rules! byte_ptr {
($ptr:expr) => {
$ptr as *const _ as CK_BYTE_PTR
};
}
pub(crate) use byte_ptr;
macro_rules! sizeof {
($type:ty) => {
CK_ULONG::try_from(std::mem::size_of::<$type>()).unwrap()
};
}
pub(crate) use sizeof;
pub(crate) unsafe fn bytes_to_slice<'a, T>(
ptr: *const T,
len: usize,
) -> &'a [T] {
if len > 0 {
unsafe { std::slice::from_raw_parts(ptr, len) }
} else {
&[]
}
}
pub(crate) unsafe fn bytes_to_slice_mut<'a, T>(
ptr: *mut T,
len: usize,
) -> Result<&'a mut [T]> {
if len > 0 {
Ok(unsafe { std::slice::from_raw_parts_mut(ptr, len) })
} else {
Err(CKR_GENERAL_ERROR)?
}
}
#[allow(dead_code)]
pub fn common_derive_data_object(
template: &[CK_ATTRIBUTE],
objfactories: &ObjectFactories,
default_len: usize,
) -> Result<(Object, usize)> {
let default_class = CKO_DATA;
let mut tmpl = CkAttrs::from(template);
tmpl.add_missing_ulong(CKA_CLASS, &default_class);
let value_len = match tmpl.remove_ulong(CKA_VALUE_LEN)? {
Some(val) => usize::try_from(val)?,
None => {
if default_len == 0 {
return Err(CKR_TEMPLATE_INCOMPLETE)?;
}
default_len
}
};
let obj = match objfactories.get_factory(ObjectType::new(CKO_DATA, 0)) {
Ok(f) => f.create(tmpl.as_slice())?,
Err(_) => return Err(CKR_GENERAL_ERROR)?,
};
Ok((obj, value_len))
}
#[allow(dead_code)]
pub fn common_derive_key_object(
key: &Object,
template: &[CK_ATTRIBUTE],
objfactories: &ObjectFactories,
default_len: usize,
) -> Result<(Object, usize)> {
let default_class = CKO_SECRET_KEY;
let mut tmpl = CkAttrs::from(template);
tmpl.add_missing_ulong(CKA_CLASS, &default_class);
let mut obj =
objfactories.derive_key_from_template(key, tmpl.as_slice())?;
let value_len = match obj.get_attr_as_ulong(CKA_VALUE_LEN) {
Ok(val) => usize::try_from(val)?,
Err(_) => {
if default_len == 0 {
return Err(CKR_TEMPLATE_INCOMPLETE)?;
}
obj.set_attr(Attribute::from_ulong(
CKA_VALUE_LEN,
CK_ULONG::try_from(default_len)?,
))?;
default_len
}
};
Ok((obj, value_len))
}
pub fn copy_sized_string(s: &[u8], d: &mut [u8]) {
let slen;
match s.last() {
None => return,
Some(c) => {
if *c == b'\0' {
slen = s.len() - 1;
} else {
slen = s.len();
}
}
}
if slen >= d.len() {
d.copy_from_slice(&s[..d.len()]);
} else {
d[..slen].copy_from_slice(&s[..slen]);
d[slen..].fill(0x20);
}
}
pub fn zeromem(mem: &mut [u8]) {
ossl::zeromem(mem);
}