Update to rustls 0.22

This commit is contained in:
Matt Brubeck 2023-12-18 07:56:52 -08:00
parent b1c7564046
commit 8809f9378c
5 changed files with 52 additions and 75 deletions

45
Cargo.lock generated
View file

@ -35,7 +35,7 @@ dependencies = [
"rcgen", "rcgen",
"rustls 0.22.1", "rustls 0.22.1",
"tokio", "tokio",
"tokio-rustls 0.24.1", "tokio-rustls 0.25.0",
"url", "url",
] ]
@ -492,22 +492,10 @@ dependencies = [
"base64 0.13.1", "base64 0.13.1",
"log", "log",
"ring 0.16.20", "ring 0.16.20",
"sct 0.6.1", "sct",
"webpki", "webpki",
] ]
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring 0.17.7",
"rustls-webpki 0.101.7",
"sct 0.7.0",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.22.1" version = "0.22.1"
@ -517,7 +505,7 @@ dependencies = [
"log", "log",
"ring 0.17.7", "ring 0.17.7",
"rustls-pki-types", "rustls-pki-types",
"rustls-webpki 0.102.0", "rustls-webpki",
"subtle", "subtle",
"zeroize", "zeroize",
] ]
@ -528,16 +516,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7673e0aa20ee4937c6aacfc12bb8341cfbf054cdd21df6bec5fd0629fe9339b" checksum = "e7673e0aa20ee4937c6aacfc12bb8341cfbf054cdd21df6bec5fd0629fe9339b"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring 0.17.7",
"untrusted 0.9.0",
]
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.102.0" version = "0.102.0"
@ -559,16 +537,6 @@ dependencies = [
"untrusted 0.7.1", "untrusted 0.7.1",
] ]
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring 0.16.20",
"untrusted 0.7.1",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.192" version = "1.0.192"
@ -740,11 +708,12 @@ dependencies = [
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.24.1" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [ dependencies = [
"rustls 0.21.10", "rustls 0.22.1",
"rustls-pki-types",
"tokio", "tokio",
] ]

View file

@ -23,7 +23,7 @@ once_cell = "1.19"
percent-encoding = "2.3" percent-encoding = "2.3"
rcgen = { version = "0.12.0" } rcgen = { version = "0.12.0" }
rustls = "0.22.1" rustls = "0.22.1"
tokio-rustls = "0.24.1" tokio-rustls = "0.25.0"
tokio = { version = "1.35", features = ["fs", "io-util", "net", "rt-multi-thread", "sync"] } tokio = { version = "1.35", features = ["fs", "io-util", "net", "rt-multi-thread", "sync"] }
url = "2.5.0" url = "2.5.0"

View file

@ -1,7 +1,9 @@
use { use {
rustls::{ rustls::{
crypto::ring::sign::any_supported_type,
pki_types::{self, CertificateDer, PrivateKeyDer},
server::{ClientHello, ResolvesServerCert}, server::{ClientHello, ResolvesServerCert},
sign::{any_supported_type, CertifiedKey, SignError}, sign::{CertifiedKey, SigningKey},
}, },
std::{ std::{
ffi::OsStr, ffi::OsStr,
@ -13,6 +15,7 @@ use {
/// A struct that holds all loaded certificates and the respective domain /// A struct that holds all loaded certificates and the respective domain
/// names. /// names.
#[derive(Debug)]
pub(crate) struct CertStore { pub(crate) struct CertStore {
/// Stores the certificates and the domains they apply to, sorted by domain /// Stores the certificates and the domains they apply to, sorted by domain
/// names, longest matches first /// names, longest matches first
@ -30,7 +33,7 @@ pub enum CertLoadError {
Empty, Empty,
/// the key file for the specified domain is bad (e.g. does not contain a /// the key file for the specified domain is bad (e.g. does not contain a
/// key or is invalid) /// key or is invalid)
BadKey(String, SignError), BadKey(String, rustls::Error),
/// the key file for the specified domain is missing (but a certificate /// the key file for the specified domain is missing (but a certificate
/// file was present) /// file was present)
MissingKey(String), MissingKey(String),
@ -74,27 +77,44 @@ fn load_domain(certs_dir: &Path, domain: String) -> Result<CertifiedKey, CertLoa
CertLoadError::MissingCert(domain) CertLoadError::MissingCert(domain)
}); });
} }
let cert = rustls::Certificate( let cert = CertificateDer::from(
std::fs::read(&path).map_err(|_| CertLoadError::MissingCert(domain.clone()))?, std::fs::read(&path).map_err(|_| CertLoadError::MissingCert(domain.clone()))?,
); );
// load key from file // load key from file
path.set_file_name(KEY_FILE_NAME); path.set_file_name(KEY_FILE_NAME);
if !path.is_file() { let Ok(der) = std::fs::read(&path) else {
return Err(CertLoadError::MissingKey(domain)); return Err(CertLoadError::MissingKey(domain));
} };
let key = rustls::PrivateKey(
std::fs::read(&path).map_err(|_| CertLoadError::MissingKey(domain.clone()))?,
);
// transform key to correct format // transform key to correct format
let key = match any_supported_type(&key) { let key = der_to_private_key(&der).map_err(|e| CertLoadError::BadKey(domain.clone(), e))?;
Ok(key) => key,
Err(e) => return Err(CertLoadError::BadKey(domain, e)),
};
Ok(CertifiedKey::new(vec![cert], key)) Ok(CertifiedKey::new(vec![cert], key))
} }
/// We don't know the key type of the private key DER file, so try each
/// possible type until we find one that works.
///
/// We should probably stop doing this and use a PEM file instead:
/// https://github.com/rustls/rustls/issues/1661
fn der_to_private_key(der: &[u8]) -> Result<Arc<dyn SigningKey>, rustls::Error> {
let keys = [
PrivateKeyDer::Pkcs1(pki_types::PrivatePkcs1KeyDer::from(der)),
PrivateKeyDer::Sec1(pki_types::PrivateSec1KeyDer::from(der)),
PrivateKeyDer::Pkcs8(pki_types::PrivatePkcs8KeyDer::from(der)),
];
let mut err = None;
for key in keys {
match any_supported_type(&key) {
Ok(key) => return Ok(key),
Err(e) => err = Some(e),
}
}
Err(err.unwrap())
}
impl CertStore { impl CertStore {
/// Load certificates from a certificate directory. /// Load certificates from a certificate directory.
/// Certificates should be stored in a folder for each hostname, for example /// Certificates should be stored in a folder for each hostname, for example

View file

@ -408,13 +408,9 @@ static TLS: Lazy<TlsAcceptor> = Lazy::new(acceptor);
fn acceptor() -> TlsAcceptor { fn acceptor() -> TlsAcceptor {
let config = if ARGS.only_tls13 { let config = if ARGS.only_tls13 {
ServerConfig::builder() ServerConfig::builder_with_protocol_versions(&[&rustls::version::TLS13])
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.expect("could not build server config")
} else { } else {
ServerConfig::builder().with_safe_defaults() ServerConfig::builder()
} }
.with_no_client_auth() .with_no_client_auth()
.with_cert_resolver(ARGS.certs.clone()); .with_cert_resolver(ARGS.certs.clone());

View file

@ -166,7 +166,7 @@ fn index_page() {
#[cfg(unix)] #[cfg(unix)]
#[test] #[test]
fn index_page_unix() { fn index_page_unix() {
use rustls::{Certificate, ClientConnection, RootCertStore}; use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
let sock_path = std::env::temp_dir().join("agate-test-unix-socket"); let sock_path = std::env::temp_dir().join("agate-test-unix-socket");
@ -184,7 +184,7 @@ fn index_page_unix() {
// set up TLS connection via unix socket // set up TLS connection via unix socket
let mut certs = RootCertStore::empty(); let mut certs = RootCertStore::empty();
certs certs
.add(&Certificate( .add(CertificateDer::from(
include_bytes!(concat!( include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"), env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der" "/tests/data/multicert/example.com/cert.der"
@ -193,7 +193,6 @@ fn index_page_unix() {
)) ))
.unwrap(); .unwrap();
let config = rustls::ClientConfig::builder() let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(certs) .with_root_certificates(certs)
.with_no_client_auth(); .with_no_client_auth();
let mut session = ClientConnection::new( let mut session = ClientConnection::new(
@ -363,7 +362,7 @@ fn username() {
#[test] #[test]
/// - URLS with invalid hostnames are rejected /// - URLS with invalid hostnames are rejected
fn percent_encode() { fn percent_encode() {
use rustls::{Certificate, ClientConnection, RootCertStore}; use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write; use std::io::Write;
use std::net::TcpStream; use std::net::TcpStream;
@ -373,7 +372,7 @@ fn percent_encode() {
let mut certs = RootCertStore::empty(); let mut certs = RootCertStore::empty();
certs certs
.add(&Certificate( .add(CertificateDer::from(
include_bytes!(concat!( include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"), env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der" "/tests/data/multicert/example.com/cert.der"
@ -382,7 +381,6 @@ fn percent_encode() {
)) ))
.unwrap(); .unwrap();
let config = rustls::ClientConfig::builder() let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(certs) .with_root_certificates(certs)
.with_no_client_auth(); .with_no_client_auth();
@ -533,12 +531,8 @@ fn explicit_tls_version() {
let server = Server::new(&["-3"]); let server = Server::new(&["-3"]);
let config = rustls::ClientConfig::builder() // try to connect using only TLS 1.2
.with_safe_default_cipher_suites() let config = rustls::ClientConfig::builder_with_protocol_versions(&[&rustls::version::TLS12])
.with_safe_default_kx_groups()
// try to connect using only TLS 1.2
.with_protocol_versions(&[&rustls::version::TLS12])
.unwrap()
.with_root_certificates(RootCertStore::empty()) .with_root_certificates(RootCertStore::empty())
.with_no_client_auth(); .with_no_client_auth();
@ -636,7 +630,7 @@ mod multicert {
#[test] #[test]
fn example_com() { fn example_com() {
use rustls::{Certificate, ClientConnection, RootCertStore}; use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write; use std::io::Write;
use std::net::TcpStream; use std::net::TcpStream;
@ -644,7 +638,7 @@ mod multicert {
let mut certs = RootCertStore::empty(); let mut certs = RootCertStore::empty();
certs certs
.add(&Certificate( .add(CertificateDer::from(
include_bytes!(concat!( include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"), env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der" "/tests/data/multicert/example.com/cert.der"
@ -653,7 +647,6 @@ mod multicert {
)) ))
.unwrap(); .unwrap();
let config = rustls::ClientConfig::builder() let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(certs) .with_root_certificates(certs)
.with_no_client_auth(); .with_no_client_auth();
@ -675,7 +668,7 @@ mod multicert {
#[test] #[test]
fn example_org() { fn example_org() {
use rustls::{Certificate, ClientConnection, RootCertStore}; use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write; use std::io::Write;
use std::net::TcpStream; use std::net::TcpStream;
@ -683,7 +676,7 @@ mod multicert {
let mut certs = RootCertStore::empty(); let mut certs = RootCertStore::empty();
certs certs
.add(&Certificate( .add(CertificateDer::from(
include_bytes!(concat!( include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"), env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.org/cert.der" "/tests/data/multicert/example.org/cert.der"
@ -692,7 +685,6 @@ mod multicert {
)) ))
.unwrap(); .unwrap();
let config = rustls::ClientConfig::builder() let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(certs) .with_root_certificates(certs)
.with_no_client_auth(); .with_no_client_auth();