From 39ba9b1dfec7f3f5ccd7954e932e64635bb7d176 Mon Sep 17 00:00:00 2001 From: Alex Sayers Date: Sat, 4 Mar 2017 01:24:33 +0900 Subject: [PATCH] Upgrade openssl dependency to 0.9.7 --- Cargo.toml | 4 ++-- examples/hyper.rs | 1 - src/client/mod.rs | 6 +++--- src/client/response.rs | 2 +- src/header/accept.rs | 14 +++++++------- src/result.rs | 20 ++++++++++++++++---- src/server/mod.rs | 18 +++++++++--------- src/server/response.rs | 2 +- src/stream.rs | 3 ++- 9 files changed, 41 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9be299b9c6..f18fb8e62f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ keywords = ["websocket", "websockets", "rfc6455"] license = "MIT" [dependencies] -hyper = ">=0.7, <0.10" +hyper = "0.10.5" unicase = "1.0.1" -openssl = "0.7.6" +openssl = "0.9.7" url = "1.0" rustc-serialize = "0.3.16" bitflags = "0.7" diff --git a/examples/hyper.rs b/examples/hyper.rs index 640bc1c6a4..3bbe690cae 100644 --- a/examples/hyper.rs +++ b/examples/hyper.rs @@ -7,7 +7,6 @@ use websocket::{Server, Message, Sender, Receiver}; use websocket::header::WebSocketProtocol; use websocket::message::Type; use hyper::Server as HttpServer; -use hyper::server::Handler; use hyper::net::Fresh; use hyper::server::request::Request; use hyper::server::response::Response; diff --git a/src/client/mod.rs b/src/client/mod.rs index b62302d0bf..5d6be2d14e 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -12,7 +12,7 @@ use stream::WebSocketStream; use dataframe::DataFrame; use ws::dataframe::DataFrame as DataFrameable; -use openssl::ssl::{SslContext, SslMethod, SslStream}; +use openssl::ssl::{SslContext, SslContextBuilder, Ssl, SslMethod}; pub use self::request::Request; pub use self::response::Response; @@ -68,7 +68,7 @@ impl Client, Receiver> { /// A connection is established, however the request is not sent to /// the server until a call to ```send()```. pub fn connect(components: T) -> WebSocketResult> { - let context = try!(SslContext::new(SslMethod::Tlsv1)); + let context = SslContextBuilder::new(SslMethod::tls())?.build(); Client::connect_ssl_context(components, &context) } /// Connects to the specified wss:// URL using the given SSL context. @@ -86,7 +86,7 @@ impl Client, Receiver> { )); let stream = if secure { - let sslstream = try!(SslStream::connect(context, connection)); + let sslstream = Ssl::new(context)?.connect(connection)?; WebSocketStream::Ssl(sslstream) } else { diff --git a/src/client/response.rs b/src/client/response.rs index e60b3fa31c..54a1a192c0 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -101,7 +101,7 @@ impl Response { let key = try!(self.request.key().ok_or( WebSocketError::RequestError("Request Sec-WebSocket-Key was invalid") )); - if self.accept() != Some(&(WebSocketAccept::new(key))) { + if self.accept() != Some(&(WebSocketAccept::new(key)?)) { return Err(WebSocketError::ResponseError("Sec-WebSocket-Accept is invalid")); } if self.headers.get() != Some(&(Upgrade(vec![Protocol{ diff --git a/src/header/accept.rs b/src/header/accept.rs index 8bc0ddab15..73904b74b4 100644 --- a/src/header/accept.rs +++ b/src/header/accept.rs @@ -5,7 +5,7 @@ use std::fmt::{self, Debug}; use std::str::FromStr; use serialize::base64::{ToBase64, FromBase64, STANDARD}; use header::WebSocketKey; -use openssl::crypto::hash::{self, hash}; +use openssl::hash::{self, hash}; use result::{WebSocketResult, WebSocketError}; static MAGIC_GUID: &'static str = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -49,18 +49,18 @@ impl FromStr for WebSocketAccept { impl WebSocketAccept { /// Create a new WebSocketAccept from the given WebSocketKey - pub fn new(key: &WebSocketKey) -> WebSocketAccept { + pub fn new(key: &WebSocketKey) -> WebSocketResult { let serialized = key.serialize(); let mut concat_key = String::with_capacity(serialized.len() + 36); concat_key.push_str(&serialized[..]); concat_key.push_str(MAGIC_GUID); - let output = hash(hash::Type::SHA1, concat_key.as_bytes()); + let output = hash(hash::MessageDigest::sha1(), concat_key.as_bytes())?; let mut iter = output.into_iter(); let mut bytes = [0u8; 20]; for i in bytes.iter_mut() { *i = iter.next().unwrap(); } - WebSocketAccept(bytes) + Ok(WebSocketAccept(bytes)) } /// Return the Base64 encoding of this WebSocketAccept pub fn serialize(&self) -> String { @@ -95,17 +95,17 @@ mod tests { #[test] fn test_header_accept() { let key = FromStr::from_str("dGhlIHNhbXBsZSBub25jZQ==").unwrap(); - let accept = WebSocketAccept::new(&key); + let accept = WebSocketAccept::new(&key).unwrap(); let mut headers = Headers::new(); headers.set(accept); - + assert_eq!(&headers.to_string()[..], "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); } #[bench] fn bench_header_accept_new(b: &mut test::Bencher) { let key = WebSocketKey::new(); b.iter(|| { - let mut accept = WebSocketAccept::new(&key); + let mut accept = WebSocketAccept::new(&key).unwrap(); test::black_box(&mut accept); }); } diff --git a/src/result.rs b/src/result.rs index f6b9b25fa8..6a96a795bf 100644 --- a/src/result.rs +++ b/src/result.rs @@ -5,7 +5,9 @@ use std::str::Utf8Error; use std::error::Error; use std::convert::From; use std::fmt; -use openssl::ssl::error::SslError; +use std::net::TcpStream; +use openssl::ssl::HandshakeError; +use openssl::error as ssl; use hyper::Error as HttpError; use url::ParseError; @@ -34,7 +36,9 @@ pub enum WebSocketError { /// A WebSocket URL error WebSocketUrlError(WSUrlErrorKind), /// An SSL error - SslError(SslError), + SslError(ssl::ErrorStack), + /// An SSL error + SslHandshakeError(HandshakeError), /// A UTF-8 error Utf8Error(Utf8Error), } @@ -59,6 +63,7 @@ impl Error for WebSocketError { WebSocketError::HttpError(_) => "HTTP failure", WebSocketError::UrlError(_) => "URL failure", WebSocketError::SslError(_) => "SSL failure", + WebSocketError::SslHandshakeError(_) => "SSL handshake failure", WebSocketError::Utf8Error(_) => "UTF-8 failure", WebSocketError::WebSocketUrlError(_) => "WebSocket URL failure", } @@ -70,6 +75,7 @@ impl Error for WebSocketError { WebSocketError::HttpError(ref error) => Some(error), WebSocketError::UrlError(ref error) => Some(error), WebSocketError::SslError(ref error) => Some(error), + WebSocketError::SslHandshakeError(ref error) => Some(error), WebSocketError::Utf8Error(ref error) => Some(error), WebSocketError::WebSocketUrlError(ref error) => Some(error), _ => None, @@ -98,12 +104,18 @@ impl From for WebSocketError { } } -impl From for WebSocketError { - fn from(err: SslError) -> WebSocketError { +impl From for WebSocketError { + fn from(err: ssl::ErrorStack) -> WebSocketError { WebSocketError::SslError(err) } } +impl From> for WebSocketError { + fn from(err: HandshakeError) -> WebSocketError { + WebSocketError::SslHandshakeError(err) + } +} + impl From for WebSocketError { fn from(err: Utf8Error) -> WebSocketError { WebSocketError::Utf8Error(err) diff --git a/src/server/mod.rs b/src/server/mod.rs index 8236b1c089..e4d989406e 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -8,8 +8,7 @@ pub use self::response::Response; use stream::WebSocketStream; -use openssl::ssl::SslContext; -use openssl::ssl::SslStream; +use openssl::ssl::{SslContext, Ssl}; pub mod request; pub mod response; @@ -52,13 +51,14 @@ pub mod response; ///use std::thread; ///use std::path::Path; ///use websocket::{Server, Message}; -///use openssl::ssl::{SslContext, SslMethod}; -///use openssl::x509::X509FileType; +///use openssl::ssl::{Ssl, SslContext, SslContextBuilder, SslMethod}; +///use openssl::x509::X509_FILETYPE_PEM; /// -///let mut context = SslContext::new(SslMethod::Tlsv1).unwrap(); -///let _ = context.set_certificate_file(&(Path::new("cert.pem")), X509FileType::PEM); -///let _ = context.set_private_key_file(&(Path::new("key.pem")), X509FileType::PEM); -///let server = Server::bind_secure("127.0.0.1:1234", &context).unwrap(); +///let mut builder = SslContextBuilder::new(SslMethod::tls()).unwrap(); +///let _ = builder.set_certificate_file(&(Path::new("cert.pem")), X509_FILETYPE_PEM); +///let _ = builder.set_private_key_file(&(Path::new("key.pem")), X509_FILETYPE_PEM); +///let ctx = builder.build(); +///let server = Server::bind_secure("127.0.0.1:1234", &ctx).unwrap(); /// ///for connection in server { /// // Spawn a new thread for each connection. @@ -114,7 +114,7 @@ impl<'a> Server<'a> { let stream = try!(self.inner.accept()).0; let wsstream = match self.context { Some(context) => { - let sslstream = match SslStream::accept(context, stream) { + let sslstream = match Ssl::new(context)?.accept(stream) { Ok(s) => s, Err(err) => { return Err(io::Error::new(io::ErrorKind::Other, err)); diff --git a/src/server/response.rs b/src/server/response.rs index 0bae5e4cd0..851531fd3a 100644 --- a/src/server/response.rs +++ b/src/server/response.rs @@ -74,7 +74,7 @@ impl Response { /// Create a new outbound WebSocket response. pub fn new(request: Request) -> Response { let mut headers = Headers::new(); - headers.set(WebSocketAccept::new(request.key().unwrap())); + headers.set(WebSocketAccept::new(request.key().unwrap()).unwrap()); headers.set(Connection(vec![ ConnectionOption::ConnectionHeader(UniCase("Upgrade".to_string())) ])); diff --git a/src/stream.rs b/src/stream.rs index 623b280bbd..51a04dba18 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -80,7 +80,8 @@ impl WebSocketStream { pub fn try_clone(&self) -> io::Result { Ok(match *self { WebSocketStream::Tcp(ref inner) => WebSocketStream::Tcp(try!(inner.try_clone())), - WebSocketStream::Ssl(ref inner) => WebSocketStream::Ssl(try!(inner.try_clone())), + // FIXME: This is **terrible**! But SslStream no longer has try_clone... + WebSocketStream::Ssl(ref inner) => WebSocketStream::Tcp(try!(inner.get_ref().try_clone())), }) }