mithril_client/certificate_client/
api.rs

1use async_trait::async_trait;
2use mithril_common::logging::LoggerExtensions;
3use std::sync::Arc;
4
5use crate::aggregator_client::AggregatorClient;
6use crate::certificate_client::fetch::InternalCertificateRetriever;
7use crate::certificate_client::{fetch, verify};
8use crate::{MithrilCertificate, MithrilCertificateListItem, MithrilResult};
9
10/// Aggregator client for the Certificate
11pub struct CertificateClient {
12    pub(super) aggregator_client: Arc<dyn AggregatorClient>,
13    pub(super) retriever: Arc<InternalCertificateRetriever>,
14    pub(super) verifier: Arc<dyn CertificateVerifier>,
15}
16
17impl CertificateClient {
18    /// Constructs a new `CertificateClient`.
19    pub fn new(
20        aggregator_client: Arc<dyn AggregatorClient>,
21        verifier: Arc<dyn CertificateVerifier>,
22        logger: slog::Logger,
23    ) -> Self {
24        let logger = logger.new_with_component_name::<Self>();
25        let retriever = Arc::new(InternalCertificateRetriever::new(
26            aggregator_client.clone(),
27            logger,
28        ));
29
30        Self {
31            aggregator_client,
32            retriever,
33            verifier,
34        }
35    }
36
37    /// Fetch a list of certificates
38    pub async fn list(&self) -> MithrilResult<Vec<MithrilCertificateListItem>> {
39        fetch::list(self).await
40    }
41
42    /// Get a single certificate full information from the aggregator.
43    pub async fn get(&self, certificate_hash: &str) -> MithrilResult<Option<MithrilCertificate>> {
44        fetch::get(self, certificate_hash).await
45    }
46
47    /// Validate the chain starting with the certificate with given `certificate_hash`, return the certificate if
48    /// the chain is valid.
49    ///
50    /// This method will fail if no certificate exists for the given `certificate_hash`.
51    pub async fn verify_chain(&self, certificate_hash: &str) -> MithrilResult<MithrilCertificate> {
52        verify::verify_chain(self, certificate_hash).await
53    }
54}
55
56/// API that defines how to validate certificates.
57#[cfg_attr(test, mockall::automock)]
58#[cfg_attr(target_family = "wasm", async_trait(?Send))]
59#[cfg_attr(not(target_family = "wasm"), async_trait)]
60pub trait CertificateVerifier: Sync + Send {
61    /// Validate the chain starting with the given certificate.
62    async fn verify_chain(&self, certificate: &MithrilCertificate) -> MithrilResult<()>;
63}
64
65#[cfg(feature = "unstable")]
66/// API that defines how to cache certificates validation results.
67#[cfg_attr(test, mockall::automock)]
68#[cfg_attr(target_family = "wasm", async_trait(?Send))]
69#[cfg_attr(not(target_family = "wasm"), async_trait)]
70pub trait CertificateVerifierCache: Sync + Send {
71    /// Store a validated certificate hash and its parent hash in the cache.
72    async fn store_validated_certificate(
73        &self,
74        certificate_hash: &str,
75        previous_certificate_hash: &str,
76    ) -> MithrilResult<()>;
77
78    /// Get the previous hash of the certificate with the given hash if available in the cache.
79    async fn get_previous_hash(&self, certificate_hash: &str) -> MithrilResult<Option<String>>;
80
81    /// Reset the stored values
82    async fn reset(&self) -> MithrilResult<()>;
83}