aboutsummaryrefslogtreecommitdiffstats
path: root/components/net/connector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/net/connector.rs')
-rw-r--r--components/net/connector.rs49
1 files changed, 46 insertions, 3 deletions
diff --git a/components/net/connector.rs b/components/net/connector.rs
index 058a27c47d6..4369e236501 100644
--- a/components/net/connector.rs
+++ b/components/net/connector.rs
@@ -8,8 +8,12 @@ use hyper::client::HttpConnector as HyperHttpConnector;
use hyper::rt::Future;
use hyper::{Body, Client};
use hyper_openssl::HttpsConnector;
-use openssl::ssl::{SslConnector, SslConnectorBuilder, SslMethod, SslOptions};
-use openssl::x509;
+use openssl::ex_data::Index;
+use openssl::ssl::{
+ SslConnector, SslConnectorBuilder, SslContext, SslMethod, SslOptions, SslVerifyMode,
+};
+use openssl::x509::{self, X509StoreContext};
+use std::sync::{Arc, Mutex};
use tokio::prelude::future::Executor;
pub const BUF_SIZE: usize = 32768;
@@ -60,7 +64,20 @@ impl Connect for HttpConnector {
pub type Connector = HttpsConnector<HttpConnector>;
pub type TlsConfig = SslConnectorBuilder;
-pub fn create_tls_config(certs: &str, alpn: &[u8]) -> TlsConfig {
+#[derive(Clone)]
+pub(crate) struct ExtraCerts(pub Arc<Mutex<Vec<Vec<u8>>>>);
+
+impl ExtraCerts {
+ pub(crate) fn new() -> Self {
+ Self(Arc::new(Mutex::new(vec![])))
+ }
+}
+
+lazy_static! {
+ static ref INDEX: Index<SslContext, ExtraCerts> = SslContext::new_ex_index().unwrap();
+}
+
+pub(crate) fn create_tls_config(certs: &str, alpn: &[u8], extra_certs: ExtraCerts) -> 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.
@@ -104,6 +121,32 @@ pub fn create_tls_config(certs: &str, alpn: &[u8]) -> TlsConfig {
SslOptions::NO_COMPRESSION,
);
+ cfg.set_ex_data(*INDEX, extra_certs);
+ cfg.set_verify_callback(SslVerifyMode::PEER, |verified, x509_store_context| {
+ if verified {
+ return true;
+ }
+ if let Some(cert) = x509_store_context.current_cert() {
+ match cert.to_pem() {
+ Ok(pem) => {
+ let ssl_idx = X509StoreContext::ssl_idx().unwrap();
+ let ssl = x509_store_context.ex_data(ssl_idx).unwrap();
+ let ssl_context = ssl.ssl_context();
+ let extra_certs = ssl_context.ex_data(*INDEX).unwrap();
+ for cert in &*extra_certs.0.lock().unwrap() {
+ if pem == *cert {
+ return true;
+ }
+ }
+ false
+ },
+ Err(_) => false,
+ }
+ } else {
+ false
+ }
+ });
+
cfg
}