Skip to main content

rsfn_file/header/fields/
error_code.rs

1use std::fmt;
2
3/// Código de erro.
4#[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}