use super::types::{KeyCtlOperation, KeySerialId, KeyType};
use crate::KeyError;
use alloc::ffi::CString;
use core::ffi::CStr;
pub(crate) fn add_key(
ktype: KeyType,
keyring: libc::c_ulong,
description: &str,
payload: Option<&[u8]>,
) -> Result<KeySerialId, KeyError> {
let description = CString::new(description).or(Err(KeyError::InvalidDescription))?;
let (payload, plen) = match payload {
Some(p) => (p.as_ptr(), p.len()),
None => (core::ptr::null(), 0),
};
let res = unsafe {
libc::syscall(
libc::SYS_add_key,
Into::<&'static CStr>::into(ktype).as_ptr(),
description.as_ptr(),
payload,
plen as libc::size_t,
keyring as u32,
)
};
if res < 0 {
return Err(KeyError::from_errno());
}
Ok(KeySerialId::new(
res.try_into().or(Err(KeyError::InvalidIdentifier))?,
))
}
pub(crate) fn request_key(
ktype: KeyType,
keyring: libc::c_ulong,
description: &str,
info: Option<&str>,
) -> Result<KeySerialId, KeyError> {
let description = CString::new(description).or(Err(KeyError::InvalidDescription))?;
let callout = CString::new(info.unwrap_or("")).or(Err(KeyError::InvalidDescription))?;
let res = unsafe {
libc::syscall(
libc::SYS_request_key,
Into::<&'static CStr>::into(ktype).as_ptr(),
description.as_ptr(),
info.map_or_else(core::ptr::null, |_| callout.as_ptr()),
keyring as u32,
)
};
if res < 0 {
return Err(KeyError::from_errno());
}
Ok(KeySerialId::new(
res.try_into().or(Err(KeyError::InvalidIdentifier))?,
))
}
pub(crate) fn keyctl_impl(
operation: KeyCtlOperation,
arg2: libc::c_ulong,
arg3: libc::c_ulong,
arg4: libc::c_ulong,
arg5: libc::c_ulong,
) -> Result<libc::c_long, KeyError> {
let res = unsafe { libc::syscall(libc::SYS_keyctl, operation as u32, arg2, arg3, arg4, arg5) };
if res < 0 {
return Err(KeyError::from_errno());
}
Ok(res)
}