pub struct CTClient { /* private fields */ }
Expand description
A stateful CT monitor.
One instance of this struct only concerns with one particular log. To monitor multiple logs, you can create multiple such instances and run them on different threads.
It remembers a last checked tree root, so that it only checks the newly added
certificates in the log each time you call update
.
Implementations§
Source§impl CTClient
impl CTClient
Sourcepub fn new_from_latest_th(base_url: &str, pub_key: &[u8]) -> Result<Self, Error>
pub fn new_from_latest_th(base_url: &str, pub_key: &[u8]) -> Result<Self, Error>
Construct a new CTClient
instance, and fetch the latest tree root.
Previous certificates in this log will not be checked.
§Errors
- If
base_url
does not ends with/
.
§Example
use ctclient::CTClient;
use base64::decode;
// URL and public key copy-pasted from https://www.gstatic.com/ct/log_list/v2/all_logs_list.json .
let public_key = decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01EAhx4o0zPQrXTcYjgCt4MVFsT0Pwjzb1RwrM0lhWDlxAYPP6/gyMCXNkOn/7KFsjL7rwk78tHMpY8rXn8AYg==").unwrap();
let client = CTClient::new_from_latest_th("https://ct.cloudflare.com/logs/nimbus2020/", &public_key).unwrap();
Sourcepub fn new_from_perv_tree_hash(
base_url: &str,
pub_key: &[u8],
tree_hash: [u8; 32],
tree_size: u64,
) -> Result<Self, Error>
pub fn new_from_perv_tree_hash( base_url: &str, pub_key: &[u8], tree_hash: [u8; 32], tree_size: u64, ) -> Result<Self, Error>
Construct a new CTClient
that will check all certificates included after
the given tree state.
Previous certificates in this log before the provided tree hash will not be checked.
§Example
use ctclient::{CTClient, utils};
use base64::decode;
// URL and public key copy-pasted from https://www.gstatic.com/ct/log_list/v2/all_logs_list.json .
let public_key = decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01EAhx4o0zPQrXTcYjgCt4MVFsT0Pwjzb1RwrM0lhWDlxAYPP6/gyMCXNkOn/7KFsjL7rwk78tHMpY8rXn8AYg==").unwrap();
use std::convert::TryInto;
// Tree captured on 2020-05-12 15:34:11 UTC
let th: [u8; 32] = (&utils::hex_to_u8("63875e88a3e37dc5b6cdbe213fe1df490d40193e4777f79467958ee157de70d6")[..]).try_into().unwrap();
let client = CTClient::new_from_perv_tree_hash("https://ct.cloudflare.com/logs/nimbus2020/", &public_key, th, 299304276).unwrap();
Sourcepub fn get_checked_tree_head(&self) -> (u64, [u8; 32])
pub fn get_checked_tree_head(&self) -> (u64, [u8; 32])
Get the last checked tree head. Returns (tree_size, root_hash)
.
Sourcepub fn get_reqwest_client(&self) -> &Client
pub fn get_reqwest_client(&self) -> &Client
Get the underlying http client used to call CT APIs.
Sourcepub fn get_base_url(&self) -> &Url
pub fn get_base_url(&self) -> &Url
Get the base_url of the log currently being monitored by this client.
This is the url that was passed to the constructor.
Sourcepub fn light_update(&mut self) -> SthResult
pub fn light_update(&mut self) -> SthResult
Calls self.update()
with None
as cert_handler
.
Sourcepub fn update<H>(&mut self, cert_handler: Option<H>) -> SthResult
pub fn update<H>(&mut self, cert_handler: Option<H>) -> SthResult
Fetch the latest tree root, check all the new certificates if cert_handler
is a Some, and update our
internal “last checked tree root”.
This function should never panic, no matter what the server does to us.
Return the latest SignedTreeHead
(STH) returned by the server, even if
it is the same as last time, or if it rolled back (new tree_size < current tree_size).
To log the behavior of CT logs, store the returned tree head and signature in some kind of database (even when error). This can be used to prove a misconduct (such as a non-extending-only tree) in the future.
Will only update the stored latest tree head if an Ok
is returned.
Sourcepub fn check_leaf<H>(
&self,
leaf: &Leaf,
cert_handler: &mut Option<H>,
) -> Result<(), Error>
pub fn check_leaf<H>( &self, leaf: &Leaf, cert_handler: &mut Option<H>, ) -> Result<(), Error>
Called by Self::update
for each leaf received
to check the certificates. Usually no need to call yourself.
Sourcepub fn check_inclusion_proof_for_sct(
&self,
sct: &SignedCertificateTimestamp,
) -> Result<u64, Error>
pub fn check_inclusion_proof_for_sct( &self, sct: &SignedCertificateTimestamp, ) -> Result<u64, Error>
Given a SignedCertificateTimestamp
, check that the CT log monitored by this client can provide
an inclusion proof that backs the sct, and return the leaf index.
Does not check the signature on the sct, and also does not check that the maximum merge delay has passed.
pub fn first_leaf_after( &self, timestamp: u64, ) -> Result<Option<(u64, Leaf)>, Error>
pub fn first_tree_head_after( &self, timestamp: u64, ) -> Result<Option<(u64, [u8; 32])>, Error>
pub fn rollback_to_timestamp(&mut self, timestamp: u64) -> Result<(), Error>
Sourcepub fn from_bytes(bytes: &[u8]) -> Result<Self, Error>
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error>
Parse a byte string returned by Self::as_bytes
.