Files
inbuxa-server/crates/common/src/network/acme/resolver.rs
T
jcoffey-dev 7dae9b29fd Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f
Enterprise-only files removed or emptied: 63
Enterprise-only snippets removed: 117 in 50 files
Dangling module declarations removed: 5
Cargo edits turning enterprise off: 14
Verification: clean
Enterprise feature gates left for rebuilt features: 19 in 18 files

Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
2026-09-18 10:21:56 -07:00

112 lines
3.5 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::{
KV_ACME, Server,
network::acme::{SerializedCert, StaticResolver, directory::ACME_TLS_ALPN_NAME},
};
use rustls::{
ServerConfig,
crypto::aws_lc_rs::sign::any_ecdsa_type,
server::{ClientHello, ResolvesServerCert},
sign::CertifiedKey,
};
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use std::sync::Arc;
use store::{
dispatch::lookup::KeyValue,
write::{AlignedBytes, Archive},
};
use trc::AcmeEvent;
impl Server {
pub(crate) async fn build_acme_certificate(&self, domain: &str) -> Option<Arc<CertifiedKey>> {
match self
.in_memory_store()
.key_get::<Archive<AlignedBytes>>(KeyValue::<()>::build_key(KV_ACME, domain))
.await
{
Ok(Some(cert_)) => match cert_.unarchive::<SerializedCert>() {
Ok(cert) => {
match any_ecdsa_type(&PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
cert.private_key.as_ref(),
))) {
Ok(key) => Some(Arc::new(CertifiedKey::new(
vec![CertificateDer::from(cert.certificate.to_vec())],
key,
))),
Err(err) => {
trc::event!(
Acme(AcmeEvent::Error),
Domain = domain.to_string(),
Reason = err.to_string(),
Details = "Failed to parse private key"
);
None
}
}
}
Err(err) => {
trc::event!(
Acme(AcmeEvent::Error),
Domain = domain.to_string(),
CausedBy = err,
Details = "Failed to unarchive certificate"
);
None
}
},
Err(err) => {
trc::event!(
Acme(AcmeEvent::Error),
Domain = domain.to_string(),
CausedBy = err
);
None
}
Ok(None) => {
trc::event!(Acme(AcmeEvent::TokenNotFound), Domain = domain.to_string());
None
}
}
}
#[inline(always)]
pub fn has_acme_tls_providers(&self) -> bool {
self.core.network.has_acme_tls_challenge
}
#[inline(always)]
pub fn has_acme_http_providers(&self) -> bool {
self.core.network.has_acme_http_challenge
}
}
impl ResolvesServerCert for StaticResolver {
fn resolve(&self, _: ClientHello) -> Option<Arc<CertifiedKey>> {
self.key.clone()
}
}
pub(crate) fn build_acme_static_resolver(key: Option<Arc<CertifiedKey>>) -> Arc<ServerConfig> {
let mut challenge = ServerConfig::builder()
.with_no_client_auth()
.with_cert_resolver(Arc::new(StaticResolver { key }));
challenge.alpn_protocols.push(ACME_TLS_ALPN_NAME.to_vec());
Arc::new(challenge)
}
pub trait IsTlsAlpnChallenge {
fn is_tls_alpn_challenge(&self) -> bool;
}
impl IsTlsAlpnChallenge for ClientHello<'_> {
fn is_tls_alpn_challenge(&self) -> bool {
self.alpn().into_iter().flatten().eq([ACME_TLS_ALPN_NAME])
}
}