openssl/
bio.rs

1use libc::c_int;
2use std::marker::PhantomData;
3use std::ptr;
4
5use crate::cvt_p;
6use crate::error::ErrorStack;
7use crate::util;
8
9pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>);
10
11impl Drop for MemBioSlice<'_> {
12    fn drop(&mut self) {
13        unsafe {
14            ffi::BIO_free_all(self.0);
15        }
16    }
17}
18
19impl<'a> MemBioSlice<'a> {
20    pub fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
21        ffi::init();
22
23        assert!(buf.len() <= c_int::MAX as usize);
24        let bio = unsafe {
25            cvt_p(ffi::BIO_new_mem_buf(
26                buf.as_ptr() as *const _,
27                buf.len() as crate::SLenType,
28            ))?
29        };
30
31        Ok(MemBioSlice(bio, PhantomData))
32    }
33
34    pub fn as_ptr(&self) -> *mut ffi::BIO {
35        self.0
36    }
37}
38
39pub struct MemBio(*mut ffi::BIO);
40
41impl Drop for MemBio {
42    fn drop(&mut self) {
43        unsafe {
44            ffi::BIO_free_all(self.0);
45        }
46    }
47}
48
49impl MemBio {
50    pub fn new() -> Result<MemBio, ErrorStack> {
51        ffi::init();
52
53        let bio = unsafe { cvt_p(ffi::BIO_new(ffi::BIO_s_mem()))? };
54        Ok(MemBio(bio))
55    }
56
57    pub fn as_ptr(&self) -> *mut ffi::BIO {
58        self.0
59    }
60
61    pub fn get_buf(&self) -> &[u8] {
62        unsafe {
63            let mut ptr = ptr::null_mut();
64            let len = ffi::BIO_get_mem_data(self.0, &mut ptr);
65            util::from_raw_parts(ptr as *const _ as *const _, len as usize)
66        }
67    }
68
69    #[cfg(not(any(boringssl, awslc)))]
70    pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio {
71        MemBio(bio)
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::MemBio;
78
79    #[test]
80    fn test_mem_bio_get_buf_empty() {
81        let b = MemBio::new().unwrap();
82        assert_eq!(b.get_buf(), &[]);
83    }
84}