1use std::io::{Cursor, Read};
3use std::fmt;
4use std::cmp::{PartialEq,Eq};
5use std::hash::{Hash, Hasher};
6
7use crate::{
9 Result,
10 HeaderCoding,
11 Encryption,
12 ValueEncoder,
13 ValueDecoder,
14 ZffError,
15 ZffErrorKind,
16 SignatureFlag,
17};
18
19use crate::{
20 ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER,
21 DEFAULT_LENGTH_VALUE_HEADER_LENGTH,
22 DEFAULT_LENGTH_HEADER_IDENTIFIER,
23 HEADER_IDENTIFIER_OBJECT_HEADER,
24 ERROR_INVALID_SIGNATURE_FLAG_VALUE,
25 ERROR_INVALID_OBJECT_TYPE_FLAG_VALUE,
26};
27
28use crate::header::{
29 EncryptionHeader,
30 CompressionHeader,
31 DescriptionHeader,
32};
33
34#[derive(Debug,Clone)]
43pub struct ObjectHeader {
44 version: u8,
45 object_number: u64,
46 encryption_header: Option<EncryptionHeader>,
47 compression_header: CompressionHeader,
48 signature_flag: SignatureFlag,
49 description_header: DescriptionHeader,
50 object_type: ObjectType
51}
52
53impl ObjectHeader {
54 pub fn new(version: u8,
56 object_number: u64,
57 encryption_header: Option<EncryptionHeader>,
58 compression_header: CompressionHeader,
59 signature_flag: SignatureFlag,
60 description_header: DescriptionHeader,
61 object_type: ObjectType) -> ObjectHeader {
62 Self {
63 version,
64 object_number,
65 encryption_header,
66 compression_header,
67 signature_flag,
68 description_header,
69 object_type,
70 }
71 }
72
73 pub fn set_object_number(&mut self, object_number: u64) {
75 self.object_number = object_number
76 }
77
78 pub fn object_number(&self) -> u64 {
80 self.object_number
81 }
82
83 pub fn description_header(&self) -> DescriptionHeader {
85 self.description_header.clone()
86 }
87
88 pub fn object_type(&self) -> ObjectType {
90 self.object_type.clone()
91 }
92
93 pub fn encryption_header(&self) -> Option<&EncryptionHeader> {
95 self.encryption_header.as_ref()
96 }
97
98 pub fn compression_header(&self) -> CompressionHeader {
100 self.compression_header.clone()
101 }
102
103 pub fn has_per_chunk_signatures(&self) -> bool {
105 matches!(&self.signature_flag, SignatureFlag::PerChunkSignatures)
106 }
107
108 pub fn has_hash_signatures(&self) -> bool {
110 !matches!(&self.signature_flag, SignatureFlag::NoSignatures)
111 }
112
113 pub fn signature_flag(&self) -> &SignatureFlag {
115 &self.signature_flag
116 }
117
118 pub fn encode_encrypted_header_directly<K>(&self, key: K) -> Result<Vec<u8>>
123 where
124 K: AsRef<[u8]>,
125 {
126 let mut vec = Vec::new();
127 let mut encoded_header = self.encode_encrypted_header(key)?;
128 let identifier = HEADER_IDENTIFIER_OBJECT_HEADER;
129 let encoded_header_length = 4 + 8 + (encoded_header.len() as u64); vec.append(&mut identifier.to_be_bytes().to_vec());
131 vec.append(&mut encoded_header_length.to_le_bytes().to_vec());
132 vec.append(&mut encoded_header);
133
134 Ok(vec)
135 }
136
137 fn encode_encrypted_header<K>(&self, key: K) -> Result<Vec<u8>>
138 where
139 K: AsRef<[u8]>
140 {
141 let encryption_header = match &self.encryption_header {
142 None => return Err(ZffError::new(ZffErrorKind::MissingEncryptionHeader, "")),
143 Some(header) => {
144 header
145 }
146 };
147 let encryption_flag: u8 = 2;
148
149 let mut vec = Vec::new();
150 vec.append(&mut self.version.encode_directly());
151 vec.append(&mut self.object_number.encode_directly());
152 vec.push(encryption_flag);
153 vec.append(&mut encryption_header.encode_directly());
154
155 let mut data_to_encrypt = Vec::new();
156 data_to_encrypt.append(&mut self.encode_content());
157
158 let encrypted_data = Encryption::encrypt_header(
159 key, data_to_encrypt,
160 encryption_header.nonce(),
161 encryption_header.algorithm()
162 )?;
163 vec.append(&mut encrypted_data.encode_directly());
164 Ok(vec)
165 }
166
167 fn encode_content(&self) -> Vec<u8> {
168 let mut vec = Vec::new();
169
170 vec.append(&mut self.compression_header.encode_directly());
171 vec.push(self.signature_flag.clone() as u8);
172 vec.append(&mut self.description_header.encode_directly());
173 vec.push(self.object_type.clone() as u8);
174 vec
175 }
176
177 pub fn decode_encrypted_header_with_password<R, P>(data: &mut R, password: P) -> Result<ObjectHeader>
179 where
180 R: Read,
181 P: AsRef<[u8]>,
182 {
183 if !Self::check_identifier(data) {
184 return Err(ZffError::new(ZffErrorKind::HeaderDecodeMismatchIdentifier, ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER));
185 };
186 let header_length = Self::decode_header_length(data)? as usize;
187 let mut header_content = vec![0u8; header_length-DEFAULT_LENGTH_HEADER_IDENTIFIER-DEFAULT_LENGTH_VALUE_HEADER_LENGTH];
188 data.read_exact(&mut header_content)?;
189 let mut cursor = Cursor::new(header_content);
190 let header_version = u8::decode_directly(&mut cursor)?;
191 let object_number = u64::decode_directly(&mut cursor)?;
192 let encryption_flag = u8::decode_directly(&mut cursor)?;
193 if encryption_flag != 2 {
194 return Err(ZffError::new(ZffErrorKind::HeaderDecodeEncryptedHeader, ""));
195 }
196 let encryption_header = EncryptionHeader::decode_directly(&mut cursor)?;
197 let encrypted_data = Vec::<u8>::decode_directly(&mut cursor)?;
198 let encryption_key = encryption_header.decrypt_encryption_key(password)?;
199 let nonce = encryption_header.nonce();
200 let algorithm = encryption_header.algorithm();
201 let decrypted_data = Encryption::decrypt_header(encryption_key, encrypted_data, nonce, algorithm)?;
202 let mut cursor = Cursor::new(decrypted_data);
203 let (compression_header,
204 signature_flag,
205 description_header,
206 object_type) = Self::decode_inner_content(&mut cursor)?;
207 let object_header = Self::new(
208 header_version,
209 object_number,
210 Some(encryption_header),
211 compression_header,
212 signature_flag,
213 description_header,
214 object_type);
215 Ok(object_header)
216 }
217
218 fn decode_inner_content<R: Read>(inner_content: &mut R) -> Result<(
219 CompressionHeader,
220 SignatureFlag,
221 DescriptionHeader,
222 ObjectType,
223 )> {
224 let compression_header = CompressionHeader::decode_directly(inner_content)?;
225 let signature_flag = match u8::decode_directly(inner_content)? {
226 0 => SignatureFlag::NoSignatures,
227 1 => SignatureFlag::HashValueSignatureOnly,
228 2 => SignatureFlag::PerChunkSignatures,
229 value => return Err(ZffError::new(ZffErrorKind::InvalidFlagValue, format!("{ERROR_INVALID_SIGNATURE_FLAG_VALUE} {value}"))),
230 };
231 let description_header = DescriptionHeader::decode_directly(inner_content)?;
232 let object_type = match u8::decode_directly(inner_content)? {
233 0 => ObjectType::Physical,
234 1 => ObjectType::Logical,
235 value => return Err(ZffError::new(ZffErrorKind::InvalidFlagValue, format!("{ERROR_INVALID_OBJECT_TYPE_FLAG_VALUE}{value}"))),
236 };
237 let inner_content = (
238 compression_header,
239 signature_flag,
240 description_header,
241 object_type);
242 Ok(inner_content)
243 }
244}
245
246#[repr(u8)]
248#[derive(Debug,Clone,Eq,PartialEq,Hash)]
249pub enum ObjectType {
250 Physical = 0,
252 Logical = 1,
254}
255
256impl fmt::Display for ObjectType {
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 let msg = match self {
259 ObjectType::Physical => "Physical",
260 ObjectType::Logical => "Logical",
261 };
262 write!(f, "{}", msg)
263 }
264}
265
266impl HeaderCoding for ObjectHeader {
267 type Item = ObjectHeader;
268 fn identifier() -> u32 {
269 HEADER_IDENTIFIER_OBJECT_HEADER
270 }
271
272 fn version(&self) -> u8 {
273 self.version
274 }
275
276 fn encode_directly(&self) -> Vec<u8> {
278 let mut vec = Vec::new();
279 let mut encoded_object_number = self.object_number.encode_directly();
280 let mut encoded_header = self.encode_header();
281 let identifier = Self::identifier();
282 let encoded_header_length = (DEFAULT_LENGTH_HEADER_IDENTIFIER + DEFAULT_LENGTH_VALUE_HEADER_LENGTH + encoded_header.len() + encoded_object_number.len() + 1) as u64; vec.append(&mut identifier.to_be_bytes().to_vec());
284 vec.append(&mut encoded_header_length.to_le_bytes().to_vec());
285 vec.push(self.version);
286 vec.append(&mut encoded_object_number);
287 vec.append(&mut encoded_header);
288 vec
289 }
290
291 fn encode_header(&self) -> Vec<u8> {
292 let mut vec = Vec::new();
293 match &self.encryption_header {
294 None => {
295 let encryption_flag: u8 = 0;
296 vec.push(encryption_flag);
297 },
298 Some(header) => {
299 let encryption_flag: u8 = 1;
300 vec.push(encryption_flag);
301 vec.append(&mut header.encode_directly());
302 },
303 };
304
305 vec.append(&mut self.encode_content());
306
307 vec
308 }
309
310 fn decode_content(data: Vec<u8>) -> Result<ObjectHeader> {
311 let mut cursor = Cursor::new(data);
312 let version = u8::decode_directly(&mut cursor)?;
313 let object_number = u64::decode_directly(&mut cursor)?;
314 let encryption_flag = u8::decode_directly(&mut cursor)?;
316 let encryption_header = match encryption_flag {
317 0 => None,
318 1 => Some(EncryptionHeader::decode_directly(&mut cursor)?),
319 flag_value => return Err(ZffError::new(ZffErrorKind::HeaderDecodeEncryptedHeader, flag_value.to_string()))
320 };
321 let (compression_header,
322 signature_flag,
323 description_header,
324 object_type) = Self::decode_inner_content(&mut cursor)?;
325
326 let object_header = Self::new(
327 version,
328 object_number,
329 encryption_header,
330 compression_header,
331 signature_flag,
332 description_header,
333 object_type);
334 Ok(object_header)
335 }
336}
337
338impl PartialEq for ObjectHeader {
339 fn eq(&self, other: &Self) -> bool {
340 self.object_number == other.object_number
341 }
342}
343
344impl Eq for ObjectHeader {}
345
346impl Hash for ObjectHeader {
347 fn hash<H: Hasher>(&self, state: &mut H) {
348 self.object_number.hash(state);
349 }
350}