1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Errors that occur during sessions

use crate::{
    connector::{ConnectionError, ConnectionErrorKind},
    error::{Error, HsmErrorKind},
    serialization::SerializationError,
    session::{SessionError, SessionErrorKind},
};
use std::{error::Error as StdError, io};

/// Session errors
pub type ClientError = Error<ClientErrorKind>;

/// Session error kinds
#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
pub enum ClientErrorKind {
    /// Couldn't authenticate session
    #[fail(display = "authentication failed")]
    AuthFail,

    /// Session is closed
    #[fail(display = "session closed")]
    ClosedSessionError,

    /// Errors with the connection to the HSM
    #[fail(display = "connection error")]
    ConnectionError {
        /// Connection error kind
        kind: ConnectionErrorKind,
    },

    /// Couldn't create session
    #[fail(display = "couldn't create session")]
    CreateFailed,

    /// Errors originating in the HSM device
    #[fail(display = "HSM error: {}", kind)]
    DeviceError {
        /// HSM error kind
        kind: HsmErrorKind,
    },

    /// Protocol error occurred
    #[fail(display = "protocol error")]
    ProtocolError,

    /// Error response from HSM we can't further specify
    #[fail(display = "HSM error")]
    ResponseError,
}

// TODO: capture causes?
impl From<ConnectionError> for ClientError {
    fn from(err: ConnectionError) -> Self {
        let kind = ClientErrorKind::ConnectionError { kind: err.kind() };
        err!(kind, err.description())
    }
}

// TODO: capture causes?
impl From<SessionError> for ClientError {
    fn from(err: SessionError) -> Self {
        let kind = match err.kind() {
            SessionErrorKind::AuthFail => ClientErrorKind::AuthFail,
            SessionErrorKind::ClosedSessionError => ClientErrorKind::ClosedSessionError,
            SessionErrorKind::CreateFailed => ClientErrorKind::CreateFailed,
            SessionErrorKind::DeviceError { kind } => ClientErrorKind::DeviceError { kind },
            SessionErrorKind::ProtocolError
            | SessionErrorKind::CommandLimitExceeded
            | SessionErrorKind::MismatchError
            | SessionErrorKind::VerifyFailed => ClientErrorKind::ProtocolError,
            SessionErrorKind::ResponseError => ClientErrorKind::ResponseError,
        };

        err!(kind, err.description())
    }
}

impl From<io::Error> for ClientError {
    fn from(err: io::Error) -> Self {
        err!(ClientErrorKind::ProtocolError, err.description())
    }
}

// TODO: capture causes?
impl From<SerializationError> for ClientError {
    fn from(err: SerializationError) -> Self {
        err!(ClientErrorKind::ProtocolError, err.description())
    }
}