aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2013-10-05 13:56:59 -0700
committerSteven Fackler <[email protected]>2013-10-05 13:56:59 -0700
commitd4d5547a7990749b554cc8e2b8b42a172ee98e5e (patch)
tree57439ff0d9357bb882e8f55e0730b2364fd4807a
parentCreate contexts (diff)
downloadrust-openssl-d4d5547a7990749b554cc8e2b8b42a172ee98e5e.tar.xz
rust-openssl-d4d5547a7990749b554cc8e2b8b42a172ee98e5e.zip
SslStream sketch
-rw-r--r--src/ssl/ffi.rs31
-rw-r--r--src/ssl/lib.rs102
-rw-r--r--src/ssl/test.rs10
3 files changed, 129 insertions, 14 deletions
diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs
index 788765fb..c3144545 100644
--- a/src/ssl/ffi.rs
+++ b/src/ssl/ffi.rs
@@ -1,14 +1,29 @@
+#[doc(hidden)];
+
use std::libc::{c_int, c_void};
pub type SSL_CTX = 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"]
-extern "C" {
- fn SSL_library_init() -> c_int;
- fn SSL_load_error_strings();
-
- fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX;
- fn SSLv23_method() -> *SSL_METHOD;
- fn SSL_CTX_free(ctx: *SSL_CTX);
-}
+extern "C" { }
+
+externfn!(fn SSL_library_init() -> c_int)
+externfn!(fn SSL_load_error_strings())
+
+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)
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
+ }
+}
diff --git a/src/ssl/test.rs b/src/ssl/test.rs
index d54613ee..501c8626 100644
--- a/src/ssl/test.rs
+++ b/src/ssl/test.rs
@@ -1,8 +1,16 @@
extern mod ssl;
-use ssl::{Sslv23, SslCtx};
+use std::rt::io::net::tcp::TcpStream;
+
+use ssl::{Sslv23, SslCtx, SslStream};
#[test]
fn test_new_ctx() {
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);
+}