aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/auth.rs4
-rw-r--r--src/error.rs61
-rw-r--r--src/util.rs2
-rw-r--r--tests/pws.rs2
5 files changed, 40 insertions, 32 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a78724..def5273 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,8 @@
- Implement `std::error::Error` for `CommandError`.
- Add the `Error` enum and the `Result` typedef.
- Return `Error` instead of `CommandError` in all public functions.
- - Move the `CommandError::RngError` variant to `Error::RandError`.
+ - Move the `CommandError::RngError` variant to `Error::RandError` and the
+ `CommandError::Unknown` variant to `Error::Unknown`.
# v0.3.4 (2019-01-20)
- Fix authentication methods that assumed that `char` is signed.
diff --git a/src/auth.rs b/src/auth.rs
index 509d3aa..e05f6b3 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -6,7 +6,7 @@ use nitrokey_sys;
use crate::config::{Config, RawConfig};
use crate::device::{Device, DeviceWrapper, Pro, Storage};
-use crate::error::{CommandError, Error};
+use crate::error::Error;
use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData};
use crate::util::{generate_password, get_command_result, get_cstring, result_from_string};
@@ -161,7 +161,7 @@ where
let temp_password_ptr = temp_password.as_ptr() as *const c_char;
return match callback(password_ptr, temp_password_ptr) {
0 => Ok(A::new(device, temp_password)),
- rv => Err((device, CommandError::from(rv).into())),
+ rv => Err((device, Error::from(rv))),
};
}
diff --git a/src/error.rs b/src/error.rs
index dfe1680..c5a975e 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -13,6 +13,18 @@ pub enum Error {
CommunicationError(CommunicationError),
/// An error that occured during random number generation.
RandError(rand_core::Error),
+ /// An unknown error returned by libnitrokey.
+ Unknown(i64),
+}
+
+impl From<raw::c_int> for Error {
+ fn from(code: raw::c_int) -> Self {
+ if let Some(err) = CommandError::try_from(code) {
+ Error::CommandError(err)
+ } else {
+ Error::Unknown(code.into())
+ }
+ }
}
impl From<CommandError> for Error {
@@ -33,6 +45,7 @@ impl error::Error for Error {
Error::CommandError(ref err) => Some(err),
Error::CommunicationError(_) => None,
Error::RandError(ref err) => Some(err),
+ Error::Unknown(_) => None,
}
}
}
@@ -43,6 +56,7 @@ impl fmt::Display for Error {
Error::CommandError(ref err) => write!(f, "Command error: {}", err),
Error::CommunicationError(_) => write!(f, "Placeholder"),
Error::RandError(ref err) => write!(f, "RNG error: {}", err),
+ Error::Unknown(ref err) => write!(f, "Unknown error: {}", err),
}
}
}
@@ -74,8 +88,6 @@ pub enum CommandError {
UnknownCommand,
/// AES decryption failed.
AesDecryptionFailed,
- /// An unknown error occurred.
- Unknown(i64),
/// An unspecified error occurred.
Undefined,
/// You passed a string containing a null byte.
@@ -98,6 +110,26 @@ pub enum CommunicationError {
}
impl CommandError {
+ fn try_from(value: raw::c_int) -> Option<Self> {
+ match value {
+ 1 => Some(CommandError::WrongCrc),
+ 2 => Some(CommandError::WrongSlot),
+ 3 => Some(CommandError::SlotNotProgrammed),
+ 4 => Some(CommandError::WrongPassword),
+ 5 => Some(CommandError::NotAuthorized),
+ 6 => Some(CommandError::Timestamp),
+ 7 => Some(CommandError::NoName),
+ 8 => Some(CommandError::NotSupported),
+ 9 => Some(CommandError::UnknownCommand),
+ 10 => Some(CommandError::AesDecryptionFailed),
+ 200 => Some(CommandError::StringTooLong),
+ 201 => Some(CommandError::InvalidSlot),
+ 202 => Some(CommandError::InvalidHexString),
+ 203 => Some(CommandError::TargetBufferTooSmall),
+ _ => None,
+ }
+ }
+
fn as_str(&self) -> borrow::Cow<'static, str> {
match *self {
CommandError::WrongCrc => {
@@ -116,9 +148,6 @@ impl CommandError {
CommandError::NotSupported => "This command is not supported by this device".into(),
CommandError::UnknownCommand => "This command is unknown".into(),
CommandError::AesDecryptionFailed => "AES decryption failed".into(),
- CommandError::Unknown(x) => {
- borrow::Cow::from(format!("An unknown error occurred ({})", x))
- }
CommandError::Undefined => "An unspecified error occurred".into(),
CommandError::InvalidString => "You passed a string containing a null byte".into(),
CommandError::StringTooLong => "The supplied string is too long".into(),
@@ -138,25 +167,3 @@ impl fmt::Display for CommandError {
write!(f, "{}", self.as_str())
}
}
-
-impl From<raw::c_int> for CommandError {
- fn from(value: raw::c_int) -> Self {
- match value {
- 1 => CommandError::WrongCrc,
- 2 => CommandError::WrongSlot,
- 3 => CommandError::SlotNotProgrammed,
- 4 => CommandError::WrongPassword,
- 5 => CommandError::NotAuthorized,
- 6 => CommandError::Timestamp,
- 7 => CommandError::NoName,
- 8 => CommandError::NotSupported,
- 9 => CommandError::UnknownCommand,
- 10 => CommandError::AesDecryptionFailed,
- 200 => CommandError::StringTooLong,
- 201 => CommandError::InvalidSlot,
- 202 => CommandError::InvalidHexString,
- 203 => CommandError::TargetBufferTooSmall,
- x => CommandError::Unknown(x.into()),
- }
- }
-}
diff --git a/src/util.rs b/src/util.rs
index 06bb854..3b9904f 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -54,7 +54,7 @@ pub fn result_from_string(ptr: *const c_char) -> Result<String, Error> {
pub fn get_command_result(value: c_int) -> Result<(), Error> {
match value {
0 => Ok(()),
- other => Err(CommandError::from(other).into()),
+ other => Err(Error::from(other)),
}
}
diff --git a/tests/pws.rs b/tests/pws.rs
index f12af48..a4647bd 100644
--- a/tests/pws.rs
+++ b/tests/pws.rs
@@ -21,7 +21,7 @@ fn get_slot_name_direct(slot: u8) -> Result<String, Error> {
let error = unsafe { nitrokey_sys::NK_get_last_command_status() } as c_int;
match error {
0 => Ok(s),
- other => Err(CommandError::from(other).into()),
+ other => Err(Error::from(other)),
}
}
false => Ok(s),