diff options
| -rw-r--r-- | src/auth.rs | 15 | ||||
| -rw-r--r-- | src/device.rs | 36 | ||||
| -rw-r--r-- | src/otp.rs | 17 | ||||
| -rw-r--r-- | src/pws.rs | 26 | ||||
| -rw-r--r-- | src/util.rs | 6 | 
5 files changed, 33 insertions, 67 deletions
| diff --git a/src/auth.rs b/src/auth.rs index 62b851f..8460fae 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -2,10 +2,9 @@ use config::{Config, RawConfig};  use device::{Device, DeviceWrapper, Pro, Storage};  use nitrokey_sys;  use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData}; -use std::ffi::CString;  use std::ops::Deref;  use std::os::raw::c_int; -use util::{generate_password, get_command_result, result_from_string, CommandError}; +use util::{generate_password, get_command_result, get_cstring, result_from_string, CommandError};  static TEMPORARY_PASSWORD_LENGTH: usize = 25; @@ -150,13 +149,11 @@ where          Ok(pw) => pw,          Err(_) => return Err((device, CommandError::RngError)),      }; -    let password = CString::new(password); -    if password.is_err() { -        return Err((device, CommandError::InvalidString)); -    } - -    let pw = password.unwrap(); -    let password_ptr = pw.as_ptr(); +    let password = match get_cstring(password) { +        Ok(password) => password, +        Err(err) => return Err((device, err)), +    }; +    let password_ptr = password.as_ptr();      let temp_password_ptr = temp_password.as_ptr() as *const i8;      return match callback(password_ptr, temp_password_ptr) {          0 => Ok(A::new(device, temp_password)), diff --git a/src/device.rs b/src/device.rs index c4e83a9..63a5654 100644 --- a/src/device.rs +++ b/src/device.rs @@ -4,8 +4,7 @@ use libc;  use nitrokey_sys;  use otp::GenerateOtp;  use pws::GetPasswordSafe; -use std::ffi::CString; -use util::{get_command_result, get_last_error, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError};  /// Available Nitrokey models.  #[derive(Debug, PartialEq)] @@ -312,13 +311,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword      fn change_admin_pin(&self, current: &str, new: &str) -> Result<(), CommandError> { -        let current_string = CString::new(current); -        let new_string = CString::new(new); -        if current_string.is_err() || new_string.is_err() { -            return Err(CommandError::InvalidString); -        } -        let current_string = current_string.unwrap(); -        let new_string = new_string.unwrap(); +        let current_string = get_cstring(current)?; +        let new_string = get_cstring(new)?;          unsafe {              get_command_result(nitrokey_sys::NK_change_admin_PIN(                  current_string.as_ptr(), @@ -353,13 +347,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword      fn change_user_pin(&self, current: &str, new: &str) -> Result<(), CommandError> { -        let current_string = CString::new(current); -        let new_string = CString::new(new); -        if current_string.is_err() || new_string.is_err() { -            return Err(CommandError::InvalidString); -        } -        let current_string = current_string.unwrap(); -        let new_string = new_string.unwrap(); +        let current_string = get_cstring(current)?; +        let new_string = get_cstring(new)?;          unsafe {              get_command_result(nitrokey_sys::NK_change_user_PIN(                  current_string.as_ptr(), @@ -394,13 +383,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword      fn unlock_user_pin(&self, admin_pin: &str, user_pin: &str) -> Result<(), CommandError> { -        let admin_pin_string = CString::new(admin_pin); -        let user_pin_string = CString::new(user_pin); -        if admin_pin_string.is_err() || user_pin_string.is_err() { -            return Err(CommandError::InvalidString); -        } -        let admin_pin_string = admin_pin_string.unwrap(); -        let user_pin_string = user_pin_string.unwrap(); +        let admin_pin_string = get_cstring(admin_pin)?; +        let user_pin_string = get_cstring(user_pin)?;          unsafe {              get_command_result(nitrokey_sys::NK_unlock_user_password(                  admin_pin_string.as_ptr(), @@ -562,11 +546,7 @@ impl Storage {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword      pub fn enable_encrypted_volume(&self, user_pin: &str) -> Result<(), CommandError> { -        let user_pin = CString::new(user_pin); -        if user_pin.is_err() { -            return Err(CommandError::InvalidString); -        } -        let user_pin = user_pin.unwrap(); +        let user_pin = get_cstring(user_pin)?;          unsafe { get_command_result(nitrokey_sys::NK_unlock_encrypted_volume(user_pin.as_ptr())) }      } @@ -1,6 +1,6 @@  use nitrokey_sys;  use std::ffi::CString; -use util::{get_command_result, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, result_from_string, CommandError};  /// Modes for one-time password generation.  #[derive(Debug, PartialEq)] @@ -389,22 +389,19 @@ impl OtpSlotData {  impl RawOtpSlotData {      pub fn new(data: OtpSlotData) -> Result<RawOtpSlotData, CommandError> { -        let name = CString::new(data.name); -        let secret = CString::new(data.secret); +        let name = get_cstring(data.name)?; +        let secret = get_cstring(data.secret)?;          let use_token_id = data.token_id.is_some(); -        let token_id = CString::new(data.token_id.unwrap_or_else(String::new)); -        if name.is_err() || secret.is_err() || token_id.is_err() { -            return Err(CommandError::InvalidString); -        } +        let token_id = get_cstring(data.token_id.unwrap_or_else(String::new))?;          Ok(RawOtpSlotData {              number: data.number, -            name: name.unwrap(), -            secret: secret.unwrap(), +            name, +            secret,              mode: data.mode,              use_enter: data.use_enter,              use_token_id, -            token_id: token_id.unwrap(), +            token_id,          })      }  } @@ -1,8 +1,7 @@  use device::{Device, DeviceWrapper, Pro, Storage};  use libc;  use nitrokey_sys; -use std::ffi::CString; -use util::{get_command_result, get_last_error, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError};  /// The number of slots in a [`PasswordSafe`][].  /// @@ -42,7 +41,7 @@ pub const SLOT_COUNT: u8 = 16;  /// let device = nitrokey::connect()?;  /// let pws = device.get_password_safe("123456")?;  /// use_password_safe(&pws); -/// device.lock(); +/// device.lock()?;  /// #     Ok(())  /// # }  /// ``` @@ -87,7 +86,7 @@ pub trait GetPasswordSafe {      /// match device.get_password_safe("123456") {      ///     Ok(pws) => {      ///         use_password_safe(&pws); -    ///         device.lock(); +    ///         device.lock()?;      ///     },      ///     Err(err) => println!("Could not open the password safe: {:?}", err),      /// }; @@ -106,11 +105,7 @@ fn get_password_safe<'a>(      device: &'a Device,      user_pin: &str,  ) -> Result<PasswordSafe<'a>, CommandError> { -    let user_pin_string = CString::new(user_pin); -    if user_pin_string.is_err() { -        return Err(CommandError::InvalidString); -    } -    let user_pin_string = user_pin_string.unwrap(); +    let user_pin_string = get_cstring(user_pin)?;      let result = unsafe {          get_command_result(nitrokey_sys::NK_enable_password_safe(              user_pin_string.as_ptr(), @@ -287,16 +282,9 @@ impl<'a> PasswordSafe<'a> {          login: &str,          password: &str,      ) -> Result<(), CommandError> { -        let name_string = CString::new(name); -        let login_string = CString::new(login); -        let password_string = CString::new(password); -        if name_string.is_err() || login_string.is_err() || password_string.is_err() { -            return Err(CommandError::InvalidString); -        } - -        let name_string = name_string.unwrap(); -        let login_string = login_string.unwrap(); -        let password_string = password_string.unwrap(); +        let name_string = get_cstring(name)?; +        let login_string = get_cstring(login)?; +        let password_string = get_cstring(password)?;          unsafe {              get_command_result(nitrokey_sys::NK_write_password_safe_slot(                  slot, diff --git a/src/util.rs b/src/util.rs index 1608952..75de799 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,7 +2,7 @@ use libc::{c_void, free};  use nitrokey_sys;  use rand::{OsRng, Rng};  use std; -use std::ffi::CStr; +use std::ffi::{CStr, CString};  use std::os::raw::{c_char, c_int};  /// Error types returned by Nitrokey device or by the library. @@ -110,6 +110,10 @@ pub fn generate_password(length: usize) -> std::io::Result<Vec<u8>> {      return Ok(data);  } +pub fn get_cstring<T: Into<Vec<u8>>>(s: T) -> Result<CString, CommandError> { +    CString::new(s).or(Err(CommandError::InvalidString)) +} +  impl From<c_int> for CommandError {      fn from(value: c_int) -> Self {          match value { | 
