use crate::response;
use failure::Fail;
pub type Error = crate::Error<ErrorKind>;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
pub enum ErrorKind {
#[fail(display = "unknown HSM error code: 0x{:02x}", code)]
Unknown {
code: u8,
},
#[fail(display = "invalid command")]
InvalidCommand,
#[fail(display = "invalid data")]
InvalidData,
#[fail(display = "invalid session")]
InvalidSession,
#[fail(display = "authentication failed")]
AuthenticationFailed,
#[fail(display = "sessions full (max 16)")]
SessionsFull,
#[fail(display = "session failed")]
SessionFailed,
#[fail(display = "storage failed")]
StorageFailed,
#[fail(display = "incorrect length")]
WrongLength,
#[fail(display = "invalid permissions")]
InsufficientPermissions,
#[fail(display = "audit log full")]
LogFull,
#[fail(display = "object not found")]
ObjectNotFound,
#[fail(display = "invalid ID")]
InvalidId,
#[fail(display = "invalid OTP")]
InvalidOtp,
#[fail(display = "demo mode")]
DemoMode,
#[fail(display = "command unexecuted")]
CommandUnexecuted,
#[fail(display = "generic error")]
GenericError,
#[fail(display = "object already exists")]
ObjectExists,
#[fail(display = "SSH CA constraint violation")]
SshCaConstraintViolation,
}
impl ErrorKind {
pub fn from_u8(tag: u8) -> ErrorKind {
match tag {
0x01 => ErrorKind::InvalidCommand,
0x02 => ErrorKind::InvalidData,
0x03 => ErrorKind::InvalidSession,
0x04 => ErrorKind::AuthenticationFailed,
0x05 => ErrorKind::SessionsFull,
0x06 => ErrorKind::SessionFailed,
0x07 => ErrorKind::StorageFailed,
0x08 => ErrorKind::WrongLength,
0x09 => ErrorKind::InsufficientPermissions,
0x0a => ErrorKind::LogFull,
0x0b => ErrorKind::ObjectNotFound,
0x0c => ErrorKind::InvalidId,
0x0d => ErrorKind::InvalidOtp,
0x0e => ErrorKind::DemoMode,
0x0f => ErrorKind::CommandUnexecuted,
0x10 => ErrorKind::GenericError,
0x11 => ErrorKind::ObjectExists,
code => ErrorKind::Unknown { code },
}
}
pub fn to_u8(self) -> u8 {
match self {
ErrorKind::Unknown { code } => code,
ErrorKind::InvalidCommand => 0x01,
ErrorKind::InvalidData => 0x02,
ErrorKind::InvalidSession => 0x03,
ErrorKind::AuthenticationFailed => 0x04,
ErrorKind::SessionsFull => 0x05,
ErrorKind::SessionFailed => 0x06,
ErrorKind::StorageFailed => 0x07,
ErrorKind::WrongLength => 0x08,
ErrorKind::InsufficientPermissions => 0x09,
ErrorKind::LogFull => 0x0a,
ErrorKind::ObjectNotFound => 0x0b,
ErrorKind::InvalidId => 0x0c,
ErrorKind::InvalidOtp => 0x0d,
ErrorKind::DemoMode => 0x0e,
ErrorKind::CommandUnexecuted => 0x0f,
ErrorKind::GenericError => 0x10,
ErrorKind::ObjectExists => 0x11,
ErrorKind::SshCaConstraintViolation => {
panic!("don't know device code for YHR_DEVICE_SSH_CA_CONSTRAINT_VIOLATION")
}
}
}
pub fn from_response_code(code: response::Code) -> Option<ErrorKind> {
Some(match code {
response::Code::DeviceInvalidCommand => ErrorKind::InvalidCommand,
response::Code::DeviceInvalidData => ErrorKind::InvalidData,
response::Code::DeviceInvalidSession => ErrorKind::InvalidSession,
response::Code::DeviceAuthenticationFailed => ErrorKind::AuthenticationFailed,
response::Code::DeviceSessionsFull => ErrorKind::SessionsFull,
response::Code::DeviceSessionFailed => ErrorKind::SessionFailed,
response::Code::DeviceStorageFailed => ErrorKind::StorageFailed,
response::Code::DeviceWrongLength => ErrorKind::WrongLength,
response::Code::DeviceInsufficientPermissions => ErrorKind::InsufficientPermissions,
response::Code::DeviceLogFull => ErrorKind::LogFull,
response::Code::DeviceObjectNotFound => ErrorKind::ObjectNotFound,
response::Code::DeviceInvalidId => ErrorKind::InvalidId,
response::Code::DeviceInvalidOtp => ErrorKind::InvalidOtp,
response::Code::DeviceDemoMode => ErrorKind::DemoMode,
response::Code::DeviceCommandUnexecuted => ErrorKind::CommandUnexecuted,
response::Code::GenericError => ErrorKind::GenericError,
response::Code::DeviceObjectExists => ErrorKind::ObjectExists,
response::Code::DeviceSshCaConstraintViolation => ErrorKind::SshCaConstraintViolation,
_ => return None,
})
}
pub(crate) fn from_response_message(response: &response::Message) -> Option<ErrorKind> {
if response.is_err() && response.data.len() == 1 {
Some(ErrorKind::from_u8(response.data[0]))
} else {
None
}
}
}