ctclient_async/sth.rs
1use openssl::pkey::PKey;
2
3use crate::{Error, internal};
4
5/// An unverified *signed tree head* (STH), as returned from the server. This encapsulate the state of the tree at
6/// some point in time.
7///
8/// This struct stores the signature but does not store the public key or log id.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct SignedTreeHead {
11 pub tree_size: u64,
12 pub timestamp: u64,
13 pub root_hash: [u8; 32],
14 /// Digitally signed struct
15 pub signature: Vec<u8>,
16}
17
18impl SignedTreeHead {
19 /// Verify the contained signature against the log's public key.
20 pub fn verify(&self, pub_key: &PKey<openssl::pkey::Public>) -> Result<(), Error> {
21 let mut verify_body: Vec<u8> = Vec::new();
22 /*
23 From go source:
24 type TreeHeadSignature struct {
25 Version Version `tls:"maxval:255"`
26 SignatureType SignatureType `tls:"maxval:255"` // == TreeHashSignatureType
27 Timestamp uint64
28 TreeSize uint64
29 SHA256RootHash SHA256Hash
30 }
31 */
32 verify_body.push(0); // Version = 0
33 verify_body.push(1); // SignatureType = TreeHashSignatureType
34 verify_body.extend_from_slice(&self.timestamp.to_be_bytes()); // Timestamp
35 verify_body.extend_from_slice(&self.tree_size.to_be_bytes()); // TreeSize
36 verify_body.extend_from_slice(&self.root_hash);
37 internal::verify_dss(&self.signature, pub_key, &verify_body).map_err(|e| match e {
38 Error::InvalidSignature(desc) => {
39 Error::InvalidSignature(format!("When checking STH signature: {}", &desc))
40 }
41 other => other,
42 })
43 }
44}