diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/device/mod.rs | 58 | ||||
| -rw-r--r-- | src/device/pro.rs | 18 | ||||
| -rw-r--r-- | src/device/storage.rs | 31 | ||||
| -rw-r--r-- | src/device/wrapper.rs | 9 | ||||
| -rw-r--r-- | src/lib.rs | 4 | 
5 files changed, 114 insertions, 6 deletions
| diff --git a/src/device/mod.rs b/src/device/mod.rs index e015886..668c230 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -153,6 +153,35 @@ impl fmt::Display for FirmwareVersion {      }  } +/// The status information common to all Nitrokey devices. +pub struct Status { +    /// The firmware version of the device. +    pub firmware_version: FirmwareVersion, +    /// The serial number of the device. +    pub serial_number: u32, +    /// The configuration of the device. +    pub config: Config, +} + +impl From<nitrokey_sys::NK_status> for Status { +    fn from(status: nitrokey_sys::NK_status) -> Self { +        Self { +            firmware_version: FirmwareVersion { +                major: status.firmware_version_major, +                minor: status.firmware_version_minor, +            }, +            serial_number: status.serial_number_smart_card, +            config: RawConfig { +                numlock: status.config_numlock, +                capslock: status.config_capslock, +                scrollock: status.config_scrolllock, +                user_password: status.otp_user_password, +            } +            .into(), +        } +    } +} +  /// A Nitrokey device.  ///  /// This trait provides the commands that can be executed without authentication and that are @@ -197,6 +226,35 @@ pub trait Device<'a>: Authenticate<'a> + GetPasswordSafe<'a> + GenerateOtp + fmt      /// # }      fn get_model(&self) -> Model; +    /// Returns the status of the Nitrokey device. +    /// +    /// This methods returns the status information common to all Nitrokey devices as a +    /// [`Status`][] struct.  Some models may provide more information, for example +    /// [`Storage::get_status`][] returns the [`StorageStatus`][] struct. +    /// +    /// # Errors +    /// +    /// - [`NotConnected`][] if the Nitrokey device has been disconnected +    /// +    /// # Example +    /// +    /// ```no_run +    /// use nitrokey::Device; +    /// +    /// let mut manager = nitrokey::take()?; +    /// let device = manager.connect()?; +    /// let status = device.get_status()?; +    /// println!("Firmware version: {}", status.firmware_version); +    /// println!("Serial number:    {:x}", status.serial_number); +    /// # Ok::<(), nitrokey::Error>(()) +    /// ``` +    /// +    /// [`NotConnected`]: enum.CommunicationError.html#variant.NotConnected +    /// [`Status`]: struct.Status.html +    /// [`Storage::get_status`]: struct.Storage.html#method.get_status +    /// [`StorageStatus`]: struct.StorageStatus.html +    fn get_status(&self) -> Result<Status, Error>; +      /// Returns the serial number of the Nitrokey device.  The serial number is the string      /// representation of a hex number.      /// diff --git a/src/device/pro.rs b/src/device/pro.rs index a65345e..591b730 100644 --- a/src/device/pro.rs +++ b/src/device/pro.rs @@ -3,8 +3,10 @@  use nitrokey_sys; -use crate::device::{Device, Model}; +use crate::device::{Device, Model, Status}; +use crate::error::Error;  use crate::otp::GenerateOtp; +use crate::util::get_command_result;  /// A Nitrokey Pro device without user or admin authentication.  /// @@ -74,6 +76,20 @@ impl<'a> Device<'a> for Pro<'a> {      fn get_model(&self) -> Model {          Model::Pro      } + +    fn get_status(&self) -> Result<Status, Error> { +        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(raw_status.into()) +    }  }  impl<'a> GenerateOtp for Pro<'a> {} diff --git a/src/device/storage.rs b/src/device/storage.rs index 370ce36..64e6848 100644 --- a/src/device/storage.rs +++ b/src/device/storage.rs @@ -1,11 +1,11 @@ -// Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org> +// Copyright (C) 2019-2019 Robin Krahl <robin.krahl@ireas.org>  // SPDX-License-Identifier: MIT  use std::fmt;  use nitrokey_sys; -use crate::device::{Device, FirmwareVersion, Model}; +use crate::device::{Device, FirmwareVersion, Model, Status};  use crate::error::Error;  use crate::otp::GenerateOtp;  use crate::util::{get_command_result, get_cstring}; @@ -678,6 +678,33 @@ impl<'a> Device<'a> for Storage<'a> {      fn get_model(&self) -> Model {          Model::Storage      } + +    fn get_status(&self) -> Result<Status, Error> { +        // Currently, the GET_STATUS command does not report the correct firmware version and +        // serial number on the Nitrokey Storage, see [0].  Until this is fixed in libnitrokey, we +        // have to manually execute the GET_DEVICE_STATUS command (Storage::get_status) and +        // complete the missing data, see [1]. +        // [0] https://github.com/Nitrokey/nitrokey-storage-firmware/issues/96 +        // [1] https://github.com/Nitrokey/libnitrokey/issues/166 + +        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) })?; +        let mut status = Status::from(raw_status); + +        let storage_status = Storage::get_status(&self)?; +        status.firmware_version = storage_status.firmware_version; +        status.serial_number = storage_status.serial_number_smart_card; + +        Ok(status) +    }  }  impl<'a> GenerateOtp for Storage<'a> {} diff --git a/src/device/wrapper.rs b/src/device/wrapper.rs index a3a18f9..adbb695 100644 --- a/src/device/wrapper.rs +++ b/src/device/wrapper.rs @@ -1,7 +1,7 @@  // Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org>  // SPDX-License-Identifier: MIT -use crate::device::{Device, Model, Pro, Storage}; +use crate::device::{Device, Model, Pro, Status, Storage};  use crate::error::Error;  use crate::otp::GenerateOtp; @@ -131,4 +131,11 @@ impl<'a> Device<'a> for DeviceWrapper<'a> {              DeviceWrapper::Storage(_) => Model::Storage,          }      } + +    fn get_status(&self) -> Result<Status, Error> { +        match self { +            DeviceWrapper::Pro(dev) => dev.get_status(), +            DeviceWrapper::Storage(dev) => Device::get_status(dev), +        } +    }  } @@ -126,8 +126,8 @@ use nitrokey_sys;  pub use crate::auth::{Admin, Authenticate, User};  pub use crate::config::Config;  pub use crate::device::{ -    Device, DeviceInfo, DeviceWrapper, Model, Pro, SdCardData, Storage, StorageProductionInfo, -    StorageStatus, VolumeMode, VolumeStatus, +    Device, DeviceInfo, DeviceWrapper, Model, Pro, SdCardData, Status, Storage, +    StorageProductionInfo, StorageStatus, VolumeMode, VolumeStatus,  };  pub use crate::error::{CommandError, CommunicationError, Error, LibraryError};  pub use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; | 
