Skip to main content

edgesentry_rs/
record.rs

1use serde::{Deserialize, Serialize};
2
3pub type Hash32 = [u8; 32];
4pub type Signature64 = [u8; 64];
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub struct AuditRecord {
8    pub device_id: String,
9    pub sequence: u64,
10    pub timestamp_ms: u64,
11    pub payload_hash: Hash32,
12    #[serde(with = "signature64_serde")]
13    pub signature: Signature64,
14    pub prev_record_hash: Hash32,
15    pub object_ref: String,
16}
17
18impl AuditRecord {
19    pub fn hash(&self) -> Hash32 {
20        let bytes = postcard::to_allocvec(self).expect("AuditRecord serialization should not fail");
21        *blake3::hash(&bytes).as_bytes()
22    }
23
24    pub fn zero_hash() -> Hash32 {
25        [0u8; 32]
26    }
27}
28
29mod signature64_serde {
30    use serde::{de::Error as DeError, Deserialize, Deserializer, Serializer};
31
32    pub fn serialize<S>(value: &[u8; 64], serializer: S) -> Result<S::Ok, S::Error>
33    where
34        S: Serializer,
35    {
36        serializer.serialize_bytes(value)
37    }
38
39    pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; 64], D::Error>
40    where
41        D: Deserializer<'de>,
42    {
43        let bytes: Vec<u8> = Vec::<u8>::deserialize(deserializer)?;
44        if bytes.len() != 64 {
45            return Err(D::Error::custom(format!(
46                "invalid signature length: expected 64, got {}",
47                bytes.len()
48            )));
49        }
50
51        let mut out = [0u8; 64];
52        out.copy_from_slice(&bytes);
53        Ok(out)
54    }
55}