commit 8809f9378cec51a36ec1eaf14727efc62eefbe88
parent b1c7564046d76cb1d8597eb0a044401467183ceb
Author: Matt Brubeck <mbrubeck@limpet.net>
Date: Mon, 18 Dec 2023 07:56:52 -0800
Update to rustls 0.22
Diffstat:
5 files changed, 52 insertions(+), 75 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -35,7 +35,7 @@ dependencies = [
"rcgen",
"rustls 0.22.1",
"tokio",
- "tokio-rustls 0.24.1",
+ "tokio-rustls 0.25.0",
"url",
]
@@ -492,24 +492,12 @@ dependencies = [
"base64 0.13.1",
"log",
"ring 0.16.20",
- "sct 0.6.1",
+ "sct",
"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]]
-name = "rustls"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe6b63262c9fcac8659abfaa96cac103d28166d3ff3eaf8f412e19f3ae9e5a48"
@@ -517,7 +505,7 @@ dependencies = [
"log",
"ring 0.17.7",
"rustls-pki-types",
- "rustls-webpki 0.102.0",
+ "rustls-webpki",
"subtle",
"zeroize",
]
@@ -530,16 +518,6 @@ 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]]
-name = "rustls-webpki"
version = "0.102.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89"
@@ -560,16 +538,6 @@ dependencies = [
]
[[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]]
name = "serde"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -740,11 +708,12 @@ dependencies = [
[[package]]
name = "tokio-rustls"
-version = "0.24.1"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
- "rustls 0.21.10",
+ "rustls 0.22.1",
+ "rustls-pki-types",
"tokio",
]
diff --git a/Cargo.toml b/Cargo.toml
@@ -23,7 +23,7 @@ once_cell = "1.19"
percent-encoding = "2.3"
rcgen = { version = "0.12.0" }
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"] }
url = "2.5.0"
diff --git a/src/certificates.rs b/src/certificates.rs
@@ -1,7 +1,9 @@
use {
rustls::{
+ crypto::ring::sign::any_supported_type,
+ pki_types::{self, CertificateDer, PrivateKeyDer},
server::{ClientHello, ResolvesServerCert},
- sign::{any_supported_type, CertifiedKey, SignError},
+ sign::{CertifiedKey, SigningKey},
},
std::{
ffi::OsStr,
@@ -13,6 +15,7 @@ use {
/// A struct that holds all loaded certificates and the respective domain
/// names.
+#[derive(Debug)]
pub(crate) struct CertStore {
/// Stores the certificates and the domains they apply to, sorted by domain
/// names, longest matches first
@@ -30,7 +33,7 @@ pub enum CertLoadError {
Empty,
/// the key file for the specified domain is bad (e.g. does not contain a
/// key or is invalid)
- BadKey(String, SignError),
+ BadKey(String, rustls::Error),
/// the key file for the specified domain is missing (but a certificate
/// file was present)
MissingKey(String),
@@ -74,27 +77,44 @@ fn load_domain(certs_dir: &Path, domain: String) -> Result<CertifiedKey, CertLoa
CertLoadError::MissingCert(domain)
});
}
- let cert = rustls::Certificate(
+ let cert = CertificateDer::from(
std::fs::read(&path).map_err(|_| CertLoadError::MissingCert(domain.clone()))?,
);
// load key from file
path.set_file_name(KEY_FILE_NAME);
- if !path.is_file() {
+ let Ok(der) = std::fs::read(&path) else {
return Err(CertLoadError::MissingKey(domain));
- }
- let key = rustls::PrivateKey(
- std::fs::read(&path).map_err(|_| CertLoadError::MissingKey(domain.clone()))?,
- );
+ };
// transform key to correct format
- let key = match any_supported_type(&key) {
- Ok(key) => key,
- Err(e) => return Err(CertLoadError::BadKey(domain, e)),
- };
+ let key = der_to_private_key(&der).map_err(|e| CertLoadError::BadKey(domain.clone(), e))?;
+
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 {
/// Load certificates from a certificate directory.
/// Certificates should be stored in a folder for each hostname, for example
diff --git a/src/main.rs b/src/main.rs
@@ -408,13 +408,9 @@ static TLS: Lazy<TlsAcceptor> = Lazy::new(acceptor);
fn acceptor() -> TlsAcceptor {
let config = if ARGS.only_tls13 {
- ServerConfig::builder()
- .with_safe_default_cipher_suites()
- .with_safe_default_kx_groups()
- .with_protocol_versions(&[&rustls::version::TLS13])
- .expect("could not build server config")
+ ServerConfig::builder_with_protocol_versions(&[&rustls::version::TLS13])
} else {
- ServerConfig::builder().with_safe_defaults()
+ ServerConfig::builder()
}
.with_no_client_auth()
.with_cert_resolver(ARGS.certs.clone());
diff --git a/tests/tests.rs b/tests/tests.rs
@@ -166,7 +166,7 @@ fn index_page() {
#[cfg(unix)]
#[test]
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");
@@ -184,7 +184,7 @@ fn index_page_unix() {
// set up TLS connection via unix socket
let mut certs = RootCertStore::empty();
certs
- .add(&Certificate(
+ .add(CertificateDer::from(
include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der"
@@ -193,7 +193,6 @@ fn index_page_unix() {
))
.unwrap();
let config = rustls::ClientConfig::builder()
- .with_safe_defaults()
.with_root_certificates(certs)
.with_no_client_auth();
let mut session = ClientConnection::new(
@@ -363,7 +362,7 @@ fn username() {
#[test]
/// - URLS with invalid hostnames are rejected
fn percent_encode() {
- use rustls::{Certificate, ClientConnection, RootCertStore};
+ use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write;
use std::net::TcpStream;
@@ -373,7 +372,7 @@ fn percent_encode() {
let mut certs = RootCertStore::empty();
certs
- .add(&Certificate(
+ .add(CertificateDer::from(
include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der"
@@ -382,7 +381,6 @@ fn percent_encode() {
))
.unwrap();
let config = rustls::ClientConfig::builder()
- .with_safe_defaults()
.with_root_certificates(certs)
.with_no_client_auth();
@@ -533,12 +531,8 @@ fn explicit_tls_version() {
let server = Server::new(&["-3"]);
- let config = rustls::ClientConfig::builder()
- .with_safe_default_cipher_suites()
- .with_safe_default_kx_groups()
- // try to connect using only TLS 1.2
- .with_protocol_versions(&[&rustls::version::TLS12])
- .unwrap()
+ // try to connect using only TLS 1.2
+ let config = rustls::ClientConfig::builder_with_protocol_versions(&[&rustls::version::TLS12])
.with_root_certificates(RootCertStore::empty())
.with_no_client_auth();
@@ -636,7 +630,7 @@ mod multicert {
#[test]
fn example_com() {
- use rustls::{Certificate, ClientConnection, RootCertStore};
+ use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write;
use std::net::TcpStream;
@@ -644,7 +638,7 @@ mod multicert {
let mut certs = RootCertStore::empty();
certs
- .add(&Certificate(
+ .add(CertificateDer::from(
include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.com/cert.der"
@@ -653,7 +647,6 @@ mod multicert {
))
.unwrap();
let config = rustls::ClientConfig::builder()
- .with_safe_defaults()
.with_root_certificates(certs)
.with_no_client_auth();
@@ -675,7 +668,7 @@ mod multicert {
#[test]
fn example_org() {
- use rustls::{Certificate, ClientConnection, RootCertStore};
+ use rustls::{pki_types::CertificateDer, ClientConnection, RootCertStore};
use std::io::Write;
use std::net::TcpStream;
@@ -683,7 +676,7 @@ mod multicert {
let mut certs = RootCertStore::empty();
certs
- .add(&Certificate(
+ .add(CertificateDer::from(
include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/data/multicert/example.org/cert.der"
@@ -692,7 +685,6 @@ mod multicert {
))
.unwrap();
let config = rustls::ClientConfig::builder()
- .with_safe_defaults()
.with_root_certificates(certs)
.with_no_client_auth();