mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add ALPN and signature algorithms to OpenSSL config
This commit is contained in:
parent
69c7595a57
commit
b811be764c
7 changed files with 74 additions and 66 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -169,6 +169,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
|
||||
[[package]]
|
||||
name = "azure"
|
||||
version = "0.37.0"
|
||||
|
@ -2354,9 +2360,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.1.17"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a"
|
||||
checksum = "2790658cddc82e82b08e25176c431d7015a0adeb1718498715cbd20138a0bf68"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -2392,9 +2398,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.12.33"
|
||||
version = "0.12.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f"
|
||||
checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
|
@ -2422,9 +2428,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-openssl"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06a137dee5fc025f1afdd4f9d1eb6405689e4c687d07b687ba287adb7d55f791"
|
||||
checksum = "f52657b5cdb2a8067efd29a02e011b7cf656b473ec8a5c34e86645e85d763006"
|
||||
dependencies = [
|
||||
"antidote",
|
||||
"bytes",
|
||||
|
@ -3684,9 +3690,9 @@ checksum = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682"
|
|||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.11"
|
||||
version = "0.10.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c24d3508b4fb6da175c10baac54c578b33f09c89ae90c6fe9788b3b4768efdc"
|
||||
checksum = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
|
@ -3704,10 +3710,11 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.35"
|
||||
version = "0.9.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129"
|
||||
checksum = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
|
|
|
@ -13,6 +13,22 @@ use openssl::x509;
|
|||
use tokio::prelude::future::Executor;
|
||||
|
||||
pub const BUF_SIZE: usize = 32768;
|
||||
pub const ALPN_H2_H1: &'static [u8] = b"\x02h2\x08http/1.1";
|
||||
pub const ALPN_H1: &'static [u8] = b"\x08http/1.1";
|
||||
|
||||
// See https://wiki.mozilla.org/Security/Server_Side_TLS for orientation.
|
||||
const TLS1_2_CIPHERSUITES: &'static str = concat!(
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:",
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:",
|
||||
"ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA"
|
||||
);
|
||||
const SIGNATURE_ALGORITHMS: &'static str = concat!(
|
||||
"ed448:ed25519:",
|
||||
"ECDSA+SHA384:ECDSA+SHA256:",
|
||||
"RSA-PSS+SHA512:RSA-PSS+SHA384:RSA-PSS+SHA256:",
|
||||
"RSA+SHA512:RSA+SHA384:RSA+SHA256"
|
||||
);
|
||||
|
||||
pub struct HttpConnector {
|
||||
inner: HyperHttpConnector,
|
||||
|
@ -42,21 +58,21 @@ impl Connect for HttpConnector {
|
|||
}
|
||||
|
||||
pub type Connector = HttpsConnector<HttpConnector>;
|
||||
pub type TlsConfig = SslConnectorBuilder;
|
||||
|
||||
pub fn create_ssl_connector_builder(certs: &str) -> SslConnectorBuilder {
|
||||
pub fn create_tls_config(certs: &str, alpn: &[u8]) -> TlsConfig {
|
||||
// certs include multiple certificates. We could add all of them at once,
|
||||
// but if any of them were already added, openssl would fail to insert all
|
||||
// of them.
|
||||
let mut certs = certs;
|
||||
let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
let mut cfg = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
loop {
|
||||
let token = "-----END CERTIFICATE-----";
|
||||
if let Some(index) = certs.find(token) {
|
||||
let (cert, rest) = certs.split_at(index + token.len());
|
||||
certs = rest;
|
||||
let cert = x509::X509::from_pem(cert.as_bytes()).unwrap();
|
||||
ssl_connector_builder
|
||||
.cert_store_mut()
|
||||
cfg.cert_store_mut()
|
||||
.add_cert(cert)
|
||||
.or_else(|e| {
|
||||
let v: Option<Option<&str>> = e.errors().iter().nth(0).map(|e| e.reason());
|
||||
|
@ -74,39 +90,31 @@ pub fn create_ssl_connector_builder(certs: &str) -> SslConnectorBuilder {
|
|||
break;
|
||||
}
|
||||
}
|
||||
ssl_connector_builder
|
||||
.set_cipher_list(DEFAULT_CIPHERS)
|
||||
.expect("could not set ciphers");
|
||||
ssl_connector_builder.set_options(
|
||||
cfg.set_alpn_protos(alpn)
|
||||
.expect("could not set alpn protocols");
|
||||
cfg.set_cipher_list(TLS1_2_CIPHERSUITES)
|
||||
.expect("could not set TLS 1.2 ciphersuites");
|
||||
cfg.set_sigalgs_list(SIGNATURE_ALGORITHMS)
|
||||
.expect("could not set signature algorithms");
|
||||
cfg.set_options(
|
||||
SslOptions::NO_SSLV2 |
|
||||
SslOptions::NO_SSLV3 |
|
||||
SslOptions::NO_TLSV1 |
|
||||
SslOptions::NO_TLSV1_1 |
|
||||
SslOptions::NO_COMPRESSION,
|
||||
);
|
||||
ssl_connector_builder
|
||||
|
||||
cfg
|
||||
}
|
||||
|
||||
pub fn create_http_client<E>(
|
||||
ssl_connector_builder: SslConnectorBuilder,
|
||||
executor: E,
|
||||
) -> Client<Connector, Body>
|
||||
pub fn create_http_client<E>(tls_config: TlsConfig, executor: E) -> Client<Connector, Body>
|
||||
where
|
||||
E: Executor<Box<dyn Future<Error = (), Item = ()> + Send + 'static>> + Sync + Send + 'static,
|
||||
{
|
||||
let connector =
|
||||
HttpsConnector::with_connector(HttpConnector::new(), ssl_connector_builder).unwrap();
|
||||
let connector = HttpsConnector::with_connector(HttpConnector::new(), tls_config).unwrap();
|
||||
|
||||
Client::builder()
|
||||
.http1_title_case_headers(true)
|
||||
.executor(executor)
|
||||
.build(connector)
|
||||
}
|
||||
|
||||
// Prefer Forward Secrecy over plain RSA, AES-GCM over AES-CBC, ECDSA over RSA.
|
||||
// A complete discussion of the issues involved in TLS configuration can be found here:
|
||||
// https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
const DEFAULT_CIPHERS: &'static str = concat!(
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:",
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:",
|
||||
"ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA"
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::connector::{create_http_client, Connector};
|
||||
use crate::connector::{create_http_client, Connector, TlsConfig};
|
||||
use crate::cookie;
|
||||
use crate::cookie_storage::CookieStorage;
|
||||
use crate::decoder::Decoder;
|
||||
|
@ -46,7 +46,6 @@ use net_traits::{CookieSource, FetchMetadata, NetworkError, ReferrerPolicy};
|
|||
use net_traits::{
|
||||
RedirectEndValue, RedirectStartValue, ResourceAttribute, ResourceFetchTiming, ResourceTimeValue,
|
||||
};
|
||||
use openssl::ssl::SslConnectorBuilder;
|
||||
use servo_arc::Arc;
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
@ -90,7 +89,7 @@ pub struct HttpState {
|
|||
}
|
||||
|
||||
impl HttpState {
|
||||
pub fn new(ssl_connector_builder: SslConnectorBuilder) -> HttpState {
|
||||
pub fn new(tls_config: TlsConfig) -> HttpState {
|
||||
HttpState {
|
||||
hsts_list: RwLock::new(HstsList::new()),
|
||||
cookie_jar: RwLock::new(CookieStorage::new(150)),
|
||||
|
@ -98,7 +97,7 @@ impl HttpState {
|
|||
history_states: RwLock::new(HashMap::new()),
|
||||
http_cache: RwLock::new(HttpCache::new()),
|
||||
http_cache_state: Mutex::new(HashMap::new()),
|
||||
client: create_http_client(ssl_connector_builder, HANDLE.lock().unwrap().executor()),
|
||||
client: create_http_client(tls_config, HANDLE.lock().unwrap().executor()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//! A thread that takes a URL and streams back the binary data.
|
||||
|
||||
use crate::connector::{create_http_client, create_ssl_connector_builder};
|
||||
use crate::connector::{create_http_client, create_tls_config, ALPN_H2_H1};
|
||||
use crate::cookie;
|
||||
use crate::cookie_storage::CookieStorage;
|
||||
use crate::fetch::cors_cache::CorsCache;
|
||||
|
@ -149,7 +149,7 @@ fn create_http_states(
|
|||
http_cache: RwLock::new(http_cache),
|
||||
http_cache_state: Mutex::new(HashMap::new()),
|
||||
client: create_http_client(
|
||||
create_ssl_connector_builder(&certs),
|
||||
create_tls_config(&certs, ALPN_H2_H1),
|
||||
HANDLE.lock().unwrap().executor(),
|
||||
),
|
||||
};
|
||||
|
@ -162,7 +162,7 @@ fn create_http_states(
|
|||
http_cache: RwLock::new(HttpCache::new()),
|
||||
http_cache_state: Mutex::new(HashMap::new()),
|
||||
client: create_http_client(
|
||||
create_ssl_connector_builder(&certs),
|
||||
create_tls_config(&certs, ALPN_H2_H1),
|
||||
HANDLE.lock().unwrap().executor(),
|
||||
),
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ use hyper::body::Body;
|
|||
use hyper::{Request as HyperRequest, Response as HyperResponse};
|
||||
use mime::{self, Mime};
|
||||
use msg::constellation_msg::TEST_PIPELINE_ID;
|
||||
use net::connector::create_ssl_connector_builder;
|
||||
use net::connector::{create_tls_config, ALPN_H2_H1};
|
||||
use net::fetch::cors_cache::CorsCache;
|
||||
use net::fetch::methods::{self, CancellationListener, FetchContext};
|
||||
use net::filemanager_thread::FileManager;
|
||||
|
@ -38,8 +38,7 @@ use net_traits::{
|
|||
};
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::fs;
|
||||
use std::iter::FromIterator;
|
||||
use std::path::Path;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
@ -218,13 +217,11 @@ fn test_fetch_file() {
|
|||
assert_eq!(content_type, mime::TEXT_CSS);
|
||||
|
||||
let resp_body = fetch_response.body.lock().unwrap();
|
||||
let mut file = File::open(path).unwrap();
|
||||
let mut bytes = vec![];
|
||||
let _ = file.read_to_end(&mut bytes);
|
||||
let file = fs::read(path).unwrap();
|
||||
|
||||
match *resp_body {
|
||||
ResponseBody::Done(ref val) => {
|
||||
assert_eq!(val, &bytes);
|
||||
assert_eq!(val, &file);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
|
@ -653,15 +650,11 @@ fn test_fetch_with_hsts() {
|
|||
.unwrap();
|
||||
let (server, url) = make_ssl_server(handler, cert_path.clone(), key_path.clone());
|
||||
|
||||
let mut ca_content = String::new();
|
||||
File::open(cert_path)
|
||||
.unwrap()
|
||||
.read_to_string(&mut ca_content)
|
||||
.unwrap();
|
||||
let ssl_client = create_ssl_connector_builder(&ca_content);
|
||||
let certs = fs::read_to_string(cert_path).expect("Couldn't find certificate file");
|
||||
let tls_config = create_tls_config(&certs, ALPN_H2_H1);
|
||||
|
||||
let mut context = FetchContext {
|
||||
state: Arc::new(HttpState::new(ssl_client)),
|
||||
state: Arc::new(HttpState::new(tls_config)),
|
||||
user_agent: DEFAULT_USER_AGENT.into(),
|
||||
devtools_chan: None,
|
||||
filemanager: FileManager::new(create_embedder_proxy()),
|
||||
|
|
|
@ -29,7 +29,7 @@ use hyper::server::conn::Http;
|
|||
use hyper::server::Server as HyperServer;
|
||||
use hyper::service::service_fn_ok;
|
||||
use hyper::{Body, Request as HyperRequest, Response as HyperResponse};
|
||||
use net::connector::create_ssl_connector_builder;
|
||||
use net::connector::{create_tls_config, ALPN_H2_H1};
|
||||
use net::fetch::cors_cache::CorsCache;
|
||||
use net::fetch::methods::{self, CancellationListener, FetchContext};
|
||||
use net::filemanager_thread::FileManager;
|
||||
|
@ -87,11 +87,11 @@ fn new_fetch_context(
|
|||
dc: Option<Sender<DevtoolsControlMsg>>,
|
||||
fc: Option<EmbedderProxy>,
|
||||
) -> FetchContext {
|
||||
let ssl_connector =
|
||||
create_ssl_connector_builder(&resources::read_string(Resource::SSLCertificates));
|
||||
let certs = resources::read_string(Resource::SSLCertificates);
|
||||
let tls_config = create_tls_config(&certs, ALPN_H2_H1);
|
||||
let sender = fc.unwrap_or_else(|| create_embedder_proxy());
|
||||
FetchContext {
|
||||
state: Arc::new(HttpState::new(ssl_connector)),
|
||||
state: Arc::new(HttpState::new(tls_config)),
|
||||
user_agent: DEFAULT_USER_AGENT.into(),
|
||||
devtools_chan: dc,
|
||||
filemanager: FileManager::new(sender),
|
||||
|
@ -187,16 +187,16 @@ where
|
|||
let url = ServoUrl::parse(&url_string).unwrap();
|
||||
|
||||
let server = listener.incoming().map_err(|_| ()).for_each(move |sock| {
|
||||
let mut ssl_builder = SslAcceptor::mozilla_modern(SslMethod::tls()).unwrap();
|
||||
ssl_builder
|
||||
let mut tls_server_config = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).unwrap();
|
||||
tls_server_config
|
||||
.set_certificate_file(&cert_path, SslFiletype::PEM)
|
||||
.unwrap();
|
||||
ssl_builder
|
||||
tls_server_config
|
||||
.set_private_key_file(&key_path, SslFiletype::PEM)
|
||||
.unwrap();
|
||||
|
||||
let handler = handler.clone();
|
||||
ssl_builder
|
||||
tls_server_config
|
||||
.build()
|
||||
.accept_async(sock)
|
||||
.map_err(|_| ())
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::connector::create_ssl_connector_builder;
|
||||
use crate::connector::{create_tls_config, ALPN_H1};
|
||||
use crate::cookie::Cookie;
|
||||
use crate::fetch::methods::should_be_blocked_due_to_bad_port;
|
||||
use crate::hosts::replace_host;
|
||||
|
@ -167,8 +167,9 @@ impl<'a> Handler for Client<'a> {
|
|||
WebSocketErrorKind::Protocol,
|
||||
format!("Unable to parse domain from {}. Needed for SSL.", url),
|
||||
))?;
|
||||
let connector = create_ssl_connector_builder(&certs).build();
|
||||
connector
|
||||
let tls_config = create_tls_config(&certs, ALPN_H1);
|
||||
tls_config
|
||||
.build()
|
||||
.connect(domain, stream)
|
||||
.map_err(WebSocketError::from)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue