1use std::{fmt, io};
2
3pub use self::fields::{
4 AsymmetricKeyAlgo, Buffer, CertSerial, ErrorCode, HashAlgo, HeaderLen, NullableBuffer, PcCert,
5 ProtocolVersion, Reserved, SpecialTreatment, SymmetricKeyAlgo,
6};
7
8mod fields;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Header {
13 pub len: HeaderLen,
15 pub version: ProtocolVersion,
17 pub error: ErrorCode,
19 pub special_treatment: SpecialTreatment,
21 pub reserved: Reserved,
23 pub dst_key_algo: AsymmetricKeyAlgo,
25 pub sym_key_algo: SymmetricKeyAlgo,
27 pub src_key_algo: AsymmetricKeyAlgo,
29 pub hash_algo: HashAlgo,
31 pub dst_pc_cert: PcCert,
33 pub dst_cert_serial: CertSerial,
35 pub src_pc_cert: PcCert,
37 pub src_cert_serial: CertSerial,
39 pub buffer_sym_key: NullableBuffer,
41 pub buffer_hash: Buffer,
43}
44
45impl Header {
46 pub fn read_from_file<R: io::Read>(file: &mut R) -> io::Result<Self> {
47 let mut c01 = [0; 2];
48 file.read_exact(&mut c01)?;
49 let mut c02 = [0; 1];
50 file.read_exact(&mut c02)?;
51 let mut c03 = [0; 1];
52 file.read_exact(&mut c03)?;
53 let mut c04 = [0; 1];
54 file.read_exact(&mut c04)?;
55 let mut c05 = [0; 1];
56 file.read_exact(&mut c05)?;
57 let mut c06 = [0; 1];
58 file.read_exact(&mut c06)?;
59 let mut c07 = [0; 1];
60 file.read_exact(&mut c07)?;
61 let mut c08 = [0; 1];
62 file.read_exact(&mut c08)?;
63 let mut c09 = [0; 1];
64 file.read_exact(&mut c09)?;
65 let mut c10 = [0; 1];
66 file.read_exact(&mut c10)?;
67 let mut c11 = [0; 32];
68 file.read_exact(&mut c11)?;
69 let mut c12 = [0; 1];
70 file.read_exact(&mut c12)?;
71 let mut c13 = [0; 32];
72 file.read_exact(&mut c13)?;
73 let mut c14 = [0; 256];
74 file.read_exact(&mut c14)?;
75 let mut c15 = [0; 256];
76 file.read_exact(&mut c15)?;
77
78 Ok(Self {
79 len: c01.into(),
80 version: c02.into(),
81 error: c03.into(),
82 special_treatment: c04.into(),
83 reserved: c05.into(),
84 dst_key_algo: c06.into(),
85 sym_key_algo: c07.into(),
86 src_key_algo: c08.into(),
87 hash_algo: c09.into(),
88 dst_pc_cert: c10.into(),
89 dst_cert_serial: c11.into(),
90 src_pc_cert: c12.into(),
91 src_cert_serial: c13.into(),
92 buffer_sym_key: c14.into(),
93 buffer_hash: c15.into(),
94 })
95 }
96
97 pub fn is_valid(&self) -> Result<(), String> {
98 let errors: Vec<_> = [
99 (self.len.is_valid(), "C01 inválido"),
100 (self.version.is_valid(), "C02 inválido"),
101 (self.error.is_valid(), "C03 inválido"),
102 (self.special_treatment.is_valid(), "C04 inválido"),
103 (self.reserved.is_valid(), "C05 inválido"),
104 (self.dst_key_algo.is_valid(), "C06 inválido"),
105 (self.sym_key_algo.is_valid(), "C07 inválido"),
106 (self.src_key_algo.is_valid(), "C08 inválido"),
107 (self.hash_algo.is_valid(), "C09 inválido"),
108 (self.dst_pc_cert.is_valid(), "C10 inválido"),
109 (self.dst_cert_serial.is_valid(), "C11 inválido"),
110 (self.src_pc_cert.is_valid(), "C12 inválido"),
111 (self.src_cert_serial.is_valid(), "C13 inválido"),
112 (self.buffer_sym_key.is_valid(), "C14 inválido"),
113 (self.buffer_hash.is_valid(), "C15 inválido"),
114 ]
115 .into_iter()
116 .filter_map(|(valid, error)| if valid { None } else { Some(error) })
117 .collect();
118
119 match errors.is_empty() {
120 true => Ok(()),
121 false => Err(errors.join(", ")),
122 }
123 }
124
125 pub fn is_encrypted_content(&self) -> bool {
126 match self.special_treatment {
127 SpecialTreatment::NotCryptBroadcast
128 | SpecialTreatment::NotCrypt
129 | SpecialTreatment::NotCompressAndNotCrypt
130 | SpecialTreatment::CompressWithoutCrypt => false,
131 _ => matches!(self.buffer_sym_key, NullableBuffer::Some(_)),
132 }
133 }
134
135 pub fn is_compressed_content(&self) -> bool {
136 matches!(
137 self.special_treatment,
138 SpecialTreatment::Compress | SpecialTreatment::CompressWithoutCrypt
139 )
140 }
141
142 pub fn to_bytes(&self) -> Vec<u8> {
143 let mut data = Vec::new();
144 self.len.to_bytes().iter().for_each(|&byte| data.push(byte));
145 self.version
146 .to_bytes()
147 .iter()
148 .for_each(|&byte| data.push(byte));
149 self.error
150 .to_bytes()
151 .iter()
152 .for_each(|&byte| data.push(byte));
153 self.special_treatment
154 .to_bytes()
155 .iter()
156 .for_each(|&byte| data.push(byte));
157 self.reserved
158 .to_bytes()
159 .iter()
160 .for_each(|&byte| data.push(byte));
161 self.dst_key_algo
162 .to_bytes()
163 .iter()
164 .for_each(|&byte| data.push(byte));
165 self.sym_key_algo
166 .to_bytes()
167 .iter()
168 .for_each(|&byte| data.push(byte));
169 self.src_key_algo
170 .to_bytes()
171 .iter()
172 .for_each(|&byte| data.push(byte));
173 self.hash_algo
174 .to_bytes()
175 .iter()
176 .for_each(|&byte| data.push(byte));
177 self.dst_pc_cert
178 .to_bytes()
179 .iter()
180 .for_each(|&byte| data.push(byte));
181 self.dst_cert_serial
182 .to_bytes()
183 .iter()
184 .for_each(|&byte| data.push(byte));
185 self.src_pc_cert
186 .to_bytes()
187 .iter()
188 .for_each(|&byte| data.push(byte));
189 self.src_cert_serial
190 .to_bytes()
191 .iter()
192 .for_each(|&byte| data.push(byte));
193 self.buffer_sym_key
194 .to_bytes()
195 .iter()
196 .for_each(|&byte| data.push(byte));
197 self.buffer_hash
198 .to_bytes()
199 .iter()
200 .for_each(|&byte| data.push(byte));
201 data
202 }
203}
204
205impl fmt::Display for Header {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 writeln!(
208 f,
209 "================================ BEGIN HEADER ================================"
210 )?;
211 writeln!(f, "{:45}: {}", "C01 Tamanho do cabeçalho", self.len)?;
212 writeln!(f, "{:45}: {}", "C02 Versão do protocolo", self.version)?;
213 writeln!(f, "{:45}: {}", "C03 Código de erro", self.error)?;
214 writeln!(
215 f,
216 "{:45}: {}",
217 "C04 Tratamento especial", self.special_treatment
218 )?;
219 writeln!(f, "{:45}: {}", "C05 Reservado", self.reserved)?;
220 writeln!(
221 f,
222 "{:45}: {}",
223 "C06 Algoritmo da chave assimétrica do destino", self.dst_key_algo
224 )?;
225 writeln!(
226 f,
227 "{:45}: {}",
228 "C07 Algoritmo da chave simétrica", self.sym_key_algo
229 )?;
230 writeln!(
231 f,
232 "{:45}: {}",
233 "C08 Algoritmo da chave assimétrica local", self.src_key_algo
234 )?;
235 writeln!(f, "{:45}: {}", "C09 Algoritmo de hash", self.hash_algo)?;
236 writeln!(
237 f,
238 "{:45}: {}",
239 "C10 PC do certificado do destino", self.dst_pc_cert
240 )?;
241 writeln!(
242 f,
243 "{:45}: {}",
244 "C11 Série do certificado do destino", self.dst_cert_serial
245 )?;
246 writeln!(
247 f,
248 "{:45}: {}",
249 "C12 PC do certificado da instituição", self.src_pc_cert
250 )?;
251 writeln!(
252 f,
253 "{:45}: {}",
254 "C13 Série do certificado da instituição", self.src_cert_serial
255 )?;
256 writeln!(
257 f,
258 "{:45}: {}",
259 "C14 Buffer da chave simétrica", self.buffer_sym_key
260 )?;
261 writeln!(
262 f,
263 "{:45}: {}",
264 "C15 Buffer da autenticação da mensagem", self.buffer_hash
265 )?;
266 write!(
267 f,
268 "================================ END HEADER ================================"
269 )
270 }
271}
272
273#[cfg(test)]
274mod tests {
275 use std::io::Cursor;
276
277 use super::*;
278
279 #[test]
280 fn value_plain() {
281 let sut = Header {
282 len: HeaderLen::Default,
283 version: ProtocolVersion::Plain,
284 error: ErrorCode::NoError,
285 special_treatment: SpecialTreatment::Normal,
286 reserved: Reserved::NoValue,
287 dst_key_algo: AsymmetricKeyAlgo::Unknown(0),
288 sym_key_algo: SymmetricKeyAlgo::Unknown(0),
289 src_key_algo: AsymmetricKeyAlgo::Unknown(0),
290 hash_algo: HashAlgo::Unknown(0),
291 dst_pc_cert: PcCert::Unknown(0),
292 dst_cert_serial: [0; 32].into(),
293 src_pc_cert: PcCert::Unknown(0),
294 src_cert_serial: [0; 32].into(),
295 buffer_sym_key: [0; 256].into(),
296 buffer_hash: [0; 256].into(),
297 };
298
299 assert_eq!(sut.to_string(), "================================ BEGIN HEADER ================================
300C01 Tamanho do cabeçalho : 0x024c [588]
301C02 Versão do protocolo : 0x00 [Em claro]
302C03 Código de erro : 0x00 [Sem erros]
303C04 Tratamento especial : 0x00 [Uso normal]
304C05 Reservado : 0x00 [-]
305C06 Algoritmo da chave assimétrica do destino: 0x00 [DESCONHECIDO]
306C07 Algoritmo da chave simétrica : 0x00 [DESCONHECIDO]
307C08 Algoritmo da chave assimétrica local : 0x00 [DESCONHECIDO]
308C09 Algoritmo de hash : 0x00 [DESCONHECIDO]
309C10 PC do certificado do destino : 0x00 [DESCONHECIDO]
310C11 Série do certificado do destino : 0x0000000000000000000000000000000000000000000000000000000000000000 [INVÁLIDO]
311C12 PC do certificado da instituição : 0x00 [DESCONHECIDO]
312C13 Série do certificado da instituição : 0x0000000000000000000000000000000000000000000000000000000000000000 [INVÁLIDO]
313C14 Buffer da chave simétrica : VAZIO
314C15 Buffer da autenticação da mensagem : blob [len=0]
315================================ END HEADER ================================");
316 }
317
318 #[test]
319 fn value_version3() {
320 let sut = Header {
321 len: HeaderLen::Default,
322 version: ProtocolVersion::Version3,
323 error: ErrorCode::NoError,
324 special_treatment: SpecialTreatment::Normal,
325 reserved: Reserved::NoValue,
326 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
327 sym_key_algo: SymmetricKeyAlgo::Aes,
328 src_key_algo: AsymmetricKeyAlgo::RSA2048,
329 hash_algo: HashAlgo::SHA256,
330 dst_pc_cert: PcCert::PessoasFisicas,
331 dst_cert_serial: [0; 32].into(),
332 src_pc_cert: PcCert::PessoasFisicas,
333 src_cert_serial: [0; 32].into(),
334 buffer_sym_key: [1; 256].into(),
335 buffer_hash: [1; 256].into(),
336 };
337
338 assert_eq!(sut.to_string(), "================================ BEGIN HEADER ================================
339C01 Tamanho do cabeçalho : 0x024c [588]
340C02 Versão do protocolo : 0x03 [Terceira versão]
341C03 Código de erro : 0x00 [Sem erros]
342C04 Tratamento especial : 0x00 [Uso normal]
343C05 Reservado : 0x00 [-]
344C06 Algoritmo da chave assimétrica do destino: 0x02 [RSA com 2048 bits]
345C07 Algoritmo da chave simétrica : 0x02 [AES com 256 bits]
346C08 Algoritmo da chave assimétrica local : 0x02 [RSA com 2048 bits]
347C09 Algoritmo de hash : 0x03 [SHA-256]
348C10 PC do certificado do destino : 0x03 [Pessoas Físicas]
349C11 Série do certificado do destino : 0x0000000000000000000000000000000000000000000000000000000000000000 [INVÁLIDO]
350C12 PC do certificado da instituição : 0x03 [Pessoas Físicas]
351C13 Série do certificado da instituição : 0x0000000000000000000000000000000000000000000000000000000000000000 [INVÁLIDO]
352C14 Buffer da chave simétrica : blob [len=256]
353C15 Buffer da autenticação da mensagem : blob [len=256]
354================================ END HEADER ================================");
355 }
356
357 #[test]
358 fn value_invalid_len() {
359 let sut = Header {
360 len: HeaderLen::Unknown(0),
361 version: ProtocolVersion::Version3,
362 error: ErrorCode::NoError,
363 special_treatment: SpecialTreatment::Normal,
364 reserved: Reserved::NoValue,
365 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
366 sym_key_algo: SymmetricKeyAlgo::Aes,
367 src_key_algo: AsymmetricKeyAlgo::RSA2048,
368 hash_algo: HashAlgo::SHA256,
369 dst_pc_cert: PcCert::PessoasFisicas,
370 dst_cert_serial: [b'1'; 32].into(),
371 src_pc_cert: PcCert::PessoasFisicas,
372 src_cert_serial: [b'1'; 32].into(),
373 buffer_sym_key: [1; 256].into(),
374 buffer_hash: [1; 256].into(),
375 };
376
377 assert_eq!(sut.is_valid().unwrap_err(), "C01 inválido");
378 }
379
380 #[test]
381 fn value_invalid_version() {
382 let sut = Header {
383 len: HeaderLen::Default,
384 version: ProtocolVersion::Unknown(1),
385 error: ErrorCode::NoError,
386 special_treatment: SpecialTreatment::Normal,
387 reserved: Reserved::NoValue,
388 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
389 sym_key_algo: SymmetricKeyAlgo::Aes,
390 src_key_algo: AsymmetricKeyAlgo::RSA2048,
391 hash_algo: HashAlgo::SHA256,
392 dst_pc_cert: PcCert::PessoasFisicas,
393 dst_cert_serial: [b'1'; 32].into(),
394 src_pc_cert: PcCert::PessoasFisicas,
395 src_cert_serial: [b'1'; 32].into(),
396 buffer_sym_key: [1; 256].into(),
397 buffer_hash: [1; 256].into(),
398 };
399
400 assert_eq!(sut.is_valid().unwrap_err(), "C02 inválido");
401 }
402
403 #[test]
404 fn value_invalid_error() {
405 let sut = Header {
406 len: HeaderLen::Default,
407 version: ProtocolVersion::Version3,
408 error: ErrorCode::Unknown(1),
409 special_treatment: SpecialTreatment::Normal,
410 reserved: Reserved::NoValue,
411 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
412 sym_key_algo: SymmetricKeyAlgo::Aes,
413 src_key_algo: AsymmetricKeyAlgo::RSA2048,
414 hash_algo: HashAlgo::SHA256,
415 dst_pc_cert: PcCert::PessoasFisicas,
416 dst_cert_serial: [b'1'; 32].into(),
417 src_pc_cert: PcCert::PessoasFisicas,
418 src_cert_serial: [b'1'; 32].into(),
419 buffer_sym_key: [1; 256].into(),
420 buffer_hash: [1; 256].into(),
421 };
422
423 assert_eq!(sut.is_valid().unwrap_err(), "C03 inválido");
424 }
425
426 #[test]
427 fn value_invalid_special_treatment() {
428 let sut = Header {
429 len: HeaderLen::Default,
430 version: ProtocolVersion::Version3,
431 error: ErrorCode::NoError,
432 special_treatment: SpecialTreatment::Unknown(7),
433 reserved: Reserved::NoValue,
434 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
435 sym_key_algo: SymmetricKeyAlgo::Aes,
436 src_key_algo: AsymmetricKeyAlgo::RSA2048,
437 hash_algo: HashAlgo::SHA256,
438 dst_pc_cert: PcCert::PessoasFisicas,
439 dst_cert_serial: [b'1'; 32].into(),
440 src_pc_cert: PcCert::PessoasFisicas,
441 src_cert_serial: [b'1'; 32].into(),
442 buffer_sym_key: [1; 256].into(),
443 buffer_hash: [1; 256].into(),
444 };
445
446 assert_eq!(sut.is_valid().unwrap_err(), "C04 inválido");
447 }
448
449 #[test]
450 fn value_invalid_reserved() {
451 let sut = Header {
452 len: HeaderLen::Default,
453 version: ProtocolVersion::Version3,
454 error: ErrorCode::NoError,
455 special_treatment: SpecialTreatment::Normal,
456 reserved: Reserved::Unknown(1),
457 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
458 sym_key_algo: SymmetricKeyAlgo::Aes,
459 src_key_algo: AsymmetricKeyAlgo::RSA2048,
460 hash_algo: HashAlgo::SHA256,
461 dst_pc_cert: PcCert::PessoasFisicas,
462 dst_cert_serial: [b'1'; 32].into(),
463 src_pc_cert: PcCert::PessoasFisicas,
464 src_cert_serial: [b'1'; 32].into(),
465 buffer_sym_key: [1; 256].into(),
466 buffer_hash: [1; 256].into(),
467 };
468
469 assert_eq!(sut.is_valid().unwrap_err(), "C05 inválido");
470 }
471
472 #[test]
473 fn value_invalid_dst_key_algo() {
474 let sut = Header {
475 len: HeaderLen::Default,
476 version: ProtocolVersion::Version3,
477 error: ErrorCode::NoError,
478 special_treatment: SpecialTreatment::Normal,
479 reserved: Reserved::NoValue,
480 dst_key_algo: AsymmetricKeyAlgo::Unknown(0),
481 sym_key_algo: SymmetricKeyAlgo::Aes,
482 src_key_algo: AsymmetricKeyAlgo::RSA2048,
483 hash_algo: HashAlgo::SHA256,
484 dst_pc_cert: PcCert::PessoasFisicas,
485 dst_cert_serial: [b'1'; 32].into(),
486 src_pc_cert: PcCert::PessoasFisicas,
487 src_cert_serial: [b'1'; 32].into(),
488 buffer_sym_key: [1; 256].into(),
489 buffer_hash: [1; 256].into(),
490 };
491
492 assert_eq!(sut.is_valid().unwrap_err(), "C06 inválido");
493 }
494
495 #[test]
496 fn value_invalid_sym_key_algo() {
497 let sut = Header {
498 len: HeaderLen::Default,
499 version: ProtocolVersion::Version3,
500 error: ErrorCode::NoError,
501 special_treatment: SpecialTreatment::Normal,
502 reserved: Reserved::NoValue,
503 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
504 sym_key_algo: SymmetricKeyAlgo::Unknown(0),
505 src_key_algo: AsymmetricKeyAlgo::RSA2048,
506 hash_algo: HashAlgo::SHA256,
507 dst_pc_cert: PcCert::PessoasFisicas,
508 dst_cert_serial: [b'1'; 32].into(),
509 src_pc_cert: PcCert::PessoasFisicas,
510 src_cert_serial: [b'1'; 32].into(),
511 buffer_sym_key: [1; 256].into(),
512 buffer_hash: [1; 256].into(),
513 };
514
515 assert_eq!(sut.is_valid().unwrap_err(), "C07 inválido");
516 }
517
518 #[test]
519 fn value_invalid_src_key_algo() {
520 let sut = Header {
521 len: HeaderLen::Default,
522 version: ProtocolVersion::Version3,
523 error: ErrorCode::NoError,
524 special_treatment: SpecialTreatment::Normal,
525 reserved: Reserved::NoValue,
526 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
527 sym_key_algo: SymmetricKeyAlgo::Aes,
528 src_key_algo: AsymmetricKeyAlgo::Unknown(0),
529 hash_algo: HashAlgo::SHA256,
530 dst_pc_cert: PcCert::PessoasFisicas,
531 dst_cert_serial: [b'1'; 32].into(),
532 src_pc_cert: PcCert::PessoasFisicas,
533 src_cert_serial: [b'1'; 32].into(),
534 buffer_sym_key: [1; 256].into(),
535 buffer_hash: [1; 256].into(),
536 };
537
538 assert_eq!(sut.is_valid().unwrap_err(), "C08 inválido");
539 }
540
541 #[test]
542 fn value_invalid_hash_algo() {
543 let sut = Header {
544 len: HeaderLen::Default,
545 version: ProtocolVersion::Version3,
546 error: ErrorCode::NoError,
547 special_treatment: SpecialTreatment::Normal,
548 reserved: Reserved::NoValue,
549 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
550 sym_key_algo: SymmetricKeyAlgo::Aes,
551 src_key_algo: AsymmetricKeyAlgo::RSA2048,
552 hash_algo: HashAlgo::Unknown(0),
553 dst_pc_cert: PcCert::PessoasFisicas,
554 dst_cert_serial: [b'1'; 32].into(),
555 src_pc_cert: PcCert::PessoasFisicas,
556 src_cert_serial: [b'1'; 32].into(),
557 buffer_sym_key: [1; 256].into(),
558 buffer_hash: [1; 256].into(),
559 };
560
561 assert_eq!(sut.is_valid().unwrap_err(), "C09 inválido");
562 }
563
564 #[test]
565 fn value_invalid_dst_pc_cert() {
566 let sut = Header {
567 len: HeaderLen::Default,
568 version: ProtocolVersion::Version3,
569 error: ErrorCode::NoError,
570 special_treatment: SpecialTreatment::Normal,
571 reserved: Reserved::NoValue,
572 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
573 sym_key_algo: SymmetricKeyAlgo::Aes,
574 src_key_algo: AsymmetricKeyAlgo::RSA2048,
575 hash_algo: HashAlgo::SHA256,
576 dst_pc_cert: PcCert::Unknown(0),
577 dst_cert_serial: [b'1'; 32].into(),
578 src_pc_cert: PcCert::PessoasFisicas,
579 src_cert_serial: [b'1'; 32].into(),
580 buffer_sym_key: [1; 256].into(),
581 buffer_hash: [1; 256].into(),
582 };
583
584 assert_eq!(sut.is_valid().unwrap_err(), "C10 inválido");
585 }
586
587 #[test]
588 fn value_invalid_dst_cert_serial() {
589 let sut = Header {
590 len: HeaderLen::Default,
591 version: ProtocolVersion::Version3,
592 error: ErrorCode::NoError,
593 special_treatment: SpecialTreatment::Normal,
594 reserved: Reserved::NoValue,
595 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
596 sym_key_algo: SymmetricKeyAlgo::Aes,
597 src_key_algo: AsymmetricKeyAlgo::RSA2048,
598 hash_algo: HashAlgo::SHA256,
599 dst_pc_cert: PcCert::PessoasFisicas,
600 dst_cert_serial: [0; 32].into(),
601 src_pc_cert: PcCert::PessoasFisicas,
602 src_cert_serial: [b'1'; 32].into(),
603 buffer_sym_key: [1; 256].into(),
604 buffer_hash: [1; 256].into(),
605 };
606
607 assert_eq!(sut.is_valid().unwrap_err(), "C11 inválido");
608 }
609
610 #[test]
611 fn value_invalid_src_pc_cert() {
612 let sut = Header {
613 len: HeaderLen::Default,
614 version: ProtocolVersion::Version3,
615 error: ErrorCode::NoError,
616 special_treatment: SpecialTreatment::Normal,
617 reserved: Reserved::NoValue,
618 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
619 sym_key_algo: SymmetricKeyAlgo::Aes,
620 src_key_algo: AsymmetricKeyAlgo::RSA2048,
621 hash_algo: HashAlgo::SHA256,
622 dst_pc_cert: PcCert::PessoasFisicas,
623 dst_cert_serial: [b'1'; 32].into(),
624 src_pc_cert: PcCert::Unknown(0),
625 src_cert_serial: [b'1'; 32].into(),
626 buffer_sym_key: [1; 256].into(),
627 buffer_hash: [1; 256].into(),
628 };
629
630 assert_eq!(sut.is_valid().unwrap_err(), "C12 inválido");
631 }
632
633 #[test]
634 fn value_invalid_src_cert_serial() {
635 let sut = Header {
636 len: HeaderLen::Default,
637 version: ProtocolVersion::Version3,
638 error: ErrorCode::NoError,
639 special_treatment: SpecialTreatment::Normal,
640 reserved: Reserved::NoValue,
641 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
642 sym_key_algo: SymmetricKeyAlgo::Aes,
643 src_key_algo: AsymmetricKeyAlgo::RSA2048,
644 hash_algo: HashAlgo::SHA256,
645 dst_pc_cert: PcCert::PessoasFisicas,
646 dst_cert_serial: [b'1'; 32].into(),
647 src_pc_cert: PcCert::PessoasFisicas,
648 src_cert_serial: [0; 32].into(),
649 buffer_sym_key: [1; 256].into(),
650 buffer_hash: [1; 256].into(),
651 };
652
653 assert_eq!(sut.is_valid().unwrap_err(), "C13 inválido");
654 }
655
656 #[test]
657 fn value_invalid_buffer_hash() {
658 let sut = Header {
659 len: HeaderLen::Default,
660 version: ProtocolVersion::Version3,
661 error: ErrorCode::NoError,
662 special_treatment: SpecialTreatment::Normal,
663 reserved: Reserved::NoValue,
664 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
665 sym_key_algo: SymmetricKeyAlgo::Aes,
666 src_key_algo: AsymmetricKeyAlgo::RSA2048,
667 hash_algo: HashAlgo::SHA256,
668 dst_pc_cert: PcCert::PessoasFisicas,
669 dst_cert_serial: [b'1'; 32].into(),
670 src_pc_cert: PcCert::PessoasFisicas,
671 src_cert_serial: [b'1'; 32].into(),
672 buffer_sym_key: [1; 256].into(),
673 buffer_hash: [0; 256].into(),
674 };
675
676 assert_eq!(sut.is_valid().unwrap_err(), "C15 inválido");
677 }
678
679 #[test]
680 fn value_invalid_all_possible_fields() {
681 let sut = Header {
682 len: HeaderLen::Unknown(0),
683 version: ProtocolVersion::Unknown(1),
684 error: ErrorCode::Unknown(15),
685 special_treatment: SpecialTreatment::Unknown(7),
686 reserved: Reserved::Unknown(1),
687 dst_key_algo: AsymmetricKeyAlgo::Unknown(0),
688 sym_key_algo: SymmetricKeyAlgo::Unknown(0),
689 src_key_algo: AsymmetricKeyAlgo::Unknown(0),
690 hash_algo: HashAlgo::Unknown(0),
691 dst_pc_cert: PcCert::Unknown(0),
692 dst_cert_serial: [0; 32].into(),
693 src_pc_cert: PcCert::Unknown(0),
694 src_cert_serial: [0; 32].into(),
695 buffer_sym_key: [0; 256].into(),
696 buffer_hash: [0; 256].into(),
697 };
698
699 assert_eq!(
700 sut.is_valid().unwrap_err(),
701 (1..=15)
702 .filter(|&i| i != 14)
703 .map(|i| format!("C{i:02} inválido"))
704 .collect::<Vec<_>>()
705 .join(", ")
706 );
707 }
708
709 #[test]
710 fn is_encrypted_content() {
711 let tests = [
712 (SpecialTreatment::NotCryptBroadcast, [1; 256], false),
713 (SpecialTreatment::NotCrypt, [1; 256], false),
714 (SpecialTreatment::NotCompressAndNotCrypt, [1; 256], false),
715 (SpecialTreatment::CompressWithoutCrypt, [1; 256], false),
716 (SpecialTreatment::Normal, [0; 256], false),
717 (SpecialTreatment::Normal, [1; 256], true),
718 ];
719 for (special_treatment, buffer_sym_key, is_encrypted) in tests {
720 let header = Header {
721 len: HeaderLen::Default,
722 version: ProtocolVersion::Version3,
723 error: ErrorCode::NoError,
724 special_treatment,
725 reserved: Reserved::NoValue,
726 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
727 sym_key_algo: SymmetricKeyAlgo::Aes,
728 src_key_algo: AsymmetricKeyAlgo::RSA2048,
729 hash_algo: HashAlgo::SHA256,
730 dst_pc_cert: PcCert::PessoasFisicas,
731 dst_cert_serial: [0; 32].into(),
732 src_pc_cert: PcCert::PessoasFisicas,
733 src_cert_serial: [0; 32].into(),
734 buffer_sym_key: buffer_sym_key.into(),
735 buffer_hash: [0; 256].into(),
736 };
737
738 assert_eq!(header.is_encrypted_content(), is_encrypted);
739 }
740 }
741
742 #[test]
743 fn is_compessed_content() {
744 let tests = [
745 (SpecialTreatment::Normal, false),
746 (SpecialTreatment::Compress, true),
747 (SpecialTreatment::CompressWithoutCrypt, true),
748 ];
749 for (special_treatment, is_compressed) in tests {
750 let header = Header {
751 len: HeaderLen::Default,
752 version: ProtocolVersion::Version3,
753 error: ErrorCode::NoError,
754 special_treatment,
755 reserved: Reserved::NoValue,
756 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
757 sym_key_algo: SymmetricKeyAlgo::Aes,
758 src_key_algo: AsymmetricKeyAlgo::RSA2048,
759 hash_algo: HashAlgo::SHA256,
760 dst_pc_cert: PcCert::PessoasFisicas,
761 dst_cert_serial: [0; 32].into(),
762 src_pc_cert: PcCert::PessoasFisicas,
763 src_cert_serial: [0; 32].into(),
764 buffer_sym_key: [0; 256].into(),
765 buffer_hash: [0; 256].into(),
766 };
767
768 assert_eq!(header.is_compressed_content(), is_compressed);
769 }
770 }
771
772 #[test]
773 fn convert_to_bytes_and_read() {
774 let a = Header {
775 len: HeaderLen::Default,
776 version: ProtocolVersion::Plain,
777 error: ErrorCode::NoError,
778 special_treatment: SpecialTreatment::Normal,
779 reserved: Reserved::NoValue,
780 dst_key_algo: AsymmetricKeyAlgo::Unknown(0),
781 sym_key_algo: SymmetricKeyAlgo::Unknown(0),
782 src_key_algo: AsymmetricKeyAlgo::Unknown(0),
783 hash_algo: HashAlgo::Unknown(0),
784 dst_pc_cert: PcCert::Unknown(0),
785 dst_cert_serial: [0; 32].into(),
786 src_pc_cert: PcCert::Unknown(0),
787 src_cert_serial: [0; 32].into(),
788 buffer_sym_key: [0; 256].into(),
789 buffer_hash: [0; 256].into(),
790 };
791 let bytes = a.to_bytes();
792
793 assert_eq!(bytes.len(), HeaderLen::Default.value() as usize);
794
795 let mut file = Cursor::new(bytes);
796 let b = Header::read_from_file(&mut file).unwrap();
797
798 assert_eq!(a, b);
799 }
800
801 #[test]
802 fn write_read_header_version3() {
803 let a = Header {
804 len: HeaderLen::Default,
805 version: ProtocolVersion::Version3,
806 error: ErrorCode::NoError,
807 special_treatment: SpecialTreatment::Normal,
808 reserved: Reserved::NoValue,
809 dst_key_algo: AsymmetricKeyAlgo::RSA2048,
810 sym_key_algo: SymmetricKeyAlgo::Aes,
811 src_key_algo: AsymmetricKeyAlgo::RSA2048,
812 hash_algo: HashAlgo::SHA256,
813 dst_pc_cert: PcCert::PessoasFisicas,
814 dst_cert_serial: [0; 32].into(),
815 src_pc_cert: PcCert::PessoasFisicas,
816 src_cert_serial: [0; 32].into(),
817 buffer_sym_key: [0; 256].into(),
818 buffer_hash: [0; 256].into(),
819 };
820 let bytes = a.to_bytes();
821
822 assert_eq!(bytes.len(), HeaderLen::Default.value() as usize);
823
824 let mut file = Cursor::new(bytes);
825 let b = Header::read_from_file(&mut file).unwrap();
826
827 assert_eq!(a, b);
828 }
829}