aea_tools/
cluster_header.rs1use crate::segment_info::SegmentInfo;
2use anyhow::Result;
3use std::io::Read;
4
5#[derive(Clone)]
7pub struct ClusterHeader {
8 pub segment_info: Vec<SegmentInfo>,
11 pub next_cluster_hmac: [u8; 32],
12 pub segment_hmacs: Vec<[u8; 32]>,
14}
15
16impl ClusterHeader {
17 pub fn decode<R: Read + Unpin>(
18 reader: &mut R,
19 chek: &[u8; 80],
20 expected_hmac: &[u8; 32],
21 segments_per_cluster: [u8; 4],
22 ) -> Result<Self> {
23 let encrypted_segment_info_size =
24 (32 + 8) * u32::from_le_bytes(segments_per_cluster) as usize;
25 let segment_hmacs_size = 32 * u32::from_le_bytes(segments_per_cluster) as usize;
26
27 let mut encrypted_segment_info = vec![0u8; encrypted_segment_info_size];
28 let mut next_cluster_hmac = [0u8; 32];
29 let mut segment_hmacs = vec![0u8; segment_hmacs_size];
30 reader.read_exact(&mut encrypted_segment_info)?;
31 reader.read_exact(&mut next_cluster_hmac)?;
32 reader.read_exact(&mut segment_hmacs)?;
33
34 let segment_info = SegmentInfo::decrypt_segment_info(
35 &next_cluster_hmac,
36 &segment_hmacs,
37 encrypted_segment_info,
38 chek,
39 expected_hmac,
40 )?;
41
42 let segment_hmacs = segment_hmacs
43 .chunks_exact(32)
44 .map(|chunk| {
45 let mut hmac = [0u8; 32];
46 hmac.copy_from_slice(chunk);
47 hmac
48 })
49 .collect::<Vec<_>>();
50
51 Ok(Self {
52 segment_info,
53 next_cluster_hmac,
54 segment_hmacs,
55 })
56 }
57
58 pub fn encoded_len(&self) -> usize {
59 (32 + 8) * self.segment_info.len() + 32 + 32 * self.segment_info.len()
60 }
61}