From 5e123df7a77e8d973b6c7a8c8a13faa47aa90a70 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 3 Aug 2015 17:01:00 -0400 Subject: [PATCH] Make SSL cert verification errors work again. Add a horrible, no-good, very bad regression test. --- components/net/http_loader.rs | 42 ++++++++++--------- tests/wpt/mozilla/meta/MANIFEST.json | 8 +++- .../tests/mozilla/bad_cert_detected.html | 28 +++++++++++++ .../tests/mozilla/resources/origin_helpers.js | 5 +++ 4 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html create mode 100644 tests/wpt/mozilla/tests/mozilla/resources/origin_helpers.js diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index ef854a504dd..ba27e5ed9c5 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -27,6 +27,7 @@ use msg::constellation_msg::{PipelineId}; use net_traits::ProgressMsg::{Done, Payload}; use net_traits::hosts::replace_hosts; use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadData, Metadata}; +use openssl::ssl::error::{SslError, OpensslError}; use openssl::ssl::{SSL_VERIFY_PEER, SslContext, SslMethod}; use resource_task::{CancellationListener, send_error, start_sending_sniffed_opt}; use std::borrow::ToOwned; @@ -210,29 +211,21 @@ impl HttpRequestFactory for NetworkHttpRequestFactory { fn create(&self, url: Url, method: Method) -> Result { let connection = Request::with_connector(method, url.clone(), &*self.connector); - let ssl_err_string = "Some(OpenSslErrors([UnknownError { library: \"SSL routines\", \ - function: \"SSL3_GET_SERVER_CERTIFICATE\", \ - reason: \"certificate verify failed\" }]))"; + if let Err(HttpError::Ssl(ref error)) = connection { + let error: &(Error + Send + 'static) = &**error; + if let Some(&SslError::OpenSslErrors(ref errors)) = error.downcast_ref::() { + if errors.iter().any(is_cert_verify_error) { + return Err( + LoadError::Ssl(url, format!("ssl error: {:?} {:?}", + error.description(), + error.cause()))); + } + } + } let request = match connection { Ok(req) => req, - Err(HttpError::Io(ref io_error)) if ( - io_error.kind() == io::ErrorKind::Other && - io_error.description() == "Error in OpenSSL" && - // FIXME: This incredibly hacky. Make it more robust, and at least test it. - format!("{:?}", io_error.cause()) == ssl_err_string - ) => { - return Err( - LoadError::Ssl( - url, - format!("ssl error {:?}: {:?} {:?}", - io_error.kind(), - io_error.description(), - io_error.cause()) - ) - ) - }, Err(e) => { return Err(LoadError::Connection(url, e.description().to_owned())) } @@ -756,3 +749,14 @@ fn send_data(reader: &mut R, let _ = progress_chan.send(Done(Ok(()))); } + +// FIXME: This incredibly hacky. Make it more robust, and at least test it. +fn is_cert_verify_error(error: &OpensslError) -> bool { + match error { + &OpensslError::UnknownError { ref library, ref function, ref reason } => { + library == "SSL routines" && + function == "SSL3_GET_SERVER_CERTIFICATE" && + reason == "certificate verify failed" + } + } +} diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 36ccf1e1a70..4e74a39ec22 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -4559,6 +4559,12 @@ "url": "/_mozilla/mozilla/MouseEvent.html" } ], + "mozilla/bad_cert_detected.html": [ + { + "path": "mozilla/bad_cert_detected.html", + "url": "/_mozilla/mozilla/bad_cert_detected.html" + } + ], "mozilla/blob.html": [ { "path": "mozilla/blob.html", @@ -9622,4 +9628,4 @@ "rev": null, "url_base": "/_mozilla/", "version": 2 -} \ No newline at end of file +} diff --git a/tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html b/tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html new file mode 100644 index 00000000000..22f6b6676e4 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/tests/wpt/mozilla/tests/mozilla/resources/origin_helpers.js b/tests/wpt/mozilla/tests/mozilla/resources/origin_helpers.js new file mode 100644 index 00000000000..35e6ebf6a05 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/resources/origin_helpers.js @@ -0,0 +1,5 @@ +var HTTP_PORT = '{{ports[http][0]}}'; +var HTTPS_PORT = '{{ports[https][0]}}'; +var ORIGINAL_HOST = '\'{{host}}\''; +var HTTP_ORIGIN = 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT; +var HTTPS_ORIGIN = 'https://' + ORIGINAL_HOST + ':' + HTTPS_PORT;