aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/bio.rs
diff options
context:
space:
mode:
authorAlex Crichton <[email protected]>2016-09-30 00:43:05 -0700
committerAlex Crichton <[email protected]>2016-10-12 22:49:55 -0700
commit43c951f743e68fac5f45119eda7c994882a1d489 (patch)
tree45169f1b92858a3ba2ad0287de1bf1ecb395804b /openssl/src/ssl/bio.rs
parentRename NoPadding to None (diff)
downloadrust-openssl-43c951f743e68fac5f45119eda7c994882a1d489.tar.xz
rust-openssl-43c951f743e68fac5f45119eda7c994882a1d489.zip
Add support for OpenSSL 1.1.0
This commit is relatively major refactoring of the `openssl-sys` crate as well as the `openssl` crate itself. The end goal here was to support OpenSSL 1.1.0, and lots of other various tweaks happened along the way. The major new features are: * OpenSSL 1.1.0 is supported * OpenSSL 0.9.8 is no longer supported (aka all OSX users by default) * All FFI bindings are verified with the `ctest` crate (same way as the `libc` crate) * CI matrixes are vastly expanded to include 32/64 of all platforms, more OpenSSL version coverage, as well as ARM coverage on Linux * The `c_helpers` module is completely removed along with the `gcc` dependency. * The `openssl-sys` build script was completely rewritten * Now uses `OPENSSL_DIR` to find the installation, not include/lib env vars. * Better error messages for mismatched versions. * Better error messages for failing to find OpenSSL on a platform (more can be done here) * Probing of OpenSSL build-time configuration to inform the API of the `*-sys` crate. * Many Cargo features have been removed as they're now enabled by default. As this is a breaking change to both the `openssl` and `openssl-sys` crates this will necessitate a major version bump of both. There's still a few more API questions remaining but let's hash that out on a PR! Closes #452
Diffstat (limited to 'openssl/src/ssl/bio.rs')
-rw-r--r--openssl/src/ssl/bio.rs176
1 files changed, 130 insertions, 46 deletions
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs
index c5663eb1..ccf3a472 100644
--- a/openssl/src/ssl/bio.rs
+++ b/openssl/src/ssl/bio.rs
@@ -1,5 +1,5 @@
use libc::{c_char, c_int, c_long, c_void, strlen};
-use ffi::{self, BIO, BIO_CTRL_FLUSH, BIO_TYPE_NONE, BIO_new, BIO_clear_retry_flags,
+use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags,
BIO_set_retry_read, BIO_set_retry_write};
use std::any::Any;
use std::io;
@@ -18,22 +18,11 @@ pub struct StreamState<S> {
}
/// Safe wrapper for BIO_METHOD
-pub struct BioMethod(ffi::BIO_METHOD);
+pub struct BioMethod(compat::BIO_METHOD);
impl BioMethod {
pub fn new<S: Read + Write>() -> BioMethod {
- BioMethod(ffi::BIO_METHOD {
- type_: BIO_TYPE_NONE,
- name: b"rust\0".as_ptr() as *const _,
- bwrite: Some(bwrite::<S>),
- bread: Some(bread::<S>),
- bputs: Some(bputs::<S>),
- bgets: None,
- ctrl: Some(ctrl::<S>),
- create: Some(create),
- destroy: Some(destroy::<S>),
- callback_ctrl: None,
- })
+ BioMethod(compat::BIO_METHOD::new::<S>())
}
}
@@ -49,9 +38,9 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), Err
});
unsafe {
- let bio = try_ssl_null!(BIO_new(&method.0));
- (*bio).ptr = Box::into_raw(state) as *mut _;
- (*bio).init = 1;
+ let bio = try_ssl_null!(BIO_new(method.0.get()));
+ compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
+ compat::BIO_set_init(bio, 1);
return Ok((bio, method));
}
@@ -62,14 +51,13 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
state.error.take()
}
-#[cfg_attr(not(feature = "nightly"), allow(dead_code))]
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
let state = state::<S>(bio);
state.panic.take()
}
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
- let state: &'a StreamState<S> = mem::transmute((*bio).ptr);
+ let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
&state.stream
}
@@ -78,24 +66,16 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
}
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
- mem::transmute((*bio).ptr)
+ mem::transmute(compat::BIO_get_data(bio))
}
-#[cfg(feature = "nightly")]
fn catch_unwind<F, T>(f: F) -> Result<T, Box<Any + Send>>
where F: FnOnce() -> T
{
::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(f))
}
-#[cfg(not(feature = "nightly"))]
-fn catch_unwind<F, T>(f: F) -> Result<T, Box<Any + Send>>
- where F: FnOnce() -> T
-{
- Ok(f())
-}
-
-unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
+unsafe extern fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@@ -117,7 +97,7 @@ unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_
}
}
-unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
+unsafe extern fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@@ -147,15 +127,15 @@ fn retriable_error(err: &io::Error) -> bool {
}
}
-unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
+unsafe extern fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
bwrite::<S>(bio, s, strlen(s) as c_int)
}
-unsafe extern "C" fn ctrl<S: Write>(bio: *mut BIO,
- cmd: c_int,
- _num: c_long,
- _ptr: *mut c_void)
- -> c_long {
+unsafe extern fn ctrl<S: Write>(bio: *mut BIO,
+ cmd: c_int,
+ _num: c_long,
+ _ptr: *mut c_void)
+ -> c_long {
if cmd == BIO_CTRL_FLUSH {
let state = state::<S>(bio);
@@ -175,22 +155,126 @@ unsafe extern "C" fn ctrl<S: Write>(bio: *mut BIO,
}
}
-unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
- (*bio).init = 0;
- (*bio).num = 0;
- (*bio).ptr = ptr::null_mut();
- (*bio).flags = 0;
+unsafe extern fn create(bio: *mut BIO) -> c_int {
+ compat::BIO_set_init(bio, 0);
+ compat::BIO_set_num(bio, 0);
+ compat::BIO_set_data(bio, ptr::null_mut());
+ compat::BIO_set_flags(bio, 0);
1
}
-unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
+unsafe extern fn destroy<S>(bio: *mut BIO) -> c_int {
if bio.is_null() {
return 0;
}
- assert!(!(*bio).ptr.is_null());
- Box::<StreamState<S>>::from_raw((*bio).ptr as *mut _);
- (*bio).ptr = ptr::null_mut();
- (*bio).init = 0;
+ let data = compat::BIO_get_data(bio);
+ assert!(!data.is_null());
+ Box::<StreamState<S>>::from_raw(data as *mut _);
+ compat::BIO_set_data(bio, ptr::null_mut());
+ compat::BIO_set_init(bio, 0);
1
}
+
+#[cfg(ossl110)]
+#[allow(bad_style)]
+mod compat {
+ use std::io::{Read, Write};
+
+ use libc::c_int;
+ use ffi;
+ pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
+
+ pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
+
+ pub struct BIO_METHOD {
+ inner: *mut ffi::BIO_METHOD,
+ }
+
+ impl BIO_METHOD {
+ pub fn new<S: Read + Write>() -> BIO_METHOD {
+ unsafe {
+ let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE,
+ b"rust\0".as_ptr() as *const _);
+ assert!(!ptr.is_null());
+ let ret = BIO_METHOD { inner: ptr };
+ assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
+ assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
+ assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
+ assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
+ assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
+ assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
+ return ret
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.inner
+ }
+ }
+
+ impl Drop for BIO_METHOD {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::BIO_meth_free(self.inner);
+ }
+ }
+ }
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use std::io::{Read, Write};
+ use std::cell::UnsafeCell;
+
+ use ffi;
+ use libc::{c_int, c_void};
+
+ pub struct BIO_METHOD {
+ inner: UnsafeCell<ffi::BIO_METHOD>,
+ }
+
+ impl BIO_METHOD {
+ pub fn new<S: Read + Write>() -> BIO_METHOD {
+ BIO_METHOD {
+ inner: UnsafeCell::new(ffi::BIO_METHOD {
+ type_: ffi::BIO_TYPE_NONE,
+ name: b"rust\0".as_ptr() as *const _,
+ bwrite: Some(super::bwrite::<S>),
+ bread: Some(super::bread::<S>),
+ bputs: Some(super::bputs::<S>),
+ bgets: None,
+ ctrl: Some(super::ctrl::<S>),
+ create: Some(super::create),
+ destroy: Some(super::destroy::<S>),
+ callback_ctrl: None,
+ }),
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.inner.get()
+ }
+ }
+
+ pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
+ (*bio).init = init;
+ }
+
+ pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
+ (*bio).flags = flags;
+ }
+
+ pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
+ (*bio).ptr
+ }
+
+ pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
+ (*bio).ptr = data;
+ }
+
+ pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
+ (*bio).num = num;
+ }
+}