diff options
| author | Robin Krahl <robin.krahl@ireas.org> | 2019-01-31 11:07:50 +0000 | 
|---|---|---|
| committer | Robin Krahl <robin.krahl@ireas.org> | 2019-01-31 12:10:38 +0100 | 
| commit | ad76653b3be57c0cfd31c8056a8d68537034324e (patch) | |
| tree | 32302d740faa9403426cc38e993402ff84edd498 | |
| parent | 9a38dd456804035f88aa7c4042066e4cde67c04c (diff) | |
| download | nitrokey-rs-ad76653b3be57c0cfd31c8056a8d68537034324e.tar.gz nitrokey-rs-ad76653b3be57c0cfd31c8056a8d68537034324e.tar.bz2 | |
Add set_encrypted_volume_mode method to Storage
Previously, we considered this command as unsupported as it only was
available with firmware version 0.49.  But as discussed in nitrocli
issue 80 [0], it will probably be re-enabled in future firmware
versions.  Therefore this patch adds the set_encrypted_volume_mode to
Storage.
[0] https://github.com/d-e-s-o/nitrocli/issues/80
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | src/device.rs | 47 | ||||
| -rw-r--r-- | tests/device.rs | 30 | 
4 files changed, 78 insertions, 3 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index c51727e..a9e3065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ SPDX-License-Identifier: MIT  - Fix timing issues with the `totp_no_pin` and `totp_pin` test cases.  - Always return a `Result` in functions that communicate with a device.  - Combine `get_{major,minor}_firmware_version` into `get_firmware_version`. +- Add `set_encrypted_volume_mode` to `Storage`.  # v0.3.4 (2019-01-20)  - Fix authentication methods that assumed that `char` is signed. @@ -38,8 +38,7 @@ supported by `nitrokey-rs`:  - `NK_is_AES_supported`.  This method is no longer needed for Nitrokey devices    with a recent firmware version.  - `NK_set_unencrypted_volume_rorw_pin_type_user`, -  `NK_set_unencrypted_read_only`, `NK_set_unencrypted_read_write`, -  `NK_set_encrypted_read_only` and `NK_set_encrypted_read_write`.  These +  `NK_set_unencrypted_read_only`, `NK_set_unencrypted_read_write`.  These    methods are only relevant for older firmware versions (pre-v0.51).  As the    Nitrokey Storage firmware can be updated easily, we do not support these    outdated versions. diff --git a/src/device.rs b/src/device.rs index d199d9a..c985802 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1142,7 +1142,7 @@ impl Storage {      ///      /// # fn try_main() -> Result<(), Error> {      /// let device = nitrokey::Storage::connect()?; -    /// match device.set_unencrypted_volume_mode("123456", VolumeMode::ReadWrite) { +    /// match device.set_unencrypted_volume_mode("12345678", VolumeMode::ReadWrite) {      ///     Ok(()) => println!("Set the unencrypted volume to read-write mode."),      ///     Err(err) => eprintln!("Could not set the unencrypted volume to read-write mode: {}", err),      /// }; @@ -1169,6 +1169,51 @@ impl Storage {          get_command_result(result)      } +    /// Sets the access mode of the encrypted volume. +    /// +    /// This command will reconnect the encrypted volume so buffers should be flushed before +    /// calling it.  It is only available in firmware version 0.49. +    /// +    /// # Errors +    /// +    /// - [`InvalidString`][] if the provided password contains a null byte +    /// - [`WrongPassword`][] if the provided admin password is wrong +    /// +    /// # Example +    /// +    /// ```no_run +    /// # use nitrokey::Error; +    /// use nitrokey::VolumeMode; +    /// +    /// # fn try_main() -> Result<(), Error> { +    /// let device = nitrokey::Storage::connect()?; +    /// match device.set_encrypted_volume_mode("12345678", VolumeMode::ReadWrite) { +    ///     Ok(()) => println!("Set the encrypted volume to read-write mode."), +    ///     Err(err) => eprintln!("Could not set the encrypted volume to read-write mode: {}", err), +    /// }; +    /// #     Ok(()) +    /// # } +    /// ``` +    /// +    /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString +    /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword +    pub fn set_encrypted_volume_mode( +        &self, +        admin_pin: &str, +        mode: VolumeMode, +    ) -> Result<(), Error> { +        let admin_pin = get_cstring(admin_pin)?; +        let result = match mode { +            VolumeMode::ReadOnly => unsafe { +                nitrokey_sys::NK_set_encrypted_read_only(admin_pin.as_ptr()) +            }, +            VolumeMode::ReadWrite => unsafe { +                nitrokey_sys::NK_set_encrypted_read_write(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 306b33f..969a7df 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -402,6 +402,36 @@ fn lock(device: Storage) {  }  #[test_device] +fn set_encrypted_volume_mode(device: Storage) { +    // This test case does not check the device status as the command only works with firmware +    // version 0.49.  For later versions, it does not do anything and always returns Ok(()). + +    assert_ok!( +        (), +        device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) +    ); + +    // TODO: re-enable once the password is checked in the firmware +    // assert_cmd_err!( +    //     CommandError::WrongPassword, +    //     device.set_encrypted_volume_mode(USER_PASSWORD, VolumeMode::ReadOnly) +    // ); + +    assert_ok!( +        (), +        device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) +    ); +    assert_ok!( +        (), +        device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadWrite) +    ); +    assert_ok!( +        (), +        device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) +    ); +} + +#[test_device]  fn set_unencrypted_volume_mode(device: Storage) {      fn assert_mode(device: &Storage, mode: VolumeMode) {          let status = unwrap_ok!(device.get_status()); | 
