diff options
| author | Steven Fackler <[email protected]> | 2016-10-31 21:23:36 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-10-31 21:23:36 -0700 |
| commit | 50d8cca640d4919474605810179f2800f7242722 (patch) | |
| tree | f855b70ba26f82e6545e8e2557cc5eb0c5574fae /openssl/src/ssl/mod.rs | |
| parent | Mention 0.7 README (diff) | |
| parent | Documentation (diff) | |
| download | rust-openssl-50d8cca640d4919474605810179f2800f7242722.tar.xz rust-openssl-50d8cca640d4919474605810179f2800f7242722.zip | |
Merge pull request #507 from sfackler/ref
Add a unified Ref type
Diffstat (limited to 'openssl/src/ssl/mod.rs')
| -rw-r--r-- | openssl/src/ssl/mod.rs | 180 |
1 files changed, 45 insertions, 135 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 5466f26e..68d411c7 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -80,7 +80,6 @@ use std::fmt; use std::io; use std::io::prelude::*; use std::mem; -use std::ops::{Deref, DerefMut}; use std::path::Path; use std::ptr; use std::str; @@ -91,14 +90,14 @@ use std::marker::PhantomData; use ffi; use {init, cvt, cvt_p}; -use dh::DhRef; -use ec_key::EcKeyRef; -use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; +use dh::Dh; +use ec_key::EcKey; +use x509::{X509StoreContext, X509FileType, X509, X509VerifyError}; #[cfg(any(ossl102, ossl110))] -use verify::X509VerifyParamRef; -use pkey::PKeyRef; +use verify::X509VerifyParam; +use pkey::PKey; use error::ErrorStack; -use opaque::Opaque; +use types::{OpenSslType, Ref}; mod error; mod connector; @@ -263,7 +262,7 @@ fn get_new_ssl_idx<T>() -> c_int { } extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -272,14 +271,14 @@ extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let verify: &F = &*(verify as *mut F); - let ctx = X509StoreContextRef::from_ptr(x509_ctx); + let ctx = Ref::from_ptr(x509_ctx); verify(preverify_ok != 0, ctx) as c_int } } extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -287,20 +286,20 @@ extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_ST let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>()); let verify: &F = &*(verify as *mut F); - let ctx = X509StoreContextRef::from_ptr(x509_ctx); + let ctx = Ref::from_ptr(x509_ctx); verify(preverify_ok != 0, ctx) as c_int } } extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int - where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send + where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send { unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let callback: &F = &*(callback as *mut F); - let ssl = SslRef::from_ptr_mut(ssl); + let ssl = Ref::from_ptr_mut(ssl); match callback(ssl) { Ok(()) => ffi::SSL_TLSEXT_ERR_OK, @@ -464,7 +463,7 @@ impl SslContextBuilder { /// Configures the certificate verification method for new connections and /// registers a verification callback. pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); @@ -480,7 +479,7 @@ impl SslContextBuilder { /// Obtain the server name with `servername` then set the corresponding context /// with `set_ssl_context` pub fn set_servername_callback<F>(&mut self, callback: F) - where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send + where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send { unsafe { let callback = Box::new(callback); @@ -513,11 +512,11 @@ impl SslContextBuilder { } } - pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { + pub fn set_tmp_dh(&mut self, dh: &Ref<Dh>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } } - pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { + pub fn set_tmp_ecdh(&mut self, key: &Ref<EcKey>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } } @@ -585,7 +584,7 @@ impl SslContextBuilder { } /// Specifies the certificate - pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { + pub fn set_certificate(&mut self, cert: &Ref<X509>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } } @@ -614,7 +613,7 @@ impl SslContextBuilder { } /// Specifies the private key - pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> { + pub fn set_private_key(&mut self, key: &Ref<PKey>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } @@ -734,25 +733,7 @@ impl SslContextBuilder { } } -/// A borrowed SSL context object. -pub struct SslContextRef(Opaque); - -impl SslContextRef { - pub unsafe fn from_ptr<'a>(ctx: *mut ffi::SSL_CTX) -> &'a SslContextRef { - &*(ctx as *mut _) - } - - pub unsafe fn from_ptr_mut<'a>(ctx: *mut ffi::SSL_CTX) -> &'a mut SslContextRef { - &mut *(ctx as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL_CTX { - self as *const _ as *mut _ - } -} - -/// An owned SSL context object. -pub struct SslContext(*mut ffi::SSL_CTX); +type_!(SslContext, ffi::SSL_CTX, ffi::SSL_CTX_free); unsafe impl Send for SslContext {} unsafe impl Sync for SslContext {} @@ -773,38 +754,10 @@ impl fmt::Debug for SslContext { } } -impl Drop for SslContext { - fn drop(&mut self) { - unsafe { ffi::SSL_CTX_free(self.as_ptr()) } - } -} - -impl Deref for SslContext { - type Target = SslContextRef; - - fn deref(&self) -> &SslContextRef { - unsafe { SslContextRef::from_ptr(self.0) } - } -} - -impl DerefMut for SslContext { - fn deref_mut(&mut self) -> &mut SslContextRef { - unsafe { SslContextRef::from_ptr_mut(self.0) } - } -} - impl SslContext { pub fn builder(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> { SslContextBuilder::new(method) } - - pub unsafe fn from_ptr(ctx: *mut ffi::SSL_CTX) -> SslContext { - SslContext(ctx) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL_CTX { - self.0 - } } @@ -816,17 +769,21 @@ pub struct CipherBits { pub algorithm: i32, } -pub struct SslCipherRef(Opaque); +pub struct SslCipher(*mut ffi::SSL_CIPHER); + +unsafe impl OpenSslType for SslCipher { + type CType = ffi::SSL_CIPHER; -impl SslCipherRef { - pub unsafe fn from_ptr<'a>(ptr: *const ffi::SSL_CIPHER) -> &'a SslCipherRef { - &*(ptr as *const _) + unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher { + SslCipher(ptr) } - pub fn as_ptr(&self) -> *const ffi::SSL_CIPHER { - self as *const _ as *const _ + fn as_ptr(&self) -> *mut ffi::SSL_CIPHER { + self.0 } +} +impl Ref<SslCipher> { /// Returns the name of cipher. pub fn name(&self) -> &'static str { let name = unsafe { @@ -870,15 +827,11 @@ impl SslCipherRef { } } -/// A reference to an `Ssl`. -pub struct SslRef(Opaque); - -unsafe impl Send for SslRef {} -unsafe impl Sync for SslRef {} +type_!(Ssl, ffi::SSL, ffi::SSL_free); -impl fmt::Debug for SslRef { +impl fmt::Debug for Ref<Ssl> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut builder = fmt.debug_struct("SslRef"); + let mut builder = fmt.debug_struct("Ssl"); builder.field("state", &self.state_string_long()); if let Some(err) = self.verify_result() { builder.field("verify_result", &err); @@ -887,19 +840,7 @@ impl fmt::Debug for SslRef { } } -impl SslRef { - pub unsafe fn from_ptr<'a>(ssl: *mut ffi::SSL) -> &'a SslRef { - &*(ssl as *mut _) - } - - pub unsafe fn from_ptr_mut<'a>(ssl: *mut ffi::SSL) -> &'a mut SslRef { - &mut *(ssl as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL { - self as *const _ as *mut _ - } - +impl Ref<Ssl> { fn get_raw_rbio(&self) -> *mut ffi::BIO { unsafe { ffi::SSL_get_rbio(self.as_ptr()) } } @@ -933,7 +874,7 @@ impl SslRef { /// to the certificate chain. It should return `true` if the certificate /// chain is valid and `false` otherwise. pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); @@ -944,14 +885,14 @@ impl SslRef { } } - pub fn current_cipher(&self) -> Option<&SslCipherRef> { + pub fn current_cipher(&self) -> Option<&Ref<SslCipher>> { unsafe { let ptr = ffi::SSL_get_current_cipher(self.as_ptr()); if ptr.is_null() { None } else { - Some(SslCipherRef::from_ptr(ptr)) + Some(Ref::from_ptr(ptr as *mut _)) } } } @@ -1092,15 +1033,15 @@ impl SslRef { } /// Changes the context corresponding to the current connection. - pub fn set_ssl_context(&mut self, ctx: &SslContextRef) -> Result<(), ErrorStack> { + pub fn set_ssl_context(&mut self, ctx: &Ref<SslContext>) -> Result<(), ErrorStack> { unsafe { cvt_p(ffi::SSL_set_SSL_CTX(self.as_ptr(), ctx.as_ptr())).map(|_| ()) } } /// Returns the context corresponding to the current connection - pub fn ssl_context(&self) -> &SslContextRef { + pub fn ssl_context(&self) -> &Ref<SslContext> { unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); - SslContextRef::from_ptr(ssl_ctx) + Ref::from_ptr(ssl_ctx) } } @@ -1108,13 +1049,13 @@ impl SslRef { /// /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] - pub fn param_mut(&mut self) -> &mut X509VerifyParamRef { + pub fn param_mut(&mut self) -> &mut Ref<X509VerifyParam> { self._param_mut() } #[cfg(any(ossl102, ossl110))] - fn _param_mut(&mut self) -> &mut X509VerifyParamRef { - unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } + fn _param_mut(&mut self) -> &mut Ref<X509VerifyParam> { + unsafe { Ref::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } } /// Returns the result of X509 certificate verification. @@ -1123,39 +1064,12 @@ impl SslRef { } } -pub struct Ssl(*mut ffi::SSL); - unsafe impl Sync for Ssl {} unsafe impl Send for Ssl {} impl fmt::Debug for Ssl { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut builder = fmt.debug_struct("Ssl"); - builder.field("state", &self.state_string_long()); - if let Some(err) = self.verify_result() { - builder.field("verify_result", &err); - } - builder.finish() - } -} - -impl Drop for Ssl { - fn drop(&mut self) { - unsafe { ffi::SSL_free(self.as_ptr()) } - } -} - -impl Deref for Ssl { - type Target = SslRef; - - fn deref(&self) -> &SslRef { - unsafe { SslRef::from_ptr(self.0) } - } -} - -impl DerefMut for Ssl { - fn deref_mut(&mut self) -> &mut SslRef { - unsafe { SslRef::from_ptr_mut(self.0) } + fmt::Debug::fmt(&**self, fmt) } } @@ -1167,10 +1081,6 @@ impl Ssl { } } - pub unsafe fn from_ptr(ssl: *mut ffi::SSL) -> Ssl { - Ssl(ssl) - } - /// Creates an SSL/TLS client operating over the provided stream. /// /// # Warning @@ -1255,7 +1165,7 @@ impl<S> MidHandshakeSslStream<S> { } /// Returns a shared reference to the `Ssl` of the stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref<Ssl> { self.stream.ssl() } @@ -1437,7 +1347,7 @@ impl<S> SslStream<S> { } /// Returns the OpenSSL `Ssl` object associated with this stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref<Ssl> { &self.ssl } } |