aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2015-12-09 23:30:29 -0800
committerSteven Fackler <[email protected]>2015-12-09 23:30:29 -0800
commit91f8c542f75ff81ce7f3f12f26c469127ff0ab18 (patch)
tree29e318fcd0031daeb420609ac0bcf1cc069f391e /openssl/src
parentImplement read and write (diff)
downloadrust-openssl-91f8c542f75ff81ce7f3f12f26c469127ff0ab18.tar.xz
rust-openssl-91f8c542f75ff81ce7f3f12f26c469127ff0ab18.zip
Replace SslStream implementation!
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/c_helpers.c5
-rw-r--r--openssl/src/ssl/mod.rs625
-rw-r--r--openssl/src/ssl/tests/mod.rs21
3 files changed, 119 insertions, 532 deletions
diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c
new file mode 100644
index 00000000..3739cfc2
--- /dev/null
+++ b/openssl/src/c_helpers.c
@@ -0,0 +1,5 @@
+#include <openssl/ssl.h>
+
+void rust_SSL_clone(SSL *ssl) {
+ CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL);
+}
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index e12d694d..5ac6d33e 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -11,7 +11,6 @@ use std::net;
use std::path::Path;
use std::ptr;
use std::sync::{Once, ONCE_INIT, Arc, Mutex};
-use std::ops::{Deref, DerefMut};
use std::cmp;
use std::any::Any;
#[cfg(any(feature = "npn", feature = "alpn"))]
@@ -20,11 +19,10 @@ use libc::{c_uchar, c_uint};
use std::slice;
use std::marker::PhantomData;
-use bio::{MemBio};
use ffi;
use ffi_extras;
use dh::DH;
-use ssl::error::{NonblockingSslError, SslError, SslSessionClosed, StreamError, OpenSslErrors};
+use ssl::error::{NonblockingSslError, SslError, StreamError, OpenSslErrors};
use x509::{X509StoreContext, X509FileType, X509};
use crypto::pkey::PKey;
@@ -33,6 +31,10 @@ mod bio;
#[cfg(test)]
mod tests;
+extern "C" {
+ fn rust_SSL_clone(ssl: *mut ffi::SSL);
+}
+
static mut VERIFY_IDX: c_int = -1;
/// Manually initialize SSL.
@@ -677,26 +679,6 @@ impl SslContext {
}
}
-#[allow(dead_code)]
-struct MemBioRef<'ssl> {
- ssl: &'ssl Ssl,
- bio: MemBio,
-}
-
-impl<'ssl> Deref for MemBioRef<'ssl> {
- type Target = MemBio;
-
- fn deref(&self) -> &MemBio {
- &self.bio
- }
-}
-
-impl<'ssl> DerefMut for MemBioRef<'ssl> {
- fn deref_mut(&mut self) -> &mut MemBio {
- &mut self.bio
- }
-}
-
pub struct Ssl {
ssl: *mut ffi::SSL
}
@@ -718,6 +700,14 @@ impl Drop for Ssl {
}
}
+impl Clone for Ssl {
+ fn clone(&self) -> Ssl {
+ unsafe { rust_SSL_clone(self.ssl) };
+ Ssl { ssl: self.ssl }
+
+ }
+}
+
impl Ssl {
pub fn new(ctx: &SslContext) -> Result<Ssl, SslError> {
let ssl = try_ssl_null!(unsafe { ffi::SSL_new(ctx.ctx) });
@@ -729,22 +719,6 @@ impl Ssl {
unsafe { ffi::SSL_get_rbio(self.ssl) }
}
- fn get_rbio<'a>(&'a self) -> MemBioRef<'a> {
- unsafe { self.wrap_bio(ffi::SSL_get_rbio(self.ssl)) }
- }
-
- fn get_wbio<'a>(&'a self) -> MemBioRef<'a> {
- unsafe { self.wrap_bio(ffi::SSL_get_wbio(self.ssl)) }
- }
-
- fn wrap_bio<'a>(&'a self, bio: *mut ffi::BIO) -> MemBioRef<'a> {
- assert!(bio != ptr::null_mut());
- MemBioRef {
- ssl: self,
- bio: MemBio::borrowed(bio)
- }
- }
-
fn connect(&self) -> c_int {
unsafe { ffi::SSL_connect(self.ssl) }
}
@@ -925,182 +899,94 @@ make_LibSslError! {
ErrorWantAccept = SSL_ERROR_WANT_ACCEPT
}
-struct IndirectStream<S> {
- stream: S,
- ssl: Arc<Ssl>,
- // Max TLS record size is 16k
- buf: Box<[u8; 16 * 1024]>,
-}
-
-impl<S: Clone> Clone for IndirectStream<S> {
- fn clone(&self) -> IndirectStream<S> {
- IndirectStream {
- stream: self.stream.clone(),
- ssl: self.ssl.clone(),
- buf: Box::new(*self.buf)
- }
- }
-}
-
-impl IndirectStream<net::TcpStream> {
- fn try_clone(&self) -> io::Result<IndirectStream<net::TcpStream>> {
- Ok(IndirectStream {
- stream: try!(self.stream.try_clone()),
- ssl: self.ssl.clone(),
- buf: Box::new(*self.buf)
- })
- }
+/// A stream wrapper which handles SSL encryption for an underlying stream.
+pub struct SslStream<S> {
+ ssl: Ssl,
+ _method: Box<ffi::BIO_METHOD>, // :(
+ _p: PhantomData<S>,
}
-impl<S: Read+Write> IndirectStream<S> {
- fn new_base<T: IntoSsl>(ssl: T, stream: S) -> Result<IndirectStream<S>, SslError> {
- let ssl = try!(ssl.into_ssl());
-
- let rbio = try!(MemBio::new());
- let wbio = try!(MemBio::new());
-
- unsafe { ffi::SSL_set_bio(ssl.ssl, rbio.unwrap(), wbio.unwrap()) }
-
- Ok(IndirectStream {
- stream: stream,
- ssl: Arc::new(ssl),
- buf: Box::new([0; 16 * 1024]),
- })
- }
-
- fn connect<T: IntoSsl>(ssl: T, stream: S) -> Result<IndirectStream<S>, SslError> {
- let mut ssl = try!(IndirectStream::new_base(ssl, stream));
- try!(ssl.in_retry_wrapper(|ssl| ssl.connect()));
- Ok(ssl)
- }
+unsafe impl<S: Send> Send for SslStream<S> {}
- fn accept<T: IntoSsl>(ssl: T, stream: S) -> Result<IndirectStream<S>, SslError> {
- let mut ssl = try!(IndirectStream::new_base(ssl, stream));
- try!(ssl.in_retry_wrapper(|ssl| ssl.accept()));
- Ok(ssl)
- }
-
- fn in_retry_wrapper<F>(&mut self, mut blk: F) -> Result<c_int, SslError>
- where F: FnMut(&Ssl) -> c_int {
- loop {
- let ret = blk(&self.ssl);
- if ret > 0 {
- return Ok(ret);
- }
-
- let e = self.ssl.get_error(ret);
- match e {
- LibSslError::ErrorWantRead => {
- try_ssl_stream!(self.flush());
- let len = try_ssl_stream!(self.stream.read(&mut self.buf[..]));
-
-
- if len == 0 {
- let method = self.ssl.get_ssl_method();
-
- if method.map(|m| m.is_dtls()).unwrap_or(false) {
- return Ok(0);
- } else {
- self.ssl.get_rbio().set_eof(true);
- }
- } else {
- try_ssl_stream!(self.ssl.get_rbio().write_all(&self.buf[..len]));
- }
- }
- LibSslError::ErrorWantWrite => { try_ssl_stream!(self.flush()) }
- LibSslError::ErrorZeroReturn => return Err(SslSessionClosed),
- LibSslError::ErrorSsl => return Err(SslError::get()),
- LibSslError::ErrorSyscall if ret == 0 => return Ok(0),
- err => panic!("unexpected error {:?} with ret {}", err, ret),
- }
- }
- }
-
- fn write_through(&mut self) -> io::Result<()> {
- io::copy(&mut *self.ssl.get_wbio(), &mut self.stream).map(|_| ())
+impl<S: Clone + Read + Write> Clone for SslStream<S> {
+ fn clone(&self) -> SslStream<S> {
+ let stream = self.get_ref().clone();
+ Self::new_base(self.ssl.clone(), stream)
}
}
-impl<S: Read+Write> Read for IndirectStream<S> {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- match self.in_retry_wrapper(|ssl| { ssl.read(buf) }) {
- Ok(len) => Ok(len as usize),
- Err(SslSessionClosed) => Ok(0),
- Err(StreamError(e)) => Err(e),
- Err(e @ OpenSslErrors(_)) => {
- Err(io::Error::new(io::ErrorKind::Other, e))
- }
+impl<S> Drop for SslStream<S> {
+ fn drop(&mut self) {
+ unsafe {
+ let _ = bio::take_stream::<S>(self.ssl.get_raw_rbio());
}
}
}
-impl<S: Read+Write> Write for IndirectStream<S> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let count = match self.in_retry_wrapper(|ssl| ssl.write(buf)) {
- Ok(len) => len as usize,
- Err(SslSessionClosed) => 0,
- Err(StreamError(e)) => return Err(e),
- Err(e @ OpenSslErrors(_)) => return Err(io::Error::new(io::ErrorKind::Other, e)),
- };
- try!(self.write_through());
- Ok(count)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- try!(self.write_through());
- self.stream.flush()
- }
-}
-
-#[derive(Clone)]
-struct DirectStream<S> {
- stream: S,
- ssl: Arc<Ssl>,
-}
-
-impl DirectStream<net::TcpStream> {
- fn try_clone(&self) -> io::Result<DirectStream<net::TcpStream>> {
- Ok(DirectStream {
- stream: try!(self.stream.try_clone()),
- ssl: self.ssl.clone(),
- })
+impl<S> fmt::Debug for SslStream<S> where S: fmt::Debug {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("SslStream")
+ .field("stream", &self.get_ref())
+ .field("ssl", &self.ssl())
+ .finish()
}
}
-impl<S> DirectStream<S> {
- fn new_base(ssl: Ssl, stream: S, sock: c_int) -> Result<DirectStream<S>, SslError> {
+impl<S: Read+Write> SslStream<S> {
+ fn new_base(ssl: Ssl, stream: S) -> Self {
unsafe {
- let bio = try_ssl_null!(ffi::BIO_new_socket(sock, 0));
+ let (bio, method) = bio::new(stream).unwrap();
ffi::SSL_set_bio(ssl.ssl, bio, bio);
- }
- Ok(DirectStream {
- stream: stream,
- ssl: Arc::new(ssl),
- })
+ SslStream {
+ ssl: ssl,
+ _method: method,
+ _p: PhantomData,
+ }
+ }
}
- fn connect(ssl: Ssl, stream: S, sock: c_int) -> Result<DirectStream<S>, SslError> {
- let ssl = try!(DirectStream::new_base(ssl, stream, sock));
- let ret = ssl.ssl.connect();
+ /// Creates an SSL/TLS client operating over the provided stream.
+ pub fn connect<T: IntoSsl>(ssl: T, stream: S) -> Result<Self, SslError> {
+ let ssl = try!(ssl.into_ssl());
+ let mut stream = Self::new_base(ssl, stream);
+ let ret = stream.ssl.connect();
if ret > 0 {
- Ok(ssl)
+ Ok(stream)
} else {
- Err(ssl.make_error(ret))
+ Err(stream.make_error(ret))
}
}
- fn accept(ssl: Ssl, stream: S, sock: c_int) -> Result<DirectStream<S>, SslError> {
- let ssl = try!(DirectStream::new_base(ssl, stream, sock));
- let ret = ssl.ssl.accept();
+ /// Creates an SSL/TLS server operating over the provided stream.
+ pub fn accept<T: IntoSsl>(ssl: T, stream: S) -> Result<Self, SslError> {
+ let ssl = try!(ssl.into_ssl());
+ let mut stream = Self::new_base(ssl, stream);
+ let ret = stream.ssl.accept();
if ret > 0 {
- Ok(ssl)
+ Ok(stream)
} else {
- Err(ssl.make_error(ret))
+ Err(stream.make_error(ret))
}
}
- fn make_error(&self, ret: c_int) -> SslError {
+ /// ### Deprecated
+ ///
+ /// Use `connect`.
+ pub fn connect_generic<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
+ Self::connect(ssl, stream)
+ }
+
+ /// ### Deprecated
+ ///
+ /// Use `accept`.
+ pub fn accept_generic<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
+ Self::accept(ssl, stream)
+ }
+}
+
+impl<S> SslStream<S> {
+ fn make_error(&mut self, ret: c_int) -> SslError {
match self.ssl.get_error(ret) {
LibSslError::ErrorSsl => SslError::get(),
LibSslError::ErrorSyscall => {
@@ -1114,199 +1000,26 @@ impl<S> DirectStream<S> {
SslError::StreamError(io::Error::new(io::ErrorKind::ConnectionAborted,
"unexpected EOF observed"))
} else {
- SslError::StreamError(io::Error::last_os_error())
+ let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
+ SslError::StreamError(error.unwrap())
}
} else {
err
}
}
LibSslError::ErrorWantWrite | LibSslError::ErrorWantRead => {
- SslError::StreamError(io::Error::last_os_error())
+ let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
+ SslError::StreamError(error.unwrap())
}
err => panic!("unexpected error {:?} with ret {}", err, ret),
}
}
-}
-
-impl<S> Read for DirectStream<S> {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- let ret = self.ssl.read(buf);
- if ret >= 0 {
- return Ok(ret as usize);
- }
-
- match self.make_error(ret) {
- SslError::StreamError(e) => Err(e),
- e => Err(io::Error::new(io::ErrorKind::Other, e)),
- }
- }
-}
-
-impl<S: Write> Write for DirectStream<S> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let ret = self.ssl.write(buf);
- if ret > 0 {
- return Ok(ret as usize);
- }
-
- match self.make_error(ret) {
- SslError::StreamError(e) => Err(e),
- e => Err(io::Error::new(io::ErrorKind::Other, e)),
- }
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.stream.flush()
- }
-}
-
-#[derive(Clone)]
-enum StreamKind<S> {
- Indirect(IndirectStream<S>),
- Direct(DirectStream<S>),
-}
-
-impl<S> StreamKind<S> {
- fn stream(&self) -> &S {
- match *self {
- StreamKind::Indirect(ref s) => &s.stream,
- StreamKind::Direct(ref s) => &s.stream,
- }
- }
-
- fn mut_stream(&mut self) -> &mut S {
- match *self {
- StreamKind::Indirect(ref mut s) => &mut s.stream,
- StreamKind::Direct(ref mut s) => &mut s.stream,
- }
- }
-
- fn ssl(&self) -> &Ssl {
- match *self {
- StreamKind::Indirect(ref s) => &s.ssl,
- StreamKind::Direct(ref s) => &s.ssl,
- }
- }
-}
-
-/// A stream wrapper which handles SSL encryption for an underlying stream.
-#[derive(Clone)]
-pub struct SslStream<S> {
- kind: StreamKind<S>,
-}
-
-impl SslStream<net::TcpStream> {
- /// Create a new independently owned handle to the underlying socket.
- pub fn try_clone(&self) -> io::Result<SslStream<net::TcpStream>> {
- let kind = match self.kind {
- StreamKind::Indirect(ref s) => StreamKind::Indirect(try!(s.try_clone())),
- StreamKind::Direct(ref s) => StreamKind::Direct(try!(s.try_clone()))
- };
- Ok(SslStream {
- kind: kind
- })
- }
-}
-
-impl<S> fmt::Debug for SslStream<S> where S: fmt::Debug {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.debug_struct("SslStream")
- .field("stream", &self.kind.stream())
- .field("ssl", &self.kind.ssl())
- .finish()
- }
-}
-
-#[cfg(unix)]
-impl<S: Read+Write+::std::os::unix::io::AsRawFd> SslStream<S> {
- /// Creates an SSL/TLS client operating over the provided stream.
- ///
- /// Streams passed to this method must implement `AsRawFd` on Unixy
- /// platforms and `AsRawSocket` on Windows. Use `connect_generic` for
- /// streams that do not.
- pub fn connect<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let ssl = try!(ssl.into_ssl());
- let fd = stream.as_raw_fd() as c_int;
- let stream = try!(DirectStream::connect(ssl, stream, fd));
- Ok(SslStream {
- kind: StreamKind::Direct(stream)
- })
- }
-
- /// Creates an SSL/TLS server operating over the provided stream.
- ///
- /// Streams passed to this method must implement `AsRawFd` on Unixy
- /// platforms and `AsRawSocket` on Windows. Use `accept_generic` for
- /// streams that do not.
- pub fn accept<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let ssl = try!(ssl.into_ssl());
- let fd = stream.as_raw_fd() as c_int;
- let stream = try!(DirectStream::accept(ssl, stream, fd));
- Ok(SslStream {
- kind: StreamKind::Direct(stream)
- })
- }
-}
-
-#[cfg(windows)]
-impl<S: Read+Write+::std::os::windows::io::AsRawSocket> SslStream<S> {
- /// Creates an SSL/TLS client operating over the provided stream.
- ///
- /// Streams passed to this method must implement `AsRawFd` on Unixy
- /// platforms and `AsRawSocket` on Windows. Use `connect_generic` for
- /// streams that do not.
- pub fn connect<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let ssl = try!(ssl.into_ssl());
- let fd = stream.as_raw_socket() as c_int;
- let stream = try!(DirectStream::connect(ssl, stream, fd));
- Ok(SslStream {
- kind: StreamKind::Direct(stream)
- })
- }
-
- /// Creates an SSL/TLS server operating over the provided stream.
- ///
- /// Streams passed to this method must implement `AsRawFd` on Unixy
- /// platforms and `AsRawSocket` on Windows. Use `accept_generic` for
- /// streams that do not.
- pub fn accept<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let ssl = try!(ssl.into_ssl());
- let fd = stream.as_raw_socket() as c_int;
- let stream = try!(DirectStream::accept(ssl, stream, fd));
- Ok(SslStream {
- kind: StreamKind::Direct(stream)
- })
- }
-}
-
-impl<S: Read+Write> SslStream<S> {
- /// Creates an SSL/TLS client operating over the provided stream.
- ///
- /// `SslStream`s returned by this method will be less efficient than ones
- /// returned by `connect`, so this method should only be used for streams
- /// that do not implement `AsRawFd` and `AsRawSocket`.
- pub fn connect_generic<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let stream = try!(IndirectStream::connect(ssl, stream));
- Ok(SslStream {
- kind: StreamKind::Indirect(stream)
- })
- }
-
- /// Creates an SSL/TLS server operating over the provided stream.
- ///
- /// `SslStream`s returned by this method will be less efficient than ones
- /// returned by `accept`, so this method should only be used for streams
- /// that do not implement `AsRawFd` and `AsRawSocket`.
- pub fn accept_generic<T: IntoSsl>(ssl: T, stream: S) -> Result<SslStream<S>, SslError> {
- let stream = try!(IndirectStream::accept(ssl, stream));
- Ok(SslStream {
- kind: StreamKind::Indirect(stream)
- })
- }
-
/// Returns a reference to the underlying stream.
pub fn get_ref(&self) -> &S {
- self.kind.stream()
+ unsafe {
+ let bio = self.ssl.get_raw_rbio();
+ bio::get_ref(bio)
+ }
}
/// Returns a mutable reference to the underlying stream.
@@ -1316,37 +1029,55 @@ impl<S: Read+Write> SslStream<S> {
/// It is inadvisable to read from or write to the underlying stream as it
/// will most likely corrupt the SSL session.
pub fn get_mut(&mut self) -> &mut S {
- self.kind.mut_stream()
+ unsafe {
+ let bio = self.ssl.get_raw_rbio();
+ bio::get_mut(bio)
+ }
}
/// Returns the OpenSSL `Ssl` object associated with this stream.
pub fn ssl(&self) -> &Ssl {
- self.kind.ssl()
+ &self.ssl
}
}
-impl<S: Read+Write> Read for SslStream<S> {
+impl SslStream<::std::net::TcpStream> {
+ /// Like `TcpStream::try_clone`.
+ pub fn try_clone(&self) -> io::Result<SslStream<::std::net::TcpStream>> {
+ let stream = try!(self.get_ref().try_clone());
+ Ok(Self::new_base(self.ssl.clone(), stream))
+ }
+}
+
+impl<S: Read> Read for SslStream<S> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- match self.kind {
- StreamKind::Indirect(ref mut s) => s.read(buf),
- StreamKind::Direct(ref mut s) => s.read(buf),
+ let ret = self.ssl.read(buf);
+ if ret >= 0 {
+ return Ok(ret as usize);
+ }
+
+ match self.make_error(ret) {
+ SslError::StreamError(e) => Err(e),
+ e => Err(io::Error::new(io::ErrorKind::Other, e)),
}
}
}
-impl<S: Read+Write> Write for SslStream<S> {
+impl<S: Write> Write for SslStream<S> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- match self.kind {
- StreamKind::Indirect(ref mut s) => s.write(buf),
- StreamKind::Direct(ref mut s) => s.write(buf),
+ let ret = self.ssl.write(buf);
+ if ret > 0 {
+ return Ok(ret as usize);
+ }
+
+ match self.make_error(ret) {
+ SslError::StreamError(e) => Err(e),
+ e => Err(io::Error::new(io::ErrorKind::Other, e)),
}
}
fn flush(&mut self) -> io::Result<()> {
- match self.kind {
- StreamKind::Indirect(ref mut s) => s.flush(),
- StreamKind::Direct(ref mut s) => s.flush(),
- }
+ self.get_mut().flush()
}
}
@@ -1660,133 +1391,3 @@ impl<S: Read+Write> NonblockingSslStream<S> {
}
}
}
-
-pub struct SslStreamNg<S> {
- ssl: Ssl,
- _method: Box<ffi::BIO_METHOD>, // :(
- _p: PhantomData<S>,
-}
-
-impl<S> Drop for SslStreamNg<S> {
- fn drop(&mut self) {
- unsafe {
- let _ = bio::take_stream::<S>(self.ssl.get_raw_rbio());
- }
- }
-}
-
-impl<S: Read + Write> SslStreamNg<S> {
- fn new_base(ssl: Ssl, stream: S) -> Result<Self, SslError> {
- unsafe {
- let (bio, method) = try!(bio::new(stream));
- ffi::SSL_set_bio(ssl.ssl, bio, bio);
-
- Ok(SslStreamNg {
- ssl: ssl,
- _method: method,
- _p: PhantomData,
- })
- }
- }
-
- /// Creates an SSL/TLS client operating over the provided stream.
- pub fn connect<T: IntoSsl>(ssl: T, stream: S) -> Result<Self, SslError> {
- let ssl = try!(ssl.into_ssl());
- let mut stream = try!(Self::new_base(ssl, stream));
- let ret = stream.ssl.connect();
- if ret > 0 {
- Ok(stream)
- } else {
- Err(stream.make_error(ret))
- }
- }
-
- /// Creates an SSL/TLS server operating over the provided stream.
- pub fn accept<T: IntoSsl>(ssl: T, stream: S) -> Result<Self, SslError> {
- let ssl = try!(ssl.into_ssl());
- let mut stream = try!(Self::new_base(ssl, stream));
- let ret = stream.ssl.accept();
- if ret > 0 {
- Ok(stream)
- } else {
- Err(stream.make_error(ret))
- }
- }
-}
-
-impl<S> SslStreamNg<S> {
- pub fn get_ref(&self) -> &S {
- unsafe {
- let bio = self.ssl.get_raw_rbio();
- bio::get_ref(bio)
- }
- }
-
- pub fn get_mut(&mut self) -> &mut S {
- unsafe {
- let bio = self.ssl.get_raw_rbio();
- bio::get_mut(bio)
- }
- }
-
- fn make_error(&mut self, ret: c_int) -> SslError {
- match self.ssl.get_error(ret) {
- LibSslError::ErrorSsl => SslError::get(),
- LibSslError::ErrorSyscall => {
- let err = SslError::get();
- let count = match err {
- SslError::OpenSslErrors(ref v) => v.len(),
- _ => unreachable!(),
- };
- if count == 0 {
- if ret == 0 {
- SslError::StreamError(io::Error::new(io::ErrorKind::ConnectionAborted,
- "unexpected EOF observed"))
- } else {
- let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
- SslError::StreamError(error.unwrap())
- }
- } else {
- err
- }
- }
- LibSslError::ErrorWantWrite | LibSslError::ErrorWantRead => {
- let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
- SslError::StreamError(error.unwrap())
- }
- err => panic!("unexpected error {:?} with ret {}", err, ret),
- }
- }
-}
-
-impl<S: Read> Read for SslStreamNg<S> {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- let ret = self.ssl.read(buf);
- if ret >= 0 {
- return Ok(ret as usize);
- }
-
- match self.make_error(ret) {
- SslError::StreamError(e) => Err(e),
- e => Err(io::Error::new(io::ErrorKind::Other, e)),
- }
- }
-}
-
-impl<S: Write> Write for SslStreamNg<S> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let ret = self.ssl.write(buf);
- if ret > 0 {
- return Ok(ret as usize);
- }
-
- match self.make_error(ret) {
- SslError::StreamError(e) => Err(e),
- e => Err(io::Error::new(io::ErrorKind::Other, e)),
- }
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.get_mut().flush()
- }
-}
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index 13d9371c..025a45a8 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -18,7 +18,7 @@ use ssl::SSL_VERIFY_PEER;
use ssl::SslMethod::Sslv23;
use ssl::SslMethod;
use ssl::error::NonblockingSslError;
-use ssl::{SslContext, SslStream, VerifyCallback, NonblockingSslStream, SslStreamNg};
+use ssl::{SslContext, SslStream, VerifyCallback, NonblockingSslStream};
use x509::X509StoreContext;
use x509::X509FileType;
use x509::X509;
@@ -929,22 +929,3 @@ fn test_read_nonblocking() {
assert!(bytes_read >= 5);
assert_eq!(&input_buffer[..5], b"HTTP/");
}
-
-#[test]
-fn ng_connect() {
- let (_s, stream) = Server::new();
- let ctx = SslContext::new(Sslv23).unwrap();
- SslStreamNg::connect(&ctx, stream).unwrap();
-}
-
-#[test]
-fn ng_get() {
- let (_s, stream) = Server::new();
- let ctx = SslContext::new(Sslv23).unwrap();
- let mut stream = SslStreamNg::connect(&ctx, stream).unwrap();
- stream.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
- let mut resp = String::new();
- stream.read_to_string(&mut resp).unwrap();
- assert!(resp.starts_with("HTTP/1.0 200"));
- assert!(resp.ends_with("</HTML>\r\n\r\n"));
-}