SslStream sketch

This commit is contained in:
Steven Fackler 2013-10-05 13:56:59 -07:00
parent 58eb7ab5c4
commit d4d5547a79
3 changed files with 128 additions and 13 deletions

View File

@ -1,14 +1,29 @@
#[doc(hidden)];
use std::libc::{c_int, c_void}; use std::libc::{c_int, c_void};
pub type SSL_CTX = c_void; pub type SSL_CTX = c_void;
pub type SSL_METHOD = c_void; pub type SSL_METHOD = c_void;
pub type SSL = c_void;
pub type BIO = c_void;
pub type BIO_METHOD = c_void;
#[link_args = "-lssl"] #[link_args = "-lssl"]
extern "C" { extern "C" { }
fn SSL_library_init() -> c_int;
fn SSL_load_error_strings();
fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX; externfn!(fn SSL_library_init() -> c_int)
fn SSLv23_method() -> *SSL_METHOD; externfn!(fn SSL_load_error_strings())
fn SSL_CTX_free(ctx: *SSL_CTX);
} externfn!(fn SSLv23_method() -> *SSL_METHOD)
externfn!(fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX)
externfn!(fn SSL_CTX_free(ctx: *SSL_CTX))
externfn!(fn SSL_new(ctx: *SSL_CTX) -> *SSL)
externfn!(fn SSL_free(ssl: *SSL))
externfn!(fn SSL_set_bio(ssl: *SSL, rbio: *BIO, wbio: *BIO))
externfn!(fn SSL_set_connect_state(ssl: *SSL))
externfn!(fn SSL_do_handshake(ssl: *SSL))
externfn!(fn BIO_s_mem() -> *BIO_METHOD)
externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO)
externfn!(fn BIO_free(a: *BIO) -> c_int)

View File

@ -1,12 +1,13 @@
use std::rt::io::{Stream, Decorator};
use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release};
use std::task; use std::task;
use std::ptr;
mod ffi; mod ffi;
static mut STARTED_INIT: AtomicBool = INIT_ATOMIC_BOOL; static mut STARTED_INIT: AtomicBool = INIT_ATOMIC_BOOL;
static mut FINISHED_INIT: AtomicBool = INIT_ATOMIC_BOOL; static mut FINISHED_INIT: AtomicBool = INIT_ATOMIC_BOOL;
#[fixed_stack_segment]
pub fn init() { pub fn init() {
unsafe { unsafe {
if STARTED_INIT.swap(true, Acquire) { if STARTED_INIT.swap(true, Acquire) {
@ -27,7 +28,6 @@ pub enum SslMethod {
} }
impl SslMethod { impl SslMethod {
#[fixed_stack_segment]
unsafe fn to_raw(&self) -> *ffi::SSL_METHOD { unsafe fn to_raw(&self) -> *ffi::SSL_METHOD {
match *self { match *self {
Sslv23 => ffi::SSLv23_method() Sslv23 => ffi::SSLv23_method()
@ -40,18 +40,110 @@ pub struct SslCtx {
} }
impl Drop for SslCtx { impl Drop for SslCtx {
#[fixed_stack_segment]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { ffi::SSL_CTX_free(self.ctx); } unsafe { ffi::SSL_CTX_free(self.ctx); }
} }
} }
impl SslCtx { impl SslCtx {
#[fixed_stack_segment]
pub fn new(method: SslMethod) -> SslCtx { pub fn new(method: SslMethod) -> SslCtx {
init(); init();
let ctx = unsafe { ffi::SSL_CTX_new(method.to_raw()) };
assert!(ctx != ptr::null());
SslCtx { 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
}
}

View File

@ -1,8 +1,16 @@
extern mod ssl; extern mod ssl;
use ssl::{Sslv23, SslCtx}; use std::rt::io::net::tcp::TcpStream;
use ssl::{Sslv23, SslCtx, SslStream};
#[test] #[test]
fn test_new_ctx() { fn test_new_ctx() {
SslCtx::new(Sslv23); SslCtx::new(Sslv23);
} }
#[test]
fn test_new_sslstream() {
let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap());
let stream = SslStream::new(SslCtx::new(Sslv23), stream);
}