hyperium / hyper-tls

Apache License 2.0
189 stars 95 forks source link

Hyper, TLS, custom server / client certificates #63

Closed grahamc closed 4 years ago

grahamc commented 4 years ago

It took me a pretty long time to follow all the type signatures around and construct a valid client. I first tried searching the issue tracker for people having trouble, but didn't seem to find one. Anyway, here is what I came up with for the next person:

use hyper::Client;
use native_tls::Certificate;
use std::path::Path;

fn load_ca_cert(pem_file: &Path) -> Result<Certificate, CertLoadError> {
    use std::fs;

    let bytes =
        fs::read(pem_file).map_err(|e| CertLoadError::Io(format!("Loading {:?}", pem_file), e))?;

    Certificate::from_pem(&bytes).map_err(CertLoadError::TlsError)
}

#[derive(Debug)]
enum CertLoadError {
    TlsError(native_tls::Error),
    Io(String, std::io::Error),
}

fn main() {
    let certificate: native_tls::Certificate =
        load_ca_cert(&Path::new("/path/to/cert.pem")).expect("Failed to load your CA cert");

    let native_tls_connector = native_tls::TlsConnector::builder()
        .add_root_certificate(certificate)
        .build()
        .expect("Building native_tls::TlsConnector");

    let tokio_tls_tls_connector = tokio_tls::TlsConnector::from(native_tls_connector);

    let mut hyper_http_connector = hyper::client::HttpConnector::new();
    hyper_http_connector.enforce_http(false);

    let hyper_tls_https_connector = hyper_tls::HttpsConnector::from((
        hyper_http_connector,
        tokio_tls_tls_connector,
    ));

    let client_main = Client::builder().build::<_, hyper::Body>(hyper_tls_https_connector);

    drop(client_main);
}
japasc commented 3 years ago

Just for the record:

tokio_tls => tokio_native_tls

for this to work today