use std::{
fmt,
ptr::NonNull,
};
use crate::{CertElement, Context, FFI};
pub struct TlsCert {
inner: NonNull<sys::xmpp_tlscert_t>,
owned: bool,
}
impl TlsCert {
#[inline]
unsafe fn with_inner(inner: *mut sys::xmpp_tlscert_t, owned: bool) -> Self {
Self { inner: NonNull::new(inner).expect("Cannot allocate memory for TLS certificate"), owned }
}
#[inline]
pub(crate) unsafe fn from_owned(inner: *mut sys::xmpp_tlscert_t) -> Self {
Self::with_inner(inner, true)
}
#[inline]
pub(crate) unsafe fn from_ref(inner: *const sys::xmpp_tlscert_t) -> Self {
Self::with_inner(inner as *mut sys::xmpp_tlscert_t, false)
}
pub(crate) fn as_ptr(&self) -> *mut sys::xmpp_tlscert_t {
self.inner.as_ptr()
}
#[inline]
pub fn context(&self) -> Context {
unsafe {
Context::from_ref_mut(sys::xmpp_tlscert_get_ctx(self.as_ptr()))
}
}
#[inline]
pub fn pem(&self) -> Option<&str> {
unsafe {
FFI(sys::xmpp_tlscert_get_pem(self.as_ptr())).receive()
}
}
#[inline]
pub fn get_dns_name(&self, n: usize) -> Option<&str> {
unsafe {
FFI(sys::xmpp_tlscert_get_dnsname(self.as_ptr(), n)).receive()
}
}
#[inline]
pub fn get_string(&self, element: CertElement) -> Option<&str> {
unsafe {
FFI(sys::xmpp_tlscert_get_string(self.as_ptr(), element)).receive()
}
}
#[inline]
pub fn get_element_description(element: CertElement) -> Option<&'static str> {
unsafe {
FFI(sys::xmpp_tlscert_get_description(element)).receive()
}
}
}
impl Drop for TlsCert {
#[inline]
fn drop(&mut self) {
if self.owned {
unsafe {
sys::xmpp_tlscert_free(self.inner.as_mut());
}
}
}
}
impl fmt::Debug for TlsCert {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut debug = f.debug_struct("TlsCert");
let elems = [
CertElement::XMPP_CERT_VERSION,
CertElement::XMPP_CERT_SERIALNUMBER,
CertElement::XMPP_CERT_SUBJECT,
CertElement::XMPP_CERT_ISSUER,
CertElement::XMPP_CERT_NOTBEFORE,
CertElement::XMPP_CERT_NOTAFTER,
CertElement::XMPP_CERT_KEYALG,
CertElement::XMPP_CERT_SIGALG,
CertElement::XMPP_CERT_FINGERPRINT_SHA1,
CertElement::XMPP_CERT_FINGERPRINT_SHA256,
];
for elem in elems {
if let Some(name) = TlsCert::get_element_description(elem) {
if let Some(val) = self.get_string(elem) {
debug.field(name, &val);
}
}
}
let mut n = 0;
while let Some(dns) = self.get_dns_name(n) {
debug.field("DNS Name", &dns);
n += 1;
}
debug.finish()
}
}