From c1f48ce6c614586042db8891d2eebf19d2212ce4 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Wed, 29 Jan 2020 13:52:19 +0100 Subject: Use NK_get_status to implement Device::get_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libnitrokey’s NK_read_config function returns a pointer to an array that has been allocated using new[]. We would have to delete this pointer using delete[], but we only have access to free. Therefore this patch modifies the Device::get_config function to call NK_get_status instead of NK_read_config. This also makes the code more safe as we get the data as a struct instead of an array. It does not add much overhead as NK_read_config also executes the GET_STATUS command on the Nitrokey device. --- CHANGELOG.md | 2 ++ src/config.rs | 11 ----------- src/device/mod.rs | 23 ++++++++++++----------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5bb7cb..c94e170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ SPDX-License-Identifier: CC0-1.0 _>` to `Result`. - Change the type of the field `DeviceInfo.serial_number` from `Option` to `Option`. +- Use `NK_get_status` instead of `NK_read_config` to implement the + `Device::get_config` function. # v0.5.2 (2020-01-28) - Use `CString` to store the temporary password instead of `Vec`. diff --git a/src/config.rs b/src/config.rs index 9b9de3c..120a51b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -94,17 +94,6 @@ impl From<&nitrokey_sys::NK_status> for RawConfig { } } -impl From<[u8; 5]> for RawConfig { - fn from(data: [u8; 5]) -> Self { - RawConfig { - numlock: data[0], - capslock: data[1], - scrollock: data[2], - user_password: data[3] != 0, - } - } -} - impl Into for RawConfig { fn into(self) -> Config { Config { diff --git a/src/device/mod.rs b/src/device/mod.rs index 403bb1f..e9ca0dc 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -9,7 +9,6 @@ use std::convert::{TryFrom, TryInto}; use std::ffi; use std::fmt; -use libc; use nitrokey_sys; use crate::auth::Authenticate; @@ -18,8 +17,7 @@ use crate::error::{CommunicationError, Error}; use crate::otp::GenerateOtp; use crate::pws::GetPasswordSafe; use crate::util::{ - get_command_result, get_cstring, get_last_error, owned_str_from_ptr, result_from_string, - result_or_error, + get_command_result, get_cstring, owned_str_from_ptr, result_from_string, result_or_error, }; pub use pro::Pro; @@ -386,14 +384,17 @@ pub trait Device<'a>: Authenticate<'a> + GetPasswordSafe<'a> + GenerateOtp + fmt /// # } /// ``` fn get_config(&self) -> Result { - let config_ptr = unsafe { nitrokey_sys::NK_read_config() }; - if config_ptr.is_null() { - return Err(get_last_error()); - } - let config_array_ptr = config_ptr as *const [u8; 5]; - let raw_config = unsafe { RawConfig::from(*config_array_ptr) }; - unsafe { libc::free(config_ptr as *mut libc::c_void) }; - Ok(raw_config.into()) + let mut raw_status = nitrokey_sys::NK_status { + firmware_version_major: 0, + firmware_version_minor: 0, + serial_number_smart_card: 0, + config_numlock: 0, + config_capslock: 0, + config_scrolllock: 0, + otp_user_password: false, + }; + get_command_result(unsafe { nitrokey_sys::NK_get_status(&mut raw_status) })?; + Ok(RawConfig::from(&raw_status).into()) } /// Changes the administrator PIN. -- cgit v1.2.1