1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum ErrorCode {
6 NoError,
7 InvalidHeaderLen,
8 InvalidVersion,
9 InvalidDstKeyAlgo,
10 InvalidSymmetricAlgo,
11 InvalidSrcKeyAlgo,
12 InvalidHashAlgo,
13 InvalidDstPC,
14 InvalidDstSerial,
15 InvalidSrcPC,
16 InvalidSrcSerial,
17 InvalidSign,
18 IncorrectSrcCert,
19 ErrorOnExtractSymmetricKey,
20 ErrorOnSymmetricAlgo,
21 InvalidMsgLen,
22 DisabledCert,
23 OverdueOrRevokedCert,
24 ErrorOnSoftware,
25 InvalidSpecificUse,
26 NotEnabledCert,
27 NotSecurityError,
28 Unknown(u8),
29}
30
31impl From<[u8; 1]> for ErrorCode {
32 fn from(value: [u8; 1]) -> Self {
33 value[0].into()
34 }
35}
36
37impl From<u8> for ErrorCode {
38 fn from(value: u8) -> Self {
39 match value {
40 0x00 => Self::NoError,
41 0x01 => Self::InvalidHeaderLen,
42 0x02 => Self::InvalidVersion,
43 0x03 => Self::InvalidDstKeyAlgo,
44 0x04 => Self::InvalidSymmetricAlgo,
45 0x05 => Self::InvalidSrcKeyAlgo,
46 0x06 => Self::InvalidHashAlgo,
47 0x07 => Self::InvalidDstPC,
48 0x08 => Self::InvalidDstSerial,
49 0x09 => Self::InvalidSrcPC,
50 0x0a => Self::InvalidSrcSerial,
51 0x0b => Self::InvalidSign,
52 0x0c => Self::IncorrectSrcCert,
53 0x0d => Self::ErrorOnExtractSymmetricKey,
54 0x0e => Self::ErrorOnSymmetricAlgo,
55 0x0f => Self::InvalidMsgLen,
56 0x10 => Self::DisabledCert,
57 0x11 => Self::OverdueOrRevokedCert,
58 0x12 => Self::ErrorOnSoftware,
59 0x13 => Self::InvalidSpecificUse,
60 0x14 => Self::NotEnabledCert,
61 0xff => Self::NotSecurityError,
62 n => Self::Unknown(n),
63 }
64 }
65}
66
67impl ErrorCode {
68 pub fn value(&self) -> u8 {
69 match self {
70 Self::NoError => 0x00,
71 Self::InvalidHeaderLen => 0x01,
72 Self::InvalidVersion => 0x02,
73 Self::InvalidDstKeyAlgo => 0x03,
74 Self::InvalidSymmetricAlgo => 0x04,
75 Self::InvalidSrcKeyAlgo => 0x05,
76 Self::InvalidHashAlgo => 0x06,
77 Self::InvalidDstPC => 0x07,
78 Self::InvalidDstSerial => 0x08,
79 Self::InvalidSrcPC => 0x09,
80 Self::InvalidSrcSerial => 0x0a,
81 Self::InvalidSign => 0x0b,
82 Self::IncorrectSrcCert => 0x0c,
83 Self::ErrorOnExtractSymmetricKey => 0x0d,
84 Self::ErrorOnSymmetricAlgo => 0x0e,
85 Self::InvalidMsgLen => 0x0f,
86 Self::DisabledCert => 0x10,
87 Self::OverdueOrRevokedCert => 0x11,
88 Self::ErrorOnSoftware => 0x12,
89 Self::InvalidSpecificUse => 0x13,
90 Self::NotEnabledCert => 0x14,
91 Self::NotSecurityError => 0xff,
92 Self::Unknown(n) => *n,
93 }
94 }
95
96 pub fn describe_value(&self) -> String {
97 match self {
98 Self::NoError => "Sem erros".to_string(),
99 Self::InvalidHeaderLen => "Tamanho do cabeçalho de segurança zerado ou incompatível com os possíveis".to_string(),
100 Self::InvalidVersion => "Versão inválida ou incompatível com o tamanho e/ou conexão".to_string(),
101 Self::InvalidDstKeyAlgo => "Algoritmo da chave do destinatário inválido ou divergente do certificado".to_string(),
102 Self::InvalidSymmetricAlgo => "Algoritmo simétrico inválido".to_string(),
103 Self::InvalidSrcKeyAlgo => "Algoritmo da chave do certificado digital da Instituição inválido ou divergente do certificado".to_string(),
104 Self::InvalidHashAlgo => "Algoritmo de \"hash\" não corresponde ao indicado ou é inválido".to_string(),
105 Self::InvalidDstPC => "Código da PC do certificado do destinatário inválido".to_string(),
106 Self::InvalidDstSerial => "Número de série do certificado do destinatário inválido (não foi emitido pela AC)".to_string(),
107 Self::InvalidSrcPC => "Código da PC do certificado inválido".to_string(),
108 Self::InvalidSrcSerial => "Número de série do certificado digital da Instituição inválido (não foi emitido pela AC)".to_string(),
109 Self::InvalidSign => "Criptograma de autenticação da Mensagem inválido ou com erro".to_string(),
110 Self::IncorrectSrcCert => "Certificado não é do emissor da mensagem (titular da fila no MQ)".to_string(),
111 Self::ErrorOnExtractSymmetricKey => "Erro na extração da chave simétrica".to_string(),
112 Self::ErrorOnSymmetricAlgo => "Erro gerado pelo algoritmo simétrico".to_string(),
113 Self::InvalidMsgLen => "Tamanho da mensagem não múltiplo de 8 bytes (específico para a segunda versão do Protocolo de Segurança)".to_string(),
114 Self::DisabledCert => "Certificado usado não está ativado".to_string(),
115 Self::OverdueOrRevokedCert => "Certificado usado está vencido ou revogado pela Instituição".to_string(),
116 Self::ErrorOnSoftware => "Erro genérico de software da camada de segurança".to_string(),
117 Self::InvalidSpecificUse => "Indicação de uso específico inválida ou incompatível".to_string(),
118 Self::NotEnabledCert => "Certificado inválido (Usar certificado \"a ativar\" na GEN0006)".to_string(),
119 Self::NotSecurityError => "Erro fora do escopo de segurança".to_string(),
120 Self::Unknown(_) => "DESCONHECIDO".to_string(),
121 }
122 }
123
124 pub fn is_valid(&self) -> bool {
125 !matches!(self, Self::Unknown(_))
126 }
127
128 pub fn to_bytes(&self) -> [u8; 1] {
129 [self.value()]
130 }
131}
132
133impl fmt::Display for ErrorCode {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 let value = self.value();
136 let desc = self.describe_value();
137 write!(f, "0x{value:02x} [{desc}]")
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn value_no_error() {
147 let sut: ErrorCode = [0x00].into();
148
149 assert_eq!(sut, ErrorCode::NoError);
150 assert_eq!(sut, 0x00.into());
151 assert_eq!(sut.value(), 0x00);
152 assert_eq!(sut.describe_value(), "Sem erros");
153 assert!(sut.is_valid());
154 assert_eq!(sut.to_bytes(), [0x00]);
155 assert_eq!(sut.to_string(), "0x00 [Sem erros]");
156 }
157
158 #[test]
159 fn value_invalid_header_len() {
160 let sut: ErrorCode = [0x01].into();
161
162 assert_eq!(sut, ErrorCode::InvalidHeaderLen);
163 assert_eq!(sut, 0x01.into());
164 assert_eq!(sut.value(), 0x01);
165 assert_eq!(
166 sut.describe_value(),
167 "Tamanho do cabeçalho de segurança zerado ou incompatível com os possíveis"
168 );
169 assert!(sut.is_valid());
170 assert_eq!(sut.to_bytes(), [0x01]);
171 assert_eq!(
172 sut.to_string(),
173 "0x01 [Tamanho do cabeçalho de segurança zerado ou incompatível com os possíveis]"
174 );
175 }
176
177 #[test]
178 fn value_invalid_version() {
179 let sut: ErrorCode = [0x02].into();
180
181 assert_eq!(sut, ErrorCode::InvalidVersion);
182 assert_eq!(sut, 0x02.into());
183 assert_eq!(sut.value(), 0x02);
184 assert_eq!(
185 sut.describe_value(),
186 "Versão inválida ou incompatível com o tamanho e/ou conexão"
187 );
188 assert!(sut.is_valid());
189 assert_eq!(sut.to_bytes(), [0x02]);
190 assert_eq!(
191 sut.to_string(),
192 "0x02 [Versão inválida ou incompatível com o tamanho e/ou conexão]"
193 );
194 }
195
196 #[test]
197 fn value_invalid_dst_key_algo() {
198 let sut: ErrorCode = [0x03].into();
199
200 assert_eq!(sut, ErrorCode::InvalidDstKeyAlgo);
201 assert_eq!(sut, 0x03.into());
202 assert_eq!(sut.value(), 0x03);
203 assert_eq!(
204 sut.describe_value(),
205 "Algoritmo da chave do destinatário inválido ou divergente do certificado"
206 );
207 assert!(sut.is_valid());
208 assert_eq!(sut.to_bytes(), [0x03]);
209 assert_eq!(
210 sut.to_string(),
211 "0x03 [Algoritmo da chave do destinatário inválido ou divergente do certificado]"
212 );
213 }
214
215 #[test]
216 fn value_invalid_symmetric_algo() {
217 let sut: ErrorCode = [0x04].into();
218
219 assert_eq!(sut, ErrorCode::InvalidSymmetricAlgo);
220 assert_eq!(sut, 0x04.into());
221 assert_eq!(sut.value(), 0x04);
222 assert_eq!(sut.describe_value(), "Algoritmo simétrico inválido");
223 assert!(sut.is_valid());
224 assert_eq!(sut.to_bytes(), [0x04]);
225 assert_eq!(sut.to_string(), "0x04 [Algoritmo simétrico inválido]");
226 }
227
228 #[test]
229 fn value_invalid_src_key_algo() {
230 let sut: ErrorCode = [0x05].into();
231
232 assert_eq!(sut, ErrorCode::InvalidSrcKeyAlgo);
233 assert_eq!(sut, 0x05.into());
234 assert_eq!(sut.value(), 0x05);
235 assert_eq!(
236 sut.describe_value(),
237 "Algoritmo da chave do certificado digital da Instituição inválido ou divergente do certificado"
238 );
239 assert!(sut.is_valid());
240 assert_eq!(sut.to_bytes(), [0x05]);
241 assert_eq!(
242 sut.to_string(),
243 "0x05 [Algoritmo da chave do certificado digital da Instituição inválido ou divergente do certificado]"
244 );
245 }
246
247 #[test]
248 fn value_invalid_hash_algo() {
249 let sut: ErrorCode = [0x06].into();
250
251 assert_eq!(sut, ErrorCode::InvalidHashAlgo);
252 assert_eq!(sut, 0x06.into());
253 assert_eq!(sut.value(), 0x06);
254 assert_eq!(
255 sut.describe_value(),
256 "Algoritmo de \"hash\" não corresponde ao indicado ou é inválido"
257 );
258 assert!(sut.is_valid());
259 assert_eq!(sut.to_bytes(), [0x06]);
260 assert_eq!(
261 sut.to_string(),
262 "0x06 [Algoritmo de \"hash\" não corresponde ao indicado ou é inválido]"
263 );
264 }
265
266 #[test]
267 fn value_invalid_dst_pc() {
268 let sut: ErrorCode = [0x07].into();
269
270 assert_eq!(sut, ErrorCode::InvalidDstPC);
271 assert_eq!(sut, 0x07.into());
272 assert_eq!(sut.value(), 0x07);
273 assert_eq!(
274 sut.describe_value(),
275 "Código da PC do certificado do destinatário inválido"
276 );
277 assert!(sut.is_valid());
278 assert_eq!(sut.to_bytes(), [0x07]);
279 assert_eq!(
280 sut.to_string(),
281 "0x07 [Código da PC do certificado do destinatário inválido]"
282 );
283 }
284
285 #[test]
286 fn value_invalid_dst_serial() {
287 let sut: ErrorCode = [0x08].into();
288
289 assert_eq!(sut, ErrorCode::InvalidDstSerial);
290 assert_eq!(sut, 0x08.into());
291 assert_eq!(sut.value(), 0x08);
292 assert_eq!(
293 sut.describe_value(),
294 "Número de série do certificado do destinatário inválido (não foi emitido pela AC)"
295 );
296 assert!(sut.is_valid());
297 assert_eq!(sut.to_bytes(), [0x08]);
298 assert_eq!(
299 sut.to_string(),
300 "0x08 [Número de série do certificado do destinatário inválido (não foi emitido pela AC)]"
301 );
302 }
303
304 #[test]
305 fn value_invalid_src_pc() {
306 let sut: ErrorCode = [0x09].into();
307
308 assert_eq!(sut, ErrorCode::InvalidSrcPC);
309 assert_eq!(sut, 0x09.into());
310 assert_eq!(sut.value(), 0x09);
311 assert_eq!(sut.describe_value(), "Código da PC do certificado inválido");
312 assert!(sut.is_valid());
313 assert_eq!(sut.to_bytes(), [0x09]);
314 assert_eq!(
315 sut.to_string(),
316 "0x09 [Código da PC do certificado inválido]"
317 );
318 }
319
320 #[test]
321 fn value_invalid_src_serial() {
322 let sut: ErrorCode = [0x0a].into();
323
324 assert_eq!(sut, ErrorCode::InvalidSrcSerial);
325 assert_eq!(sut, 0x0a.into());
326 assert_eq!(sut.value(), 0x0a);
327 assert_eq!(
328 sut.describe_value(),
329 "Número de série do certificado digital da Instituição inválido (não foi emitido pela AC)"
330 );
331 assert!(sut.is_valid());
332 assert_eq!(sut.to_bytes(), [0x0a]);
333 assert_eq!(
334 sut.to_string(),
335 "0x0a [Número de série do certificado digital da Instituição inválido (não foi emitido pela AC)]"
336 );
337 }
338
339 #[test]
340 fn value_invalid_sign() {
341 let sut: ErrorCode = [0x0b].into();
342
343 assert_eq!(sut, ErrorCode::InvalidSign);
344 assert_eq!(sut, 0x0b.into());
345 assert_eq!(sut.value(), 0x0b);
346 assert_eq!(
347 sut.describe_value(),
348 "Criptograma de autenticação da Mensagem inválido ou com erro"
349 );
350 assert!(sut.is_valid());
351 assert_eq!(sut.to_bytes(), [0x0b]);
352 assert_eq!(
353 sut.to_string(),
354 "0x0b [Criptograma de autenticação da Mensagem inválido ou com erro]"
355 );
356 }
357
358 #[test]
359 fn value_incorrect_src_cert() {
360 let sut: ErrorCode = [0x0c].into();
361
362 assert_eq!(sut, ErrorCode::IncorrectSrcCert);
363 assert_eq!(sut, 0x0c.into());
364 assert_eq!(sut.value(), 0x0c);
365 assert_eq!(
366 sut.describe_value(),
367 "Certificado não é do emissor da mensagem (titular da fila no MQ)"
368 );
369 assert!(sut.is_valid());
370 assert_eq!(sut.to_bytes(), [0x0c]);
371 assert_eq!(
372 sut.to_string(),
373 "0x0c [Certificado não é do emissor da mensagem (titular da fila no MQ)]"
374 );
375 }
376
377 #[test]
378 fn value_error_on_extract_symmetric_key() {
379 let sut: ErrorCode = [0x0d].into();
380
381 assert_eq!(sut, ErrorCode::ErrorOnExtractSymmetricKey);
382 assert_eq!(sut, 0x0d.into());
383 assert_eq!(sut.value(), 0x0d);
384 assert_eq!(sut.describe_value(), "Erro na extração da chave simétrica");
385 assert!(sut.is_valid());
386 assert_eq!(sut.to_bytes(), [0x0d]);
387 assert_eq!(
388 sut.to_string(),
389 "0x0d [Erro na extração da chave simétrica]"
390 );
391 }
392
393 #[test]
394 fn value_error_on_symmetric_algo() {
395 let sut: ErrorCode = [0x0e].into();
396
397 assert_eq!(sut, ErrorCode::ErrorOnSymmetricAlgo);
398 assert_eq!(sut, 0x0e.into());
399 assert_eq!(sut.value(), 0x0e);
400 assert_eq!(sut.describe_value(), "Erro gerado pelo algoritmo simétrico");
401 assert!(sut.is_valid());
402 assert_eq!(sut.to_bytes(), [0x0e]);
403 assert_eq!(
404 sut.to_string(),
405 "0x0e [Erro gerado pelo algoritmo simétrico]"
406 );
407 }
408
409 #[test]
410 fn value_invalid_msg_len() {
411 let sut: ErrorCode = [0x0f].into();
412
413 assert_eq!(sut, ErrorCode::InvalidMsgLen);
414 assert_eq!(sut, 0x0f.into());
415 assert_eq!(sut.value(), 0x0f);
416 assert_eq!(
417 sut.describe_value(),
418 "Tamanho da mensagem não múltiplo de 8 bytes (específico para a segunda versão do Protocolo de Segurança)"
419 );
420 assert!(sut.is_valid());
421 assert_eq!(sut.to_bytes(), [0x0f]);
422 assert_eq!(
423 sut.to_string(),
424 "0x0f [Tamanho da mensagem não múltiplo de 8 bytes (específico para a segunda versão do Protocolo de Segurança)]"
425 );
426 }
427
428 #[test]
429 fn value_disabled_cert() {
430 let sut: ErrorCode = [0x10].into();
431
432 assert_eq!(sut, ErrorCode::DisabledCert);
433 assert_eq!(sut, 0x10.into());
434 assert_eq!(sut.value(), 0x10);
435 assert_eq!(sut.describe_value(), "Certificado usado não está ativado");
436 assert!(sut.is_valid());
437 assert_eq!(sut.to_bytes(), [0x10]);
438 assert_eq!(sut.to_string(), "0x10 [Certificado usado não está ativado]");
439 }
440
441 #[test]
442 fn value_overdue_or_revoked_cert() {
443 let sut: ErrorCode = [0x11].into();
444
445 assert_eq!(sut, ErrorCode::OverdueOrRevokedCert);
446 assert_eq!(sut, 0x11.into());
447 assert_eq!(sut.value(), 0x11);
448 assert_eq!(
449 sut.describe_value(),
450 "Certificado usado está vencido ou revogado pela Instituição"
451 );
452 assert!(sut.is_valid());
453 assert_eq!(sut.to_bytes(), [0x11]);
454 assert_eq!(
455 sut.to_string(),
456 "0x11 [Certificado usado está vencido ou revogado pela Instituição]"
457 );
458 }
459
460 #[test]
461 fn value_error_on_software() {
462 let sut: ErrorCode = [0x12].into();
463
464 assert_eq!(sut, ErrorCode::ErrorOnSoftware);
465 assert_eq!(sut, 0x12.into());
466 assert_eq!(sut.value(), 0x12);
467 assert_eq!(
468 sut.describe_value(),
469 "Erro genérico de software da camada de segurança"
470 );
471 assert!(sut.is_valid());
472 assert_eq!(sut.to_bytes(), [0x12]);
473 assert_eq!(
474 sut.to_string(),
475 "0x12 [Erro genérico de software da camada de segurança]"
476 );
477 }
478
479 #[test]
480 fn value_invalid_specific_use() {
481 let sut: ErrorCode = [0x13].into();
482
483 assert_eq!(sut, ErrorCode::InvalidSpecificUse);
484 assert_eq!(sut, 0x13.into());
485 assert_eq!(sut.value(), 0x13);
486 assert_eq!(
487 sut.describe_value(),
488 "Indicação de uso específico inválida ou incompatível"
489 );
490 assert!(sut.is_valid());
491 assert_eq!(sut.to_bytes(), [0x13]);
492 assert_eq!(
493 sut.to_string(),
494 "0x13 [Indicação de uso específico inválida ou incompatível]"
495 );
496 }
497
498 #[test]
499 fn value_not_enabled_cert() {
500 let sut: ErrorCode = [0x14].into();
501
502 assert_eq!(sut, ErrorCode::NotEnabledCert);
503 assert_eq!(sut, 0x14.into());
504 assert_eq!(sut.value(), 0x14);
505 assert_eq!(
506 sut.describe_value(),
507 "Certificado inválido (Usar certificado \"a ativar\" na GEN0006)"
508 );
509 assert!(sut.is_valid());
510 assert_eq!(sut.to_bytes(), [0x14]);
511 assert_eq!(
512 sut.to_string(),
513 "0x14 [Certificado inválido (Usar certificado \"a ativar\" na GEN0006)]"
514 );
515 }
516
517 #[test]
518 fn value_not_security_error() {
519 let sut: ErrorCode = [0xff].into();
520
521 assert_eq!(sut, ErrorCode::NotSecurityError);
522 assert_eq!(sut, 0xff.into());
523 assert_eq!(sut.value(), 0xff);
524 assert_eq!(sut.describe_value(), "Erro fora do escopo de segurança");
525 assert!(sut.is_valid());
526 assert_eq!(sut.to_bytes(), [0xff]);
527 assert_eq!(sut.to_string(), "0xff [Erro fora do escopo de segurança]");
528 }
529
530 #[test]
531 fn value_unknown() {
532 let sut: ErrorCode = [0x15].into();
533
534 assert_eq!(sut, ErrorCode::Unknown(0x15));
535 assert_eq!(sut, 0x15.into());
536 assert_eq!(sut.value(), 0x15);
537 assert_eq!(sut.describe_value(), "DESCONHECIDO");
538 assert!(!sut.is_valid());
539 assert_eq!(sut.to_bytes(), [0x15]);
540 assert_eq!(sut.to_string(), "0x15 [DESCONHECIDO]");
541 }
542}