From 13006c00dcbd570cf8347d89557834e320427377 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Wed, 30 Jan 2019 18:40:11 +0000 Subject: Store mutable reference to Device in PasswordSafe The current implementation of PasswordSafe stored a normal reference to the Device. This patch changes the PasswordSafe struct to use a mutable reference instead. This allows the borrow checker to make sure that there is only one PasswordSafe instance at a time. While this is currently not needed, it will become important once we can lock the PWS on the Nitrokey when dropping the PasswordSafe instance. --- CHANGELOG.md | 2 ++ TODO.md | 1 - src/pws.rs | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e6cb9c..9227510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ SPDX-License-Identifier: MIT - Require a mutable `Device` reference if a method changes the device state. - Let `Admin` and `User` store a mutable reference to the `Device` instead of the `Device` value. +- Let `PasswordStore` store a mutable reference to the `Device` instead of a + non-mutable reference. # v0.3.4 (2019-01-20) - Fix authentication methods that assumed that `char` is signed. diff --git a/TODO.md b/TODO.md index 1ff723d..d6a3509 100644 --- a/TODO.md +++ b/TODO.md @@ -13,7 +13,6 @@ SPDX-License-Identifier: MIT - Clear passwords from memory. - Lock password safe in `PasswordSafe::drop()` (see [nitrokey-storage-firmware issue 65][]). -- Disable creation of multiple password safes at the same time. - Check timing in Storage tests. - Consider restructuring `device::StorageStatus`. diff --git a/src/pws.rs b/src/pws.rs index 371de6e..a5b9d33 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -18,8 +18,7 @@ pub const SLOT_COUNT: u8 = 16; /// The password safe stores a tuple consisting of a name, a login and a password on a slot. The /// number of available slots is [`SLOT_COUNT`][]. The slots are addressed starting with zero. To /// retrieve a password safe from a Nitrokey device, use the [`get_password_safe`][] method from -/// the [`GetPasswordSafe`][] trait. Note that the device must live at least as long as the -/// password safe. +/// the [`GetPasswordSafe`][] trait. /// /// Once the password safe has been unlocked, it can be accessed without a password. Therefore it /// is mandatory to call [`lock`][] on the corresponding device after the password store is used. @@ -58,21 +57,17 @@ pub const SLOT_COUNT: u8 = 16; /// [`GetPasswordSafe`]: trait.GetPasswordSafe.html #[derive(Debug)] pub struct PasswordSafe<'a> { - _device: &'a dyn Device, + device: &'a mut dyn Device, } /// Provides access to a [`PasswordSafe`][]. /// -/// The device that implements this trait must always live at least as long as a password safe -/// retrieved from it. -/// /// [`PasswordSafe`]: struct.PasswordSafe.html pub trait GetPasswordSafe { /// Enables and returns the password safe. /// - /// The underlying device must always live at least as long as a password safe retrieved from - /// it. It is mandatory to lock the underlying device using [`lock`][] after the password safe - /// has been used. Otherwise, other applications can access the password store without + /// It is mandatory to lock the underlying device using [`lock`][] after the password safe has + /// been used. Otherwise, other applications can access the password store without /// authentication. /// /// If this method returns an `AesDecryptionFailed` (Nitrokey Pro) or `Unknown` (Nitrokey @@ -121,12 +116,17 @@ pub trait GetPasswordSafe { } fn get_password_safe<'a>( - device: &'a dyn Device, + device: &'a mut dyn Device, user_pin: &str, ) -> Result, Error> { let user_pin_string = get_cstring(user_pin)?; - get_command_result(unsafe { nitrokey_sys::NK_enable_password_safe(user_pin_string.as_ptr()) }) - .map(|_| PasswordSafe { _device: device }) + let result = get_command_result(unsafe { + nitrokey_sys::NK_enable_password_safe(user_pin_string.as_ptr()) + }); + match result { + Ok(()) => Ok(PasswordSafe { device }), + Err(err) => Err(err), + } } fn get_pws_result(s: String) -> Result { -- cgit v1.2.1