zff/header/version2/
hash_header.rs

1// - STD
2use std::io::{Cursor, Read};
3
4// - internal
5use crate::{
6	Result,
7	ValueEncoder,
8	ValueDecoder,
9	HeaderCoding,
10	HashType,
11	ZffError,
12	HEADER_IDENTIFIER_HASH_HEADER,
13	HEADER_IDENTIFIER_HASH_VALUE,
14	ERROR_HEADER_DECODER_UNKNOWN_HASH_TYPE,
15};
16
17// - external
18use ed25519_dalek::{SIGNATURE_LENGTH};
19
20/// Header for the hash values of the dumped data stream.
21/// This header is part of various footers and contains 0 or more hash values of the dumped data.\
22#[derive(Debug,Clone,Eq,PartialEq)]
23pub struct HashHeader {
24	version: u8,
25	hashes: Vec<HashValue>,
26}
27
28impl HashHeader {
29	/// creates a new HashHeader by given values/hashes.
30	pub fn new(version: u8, hashes: Vec<HashValue>) -> HashHeader {
31		Self {
32			version,
33			hashes,
34		}
35	}
36
37	/// returns a reference to the underlying [HashValue]s.
38	pub fn hash_values(&self) -> &Vec<HashValue> {
39		&self.hashes
40	}
41}
42
43impl HeaderCoding for HashHeader {
44	type Item = HashHeader;
45
46	fn identifier() -> u32 {
47		HEADER_IDENTIFIER_HASH_HEADER
48	}
49
50	fn version(&self) -> u8 {
51		self.version
52	}
53
54	fn encode_header(&self) -> Vec<u8> {
55		let mut vec = Vec::new();
56		vec.append(&mut self.version.encode_directly());
57		vec.append(&mut self.hashes.encode_directly());
58
59		vec
60	}
61
62	fn decode_content(data: Vec<u8>) -> Result<HashHeader> {
63		let mut cursor = Cursor::new(data);
64		let header_version = u8::decode_directly(&mut cursor)?;
65		let hashes = Vec::<HashValue>::decode_directly(&mut cursor)?;
66		Ok(HashHeader::new(header_version, hashes))
67	}
68}
69
70/// This is a part of the [HashHeader].
71/// The HashValue-struct contains the appropriate hash algorithm and the hash. This struct has a version also.
72#[derive(Debug,Clone,PartialEq,Eq)]
73pub struct HashValue {
74	version: u8,
75	hash_type: HashType,
76	hash: Vec<u8>,
77	ed25519_signature: Option<[u8; SIGNATURE_LENGTH]>,
78}
79
80impl HashValue {
81	/// creates a new [HashValue] with the given parameters.
82	pub fn new(version: u8, hash_type: HashType, hash: Vec<u8>, ed25519_signature: Option<[u8; SIGNATURE_LENGTH]>,) -> HashValue{
83		Self {
84			version,
85			hash_type,
86			hash,
87			ed25519_signature,
88		}
89	}
90	/// creates a new, empty [HashValue] for a given hashtype.
91	pub fn new_empty(structure_version: u8, hash_type: HashType) -> HashValue {
92		let hash_default_len = hash_type.default_len();
93		Self {
94			version: structure_version,
95			hash_type,
96			hash: vec!(0u8; hash_default_len/8),
97			ed25519_signature: None
98		}
99	}
100
101	/// returns the type of hash as [HashType](crate::hashing::HashType).
102	pub fn hash_type(&self) -> &HashType {
103		&self.hash_type
104	}
105
106	/// sets the hash value.
107	pub fn set_hash(&mut self, hash: Vec<u8>) {
108		self.hash = hash
109	}
110
111	/// returns the underlying hash value
112	pub fn hash(&self) -> &Vec<u8> {
113		&self.hash
114	}
115
116	/// sets the appropriate ed25519 signature
117	pub fn set_ed25519_signature(&mut self, signature: [u8; SIGNATURE_LENGTH]) {
118		self.ed25519_signature = Some(signature)
119	}
120
121	/// returns the appropriate signature
122	pub fn ed25519_signature(&self) -> Option<[u8; SIGNATURE_LENGTH]> {
123		self.ed25519_signature
124	}
125}
126
127
128impl HeaderCoding for HashValue {
129	type Item = HashValue;
130
131	fn identifier() -> u32 {
132		HEADER_IDENTIFIER_HASH_VALUE
133	}
134
135	fn version(&self) -> u8 {
136		self.version
137	}
138	
139	fn encode_header(&self) -> Vec<u8> {
140		let mut vec = Vec::new();
141		vec.append(&mut self.version.encode_directly());
142		vec.push(self.hash_type.clone() as u8);
143		vec.append(&mut self.hash.encode_directly());
144		match self.ed25519_signature {
145			None => (),
146			Some(signature) => vec.append(&mut signature.encode_directly()),
147		};
148		vec
149	}
150
151	fn decode_content(data: Vec<u8>) -> Result<HashValue> {
152		let mut cursor = Cursor::new(&data);
153		let structure_version = u8::decode_directly(&mut cursor)?;
154		let hash_type = match u8::decode_directly(&mut cursor)? {
155			0 => HashType::Blake2b512,
156			1 => HashType::SHA256,
157			2 => HashType::SHA512,
158			3 => HashType::SHA3_256,
159			4 => HashType::Blake3,
160			_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_HASH_TYPE)),
161		};
162	 	let hash = Vec::<u8>::decode_directly(&mut cursor)?;
163	 	
164	 	let mut ed25519_signature = None;
165		if cursor.position() < (data.len() as u64 - 1) {
166			let mut buffer = [0; SIGNATURE_LENGTH];
167			cursor.read_exact(&mut buffer)?;
168			ed25519_signature = Some(buffer);
169		}
170
171		Ok(HashValue::new(structure_version, hash_type, hash, ed25519_signature))
172	}
173}