diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 5204c3bf..b347b949 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -271,6 +271,7 @@ extern "C" { pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; pub fn BIO_free_all(b: *mut BIO); pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; + pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO; pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; pub fn BIO_s_mem() -> *const BIO_METHOD; diff --git a/openssl/src/bio/mod.rs b/openssl/src/bio/mod.rs index e0a7d0c9..7eea16d8 100644 --- a/openssl/src/bio/mod.rs +++ b/openssl/src/bio/mod.rs @@ -76,8 +76,7 @@ impl Read for MemBio { if is_eof != 0 { Ok(0) } else { - Err(io::Error::new(io::ErrorKind::Other, - SslError::get())) + Err(io::Error::new(io::ErrorKind::Other, SslError::get())) } } else { Ok(ret as usize) @@ -93,8 +92,7 @@ impl Write for MemBio { }; if ret < 0 { - Err(io::Error::new(io::ErrorKind::Other, - SslError::get())) + Err(io::Error::new(io::ErrorKind::Other, SslError::get())) } else { Ok(ret as usize) } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index fbad7dcc..0768fead 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -496,7 +496,7 @@ impl SslContext { pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(),SslError> { wrap_ssl_result( unsafe { - let cipher_list = CString::new(cipher_list.as_bytes()).unwrap(); + let cipher_list = CString::new(cipher_list).unwrap(); ffi::SSL_CTX_set_cipher_list(self.ctx, cipher_list.as_ptr()) }) } @@ -766,36 +766,41 @@ impl fmt::Debug for SslStream where S: fmt::Debug { } impl SslStream { - fn new_base(ssl:Ssl, stream: S) -> SslStream { - SslStream { + fn new_base(ssl: T, stream: S) -> Result, SslError> { + let ssl = try!(ssl.into_ssl()); + Ok(SslStream { stream: stream, ssl: Arc::new(ssl), // Maximum TLS record size is 16k buf: iter::repeat(0).take(16 * 1024).collect(), - } + }) } + pub fn new_client(ssl: T, stream: S) -> Result, SslError> { + let mut ssl = try!(SslStream::new_base(ssl, stream)); + try!(ssl.in_retry_wrapper(|ssl| ssl.connect())); + Ok(ssl) + } + + pub fn new_server(ssl: T, stream: S) -> Result, SslError> { + let mut ssl = try!(SslStream::new_base(ssl, stream)); + try!(ssl.in_retry_wrapper(|ssl| ssl.accept())); + Ok(ssl) + } + + /// # Deprecated pub fn new_server_from(ssl: Ssl, stream: S) -> Result, SslError> { - let mut ssl = SslStream::new_base(ssl, stream); - ssl.in_retry_wrapper(|ssl| { ssl.accept() }).and(Ok(ssl)) + SslStream::new_server(ssl, stream) } - /// Attempts to create a new SSL stream from a given `Ssl` instance. + /// # Deprecated pub fn new_from(ssl: Ssl, stream: S) -> Result, SslError> { - let mut ssl = SslStream::new_base(ssl, stream); - ssl.in_retry_wrapper(|ssl| { ssl.connect() }).and(Ok(ssl)) + SslStream::new_client(ssl, stream) } - /// Creates a new SSL stream + /// # Deprecated pub fn new(ctx: &SslContext, stream: S) -> Result, SslError> { - let ssl = try!(Ssl::new(ctx)); - SslStream::new_from(ssl, stream) - } - - /// Creates a new SSL server stream - pub fn new_server(ctx: &SslContext, stream: S) -> Result, SslError> { - let ssl = try!(Ssl::new(ctx)); - SslStream::new_server_from(ssl, stream) + SslStream::new_client(ctx, stream) } #[doc(hidden)] @@ -920,6 +925,22 @@ impl Write for SslStream { } } +pub trait IntoSsl { + fn into_ssl(self) -> Result; +} + +impl IntoSsl for Ssl { + fn into_ssl(self) -> Result { + Ok(self) + } +} + +impl<'a> IntoSsl for &'a SslContext { + fn into_ssl(self) -> Result { + Ssl::new(self) + } +} + /// A utility type to help in cases where the use of SSL is decided at runtime. #[derive(Debug)] pub enum MaybeSslStream where S: Read+Write { diff --git a/openssl/src/ssl/tests.rs b/openssl/src/ssl/tests.rs index dcaee215..a0e4a9d6 100644 --- a/openssl/src/ssl/tests.rs +++ b/openssl/src/ssl/tests.rs @@ -83,14 +83,14 @@ run_test!(new_ctx, |method, _| { }); run_test!(new_sslstream, |method, stream| { - SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap(); + SslStream::new_client(&SslContext::new(method).unwrap(), stream).unwrap(); }); run_test!(verify_untrusted, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, None); - match SslStream::new(&ctx, stream) { + match SslStream::new_client(&ctx, stream) { Ok(_) => panic!("expected failure"), Err(err) => println!("error {:?}", err) } @@ -104,7 +104,7 @@ run_test!(verify_trusted, |method, stream| { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - match SslStream::new(&ctx, stream) { + match SslStream::new_client(&ctx, stream) { Ok(_) => (), Err(err) => panic!("Expected success, got {:?}", err) } @@ -118,7 +118,7 @@ run_test!(verify_untrusted_callback_override_ok, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback)); - match SslStream::new(&ctx, stream) { + match SslStream::new_client(&ctx, stream) { Ok(_) => (), Err(err) => panic!("Expected success, got {:?}", err) } @@ -132,7 +132,7 @@ run_test!(verify_untrusted_callback_override_bad, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback)); - assert!(SslStream::new(&ctx, stream).is_err()); + assert!(SslStream::new_client(&ctx, stream).is_err()); }); run_test!(verify_trusted_callback_override_ok, |method, stream| { @@ -147,7 +147,7 @@ run_test!(verify_trusted_callback_override_ok, |method, stream| { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - match SslStream::new(&ctx, stream) { + match SslStream::new_client(&ctx, stream) { Ok(_) => (), Err(err) => panic!("Expected success, got {:?}", err) } @@ -165,7 +165,7 @@ run_test!(verify_trusted_callback_override_bad, |method, stream| { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - assert!(SslStream::new(&ctx, stream).is_err()); + assert!(SslStream::new_client(&ctx, stream).is_err()); }); run_test!(verify_callback_load_certs, |method, stream| { @@ -177,7 +177,7 @@ run_test!(verify_callback_load_certs, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback)); - assert!(SslStream::new(&ctx, stream).is_ok()); + assert!(SslStream::new_client(&ctx, stream).is_ok()); }); run_test!(verify_trusted_get_error_ok, |method, stream| { @@ -193,7 +193,7 @@ run_test!(verify_trusted_get_error_ok, |method, stream| { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - assert!(SslStream::new(&ctx, stream).is_ok()); + assert!(SslStream::new_client(&ctx, stream).is_ok()); }); run_test!(verify_trusted_get_error_err, |method, stream| { @@ -205,7 +205,7 @@ run_test!(verify_trusted_get_error_err, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback)); - assert!(SslStream::new(&ctx, stream).is_err()); + assert!(SslStream::new_client(&ctx, stream).is_err()); }); run_test!(verify_callback_data, |method, stream| { @@ -230,7 +230,7 @@ run_test!(verify_callback_data, |method, stream| { ctx.set_verify_with_data(SSL_VERIFY_PEER, callback, node_id); ctx.set_verify_depth(1); - match SslStream::new(&ctx, stream) { + match SslStream::new_client(&ctx, stream) { Ok(_) => (), Err(err) => panic!("Expected success, got {:?}", err) } @@ -245,7 +245,7 @@ fn test_write_hits_stream() { let guard = thread::spawn(move || { let ctx = SslContext::new(Sslv23).unwrap(); let stream = TcpStream::connect(addr).unwrap(); - let mut stream = SslStream::new(&ctx, stream).unwrap(); + let mut stream = SslStream::new_client(&ctx, stream).unwrap(); stream.write_all(b"hello").unwrap(); stream @@ -310,7 +310,7 @@ run_test!(clear_ctx_options, |method, _| { #[test] fn test_write() { let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); - let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), stream).unwrap(); + let mut stream = SslStream::new_client(&SslContext::new(Sslv23).unwrap(), stream).unwrap(); stream.write_all("hello".as_bytes()).unwrap(); stream.flush().unwrap(); stream.write_all(" there".as_bytes()).unwrap(); @@ -319,7 +319,7 @@ fn test_write() { run_test!(get_peer_certificate, |method, stream| { //let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); - let stream = SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap(); + let stream = SslStream::new_client(&SslContext::new(method).unwrap(), stream).unwrap(); let cert = stream.get_peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA256).unwrap(); let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; @@ -333,7 +333,7 @@ fn test_write_dtlsv1() { let sock = UdpSocket::bind("127.0.0.1:0").unwrap(); let stream = sock.connect("127.0.0.1:15410").unwrap(); - let mut stream = SslStream::new(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap(); + let mut stream = SslStream::new_client(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap(); stream.write_all("hello".as_bytes()).unwrap(); stream.flush().unwrap(); stream.write_all(" there".as_bytes()).unwrap(); @@ -343,7 +343,7 @@ fn test_write_dtlsv1() { #[test] fn test_read() { let tcp = TcpStream::connect("127.0.0.1:15418").unwrap(); - let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), tcp).unwrap(); + let mut stream = SslStream::new_client(&SslContext::new(Sslv23).unwrap(), tcp).unwrap(); stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); stream.flush().unwrap(); io::copy(&mut stream, &mut io::sink()).ok().expect("read error"); @@ -353,7 +353,7 @@ fn test_read() { #[test] fn test_pending() { let tcp = TcpStream::connect("127.0.0.1:15418").unwrap(); - let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), tcp).unwrap(); + let mut stream = SslStream::new_client(&SslContext::new(Sslv23).unwrap(), tcp).unwrap(); stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); stream.flush().unwrap(); @@ -386,7 +386,7 @@ fn test_connect_with_unilateral_npn() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::new_client(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; @@ -410,7 +410,7 @@ fn test_connect_with_npn_successful_multiple_matching() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::new_client(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; @@ -435,7 +435,7 @@ fn test_connect_with_npn_successful_single_match() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::new_client(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; @@ -477,7 +477,7 @@ fn test_npn_server_advertise_multiple() { } // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::new_client(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; @@ -514,7 +514,7 @@ fn test_read_dtlsv1() { let server = udp::next_server(); let stream = sock.connect(&server[..]).unwrap(); - let mut stream = SslStream::new(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap(); + let mut stream = SslStream::new_client(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap(); let mut buf = [0u8;100]; assert!(stream.read(&mut buf).is_ok()); } @@ -523,5 +523,5 @@ fn test_read_dtlsv1() { #[cfg(feature = "sslv2")] fn test_sslv2_connect_failure() { let tcp = TcpStream::connect("127.0.0.1:15420").unwrap(); - SslStream::new(&SslContext::new(Sslv2).unwrap(), tcp).err().unwrap(); + SslStream::new_client(&SslContext::new(Sslv2).unwrap(), tcp).err().unwrap(); }