diff --git a/Cargo.toml b/Cargo.toml index ce61185..08f6037 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,21 +18,22 @@ serde = { version = "1.0.137", features = ["derive"] } ring = { version = "0.17.0", features = ["std"] } base64 = "0.21.0" log = "0.4.17" -webpki-roots = "0.25.2" +webpki-roots = "0.26" pem = "3.0" thiserror = "1.0.31" x509-parser = "0.16" chrono = { version = "0.4.24", default-features = false, features = ["clock"] } url = "2.2.2" async-trait = "0.1.53" -rustls = "0.21" +rustls = { version = "0.23", default-features = false, features = ["ring"] } +time = "0.3.36" # force the transitive dependency to a more recent minimal version. The build fails with 0.3.20 tokio = { version = "1.20.1", default-features = false } -tokio-rustls = { version = "0.24" } -reqwest = { version = "0.11.19", default-features = false, features = ["rustls-tls"] } +tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] } +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] } # Axum -axum-server = { version = "0.6", features = ["tls-rustls"], optional = true } +axum-server = { version = "0.7", features = ["tokio-rustls"], optional = true } [dependencies.proc-macro2] # This is a transitive dependency, we specify it to make sure we have @@ -54,7 +55,7 @@ axum = "0.7" tokio = { version="1.19.2", features = ["full"] } tokio-stream = { version="0.1.9", features = ["net"] } tokio-util = { version="0.7.3", features = ["compat"] } -warp = "0.3.4" +warp = "0.3.7" [package.metadata.docs.rs] all-features = true diff --git a/examples/low_level.rs b/examples/low_level.rs index fbbcc92..5971744 100644 --- a/examples/low_level.rs +++ b/examples/low_level.rs @@ -42,7 +42,6 @@ async fn main() { .directory_lets_encrypt(args.prod) .state(); let rustls_config = ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_cert_resolver(state.resolver()); let acceptor = state.acceptor(); diff --git a/examples/low_level_axum.rs b/examples/low_level_axum.rs index 12c991d..769a879 100644 --- a/examples/low_level_axum.rs +++ b/examples/low_level_axum.rs @@ -42,7 +42,6 @@ async fn main() { .directory_lets_encrypt(args.prod) .state(); let rustls_config = ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_cert_resolver(state.resolver()); let acceptor = state.axum_acceptor(Arc::new(rustls_config)); diff --git a/src/acceptor.rs b/src/acceptor.rs index c2162dc..ceb0f1b 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -18,7 +18,6 @@ pub struct AcmeAcceptor { impl AcmeAcceptor { pub(crate) fn new(resolver: Arc) -> Self { let mut config = ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_cert_resolver(resolver); config.alpn_protocols.push(ACME_TLS_ALPN_NAME.to_vec()); diff --git a/src/acme.rs b/src/acme.rs index 52009a0..653ef33 100644 --- a/src/acme.rs +++ b/src/acme.rs @@ -8,8 +8,11 @@ use rcgen::{Certificate, CustomExtension, Error as RcgenError, PKCS_ECDSA_P256_S use ring::error::{KeyRejected, Unspecified}; use ring::rand::SystemRandom; use ring::signature::{EcdsaKeyPair, EcdsaSigningAlgorithm, ECDSA_P256_SHA256_FIXED_SIGNING}; -use rustls::sign::{any_ecdsa_type, CertifiedKey}; -use rustls::{ClientConfig, PrivateKey}; +use rustls::{crypto::ring::sign::any_ecdsa_type, sign::CertifiedKey}; +use rustls::{ + pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer}, + ClientConfig, +}; use serde::{Deserialize, Serialize}; use serde_json::json; use thiserror::Error; @@ -178,8 +181,12 @@ impl Account { params.alg = &PKCS_ECDSA_P256_SHA256; params.custom_extensions = vec![CustomExtension::new_acme_identifier(key_auth.as_ref())]; let cert = Certificate::from_params(params)?; - let pk = any_ecdsa_type(&PrivateKey(cert.serialize_private_key_der())).unwrap(); - let certified_key = CertifiedKey::new(vec![rustls::Certificate(cert.serialize_der()?)], pk); + let pk_bytes = cert.serialize_private_key_der(); + let pk_der: PrivatePkcs8KeyDer = pk_bytes.into(); + let pk_der: PrivateKeyDer = pk_der.into(); + let pk = any_ecdsa_type(&pk_der).unwrap(); + let cert_bytes = cert.serialize_der()?; + let certified_key = CertifiedKey::new(vec![cert_bytes.into()], pk); Ok((challenge, certified_key)) } } diff --git a/src/config.rs b/src/config.rs index 625f468..40a70c6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -50,16 +50,17 @@ impl AcmeConfig { /// pub fn new(domains: impl IntoIterator>) -> Self { let mut root_store = RootCertStore::empty(); - root_store.add_trust_anchors(TLS_SERVER_ROOTS.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + root_store.extend( + TLS_SERVER_ROOTS + .iter() + .map(|ta| rustls::pki_types::TrustAnchor { + subject: ta.subject.clone(), + subject_public_key_info: ta.subject_public_key_info.clone(), + name_constraints: ta.name_constraints.clone(), + }), + ); let client_config = Arc::new( ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_store) .with_no_client_auth(), ); diff --git a/src/https_helper.rs b/src/https_helper.rs index b815ed1..0f5e508 100644 --- a/src/https_helper.rs +++ b/src/https_helper.rs @@ -1,6 +1,4 @@ -use rustls::client::InvalidDnsNameError; -use rustls::ClientConfig; -use std::sync::Arc; +use rustls::{pki_types::InvalidDnsNameError, ClientConfig}; use thiserror::Error; pub use reqwest::Response; @@ -23,15 +21,14 @@ impl From for reqwest::Method { } pub(crate) async fn https( - client_config: &Arc, + client_config: &ClientConfig, url: impl AsRef, method: Method, body: Option, ) -> Result { let method: reqwest::Method = method.into(); - let client_config: ClientConfig = client_config.as_ref().clone(); let client = reqwest::ClientBuilder::new() - .use_preconfigured_tls(client_config) + .use_preconfigured_tls(client_config.clone()) .build()?; let mut request = client.request(method, url.as_ref()); if let Some(body) = body { diff --git a/src/incoming.rs b/src/incoming.rs index 5062f24..94070e9 100644 --- a/src/incoming.rs +++ b/src/incoming.rs @@ -50,7 +50,6 @@ impl< alpn_protocols: Vec>, ) -> Self { let mut config = ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_cert_resolver(state.resolver()); config.alpn_protocols = alpn_protocols; diff --git a/src/lib.rs b/src/lib.rs index 242d400..f9c19d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,7 +108,7 @@ //! [rustls](https://github.com/ctz/rustls), //! [tokio-rustls](https://github.com/tokio-rs/tls/tree/master/tokio-rustls) and many others. -#![cfg_attr(doc_auto_cfg, feature(doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] mod acceptor; pub mod acme; diff --git a/src/resolver.rs b/src/resolver.rs index 89acdf2..ae57156 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -5,10 +5,12 @@ use std::collections::BTreeMap; use std::sync::Arc; use std::sync::Mutex; +#[derive(Debug)] pub struct ResolvesServerCertAcme { inner: Mutex, } +#[derive(Debug)] struct Inner { cert: Option>, auth_keys: BTreeMap>, diff --git a/src/state.rs b/src/state.rs index 9e04156..4913c34 100644 --- a/src/state.rs +++ b/src/state.rs @@ -10,9 +10,9 @@ use chrono::{DateTime, TimeZone, Utc}; use futures::future::try_join_all; use futures::{ready, FutureExt, Stream}; use rcgen::{CertificateParams, DistinguishedName, Error as RcgenError, PKCS_ECDSA_P256_SHA256}; -use rustls::sign::{any_ecdsa_type, CertifiedKey}; -use rustls::Certificate as RustlsCertificate; -use rustls::PrivateKey; +use rustls::crypto::ring::sign::any_ecdsa_type; +use rustls::pki_types::{CertificateDer as RustlsCertificate, PrivateKeyDer, PrivatePkcs8KeyDer}; +use rustls::sign::CertifiedKey; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio::time::Sleep; @@ -31,6 +31,7 @@ pub fn after(d: std::time::Duration) -> Timer { Box::pin(tokio::time::sleep(d)) } +#[allow(clippy::type_complexity)] pub struct AcmeState { config: Arc>, resolver: Arc, @@ -162,15 +163,16 @@ impl AcmeState { if pems.len() < 2 { return Err(CertParseError::TooFewPem(pems.len())); } - let pk = match any_ecdsa_type(&PrivateKey(pems.remove(0).into_contents())) { + let pk_bytes = pems.remove(0).into_contents(); + let pk_der: PrivatePkcs8KeyDer = pk_bytes.into(); + let pk: PrivateKeyDer = pk_der.into(); + let pk = match any_ecdsa_type(&pk) { Ok(pk) => pk, Err(_) => return Err(CertParseError::InvalidPrivateKey), }; - let cert_chain: Vec = pems - .into_iter() - .map(|p| RustlsCertificate(p.into_contents())) - .collect(); - let validity = match parse_x509_certificate(cert_chain[0].0.as_slice()) { + let cert_chain: Vec = + pems.into_iter().map(|p| p.into_contents().into()).collect(); + let validity = match parse_x509_certificate(cert_chain[0].as_ref()) { Ok((_, cert)) => { let validity = cert.validity(); [validity.not_before, validity.not_after]