SslStream sketch
This commit is contained in:
parent
58eb7ab5c4
commit
d4d5547a79
|
|
@ -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)
|
||||||
|
|
|
||||||
102
src/ssl/lib.rs
102
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::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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue