summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md3
-rw-r--r--src/device.rs118
-rw-r--r--src/tests/device.rs10
3 files changed, 126 insertions, 5 deletions
diff --git a/TODO.md b/TODO.md
index 2d865a4..6086ad8 100644
--- a/TODO.md
+++ b/TODO.md
@@ -18,7 +18,6 @@
- `NK_clear_new_sd_card_warning`
- `NK_fill_SD_card_with_random_data`
- `NK_change_update_password`
- - `NK_get_status_storage_as_string`
- `NK_get_SD_usage_data_as_string`
- `NK_get_progress_bar_value`
- `NK_list_devices_by_cpuID`
@@ -27,7 +26,6 @@
- `NK_get_library_version`
- `NK_get_major_library_version`
- `NK_get_minor_libray_version`
- - `NK_get_status_storage`
- `NK_get_storage_production_info`
- `NK_totp_set_time_soft`
- `NK_wink`
@@ -43,5 +41,6 @@
issue 65][]).
- Disable creation of multiple password safes at the same time.
- Check timing in Storage tests.
+- Consider restructuring `device::StorageStatus`.
[nitrokey-storage-firmware issue 65]: https://github.com/Nitrokey/nitrokey-storage-firmware/issues/65
diff --git a/src/device.rs b/src/device.rs
index 843b41d..f135261 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -164,6 +164,47 @@ pub struct Pro {}
#[derive(Debug)]
pub struct Storage {}
+/// The status of a volume on a Nitrokey Storage device.
+#[derive(Debug)]
+pub struct VolumeStatus {
+ /// Indicates whether the volume is read-only.
+ pub read_only: bool,
+ /// Indicates whether the volume is active.
+ pub active: bool,
+}
+
+/// The status of a Nitrokey Storage device.
+#[derive(Debug)]
+pub struct StorageStatus {
+ /// The status of the unencrypted volume.
+ pub unencrypted_volume: VolumeStatus,
+ /// The status of the encrypted volume.
+ pub encrypted_volume: VolumeStatus,
+ /// The status of the hidden volume.
+ pub hidden_volume: VolumeStatus,
+ /// The major firmware version, e. g. 0 in v0.40.
+ pub firmware_version_major: u8,
+ /// The minor firmware version, e. g. 40 in v0.40.
+ pub firmware_version_minor: u8,
+ /// Indicates whether the firmware is locked.
+ pub firmware_locked: bool,
+ /// The serial number of the SD card in the Storage stick.
+ pub serial_number_sd_card: u32,
+ /// The serial number of the smart card in the Storage stick.
+ pub serial_number_smart_card: u32,
+ /// The number of remaining login attempts for the user PIN.
+ pub user_retry_count: u8,
+ /// The number of remaining login attempts for the admin PIN.
+ pub admin_retry_count: u8,
+ /// Indicates whether a new SD card was found.
+ pub new_sd_card_found: bool,
+ /// Indicates whether the SD card is filled with random characters.
+ pub filled_with_random: bool,
+ /// Indicates whether the stick has been initialized by generating
+ /// the AES keys.
+ pub stick_initialized: bool,
+}
+
/// A Nitrokey device.
///
/// This trait provides the commands that can be executed without authentication and that are
@@ -616,12 +657,54 @@ impl Storage {
/// # Ok(())
/// # }
/// ```
- ///
- /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString
- /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword
pub fn disable_encrypted_volume(&self) -> Result<(), CommandError> {
unsafe { get_command_result(nitrokey_sys::NK_lock_encrypted_volume()) }
}
+
+
+ /// Returns the status of the connected storage device.
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// # use nitrokey::CommandError;
+ ///
+ /// fn use_volume() {}
+ ///
+ /// # fn try_main() -> Result<(), CommandError> {
+ /// let device = nitrokey::Storage::connect()?;
+ /// match device.get_status() {
+ /// Ok(status) => {
+ /// println!("SD card ID: {:#x}", status.serial_number_sd_card);
+ /// },
+ /// Err(err) => println!("Could not get Storage status: {}", err),
+ /// };
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn get_status(&self) -> Result<StorageStatus, CommandError> {
+ let mut raw_status = nitrokey_sys::NK_storage_status {
+ unencrypted_volume_read_only: false,
+ unencrypted_volume_active: false,
+ encrypted_volume_read_only: false,
+ encrypted_volume_active: false,
+ hidden_volume_read_only: false,
+ hidden_volume_active: false,
+ firmware_version_major: 0,
+ firmware_version_minor: 0,
+ firmware_locked: false,
+ serial_number_sd_card: 0,
+ serial_number_smart_card: 0,
+ user_retry_count: 0,
+ admin_retry_count: 0,
+ new_sd_card_found: false,
+ filled_with_random: false,
+ stick_initialized: false,
+ };
+ let raw_result = unsafe { nitrokey_sys::NK_get_status_storage(&mut raw_status) };
+ let result = get_command_result(raw_result);
+ result.and(Ok(StorageStatus::from(raw_status)))
+ }
}
impl Drop for Storage {
@@ -635,3 +718,32 @@ impl Drop for Storage {
impl Device for Storage {}
impl GenerateOtp for Storage {}
+
+impl From<nitrokey_sys::NK_storage_status> for StorageStatus {
+ fn from(status: nitrokey_sys::NK_storage_status) -> Self {
+ StorageStatus {
+ unencrypted_volume: VolumeStatus {
+ read_only: status.unencrypted_volume_read_only,
+ active: status.unencrypted_volume_active,
+ },
+ encrypted_volume: VolumeStatus {
+ read_only: status.encrypted_volume_read_only,
+ active: status.encrypted_volume_active,
+ },
+ hidden_volume: VolumeStatus {
+ read_only: status.hidden_volume_read_only,
+ active: status.hidden_volume_active,
+ },
+ firmware_version_major: status.firmware_version_major,
+ firmware_version_minor: status.firmware_version_minor,
+ firmware_locked: status.firmware_locked,
+ serial_number_sd_card: status.serial_number_sd_card,
+ serial_number_smart_card: status.serial_number_smart_card,
+ user_retry_count: status.user_retry_count,
+ admin_retry_count: status.admin_retry_count,
+ new_sd_card_found: status.new_sd_card_found,
+ filled_with_random: status.filled_with_random,
+ stick_initialized: status.stick_initialized,
+ }
+ }
+}
diff --git a/src/tests/device.rs b/src/tests/device.rs
index c2c5336..fed465d 100644
--- a/src/tests/device.rs
+++ b/src/tests/device.rs
@@ -292,3 +292,13 @@ fn lock() {
assert!(device.lock().is_ok());
assert_eq!(1, count_nitrokey_block_devices());
}
+
+#[test]
+#[cfg_attr(not(feature = "test-storage"), ignore)]
+fn get_storage_status() {
+ let device = Storage::connect().unwrap();
+ let status = device.get_status().unwrap();
+
+ assert!(status.serial_number_sd_card > 0);
+ assert!(status.serial_number_smart_card > 0);
+}