From 8e2d5242a3f498e3c75a3e45e7fe2255ac96298f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 12 Oct 2013 21:48:08 -0700 Subject: [PATCH] Start of cert verification --- src/ssl/ffi.rs | 11 +++++++++-- src/ssl/lib.rs | 20 ++++++++++++++++---- src/ssl/test.rs | 19 +++++++++++++++---- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs index f87625ba..daa02731 100644 --- a/src/ssl/ffi.rs +++ b/src/ssl/ffi.rs @@ -1,6 +1,6 @@ #[doc(hidden)]; -use std::libc::{c_int, c_void}; +use std::libc::{c_int, c_void, c_ulong, c_char}; // openssl/ssl.h pub type SSL_CTX = c_void; @@ -8,6 +8,7 @@ pub type SSL_METHOD = c_void; pub type SSL = c_void; pub type BIO = c_void; pub type BIO_METHOD = c_void; +pub type X509_STORE_CTX = c_void; pub static SSL_ERROR_NONE: c_int = 0; pub static SSL_ERROR_SSL: c_int = 1; @@ -19,15 +20,21 @@ pub static SSL_ERROR_ZERO_RETURN: c_int = 6; pub static SSL_ERROR_WANT_CONNECT: c_int = 7; pub static SSL_ERROR_WANT_ACCEPT: c_int = 8; +pub static SSL_VERIFY_NONE: c_int = 0; +pub static SSL_VERIFY_PEER: c_int = 1; + #[link_args = "-lssl"] extern "C" { } +externfn!(fn ERR_get_error() -> c_ulong) + 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_CTX_set_verify(ctx: *SSL_CTX, mode: c_int, + verify_callback: Option)) externfn!(fn SSL_new(ctx: *SSL_CTX) -> *SSL) externfn!(fn SSL_free(ssl: *SSL)) diff --git a/src/ssl/lib.rs b/src/ssl/lib.rs index 6d08e168..faf9e651 100644 --- a/src/ssl/lib.rs +++ b/src/ssl/lib.rs @@ -22,7 +22,6 @@ pub fn init() { } ffi::SSL_library_init(); - ffi::SSL_load_error_strings(); FINISHED_INIT.store(true, Release); } } @@ -60,6 +59,15 @@ impl SslCtx { ctx: ctx } } + + pub fn set_verify(&mut self, mode: SslVerifyMode) { + unsafe { ffi::SSL_CTX_set_verify(self.ctx, mode as c_int, None) } + } +} + +pub enum SslVerifyMode { + SslVerifyNone = ffi::SSL_VERIFY_NONE, + SslVerifyPeer = ffi::SSL_VERIFY_PEER } #[deriving(Eq, TotalEq, ToStr)] @@ -186,7 +194,7 @@ pub struct SslStream { } impl SslStream { - pub fn new(ctx: SslCtx, stream: S) -> SslStream { + pub fn new(ctx: SslCtx, stream: S) -> Result, uint> { let ssl = Ssl::new(&ctx); let rbio = MemBio::new(); @@ -205,11 +213,15 @@ impl SslStream { stream: stream }; - do stream.in_retry_wrapper |ssl| { + let ret = do stream.in_retry_wrapper |ssl| { ssl.ssl.connect() }; - stream + match ret { + Ok(_) => Ok(stream), + // FIXME + Err(_err) => Err(unsafe { ffi::ERR_get_error() as uint }) + } } fn in_retry_wrapper(&mut self, blk: &fn(&mut SslStream) -> int) diff --git a/src/ssl/test.rs b/src/ssl/test.rs index 3432e2a7..b97e6b00 100644 --- a/src/ssl/test.rs +++ b/src/ssl/test.rs @@ -6,7 +6,7 @@ use std::rt::io::net::tcp::TcpStream; use std::vec; use std::str; -use ssl::{Sslv23, SslCtx, SslStream}; +use ssl::{Sslv23, SslCtx, SslStream, SslVerifyPeer}; #[test] fn test_new_ctx() { @@ -16,13 +16,24 @@ fn test_new_ctx() { #[test] fn test_new_sslstream() { let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); - SslStream::new(SslCtx::new(Sslv23), stream); + SslStream::new(SslCtx::new(Sslv23), stream).unwrap(); +} + +#[test] +fn test_verify() { + let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); + let mut ctx = SslCtx::new(Sslv23); + ctx.set_verify(SslVerifyPeer); + match SslStream::new(ctx, stream) { + Ok(_) => fail2!("expected failure"), + Err(err) => println!("error {}", err) + } } #[test] fn test_write() { let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); - let mut stream = SslStream::new(SslCtx::new(Sslv23), stream); + let mut stream = SslStream::new(SslCtx::new(Sslv23), stream).unwrap(); stream.write("hello".as_bytes()); stream.flush(); stream.write(" there".as_bytes()); @@ -33,7 +44,7 @@ fn test_write() { #[test] fn test_read() { let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); - let mut stream = SslStream::new(SslCtx::new(Sslv23), stream); + let mut stream = SslStream::new(SslCtx::new(Sslv23), stream).unwrap(); stream.write("GET /\r\n\r\n".as_bytes()); stream.flush(); let buf = stream.read_to_end();