Skip to main content

CertManager

Struct CertManager 

Source
pub struct CertManager { /* private fields */ }
Expand description

Certificate manager for TLS certificate provisioning and caching

The CertManager handles:

  • Loading existing certificates from disk
  • Caching certificates in memory
  • Provisioning new certificates via ACME

Implementations§

Source§

impl CertManager

Source

pub async fn new( storage_path: String, acme_email: Option<String>, ) -> Result<Self, Box<dyn Error + Send + Sync>>

Create a new certificate manager

§Arguments
  • storage_path - Directory to store certificates
  • acme_email - Optional email for ACME account registration
§Errors

Returns an error if the storage directory cannot be created or if loading an existing account fails.

Source

pub async fn with_directory( storage_path: String, acme_email: Option<String>, acme_directory: String, ) -> Result<Self, Box<dyn Error + Send + Sync>>

Create a new certificate manager with a custom ACME directory

§Arguments
  • storage_path - Directory to store certificates
  • acme_email - Optional email for ACME account registration
  • acme_directory - ACME directory URL (e.g., Let’s Encrypt production/staging)
§Errors

Returns an error if the storage directory cannot be created.

Source

pub fn acme_directory(&self) -> &str

Get the ACME directory URL

Source

pub async fn get_cert( &self, domain: &str, ) -> Result<(String, String), Box<dyn Error + Send + Sync>>

Get a certificate for a domain

This method:

  1. Checks the memory cache
  2. Checks disk storage
  3. Provisions via ACME if not found (future)
§Arguments
  • domain - The domain to get a certificate for
§Returns

Tuple of (certificate_pem, private_key_pem)

§Errors

Returns an error if the certificate is not found and ACME provisioning fails.

Source

pub async fn store_cert( &self, domain: &str, cert: &str, key: &str, ) -> Result<(), Box<dyn Error + Send + Sync>>

Store a certificate

This method stores the certificate and key to disk, updates the memory cache, and extracts/saves certificate metadata for renewal tracking.

§Arguments
  • domain - The domain
  • cert - Certificate PEM content
  • key - Private key PEM content
§Errors

Returns an error if writing the certificate or key files to disk fails.

Source

pub async fn has_cert(&self, domain: &str) -> bool

Check if a certificate exists for a domain

Source

pub fn acme_email(&self) -> Option<&str>

Get the ACME email (if configured)

Source

pub fn storage_path(&self) -> &PathBuf

Get the storage path

Source

pub async fn clear_cache(&self)

Clear the certificate cache

Source

pub async fn cached_count(&self) -> usize

Get cached certificate count

Source

pub async fn list_cached_domains(&self) -> Vec<String>

Return the list of domain names currently held in the certificate cache.

Source

pub fn parse_cert_expiry( cert_pem: &str, ) -> Result<(DateTime<Utc>, DateTime<Utc>), Box<dyn Error + Send + Sync>>

Parse certificate expiry dates from a PEM-encoded certificate

§Arguments
  • cert_pem - The PEM-encoded certificate string
§Returns

Tuple of (not_before, not_after) as DateTime

§Errors

Returns an error if the PEM cannot be parsed or the X.509 certificate contains invalid timestamps.

Source

pub async fn load_cert_metadata(&self, domain: &str) -> Option<CertMetadata>

Load certificate metadata from disk

§Arguments
  • domain - The domain to load metadata for
§Returns

The certificate metadata if it exists

Source

pub async fn get_domains_needing_renewal(&self) -> Vec<String>

Get domains with certificates expiring within a threshold

Returns domains with certificates that expire within 30 days (RENEWAL_THRESHOLD_DAYS).

§Returns

Vector of domain names with certificates needing renewal

Source

pub fn start_renewal_task( self: Arc<Self>, sni_resolver: Arc<SniCertResolver>, ) -> JoinHandle<()>

Start background certificate renewal task

This spawns a tokio task that checks certificates every 12 hours and renews any that expire within 30 days.

§Arguments
  • sni_resolver - The SNI resolver to update with renewed certificates
§Returns

A JoinHandle for the spawned renewal task

Source

pub async fn run_renewal_check( &self, sni_resolver: &SniCertResolver, ) -> Vec<String>

Run a single renewal check (for testing or on-demand renewal)

This method checks for certificates needing renewal and attempts to renew them. Unlike start_renewal_task, this runs once and returns immediately.

§Arguments
  • sni_resolver - The SNI resolver to update with renewed certificates
§Returns

Vector of domain names that were successfully renewed

Source

pub async fn load_account(&self) -> Option<AcmeAccount>

Load an existing ACME account from disk

This loads the account metadata. Use load_credentials() to load the actual credentials needed for ACME operations.

§Returns

The account if it exists and is valid, None otherwise

Source

pub async fn save_account( &self, account: &AcmeAccount, ) -> Result<(), Box<dyn Error + Send + Sync>>

Save an ACME account to disk (metadata only)

§Arguments
  • account - The account to save
§Errors

Returns an error if serialization or writing to disk fails.

Source

pub async fn get_or_create_account( &self, ) -> Result<AcmeAccount, Box<dyn Error + Send + Sync>>

Get or create an ACME account (returns our metadata struct)

This method:

  1. Returns the cached account if available
  2. Loads the account from disk if it exists
  3. Creates a new account via ACME
§Errors

Returns an error if ACME account creation or restoration fails.

Source

pub async fn get_account(&self) -> Option<AcmeAccount>

Get the cached ACME account (if any)

§Returns

The cached account, or None if not loaded

Source

pub async fn has_account(&self) -> bool

Check if an ACME account exists (either cached or on disk)

Source

pub fn store_challenge( &self, token: &str, domain: &str, key_authorization: &str, )

Store an ACME HTTP-01 challenge token

This stores the challenge token that will be served at /.well-known/acme-challenge/{token} for domain validation.

§Arguments
  • token - The challenge token from the ACME server
  • domain - The domain being validated
  • key_authorization - The key authorization response (token.thumbprint)
Source

pub fn get_challenge_response(&self, token: &str) -> Option<String>

Get the key authorization response for a challenge token

§Arguments
  • token - The challenge token from the request path
§Returns

The key authorization string if the token exists and hasn’t expired

Source

pub fn remove_challenge(&self, token: &str)

Remove a challenge token after validation completes

§Arguments
  • token - The challenge token to remove
Source

pub fn clear_challenges_for_domain(&self, domain: &str)

Clear all challenge tokens for a specific domain

Useful when certificate issuance completes or fails for a domain.

§Arguments
  • domain - The domain to clear challenges for
Source

pub fn cleanup_expired_challenges(&self)

Clean up expired challenge tokens

Removes all challenge tokens older than 5 minutes. This should be called periodically to prevent memory leaks.

Source

pub fn challenge_count(&self) -> usize

Get the number of active challenge tokens

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more