diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2018-05-21 22:44:22 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2018-05-22 00:44:45 +0200 |
commit | 57cab82dc3063cb6608aaf2ee937ad7af231c52a (patch) | |
tree | e356de0f4db205d294d9ba495fa91203bf2ddc81 /src | |
parent | ba716c0ba1fdcdfe824d84f04f7580a1c8501777 (diff) | |
download | nitrokey-rs-57cab82dc3063cb6608aaf2ee937ad7af231c52a.tar.gz nitrokey-rs-57cab82dc3063cb6608aaf2ee937ad7af231c52a.tar.bz2 |
Add support for change_admin_pin and change_user_pin
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 76 | ||||
-rw-r--r-- | src/tests/pro.rs | 48 |
2 files changed, 123 insertions, 1 deletions
@@ -211,7 +211,6 @@ struct RawConfig { pub user_password: bool, } -#[derive(Debug)] /// A Nitrokey device without user or admin authentication. /// /// Use [`connect`][] or [`connect_model`][] to obtain an instance. If you @@ -250,6 +249,7 @@ struct RawConfig { /// [`authenticate_user`]: #method.authenticate_user /// [`connect`]: fn.connect.html /// [`connect_model`]: fn.connect_model.html +#[derive(Debug)] pub struct UnauthenticatedDevice {} /// A Nitrokey device with user authentication. @@ -261,6 +261,7 @@ pub struct UnauthenticatedDevice {} /// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin /// [`device`]: #method.device /// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html +#[derive(Debug)] pub struct UserAuthenticatedDevice { device: UnauthenticatedDevice, temp_password: Vec<u8>, @@ -275,6 +276,7 @@ pub struct UserAuthenticatedDevice { /// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin /// [`device`]: #method.device /// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html +#[derive(Debug)] pub struct AdminAuthenticatedDevice { device: UnauthenticatedDevice, temp_password: Vec<u8>, @@ -634,6 +636,78 @@ pub trait Device { return result_from_string(nitrokey_sys::NK_get_totp_code(slot, 0, 0, 0)); } } + + /// Changes the administrator PIN. + /// + /// # Errors + /// + /// - [`InvalidString`][] if one of the provided passwords contains a null byte + /// - [`WrongPassword`][] if the current admin password is wrong + /// + /// # Example + /// + /// ```no_run + /// use nitrokey::Device; + /// # use nitrokey::CommandError; + /// + /// # fn try_main() -> Result<(), CommandError> { + /// let device = nitrokey::connect()?; + /// match device.change_admin_pin("12345678", "12345679") { + /// CommandStatus::Success => println!("Updated admin PIN."), + /// CommandStatus::Error(err) => println!("Failed to update admin PIN: {:?}", err), + /// }; + /// # Ok(()) + /// # } + /// ``` + /// + /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword + fn change_admin_pin(&self, current: &str, new: &str) -> CommandStatus { + let current_string = CString::new(current); + let new_string = CString::new(new); + if current_string.is_err() || new_string.is_err() { + return CommandStatus::Error(CommandError::InvalidString); + } + let current_string = current_string.unwrap(); + let new_string = new_string.unwrap(); + unsafe { CommandStatus::from(nitrokey_sys::NK_change_admin_PIN(current_string.as_ptr(), new_string.as_ptr())) } + } + + /// Changes the user PIN. + /// + /// # Errors + /// + /// - [`InvalidString`][] if one of the provided passwords contains a null byte + /// - [`WrongPassword`][] if the current user password is wrong + /// + /// # Example + /// + /// ```no_run + /// use nitrokey::Device; + /// # use nitrokey::CommandError; + /// + /// # fn try_main() -> Result<(), CommandError> { + /// let device = nitrokey::connect()?; + /// match device.change_user_pin("123456", "123457") { + /// CommandStatus::Success => println!("Updated admin PIN."), + /// CommandStatus::Error(err) => println!("Failed to update admin PIN: {:?}", err), + /// }; + /// # Ok(()) + /// # } + /// ``` + /// + /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword + fn change_user_pin(&self, current: &str, new: &str) -> CommandStatus { + let current_string = CString::new(current); + let new_string = CString::new(new); + if current_string.is_err() || new_string.is_err() { + return CommandStatus::Error(CommandError::InvalidString); + } + let current_string = current_string.unwrap(); + let new_string = new_string.unwrap(); + unsafe { CommandStatus::from(nitrokey_sys::NK_change_user_PIN(current_string.as_ptr(), new_string.as_ptr())) } + } } trait AuthenticatedDevice { diff --git a/src/tests/pro.rs b/src/tests/pro.rs index a23d42a..d2132f8 100644 --- a/src/tests/pro.rs +++ b/src/tests/pro.rs @@ -4,7 +4,9 @@ use {set_debug, AdminAuthenticatedDevice, CommandError, CommandStatus, Config, D OtpMode, OtpSlotData, UnauthenticatedDevice}; static ADMIN_PASSWORD: &str = "12345678"; +static ADMIN_NEW_PASSWORD: &str = "1234567890"; static USER_PASSWORD: &str = "123456"; +static USER_NEW_PASSWORD: &str = "abcdefghij"; // test suite according to RFC 4226, Appendix D static HOTP_SECRET: &str = "3132333435363738393031323334353637383930"; @@ -330,3 +332,49 @@ fn read_write_config() { let get_config = admin.get_config().unwrap(); assert_eq!(config, get_config); } + +#[test] +#[cfg_attr(not(feature = "test-pro"), ignore)] +fn change_user_pin() { + let device = get_test_device(); + let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); + let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; + + let result = device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD); + assert_eq!(CommandStatus::Success, result); + + let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0; + let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap().device(); + + let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); + assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result); + + let result = device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD); + assert_eq!(CommandStatus::Success, result); + + let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); + device.authenticate_user(USER_NEW_PASSWORD).unwrap_err(); +} + +#[test] +#[cfg_attr(not(feature = "test-pro"), ignore)] +fn change_admin_pin() { + let device = get_test_device(); + let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); + let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; + + let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD); + assert_eq!(CommandStatus::Success, result); + + let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0; + let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap().device(); + + let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD); + assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result); + + let result = device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD); + assert_eq!(CommandStatus::Success, result); + + let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); + device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); +} |