diff --git a/src/api/endpoints.rs b/src/api/endpoints.rs index 2fddfe8..528d01d 100644 --- a/src/api/endpoints.rs +++ b/src/api/endpoints.rs @@ -60,3 +60,21 @@ pub const ADD_CHAIN: Endpoint = (reqwest::Method::POST, "/ct/v1/add-chain"); /// Outputs are the same as in Section 4.1. /// ``` pub const ADD_PRE_CHAIN: Endpoint = (reqwest::Method::POST, "/ct/v1/add-pre-chain"); + +/// Reference: https://datatracker.ietf.org/doc/html/rfc6962#section-4.3 +/// ```txt +/// GET https:///ct/v1/get-sth +/// +/// No inputs. +/// +/// Outputs: +/// +/// tree_size: The size of the tree, in entries, in decimal. +/// +/// timestamp: The timestamp, in decimal. +/// +/// sha256_root_hash: The Merkle Tree Hash of the tree, in base64. +/// +/// tree_head_signature: A TreeHeadSignature for the above data. +/// ``` +pub const GET_STH: Endpoint = (reqwest::Method::GET, "/ct/v1/get-sth"); \ No newline at end of file diff --git a/src/api/mod.rs b/src/api/mod.rs index edeba4f..342b455 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,5 +1,5 @@ use reqwest::Url; -use responses::{AddChainRequest, AddChainResponse}; +use responses::{AddChainRequest, AddChainResponse, GetSthResponse}; pub mod endpoints; pub mod responses; @@ -77,4 +77,19 @@ impl CtApiClient { .json() .await } + + pub async fn get_signed_tree_head( + &self + ) -> reqwest::Result { + self.inner_client + .request( + endpoints::GET_STH.0, + self.log_url.to_string() + endpoints::GET_STH.1 + ) + .send() + .await? + .error_for_status()? + .json() + .await + } } diff --git a/src/api/responses.rs b/src/api/responses.rs index b3a2c83..2a831ec 100644 --- a/src/api/responses.rs +++ b/src/api/responses.rs @@ -21,3 +21,14 @@ pub struct AddChainResponse { pub extensions: String, pub signature: String } + +/// A response given when fetching the Signed Tree Head of a CT log +/// +/// See: [`super::endpoints::GET_STH`] +#[derive(Debug, Deserialize)] +pub struct GetSthResponse { + pub tree_size: u64, + pub timestamp: u64, + pub sha256_root_hash: String, + pub tree_head_signature: String +}