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

Simplify rustls usage #1046

Merged
merged 5 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ rand = "0.9"
redis = { version = "0.27" }
reqwest = { version = "0.12", features = ["json", "stream"] }
rustls = "0.23"
rustls-pemfile = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
time = "0.3"
Expand Down
1 change: 0 additions & 1 deletion https-tls/acme-letsencrypt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ env_logger.workspace = true
eyre.workspace = true
log.workspace = true
rustls.workspace = true
rustls-pemfile.workspace = true
tokio = { workspace = true, features = ["fs"] }
9 changes: 4 additions & 5 deletions https-tls/acme-letsencrypt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use acme::{Certificate, Directory, DirectoryUrl, create_p256_key};
use actix_files::Files;
use actix_web::{App, HttpRequest, HttpServer, Responder, rt, web};
use eyre::eyre;
use rustls::pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer};
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, pem::PemObject};
use tokio::fs;

const CHALLENGE_DIR: &str = "./acme-challenges";
Expand Down Expand Up @@ -188,10 +188,9 @@ fn load_rustls_config(cert: Certificate) -> eyre::Result<rustls::ServerConfig> {
let private_key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(cert.private_key_der()?));

// convert ACME-obtained certificate chain
let cert_chain =
rustls_pemfile::certs(&mut std::io::BufReader::new(cert.certificate().as_bytes()))
.collect::<Result<Vec<_>, _>>()
.unwrap();
let cert_chain = CertificateDer::pem_slice_iter(cert.certificate().as_bytes())
.flatten()
.collect();

Ok(config.with_single_cert(cert_chain, private_key)?)
}
1 change: 0 additions & 1 deletion https-tls/cert-watch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ eyre.workspace = true
log.workspace = true
notify = "6"
rustls.workspace = true
rustls-pemfile.workspace = true
tokio = { workspace = true, features = ["time", "rt", "macros"] }
44 changes: 19 additions & 25 deletions https-tls/cert-watch/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::{fs::File, io::BufReader, path::Path};
use std::path::Path;

use actix_web::{
App, HttpRequest, HttpResponse, HttpServer, http::header::ContentType, middleware, web,
};
use log::debug;
use notify::{Event, RecursiveMode, Watcher as _};
use rustls::{ServerConfig, pki_types::PrivateKeyDer};
use rustls_pemfile::{certs, pkcs8_private_keys};
use rustls::{
ServerConfig,
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};
use tokio::sync::mpsc;

#[derive(Debug)]
Expand All @@ -27,6 +29,11 @@ async fn main() -> eyre::Result<()> {
color_eyre::install()?;
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));

// Load default provider, to be done once for the process
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.unwrap();

// signal channel used to notify main event loop of cert/key file changes
let (reload_tx, mut reload_rx) = mpsc::channel(1);

Expand Down Expand Up @@ -100,29 +107,16 @@ async fn main() -> eyre::Result<()> {
}

fn load_rustls_config() -> eyre::Result<rustls::ServerConfig> {
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.unwrap();

// init server config builder with safe defaults
let config = ServerConfig::builder().with_no_client_auth();

// load TLS key/cert files
let cert_file = &mut BufReader::new(File::open("cert.pem")?);
let key_file = &mut BufReader::new(File::open("key.pem")?);

// convert files to key/cert objects
let cert_chain = certs(cert_file).collect::<Result<Vec<_>, _>>().unwrap();
let mut keys = pkcs8_private_keys(key_file)
.map(|key| key.map(PrivateKeyDer::Pkcs8))
.collect::<Result<Vec<_>, _>>()
.unwrap();
let cert_chain = CertificateDer::pem_file_iter("cert.pem")
.unwrap()
.flatten()
.collect();

// exit if no keys could be parsed
if keys.is_empty() {
eprintln!("Could not locate PKCS 8 private keys.");
std::process::exit(1);
}
let key_der =
PrivateKeyDer::from_pem_file("key.pem").expect("Could not locate PKCS 8 private keys.");

Ok(config.with_single_cert(cert_chain, keys.remove(0))?)
Ok(ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, key_der)?)
}
1 change: 0 additions & 1 deletion https-tls/rustls-client-cert/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ actix-web = { workspace = true, features = ["rustls-0_23"] }
env_logger.workspace = true
log.workspace = true
rustls.workspace = true
rustls-pemfile.workspace = true
33 changes: 15 additions & 18 deletions https-tls/rustls-client-cert/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This example shows how to use `actix_web::HttpServer::on_connect` to access client certificates
//! pass them to a handler through connection-local data.

use std::{any::Any, fs::File, io::BufReader, net::SocketAddr, sync::Arc};
use std::{any::Any, net::SocketAddr, sync::Arc};

use actix_tls::accept::rustls_0_23::TlsStream;
use actix_web::{
Expand All @@ -10,10 +10,9 @@ use actix_web::{
use log::info;
use rustls::{
RootCertStore, ServerConfig,
pki_types::{CertificateDer, PrivateKeyDer},
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
server::WebPkiClientVerifier,
};
use rustls_pemfile::{certs, pkcs8_private_keys};

const CA_CERT: &str = "certs/rootCA.pem";
const SERVER_CERT: &str = "certs/server-cert.pem";
Expand Down Expand Up @@ -80,29 +79,27 @@ async fn main() -> std::io::Result<()> {
let mut cert_store = RootCertStore::empty();

// import CA cert
let ca_cert = &mut BufReader::new(File::open(CA_CERT)?);
let ca_cert = certs(ca_cert).collect::<Result<Vec<_>, _>>().unwrap();

for cert in ca_cert {
cert_store.add(cert).expect("root CA not added to store");
}
CertificateDer::pem_file_iter(CA_CERT)
.unwrap()
.flatten()
.for_each(|der| cert_store.add(der).unwrap());

// set up client authentication requirements
let client_auth = WebPkiClientVerifier::builder(Arc::new(cert_store))
.build()
.unwrap();
let config = ServerConfig::builder().with_client_cert_verifier(client_auth);

// import server cert and key
let cert_file = &mut BufReader::new(File::open(SERVER_CERT)?);
let key_file = &mut BufReader::new(File::open(SERVER_KEY)?);

let cert_chain = certs(cert_file).collect::<Result<Vec<_>, _>>().unwrap();
let mut keys = pkcs8_private_keys(key_file)
.map(|key| key.map(PrivateKeyDer::Pkcs8))
.collect::<Result<Vec<_>, _>>()
let key_der = PrivateKeyDer::from_pem_file(SERVER_KEY).unwrap();
let cert_chain = CertificateDer::pem_file_iter(SERVER_CERT)
.unwrap()
.flatten()
.collect();

let config = ServerConfig::builder()
.with_client_cert_verifier(client_auth)
.with_single_cert(cert_chain, key_der)
.unwrap();
let config = config.with_single_cert(cert_chain, keys.remove(0)).unwrap();

log::info!("starting HTTP server at http://localhost:8080 and https://localhost:8443");

Expand Down
1 change: 0 additions & 1 deletion https-tls/rustls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ actix-files.workspace = true
env_logger.workspace = true
log.workspace = true
rustls.workspace = true
rustls-pemfile.workspace = true
40 changes: 16 additions & 24 deletions https-tls/rustls/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{fs::File, io::BufReader};

use actix_files::Files;
use actix_web::{
App, HttpRequest, HttpResponse, HttpServer, http::header::ContentType, middleware, web,
};
use log::debug;
use rustls::{ServerConfig, pki_types::PrivateKeyDer};
use rustls_pemfile::{certs, pkcs8_private_keys};
use rustls::{
ServerConfig,
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};

/// simple handle
async fn index(req: HttpRequest) -> HttpResponse {
Expand Down Expand Up @@ -46,25 +46,17 @@ fn load_rustls_config() -> rustls::ServerConfig {
.install_default()
.unwrap();

// init server config builder with safe defaults
let config = ServerConfig::builder().with_no_client_auth();

// load TLS key/cert files
let cert_file = &mut BufReader::new(File::open("cert.pem").unwrap());
let key_file = &mut BufReader::new(File::open("key.pem").unwrap());

// convert files to key/cert objects
let cert_chain = certs(cert_file).collect::<Result<Vec<_>, _>>().unwrap();
let mut keys = pkcs8_private_keys(key_file)
.map(|key| key.map(PrivateKeyDer::Pkcs8))
.collect::<Result<Vec<_>, _>>()
.unwrap();

// exit if no keys could be parsed
if keys.is_empty() {
eprintln!("Could not locate PKCS 8 private keys.");
std::process::exit(1);
}

config.with_single_cert(cert_chain, keys.remove(0)).unwrap()
let cert_chain = CertificateDer::pem_file_iter("cert.pem")
.unwrap()
.flatten()
.collect();

let key_der =
PrivateKeyDer::from_pem_file("key.pem").expect("Could not locate PKCS 8 private keys.");

ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, key_der)
.unwrap()
}
1 change: 0 additions & 1 deletion middleware/http-to-https/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ env_logger.workspace = true
futures-util.workspace = true
log.workspace = true
rustls.workspace = true
rustls-pemfile.workspace = true
23 changes: 11 additions & 12 deletions middleware/http-to-https/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{fs::File, io::BufReader};

use actix_web::{App, HttpResponse, HttpServer, dev::Service, get, http};
use futures_util::future::{self, Either, FutureExt};
use rustls::{ServerConfig, pki_types::PrivateKeyDer};
use rustls_pemfile::{certs, pkcs8_private_keys};
use rustls::{
ServerConfig,
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};

#[get("/")]
async fn index() -> String {
Expand All @@ -18,18 +18,17 @@ async fn main() -> std::io::Result<()> {
.install_default()
.unwrap();

let cert_file = &mut BufReader::new(File::open("cert.pem").unwrap());
let key_file = &mut BufReader::new(File::open("key.pem").unwrap());
let cert_chain = CertificateDer::pem_file_iter("cert.pem")
.unwrap()
.flatten()
.collect();

let cert_chain = certs(cert_file).collect::<Result<Vec<_>, _>>().unwrap();
let mut keys = pkcs8_private_keys(key_file)
.map(|key| key.map(PrivateKeyDer::Pkcs8))
.collect::<Result<Vec<_>, _>>()
.unwrap();
let key_der =
PrivateKeyDer::from_pem_file("key.pem").expect("Could not locate PKCS 8 private keys.");

let config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, keys.remove(0))
.with_single_cert(cert_chain, key_der)
.unwrap();

log::info!(
Expand Down
Loading