mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #6935 - jdm:sslverify, r=Manishearth
Make SSL cert verification errors work again. Add a horrible, no-good… …, very bad regression test. Here are the list of awful things this test exploits: - Servo can't load HTTPS content in WPT tests (#6919) - Our web workers don't report error events to the parent worker object after the initial network load completes - Our worker resource load don't have a same-origin check The good news is that this test should start failing if any of those "features" change, so this should not silently break on us. Other attempts to test this included: - iframes (didn't work because of #6672 and #3939) - XMLHttpRequest (I was hit by CORS, I think; maybe I could have made it work if I returned the right headers) r? @Ms2ger <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6935) <!-- Reviewable:end -->
This commit is contained in:
commit
0735cec351
4 changed files with 63 additions and 20 deletions
|
@ -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<WrappedHttpRequest, LoadError> {
|
||||
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::<SslError>() {
|
||||
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<R: Read>(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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
28
tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html
Normal file
28
tests/wpt/mozilla/tests/mozilla/bad_cert_detected.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/origin_helpers.js?pipe=sub"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Invalid SSL cert noticed");
|
||||
t.step(function() {
|
||||
var target = location.href.replace(HTTP_ORIGIN, HTTPS_ORIGIN)
|
||||
.replace('bad_cert_detected.html',
|
||||
'resources/origin_helpers.js');
|
||||
// Servo currently lacks the ability to introspect any content that is blocked
|
||||
// due to a cert error, so we use a roundabout method to infer that that's happened.
|
||||
// When the worker has a cert failure, that translates into attempting to evaluate the
|
||||
// contents of badcert.html as JS, which triggers an exception that currently does not
|
||||
// propagate to the parent scope. If we _do_ get an error event in the parent scope,
|
||||
// that means that the cert verification was treated no different than any other
|
||||
// network error, since we dispatch an error event in that case.
|
||||
var w = new Worker(target);
|
||||
w.addEventListener('error', t.unreached_func("cert not detected as invalid"), false);
|
||||
// We infer that we detected an invalid cert if nothing happens for a few seconds.
|
||||
setTimeout(function() { t.done() }, 3000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -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;
|
Loading…
Add table
Add a link
Reference in a new issue