summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--TODO.md2
-rw-r--r--src/device.rs46
-rw-r--r--tests/device.rs34
4 files changed, 81 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b475168..b5f7b45 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,8 @@
`CommandError::InvalidHexString` and `CommandError::TargetBufferTooSmall`.
- Add the `get_library_version` function to query the libnitrokey version.
- Add the `wink` method to the `Storage` struct.
+- Add the `set_unencrypted_volume_mode` to set the access mode of the
+ unencrypted volume.
# v0.3.1 (2019-01-07)
- Use `nitrokey-test` to select and execute the unit tests.
diff --git a/TODO.md b/TODO.md
index cd258fc..65ee4ea 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,9 +3,7 @@
- `NK_is_AES_supported`
- `NK_send_startup`
- `NK_set_unencrypted_read_only`
- - `NK_set_unencrypted_read_only_admin`
- `NK_set_unencrypted_read_write`
- - `NK_set_unencrypted_read_write_admin`
- `NK_set_encrypted_read_only`
- `NK_set_encrypted_read_write`
- `NK_export_firmware`
diff --git a/src/device.rs b/src/device.rs
index 792ac2f..ee8e31c 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -1076,6 +1076,52 @@ impl Storage {
}
}
+ /// Sets the access mode of the unencrypted volume.
+ ///
+ /// This command will reconnect the unencrypted volume so buffers should be flushed before
+ /// calling it. Since firmware version v0.51, this command requires the admin PIN. Older
+ /// firmware versions are not supported.
+ ///
+ /// # Errors
+ ///
+ /// - [`InvalidString`][] if the provided password contains a null byte
+ /// - [`WrongPassword`][] if the provided admin password is wrong
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// # use nitrokey::CommandError;
+ /// use nitrokey::VolumeMode;
+ ///
+ /// # fn try_main() -> Result<(), CommandError> {
+ /// let device = nitrokey::Storage::connect()?;
+ /// match device.set_unencrypted_volume_mode("123456", VolumeMode::ReadWrite) {
+ /// Ok(()) => println!("Set the unencrypted volume to read-write mode."),
+ /// Err(err) => println!("Could not set the unencrypted volume to read-write mode: {}", err),
+ /// };
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString
+ /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword
+ pub fn set_unencrypted_volume_mode(
+ &self,
+ admin_pin: &str,
+ mode: VolumeMode,
+ ) -> Result<(), CommandError> {
+ let admin_pin = get_cstring(admin_pin)?;
+ let result = match mode {
+ VolumeMode::ReadOnly => unsafe {
+ nitrokey_sys::NK_set_unencrypted_read_only_admin(admin_pin.as_ptr())
+ },
+ VolumeMode::ReadWrite => unsafe {
+ nitrokey_sys::NK_set_unencrypted_read_write_admin(admin_pin.as_ptr())
+ },
+ };
+ get_command_result(result)
+ }
+
/// Returns the status of the connected storage device.
///
/// # Example
diff --git a/tests/device.rs b/tests/device.rs
index 6f21dcb..9985e7a 100644
--- a/tests/device.rs
+++ b/tests/device.rs
@@ -6,7 +6,7 @@ use std::{thread, time};
use nitrokey::{
Authenticate, CommandError, Config, ConfigureOtp, Device, GenerateOtp, GetPasswordSafe,
- OtpMode, OtpSlotData,
+ OtpMode, OtpSlotData, Storage, VolumeMode,
};
use nitrokey_test::test as test_device;
@@ -399,6 +399,38 @@ fn lock(device: Storage) {
}
#[test_device]
+fn set_unencrypted_volume_mode(device: Storage) {
+ fn assert_mode(device: &Storage, mode: VolumeMode) {
+ let status = device.get_status();
+ assert!(status.is_ok());
+ assert_eq!(
+ status.unwrap().unencrypted_volume.read_only,
+ mode == VolumeMode::ReadOnly
+ );
+ }
+
+ fn assert_success(device: &Storage, mode: VolumeMode) {
+ assert_eq!(
+ Ok(()),
+ device.set_unencrypted_volume_mode(ADMIN_PASSWORD, mode)
+ );
+ assert_mode(&device, mode);
+ }
+
+ assert_success(&device, VolumeMode::ReadOnly);
+
+ assert_eq!(
+ Err(CommandError::WrongPassword),
+ device.set_unencrypted_volume_mode(USER_PASSWORD, VolumeMode::ReadOnly)
+ );
+ assert_mode(&device, VolumeMode::ReadOnly);
+
+ assert_success(&device, VolumeMode::ReadWrite);
+ assert_success(&device, VolumeMode::ReadWrite);
+ assert_success(&device, VolumeMode::ReadOnly);
+}
+
+#[test_device]
fn get_storage_status(device: Storage) {
let status = device.get_status().unwrap();