#[cfg(not(any(feature = "aws-lc-rs", feature = "ring")))]
compile_error!("Either the `aws-lc-rs` (default) or `ring` feature must be enabled");
use std::sync::Arc;
pub fn install_default_crypto_provider() {
#[cfg(feature = "aws-lc-rs")]
{
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
}
#[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))]
{
let _ = rustls::crypto::ring::default_provider().install_default();
}
}
pub mod account;
pub mod acme_client;
pub mod acme_issuer;
pub mod async_jobs;
pub mod cache;
pub mod certificates;
pub mod config;
pub mod crypto;
pub mod dns_util;
pub mod error;
pub mod file_storage;
pub mod handshake;
pub mod http_handler;
pub mod maintain;
pub mod ocsp;
pub mod rate_limiter;
pub mod redirect;
pub mod solvers;
pub mod storage;
pub mod zerossl_issuer;
pub use account::{prompt_user_agreement, prompt_user_for_email};
pub use acme_client::{
LETS_ENCRYPT_PRODUCTION, LETS_ENCRYPT_STAGING, RenewalInfo, RenewalWindow, ZEROSSL_PRODUCTION,
ari_cert_id,
};
pub use acme_issuer::{
AcmeIssuer, AcmeIssuerBuilder, CertIssuer, IssuedCertificate, Manager, PreChecker, Revoker,
};
pub use cache::{CacheOptions, CertCache};
pub use certificates::Certificate;
pub use config::{CertificateSelector, Config, ConfigBuilder, IssuerPolicy};
pub use crypto::{KeyType, PrivateKey};
pub use error::{Error, Result};
pub use file_storage::FileStorage;
pub use handshake::{CertResolver, OnDemandConfig};
pub use maintain::MaintenanceConfig;
pub use ocsp::OcspConfig;
pub use redirect::{HttpsRedirectHandler, start_https_redirect};
pub use solvers::{
DistributedSolver, Dns01Solver, DnsProvider, Http01Solver, Solver, TlsAlpn01Solver,
};
pub use storage::{CertificateResource, KeyInfo, Storage, StorageKeys};
pub use zerossl_issuer::{ZeroSslApiIssuer, ZeroSslIssuer};
pub async fn manage(domains: &[String]) -> Result<rustls::ServerConfig> {
install_default_crypto_provider();
let storage: Arc<dyn Storage> = Arc::new(FileStorage::default());
let config = Config::builder().storage(storage).build();
config.manage_sync(domains).await?;
let resolver = CertResolver::new(config.cache.clone());
let tls_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_cert_resolver(Arc::new(resolver));
Ok(tls_config)
}
pub async fn tls_config(domains: &[String]) -> Result<rustls::ServerConfig> {
manage(domains).await
}
pub async fn listen(domains: &[String], addr: &str) -> Result<tokio_rustls::TlsAcceptor> {
let tls_cfg = manage(domains).await?;
let _listener = tokio::net::TcpListener::bind(addr)
.await
.map_err(|e| Error::Other(format!("failed to bind listener on {addr}: {e}")))?;
Ok(tokio_rustls::TlsAcceptor::from(Arc::new(tls_cfg)))
}
pub async fn manage_sync(domains: &[String]) -> Result<()> {
let storage: Arc<dyn Storage> = Arc::new(FileStorage::default());
let config = Config::builder().storage(storage).build();
config.manage_sync(domains).await
}
pub fn manage_async(domains: &[String]) -> tokio::task::JoinHandle<Result<()>> {
let domains = domains.to_vec();
tokio::spawn(async move { manage_sync(&domains).await })
}
pub fn start_maintenance(config: &Config) -> tokio::task::JoinHandle<()> {
let cache = config.cache.clone();
let maint_config = MaintenanceConfig {
renew_check_interval: maintain::DEFAULT_RENEW_CHECK_INTERVAL,
ocsp_check_interval: maintain::DEFAULT_OCSP_CHECK_INTERVAL,
ocsp: config.ocsp.clone(),
storage: config.storage.clone(),
};
let config_storage = config.storage.clone();
let config_cache = config.cache.clone();
let config_issuers = config.issuers.clone();
let config_key_type = config.key_type;
let config_ocsp = config.ocsp.clone();
let config_renewal_ratio = config.renewal_window_ratio;
let renew_func: Arc<maintain::RenewFn> = Arc::new(move |domain: String| {
let storage = config_storage.clone();
let cache = config_cache.clone();
let issuers = config_issuers.clone();
let key_type = config_key_type;
let ocsp_cfg = config_ocsp.clone();
let renewal_ratio = config_renewal_ratio;
Box::pin(async move {
let cfg = Config::builder().storage(storage).build();
let _ = (cache, issuers, key_type, ocsp_cfg, renewal_ratio);
cfg.manage_sync(&[domain]).await
})
});
maintain::start_maintenance(cache, maint_config, renew_func)
}