Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ALPN and signature algorithms to OpenSSL config #24976

Merged
merged 1 commit into from Dec 10, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add ALPN and signature algorithms to OpenSSL config

  • Loading branch information
Darkspirit committed Nov 30, 2019
commit b811be764c0f342ba890975009b4b0c65aa3ebe4

Some generated files are not rendered by default. Learn more.

@@ -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,15 +89,15 @@ 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)),
auth_cache: RwLock::new(AuthCache::new()),
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)
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.