drogue-tls 0.1.0

A no_std mbedTLS crate
use drogue_tls_sys::{
    ssl_context, ssl_init, ssl_set_hostname, ssl_setup, ERR_SSL_ALLOC_FAILED, ERR_SSL_BAD_INPUT_DATA,
};


use crate::ffi::CStr;
use crate::platform::strlen;
use core::ptr::slice_from_raw_parts;
use core::str::from_utf8;
use drogue_tls_sys::types::c_char;
use heapless::consts::*;
use crate::ssl::config::SslConfig;

pub struct SslContext(ssl_context);

#[derive(Debug)]
pub enum HostnameError {
    AllocFailed,
    BadInputData,
    Unknown,
}

impl SslContext {
    pub(crate) fn inner(&self) -> *const ssl_context {
        &self.0
    }

    pub(crate) fn inner_mut(&mut self) -> *mut ssl_context {
        &mut self.0
    }

    pub fn new() -> Self {
        let mut ctx = ssl_context::default();
        unsafe { ssl_init(&mut ctx) };
        Self(ctx)
    }

    pub fn setup(&mut self, config: &SslConfig) -> Result<(), ()> {
        let result = unsafe {
            ssl_setup(self.inner_mut(), config.inner())
        };

        if result != 0 {
            Err(())
        } else {
            Ok(())
        }
    }

    pub fn set_hostname(&mut self, hostname: &str) -> Result<(), HostnameError> {
        let hostname_cstr: CStr<U255> = CStr::new(hostname);
        match unsafe { ssl_set_hostname(self.inner_mut(), hostname_cstr.c_str()) } {
            0 => Ok(()),
            ERR_SSL_BAD_INPUT_DATA => Err(HostnameError::BadInputData),
            ERR_SSL_ALLOC_FAILED => Err(HostnameError::AllocFailed),
            _ => Err(HostnameError::Unknown),
        }
    }

    pub fn get_hostname(&self) -> &str {
        let str: *const c_char = unsafe { (*self.inner()).hostname };
        let slice = unsafe { &(*slice_from_raw_parts(str, strlen(str))) };
        from_utf8(slice).unwrap()
    }
}

impl Default for SslContext {
    fn default() -> Self {
        Self::new()
    }
}