diff options
Diffstat (limited to 'src/ssl/lib.rs')
| -rw-r--r-- | src/ssl/lib.rs | 102 |
1 files changed, 97 insertions, 5 deletions
diff --git a/src/ssl/lib.rs b/src/ssl/lib.rs index a7c5588f..a65d8eac 100644 --- a/src/ssl/lib.rs +++ b/src/ssl/lib.rs @@ -1,12 +1,13 @@ +use std::rt::io::{Stream, Decorator}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::task; +use std::ptr; mod ffi; static mut STARTED_INIT: AtomicBool = INIT_ATOMIC_BOOL; static mut FINISHED_INIT: AtomicBool = INIT_ATOMIC_BOOL; -#[fixed_stack_segment] pub fn init() { unsafe { if STARTED_INIT.swap(true, Acquire) { @@ -27,7 +28,6 @@ pub enum SslMethod { } impl SslMethod { - #[fixed_stack_segment] unsafe fn to_raw(&self) -> *ffi::SSL_METHOD { match *self { Sslv23 => ffi::SSLv23_method() @@ -40,18 +40,110 @@ pub struct SslCtx { } impl Drop for SslCtx { - #[fixed_stack_segment] fn drop(&mut self) { unsafe { ffi::SSL_CTX_free(self.ctx); } } } impl SslCtx { - #[fixed_stack_segment] pub fn new(method: SslMethod) -> SslCtx { init(); + + let ctx = unsafe { ffi::SSL_CTX_new(method.to_raw()) }; + assert!(ctx != ptr::null()); + SslCtx { - ctx: unsafe { ffi::SSL_CTX_new(method.to_raw()) } + ctx: ctx } } } + +struct Ssl { + ssl: *ffi::SSL +} + +impl Drop for Ssl { + fn drop(&mut self) { + unsafe { ffi::SSL_free(self.ssl); } + } +} + +impl Ssl { + fn new(ctx: &SslCtx) -> Ssl { + let ssl = unsafe { ffi::SSL_new(ctx.ctx) }; + assert!(ssl != ptr::null()); + + Ssl { ssl: ssl } + } + + fn set_bio(&self, rbio: &MemBio, wbio: &MemBio) { + unsafe { ffi::SSL_set_bio(self.ssl, rbio.bio, wbio.bio); } + } + + fn set_connect_state(&self) { + unsafe { ffi::SSL_set_connect_state(self.ssl); } + } +} + +struct MemBio { + bio: *ffi::BIO +} + +impl Drop for MemBio { + fn drop(&mut self) { + unsafe { ffi::BIO_free(self.bio); } + } +} + +impl MemBio { + fn new() -> MemBio { + let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; + assert!(bio != ptr::null()); + + MemBio { bio: bio } + } +} + +pub struct SslStream<S> { + priv ctx: SslCtx, + priv ssl: Ssl, + priv rbio: MemBio, + priv wbio: MemBio, + priv stream: S +} + +impl<S: Stream> SslStream<S> { + pub fn new(ctx: SslCtx, stream: S) -> SslStream<S> { + let ssl = Ssl::new(&ctx); + + let rbio = MemBio::new(); + let wbio = MemBio::new(); + + ssl.set_bio(&rbio, &wbio); + ssl.set_connect_state(); + + let stream = SslStream { + ctx: ctx, + ssl: ssl, + rbio: rbio, + wbio: wbio, + stream: stream + } + + stream + } +} + +impl<S: Stream> Decorator<S> for SslStream<S> { + fn inner(self) -> S { + self.stream + } + + fn inner_ref<'a>(&'a self) -> &'a S { + &self.stream + } + + fn inner_mut_ref<'a>(&'a mut self) -> &'a mut S { + &mut self.stream + } +} |