From d0f63513bb935d3d931c86a1ab7b68d6ed44bf27 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 01:53:08 +0000 Subject: Move util::CommandError to the new error module This prepares the refactoring of util::CommandError into multiple enums. --- src/util.rs | 113 +----------------------------------------------------------- 1 file changed, 1 insertion(+), 112 deletions(-) (limited to 'src/util.rs') diff --git a/src/util.rs b/src/util.rs index 567c478..88a381c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,53 +1,11 @@ -use std::borrow; use std::ffi::{CStr, CString}; -use std::fmt; use std::os::raw::{c_char, c_int}; use libc::{c_void, free}; use rand_core::RngCore; use rand_os::OsRng; -/// Error types returned by Nitrokey device or by the library. -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum CommandError { - /// A packet with a wrong checksum has been sent or received. - WrongCrc, - /// A command tried to access an OTP slot that does not exist. - WrongSlot, - /// A command tried to generate an OTP on a slot that is not configured. - SlotNotProgrammed, - /// The provided password is wrong. - WrongPassword, - /// You are not authorized for this command or provided a wrong temporary - /// password. - NotAuthorized, - /// An error occurred when getting or setting the time. - Timestamp, - /// You did not provide a name for the OTP slot. - NoName, - /// This command is not supported by this device. - NotSupported, - /// This command is unknown. - UnknownCommand, - /// AES decryption failed. - AesDecryptionFailed, - /// An unknown error occurred. - Unknown(i64), - /// An unspecified error occurred. - Undefined, - /// You passed a string containing a null byte. - InvalidString, - /// A supplied string exceeded a length limit. - StringTooLong, - /// You passed an invalid slot. - InvalidSlot, - /// The supplied string was not in hexadecimal format. - InvalidHexString, - /// The target buffer was smaller than the source. - TargetBufferTooSmall, - /// An error occurred during random number generation. - RngError, -} +use crate::error::CommandError; /// Log level for libnitrokey. /// @@ -123,75 +81,6 @@ pub fn get_cstring>>(s: T) -> Result { CString::new(s).or(Err(CommandError::InvalidString)) } -impl CommandError { - fn as_str(&self) -> borrow::Cow<'static, str> { - match *self { - CommandError::WrongCrc => { - "A packet with a wrong checksum has been sent or received".into() - } - CommandError::WrongSlot => "The given OTP slot does not exist".into(), - CommandError::SlotNotProgrammed => "The given OTP slot is not programmed".into(), - CommandError::WrongPassword => "The given password is wrong".into(), - CommandError::NotAuthorized => { - "You are not authorized for this command or provided a wrong temporary \ - password" - .into() - } - CommandError::Timestamp => "An error occurred when getting or setting the time".into(), - CommandError::NoName => "You did not provide a name for the OTP slot".into(), - 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(), - CommandError::InvalidSlot => "The given slot is invalid".into(), - CommandError::InvalidHexString => { - "The supplied string is not in hexadecimal format".into() - } - CommandError::TargetBufferTooSmall => "The target buffer is too small".into(), - CommandError::RngError => "An error occurred during random number generation".into(), - } - } -} - -impl fmt::Display for CommandError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.as_str()) - } -} - -impl From for CommandError { - fn from(value: 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()), - } - } -} - -impl From for CommandError { - fn from(_error: rand_core::Error) -> Self { - CommandError::RngError - } -} - impl Into for LogLevel { fn into(self) -> i32 { match self { -- cgit v1.2.1 From 94390aadc8a3997d379bf5e4c0bc00c2a9669a34 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 20 Jan 2019 20:58:18 +0000 Subject: Return Error instead of CommandError This patch changes all public functions to return the Error enum instead of the CommandError enum. This breaks the tests which will be fixed with the next patch. This patch also adds a placeholder variant Error::CommandError and a placeholder enum CommandError to make the transition to a new nitrokey-test version easier. --- src/util.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/util.rs') diff --git a/src/util.rs b/src/util.rs index 88a381c..8855275 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,7 @@ use libc::{c_void, free}; use rand_core::RngCore; use rand_os::OsRng; -use crate::error::CommandError; +use crate::error::{CommandError, Error}; /// Log level for libnitrokey. /// @@ -34,9 +34,9 @@ pub fn owned_str_from_ptr(ptr: *const c_char) -> String { } } -pub fn result_from_string(ptr: *const c_char) -> Result { +pub fn result_from_string(ptr: *const c_char) -> Result { if ptr.is_null() { - return Err(CommandError::Undefined); + return Err(CommandError::Undefined.into()); } unsafe { let s = owned_str_from_ptr(ptr); @@ -51,34 +51,34 @@ pub fn result_from_string(ptr: *const c_char) -> Result { } } -pub fn get_command_result(value: c_int) -> Result<(), CommandError> { +pub fn get_command_result(value: c_int) -> Result<(), Error> { match value { 0 => Ok(()), - other => Err(CommandError::from(other)), + other => Err(CommandError::from(other).into()), } } -pub fn get_last_result() -> Result<(), CommandError> { +pub fn get_last_result() -> Result<(), Error> { let value = unsafe { nitrokey_sys::NK_get_last_command_status() } as c_int; get_command_result(value) } -pub fn get_last_error() -> CommandError { +pub fn get_last_error() -> Error { return match get_last_result() { - Ok(()) => CommandError::Undefined, + Ok(()) => CommandError::Undefined.into(), Err(err) => err, }; } -pub fn generate_password(length: usize) -> Result, CommandError> { - let mut rng = OsRng::new()?; +pub fn generate_password(length: usize) -> Result, Error> { + let mut rng = OsRng::new().map_err(CommandError::from)?; let mut data = vec![0u8; length]; rng.fill_bytes(&mut data[..]); Ok(data) } -pub fn get_cstring>>(s: T) -> Result { - CString::new(s).or(Err(CommandError::InvalidString)) +pub fn get_cstring>>(s: T) -> Result { + CString::new(s).or(Err(CommandError::InvalidString.into())) } impl Into for LogLevel { -- cgit v1.2.1 From cafc3a6f8cfb9f82343c1d3fe843c7f8d7ef1136 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 20 Jan 2019 21:05:58 +0000 Subject: Refactor CommandError::RngError into Error::RandError We reserve CommandError for errors returned by the Nitrokey device. Errors during random number generation should have their own type. --- src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/util.rs') diff --git a/src/util.rs b/src/util.rs index 8855275..06bb854 100644 --- a/src/util.rs +++ b/src/util.rs @@ -71,7 +71,7 @@ pub fn get_last_error() -> Error { } pub fn generate_password(length: usize) -> Result, Error> { - let mut rng = OsRng::new().map_err(CommandError::from)?; + let mut rng = OsRng::new()?; let mut data = vec![0u8; length]; rng.fill_bytes(&mut data[..]); Ok(data) -- cgit v1.2.1 From 944e1fa0d51e547dde2a9368d2b8431b109f63c4 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 04:15:31 +0000 Subject: Move the CommandError::Unknown to Error An error code can not only indiciate a command error, but also a library or device communication error. Therefore, the variant for an unknown error code should be placed in the top-level Error enum instead of the CommandError enum. --- src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/util.rs') 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 { 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)), } } -- cgit v1.2.1 From 5e258d26b55af6bed7c316b1c7ac12e20946702d Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 12:47:52 +0000 Subject: Refactor library errors into LibraryError enum Previously, library errors were part of the CommandError enum. As command errors and library errors are two different error types, they should be split into two enums. --- src/util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/util.rs') diff --git a/src/util.rs b/src/util.rs index 3b9904f..2738fce 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,7 @@ use libc::{c_void, free}; use rand_core::RngCore; use rand_os::OsRng; -use crate::error::{CommandError, Error}; +use crate::error::{CommandError, Error, LibraryError}; /// Log level for libnitrokey. /// @@ -78,7 +78,7 @@ pub fn generate_password(length: usize) -> Result, Error> { } pub fn get_cstring>>(s: T) -> Result { - CString::new(s).or(Err(CommandError::InvalidString.into())) + CString::new(s).or(Err(LibraryError::InvalidString.into())) } impl Into for LogLevel { -- cgit v1.2.1 From c191e875492ff8aeab1b4493b87486cd265f0edc Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 13:38:28 +0000 Subject: Introduce the Error::UnexpectedError variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UnexpectedError variant is used when a libnitrokey function returns a value that violates the function’s contract, for example if a function returns a null pointer although it guarantees to never return null. Previously, we returned a CommandError::Unspecified in these cases. --- src/util.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/util.rs') diff --git a/src/util.rs b/src/util.rs index 2738fce..79b8c34 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,7 @@ use libc::{c_void, free}; use rand_core::RngCore; use rand_os::OsRng; -use crate::error::{CommandError, Error, LibraryError}; +use crate::error::{Error, LibraryError}; /// Log level for libnitrokey. /// @@ -36,7 +36,7 @@ pub fn owned_str_from_ptr(ptr: *const c_char) -> String { pub fn result_from_string(ptr: *const c_char) -> Result { if ptr.is_null() { - return Err(CommandError::Undefined.into()); + return Err(Error::UnexpectedError); } unsafe { let s = owned_str_from_ptr(ptr); @@ -65,7 +65,7 @@ pub fn get_last_result() -> Result<(), Error> { pub fn get_last_error() -> Error { return match get_last_result() { - Ok(()) => CommandError::Undefined.into(), + Ok(()) => Error::UnexpectedError, Err(err) => err, }; } -- cgit v1.2.1