1use std::error::Error;
2use std::fmt::{Display, Formatter};
3use std::num::ParseIntError;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum PayloadError {
8 InvalidCipherBlockLength,
10
11 InvalidTotalPayloadLength,
13
14 KeyTooLong { max: usize, actual: usize },
16
17 RandomSeedTooShort { required: usize, actual: usize },
19
20 PayloadTooShort { minimum: usize, actual: usize },
22
23 PayloadTooShortForKey { required: usize, actual: usize },
26}
27
28impl Display for PayloadError {
29 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Self::InvalidCipherBlockLength => write!(
32 f,
33 "ERROR TR-31 PAYLOAD: Cipher block length must be greater than zero"
34 ),
35
36 Self::InvalidTotalPayloadLength => {
37 write!(f, "ERROR TR-31 PAYLOAD: Invalid total payload length")
38 }
39
40 Self::KeyTooLong { .. } => write!(
41 f,
42 "ERROR TR-31 PAYLOAD: Key length exceeds maximum representable length"
43 ),
44
45 Self::RandomSeedTooShort { .. } => write!(
46 f,
47 "ERROR TR-31 PAYLOAD: The provided random seed is too short for the padding requirement"
48 ),
49
50 Self::PayloadTooShort { .. } => write!(
51 f,
52 "ERROR TR-31 PAYLOAD: Payload too short to contain valid key length"
53 ),
54
55 Self::PayloadTooShortForKey { .. } => write!(
56 f,
57 "ERROR TR-31 PAYLOAD: Payload too short for the specified key length"
58 ),
59 }
60 }
61}
62
63impl Error for PayloadError {}
64
65#[derive(Debug)]
68pub enum OptBlockError {
69 StringTooShort { minimum: usize, actual: usize },
72
73 NonAsciiInput,
76
77 ExtendedLengthStringTooShort { minimum: usize, actual: usize },
79
80 StringTooShortForLength { required: usize, actual: usize },
82
83 Uninitialized { length: usize },
85
86 InvalidId(String),
88
89 IdNotSet,
91
92 NonAsciiData(String),
94
95 BlockTooLong { maximum: usize, actual: usize },
97
98 InvalidLengthFieldWidth { value: String, expected: usize },
101
102 InvalidLengthFieldHex {
104 value: String,
105 source: ParseIntError,
106 },
107
108 LengthFieldTooSmall { minimum: usize, actual: usize },
110
111 InvalidExtendedLengthField(String),
113
114 InvalidLengthOfLengthField(String),
117
118 InvalidExtendedLengthHex {
120 value: String,
121 source: ParseIntError,
122 },
123
124 ExtendedLengthTooSmall { value: String },
127}
128
129impl Display for OptBlockError {
130 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
131 match self {
132 Self::StringTooShort { .. } => write!(
133 f,
134 "ERROR TR-31 OPT BLOCK: String too short. Expected at least 4 characters"
135 ),
136
137 Self::NonAsciiInput => write!(
138 f,
139 "ERROR TR-31 OPT BLOCK: Input contains non ASCII characters"
140 ),
141
142 Self::ExtendedLengthStringTooShort { .. } => write!(
143 f,
144 "ERROR TR-31 OPT BLOCK: String containing extended length too short. Expected at least 256 characters"
145 ),
146
147 Self::StringTooShortForLength { required, .. } => write!(
148 f,
149 "ERROR TR-31 OPT BLOCK: String too short for given length. Expected at least {} characters.",
150 required
151 ),
152
153 Self::Uninitialized { .. } => write!(
154 f,
155 "ERROR TR-31 OPT BLOCK: Length must be greater than 4, indicating uninitialized OptBlock"
156 ),
157
158 Self::InvalidId(id) => write!(f, "ERROR TR-31 OPT BLOCK: Invalid ID: {}", id),
159
160 Self::IdNotSet => write!(
161 f,
162 "ERROR TR-31 OPT BLOCK: ID not set (has to be set before data)"
163 ),
164
165 Self::NonAsciiData(data) => write!(
166 f,
167 "ERROR TR-31 OPT BLOCK: Data has non ASCII characters: {}",
168 data
169 ),
170
171 Self::BlockTooLong { actual, .. } => write!(
172 f,
173 "ERROR TR-31 OPT BLOCK: Block size '{}' is too long (must be max. 65535)",
174 actual
175 ),
176
177 Self::InvalidLengthFieldWidth { value, .. } => write!(
178 f,
179 "ERROR TR-31 OPT BLOCK: Invalid length field: Expected a string with 2 characters, found '{}'",
180 value
181 ),
182
183 Self::InvalidLengthFieldHex { value, .. } => write!(
184 f,
185 "ERROR TR-31 OPT BLOCK: Invalid length field: '{}' is not a valid hexadecimal number",
186 value
187 ),
188
189 Self::LengthFieldTooSmall { actual, .. } => write!(
190 f,
191 "ERROR TR-31 OPT BLOCK: Invalid length field: value {} is too small (must be at least 4)",
192 actual
193 ),
194
195 Self::InvalidExtendedLengthField(value) => write!(
196 f,
197 "ERROR TR-31 OPT BLOCK: Invalid extended length field: {}",
198 value
199 ),
200
201 Self::InvalidLengthOfLengthField(value) => write!(
202 f,
203 "ERROR TR-31 OPT BLOCK: Invalid length of length field: {}",
204 value
205 ),
206
207 Self::InvalidExtendedLengthHex { source, .. } => {
208 Display::fmt(source, f)
211 }
212
213 Self::ExtendedLengthTooSmall { value } => write!(
214 f,
215 "ERROR TR-31 OPT BLOCK: Extended length is not greater than 255: {}",
216 value
217 ),
218 }
219 }
220}
221
222impl Error for OptBlockError {
223 fn source(&self) -> Option<&(dyn Error + 'static)> {
224 match self {
225 Self::InvalidLengthFieldHex { source, .. }
226 | Self::InvalidExtendedLengthHex { source, .. } => Some(source),
227
228 _ => None,
229 }
230 }
231}
232
233#[derive(Debug)]
236pub enum KeyBlockHeaderError {
237 InvalidDataLength {
238 minimum: usize,
239 actual: usize,
240 },
241
242 NonAsciiHeader,
243
244 InvalidKeyBlockLength,
245
246 InvalidNumberOfOptionalBlocks,
247
248 InvalidHeaderLengthWithOptionalBlocks {
249 minimum: usize,
250 actual: usize,
251 },
252
253 InvalidVersionId(String),
254
255 InvalidKeyUsage(String),
256
257 InvalidAlgorithm(String),
258
259 InvalidModeOfUse(String),
260
261 InvalidKeyVersionNumberLength(String),
262
263 InvalidKeyVersionNumberEncoding(String),
264
265 InvalidExportability(String),
266
267 TooManyOptionalBlocks {
268 maximum: u8,
269 actual: u8,
270 },
271
272 InvalidReservedField(String),
273
274 ExportFailedEmptyFields,
275
276 OptionalBlock(OptBlockError),
278
279 FailedToParseOptionalBlocks(OptBlockError),
281}
282
283impl Display for KeyBlockHeaderError {
284 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
285 match self {
286 Self::InvalidDataLength { .. } => write!(f, "ERROR TR-31 HEADER: Invalid data length"),
287
288 Self::NonAsciiHeader => write!(
289 f,
290 "ERROR TR-31 HEADER: Header contains non ASCII characters"
291 ),
292
293 Self::InvalidKeyBlockLength => {
294 write!(f, "ERROR TR-31 HEADER: Invalid key block length")
295 }
296
297 Self::InvalidNumberOfOptionalBlocks => {
298 write!(f, "ERROR TR-31 HEADER: Invalid number of optional blocks")
299 }
300
301 Self::InvalidHeaderLengthWithOptionalBlocks { .. } => write!(
302 f,
303 "ERROR TR-31 HEADER: Invalid header length containing optional blocks"
304 ),
305
306 Self::InvalidVersionId(value) => {
307 write!(f, "ERROR TR-31 HEADER: Invalid version ID: {}", value)
308 }
309
310 Self::InvalidKeyUsage(value) => {
311 write!(f, "ERROR TR-31 HEADER: Invalid key usage: {}", value)
312 }
313
314 Self::InvalidAlgorithm(value) => {
315 write!(f, "ERROR TR-31 HEADER: Invalid algorithm: {}", value)
316 }
317
318 Self::InvalidModeOfUse(value) => {
319 write!(f, "ERROR TR-31 HEADER: Invalid mode of use: {}", value)
320 }
321
322 Self::InvalidKeyVersionNumberLength(value) => write!(
323 f,
324 "ERROR TR-31 HEADER: Key version number must consist of 2 ASCII characters: {}",
325 value
326 ),
327
328 Self::InvalidKeyVersionNumberEncoding(value) => write!(
329 f,
330 "ERROR TR-31 HEADER: Key version number must consist of ASCII characters: {}",
331 value
332 ),
333
334 Self::InvalidExportability(value) => {
335 write!(f, "ERROR TR-31 HEADER: Invalid exportability: {}", value)
336 }
337
338 Self::TooManyOptionalBlocks { .. } => write!(
339 f,
340 "ERROR TR-31 HEADER: Number of opt blocks value is too large"
341 ),
342
343 Self::InvalidReservedField(value) => write!(
344 f,
345 "ERROR TR-31 HEADER: Invalid value for reserved field: {}",
346 value
347 ),
348
349 Self::ExportFailedEmptyFields => write!(
350 f,
351 "ERROR TR-31 HEADER: Export failed due to empty field(s) or zero length"
352 ),
353
354 Self::OptionalBlock(error) => Display::fmt(error, f),
355
356 Self::FailedToParseOptionalBlocks(error) => write!(
357 f,
358 "ERROR TR-31 HEADER: Failed to parse optional blocks: {}",
359 error
360 ),
361 }
362 }
363}
364
365impl Error for KeyBlockHeaderError {
366 fn source(&self) -> Option<&(dyn Error + 'static)> {
367 match self {
368 Self::OptionalBlock(error) | Self::FailedToParseOptionalBlocks(error) => Some(error),
369
370 _ => None,
371 }
372 }
373}
374
375impl From<OptBlockError> for KeyBlockHeaderError {
376 fn from(error: OptBlockError) -> Self {
377 Self::OptionalBlock(error)
378 }
379}
380
381#[derive(Debug)]
383pub enum Tr31Error {
384 UnsupportedVersion(String),
387
388 TotalBlockLengthNotMultiple {
390 block_length: usize,
391 actual: usize,
392 },
393
394 KeyBlockLengthMismatch {
397 expected: usize,
398 actual: usize,
399 },
400
401 KeyBlockBelowMinimum {
403 minimum: usize,
404 actual: usize,
405 },
406
407 InvalidMacLength {
409 expected: usize,
410 actual: usize,
411 },
412
413 MacVerificationFailed,
415
416 Header(KeyBlockHeaderError),
418
419 Payload(PayloadError),
421
422 Hex(hex::FromHexError),
424
425 KeyBlockLengthTooLarge {
426 maximum: usize,
427 actual: usize,
428 },
429}
430
431impl Display for Tr31Error {
432 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
433 match self {
434 Self::UnsupportedVersion(version) => write!(
435 f,
436 "ERROR TR-31: Key block version not supported by implementation: {}",
437 version
438 ),
439
440 Self::TotalBlockLengthNotMultiple { block_length, .. } => write!(
441 f,
442 "ERROR TR-31: Total block length is not a multiple of block length: {}",
443 block_length
444 ),
445
446 Self::KeyBlockLengthMismatch { .. } => write!(
447 f,
448 "ERROR TR-31: Key block length does not match its length in the header"
449 ),
450
451 Self::KeyBlockBelowMinimum { .. } => write!(
452 f,
453 "ERROR TR-31: Key block length is below minimum required length"
454 ),
455
456 Self::InvalidMacLength { expected, actual } => write!(
457 f,
458 "ERROR TR-31: Invalid MAC length: expected {} bytes, found {}",
459 expected, actual
460 ),
461
462 Self::MacVerificationFailed => write!(f, "ERROR TR-31: MAC check failed"),
463
464 Self::Header(error) => Display::fmt(error, f),
465
466 Self::Payload(error) => Display::fmt(error, f),
467
468 Self::Hex(error) => Display::fmt(error, f),
469
470 Self::KeyBlockLengthTooLarge { maximum, actual } => write!(
471 f,
472 "ERROR TR-31: Key block length exceeds maximum: maximum {}, actual {}",
473 maximum, actual
474 ),
475 }
476 }
477}
478
479impl Error for Tr31Error {
480 fn source(&self) -> Option<&(dyn Error + 'static)> {
481 match self {
482 Self::Header(error) => Some(error),
483 Self::Payload(error) => Some(error),
484 Self::Hex(error) => Some(error),
485
486 _ => None,
487 }
488 }
489}
490
491impl From<KeyBlockHeaderError> for Tr31Error {
492 fn from(error: KeyBlockHeaderError) -> Self {
493 Self::Header(error)
494 }
495}
496
497impl From<PayloadError> for Tr31Error {
498 fn from(error: PayloadError) -> Self {
499 Self::Payload(error)
500 }
501}
502
503impl From<hex::FromHexError> for Tr31Error {
504 fn from(error: hex::FromHexError) -> Self {
505 Self::Hex(error)
506 }
507}
508
509#[derive(Debug)]
512pub enum Tr31CryptoError<E> {
513 Tr31(Tr31Error),
515
516 Crypto(E),
518}
519
520impl<E> Display for Tr31CryptoError<E>
521where
522 E: Display,
523{
524 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
525 match self {
526 Self::Tr31(error) => Display::fmt(error, f),
527
528 Self::Crypto(error) => Display::fmt(error, f),
529 }
530 }
531}
532
533impl<E> Error for Tr31CryptoError<E>
534where
535 E: Error + 'static,
536{
537 fn source(&self) -> Option<&(dyn Error + 'static)> {
538 match self {
539 Self::Tr31(error) => Some(error),
540 Self::Crypto(error) => Some(error),
541 }
542 }
543}
544
545impl<E> From<Tr31Error> for Tr31CryptoError<E> {
546 fn from(error: Tr31Error) -> Self {
547 Self::Tr31(error)
548 }
549}
550
551impl<E> From<KeyBlockHeaderError> for Tr31CryptoError<E> {
552 fn from(error: KeyBlockHeaderError) -> Self {
553 Self::Tr31(Tr31Error::Header(error))
554 }
555}
556
557impl<E> From<PayloadError> for Tr31CryptoError<E> {
558 fn from(error: PayloadError) -> Self {
559 Self::Tr31(Tr31Error::Payload(error))
560 }
561}
562
563impl<E> From<hex::FromHexError> for Tr31CryptoError<E> {
564 fn from(error: hex::FromHexError) -> Self {
565 Self::Tr31(Tr31Error::Hex(error))
566 }
567}