diff options
| author | Steven Fackler <[email protected]> | 2014-09-30 00:47:00 -0400 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2014-09-30 00:47:00 -0400 |
| commit | 359043a7aaac6b10d6eb8692e613aa70f52cfc1b (patch) | |
| tree | 3b437a6da2a48cfa06e6238dfeda02d49791c6a7 /src/bio | |
| parent | Merge pull request #55 from cjcole/master (diff) | |
| parent | Addressed review comments (diff) | |
| download | rust-openssl-359043a7aaac6b10d6eb8692e613aa70f52cfc1b.tar.xz rust-openssl-359043a7aaac6b10d6eb8692e613aa70f52cfc1b.zip | |
Merge pull request #53 from vhbit/cert-gen
Certificate/PKey generation & PEM export
Diffstat (limited to 'src/bio')
| -rw-r--r-- | src/bio/mod.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/bio/mod.rs b/src/bio/mod.rs new file mode 100644 index 00000000..f81114de --- /dev/null +++ b/src/bio/mod.rs @@ -0,0 +1,103 @@ +use libc::{c_void, c_int}; +use std::io::{IoResult, IoError, OtherIoError}; +use std::io::{Reader, Writer}; +use std::ptr; + +use ssl::error::{SslError}; + +pub struct MemBio { + bio: *mut ffi::BIO, + owned: bool +} + +impl Drop for MemBio { + fn drop(&mut self) { + if self.owned { + unsafe { + ffi::BIO_free_all(self.bio); + } + } + } +} + +impl MemBio { + /// Creates a new owned memory based BIO + pub fn new() -> Result<MemBio, SslError> { + let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; + try_ssl_null!(bio); + + Ok(MemBio { + bio: bio, + owned: true + }) + } + + /// Returns a "borrow", i.e. it has no ownership + pub fn borrowed(bio: *mut ffi::BIO) -> MemBio { + MemBio { + bio: bio, + owned: false + } + } + + /// Consumes current bio and returns wrapped value + /// Note that data ownership is lost and + /// should be handled manually + pub unsafe fn unwrap(mut self) -> *mut ffi::BIO { + self.owned = false; + self.bio + } + + /// Temporarily gets wrapped value + pub unsafe fn get_handle(&self) -> *mut ffi::BIO { + self.bio + } +} + +impl Reader for MemBio { + fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { + let ret = unsafe { + ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void, + buf.len() as c_int) + }; + + if ret < 0 { + // FIXME: provide details from OpenSSL + Err(IoError{kind: OtherIoError, desc: "mem bio read error", detail: None}) + } else { + Ok(ret as uint) + } + } +} + +impl Writer for MemBio { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + let ret = unsafe { + ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void, + buf.len() as c_int) + }; + if buf.len() != ret as uint { + // FIXME: provide details from OpenSSL + Err(IoError{kind: OtherIoError, desc: "mem bio write error", detail: None}) + } else { + Ok(()) + } + } +} + +pub mod ffi { + #![allow(non_camel_case_types)] + + use libc::{c_int, c_void}; + + pub type BIO = c_void; + pub type BIO_METHOD = c_void; + + extern "C" { + pub fn BIO_s_mem() -> *const BIO_METHOD; + pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; + pub fn BIO_free_all(a: *mut BIO); + pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; + pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; + } +} |