use crate::bindings;
use crate::XmlSecError;
use crate::XmlSecResult;
use std::ptr::null;
use std::ptr::null_mut;
use std::os::raw::c_char;
use std::os::raw::c_uchar;
use std::ffi::CStr;
use std::ffi::CString;
#[allow(missing_docs)]
#[repr(u32)]
pub enum XmlSecKeyFormat
{
Unknown = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatUnknown,
Binary = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatBinary,
Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPem,
Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatDer,
Pkcs8Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Pem,
Pkcs8Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Der,
Pkcs12 = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs12,
CertPem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertPem,
CertDer = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertDer,
}
#[derive(Debug)]
pub struct XmlSecKey(*mut bindings::xmlSecKey);
impl XmlSecKey
{
pub fn from_file(path: &str, format: XmlSecKeyFormat, password: Option<&str>) -> XmlSecResult<Self>
{
crate::xmlsec::guarantee_xmlsec_init();
let cpath = CString::new(path).unwrap();
let cpasswd = password.map(|p| CString::new(p).unwrap());
let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr())
.unwrap_or(null());
let key = unsafe { bindings::xmlSecOpenSSLAppKeyLoad(
cpath.as_ptr(),
format as u32,
cpasswd_ptr,
null_mut(),
null_mut()
) };
if key.is_null() {
return Err(XmlSecError::KeyLoadError);
}
Ok(Self(key))
}
pub fn from_memory(buffer: &[u8], format: XmlSecKeyFormat, password: Option<&str>) -> XmlSecResult<Self>
{
crate::xmlsec::guarantee_xmlsec_init();
let cpasswd = password.map(|p| CString::new(p).unwrap());
let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr())
.unwrap_or(null());
let key = unsafe { bindings::xmlSecOpenSSLAppKeyLoadMemory(
buffer.as_ptr(),
buffer.len() as u32,
format as u32,
cpasswd_ptr,
null_mut(),
null_mut()
) };
if key.is_null() {
return Err(XmlSecError::KeyLoadError);
}
Ok(Self(key))
}
pub fn load_cert_from_file(&self, path: &str, format: XmlSecKeyFormat) -> XmlSecResult<()>
{
let cpath = CString::new(path).unwrap();
let rc = unsafe { bindings::xmlSecOpenSSLAppKeyCertLoad(self.0, cpath.as_ptr(), format as u32) };
if rc != 0 {
return Err(XmlSecError::CertLoadError);
}
Ok(())
}
pub fn load_cert_from_memory(&self, buff: &[u8], format: XmlSecKeyFormat) -> XmlSecResult<()>
{
let rc = unsafe {
bindings::xmlSecOpenSSLAppKeyCertLoadMemory(
self.0,
buff.as_ptr(),
buff.len() as u32,
format as u32
)
};
if rc != 0 {
return Err(XmlSecError::CertLoadError);
}
Ok(())
}
pub fn set_name(&mut self, name: &str)
{
let cname = CString::new(name).unwrap();
let rc = unsafe { bindings::xmlSecKeySetName(
self.0,
cname.as_ptr() as *const c_uchar
) };
if rc < 0 {
panic!("Failed to set name for key"); }
}
pub fn get_name(&self) -> &str
{
let raw = unsafe { bindings::xmlSecKeyGetName(self.0) };
let cname = unsafe { CStr::from_ptr(raw as *const c_char) };
cname.to_str().unwrap() }
pub unsafe fn from_ptr(ptr: *mut bindings::xmlSecKey) -> Self
{
Self(ptr)
}
pub unsafe fn as_ptr(&self) -> *mut bindings::xmlSecKey
{
self.0
}
pub unsafe fn leak(key: Self) -> *mut bindings::xmlSecKey
{
let ptr = key.0;
std::mem::forget(key);
ptr
}
}
impl PartialEq for XmlSecKey
{
fn eq(&self, other: &Self) -> bool
{
self.0 == other.0 }
}
impl Eq for XmlSecKey {}
impl Clone for XmlSecKey
{
fn clone(&self) -> Self
{
let new = unsafe { bindings::xmlSecKeyDuplicate(self.0) };
Self(new)
}
}
impl Drop for XmlSecKey
{
fn drop(&mut self)
{
unsafe { bindings::xmlSecKeyDestroy(self.0) };
}
}