summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/device.rs121
-rw-r--r--src/lib.rs8
-rw-r--r--src/otp.rs8
-rw-r--r--src/tests/pro.rs2
4 files changed, 80 insertions, 59 deletions
diff --git a/src/device.rs b/src/device.rs
index ce45a50..ab90d3d 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -28,7 +28,7 @@ pub enum Model {
/// Authentication with error handling:
///
/// ```no_run
-/// use nitrokey::{UnauthenticatedDevice, UserAuthenticatedDevice};
+/// use nitrokey::{Authenticate, UnauthenticatedDevice, UserAuthenticatedDevice};
/// # use nitrokey::CommandError;
///
/// fn perform_user_task(device: &UserAuthenticatedDevice) {}
@@ -51,8 +51,8 @@ pub enum Model {
/// # }
/// ```
///
-/// [`authenticate_admin`]: #method.authenticate_admin
-/// [`authenticate_user`]: #method.authenticate_user
+/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
+/// [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user
/// [`connect`]: fn.connect.html
/// [`connect_model`]: fn.connect_model.html
#[derive(Debug)]
@@ -64,7 +64,7 @@ pub struct UnauthenticatedDevice {}
/// method on an [`UnauthenticatedDevice`][]. To get back to an
/// unauthenticated device, use the [`device`][] method.
///
-/// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin
+/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
/// [`device`]: #method.device
/// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html
#[derive(Debug)]
@@ -79,7 +79,7 @@ pub struct UserAuthenticatedDevice {
/// method on an [`UnauthenticatedDevice`][]. To get back to an
/// unauthenticated device, use the [`device`][] method.
///
-/// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin
+/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
/// [`device`]: #method.device
/// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html
#[derive(Debug)]
@@ -350,38 +350,10 @@ pub trait Device {
}
}
-trait AuthenticatedDevice {
- fn new(device: UnauthenticatedDevice, temp_password: Vec<u8>) -> Self;
-}
-
-impl UnauthenticatedDevice {
- fn authenticate<D, T>(
- self,
- password: &str,
- callback: T,
- ) -> Result<D, (UnauthenticatedDevice, CommandError)>
- where
- D: AuthenticatedDevice,
- T: Fn(*const i8, *const i8) -> c_int,
- {
- let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) {
- Ok(pw) => pw,
- Err(_) => return Err((self, CommandError::RngError)),
- };
- let password = CString::new(password);
- if password.is_err() {
- return Err((self, CommandError::InvalidString));
- }
-
- let pw = password.unwrap();
- let password_ptr = pw.as_ptr();
- let temp_password_ptr = temp_password.as_ptr() as *const i8;
- return match callback(password_ptr, temp_password_ptr) {
- 0 => Ok(D::new(self, temp_password)),
- rv => Err((self, CommandError::from(rv))),
- };
- }
-
+/// Provides methods to authenticate as a user or as an admin using a PIN. The authenticated
+/// methods will consume the current device instance. On success, they return the authenticated
+/// device. Otherwise, they return the current unauthenticated device and the error code.
+pub trait Authenticate {
/// Performs user authentication. This method consumes the device. If
/// successful, an authenticated device is returned. Otherwise, the
/// current unauthenticated device and the error are returned.
@@ -398,7 +370,7 @@ impl UnauthenticatedDevice {
/// # Example
///
/// ```no_run
- /// use nitrokey::{UnauthenticatedDevice, UserAuthenticatedDevice};
+ /// use nitrokey::{Authenticate, UnauthenticatedDevice, UserAuthenticatedDevice};
/// # use nitrokey::CommandError;
///
/// fn perform_user_task(device: &UserAuthenticatedDevice) {}
@@ -424,14 +396,12 @@ impl UnauthenticatedDevice {
/// [`InvalidString`]: enum.CommandError.html#variant.InvalidString
/// [`RngError`]: enum.CommandError.html#variant.RngError
/// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword
- pub fn authenticate_user(
+ fn authenticate_user(
self,
password: &str,
- ) -> Result<UserAuthenticatedDevice, (UnauthenticatedDevice, CommandError)> {
- return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe {
- nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr)
- });
- }
+ ) -> Result<UserAuthenticatedDevice, (Self, CommandError)>
+ where
+ Self: Sized;
/// Performs admin authentication. This method consumes the device. If
/// successful, an authenticated device is returned. Otherwise, the
@@ -449,7 +419,7 @@ impl UnauthenticatedDevice {
/// # Example
///
/// ```no_run
- /// use nitrokey::{AdminAuthenticatedDevice, UnauthenticatedDevice};
+ /// use nitrokey::{Authenticate, AdminAuthenticatedDevice, UnauthenticatedDevice};
/// # use nitrokey::CommandError;
///
/// fn perform_admin_task(device: &AdminAuthenticatedDevice) {}
@@ -475,10 +445,61 @@ impl UnauthenticatedDevice {
/// [`InvalidString`]: enum.CommandError.html#variant.InvalidString
/// [`RngError`]: enum.CommandError.html#variant.RngError
/// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword
- pub fn authenticate_admin(
+ fn authenticate_admin(
+ self,
+ password: &str,
+ ) -> Result<AdminAuthenticatedDevice, (Self, CommandError)>
+ where
+ Self: Sized;
+}
+
+trait AuthenticatedDevice {
+ fn new(device: UnauthenticatedDevice, temp_password: Vec<u8>) -> Self;
+}
+
+impl UnauthenticatedDevice {
+ fn authenticate<D, T>(
+ self,
+ password: &str,
+ callback: T,
+ ) -> Result<D, (UnauthenticatedDevice, CommandError)>
+ where
+ D: AuthenticatedDevice,
+ T: Fn(*const i8, *const i8) -> c_int,
+ {
+ let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) {
+ Ok(pw) => pw,
+ Err(_) => return Err((self, CommandError::RngError)),
+ };
+ let password = CString::new(password);
+ if password.is_err() {
+ return Err((self, CommandError::InvalidString));
+ }
+
+ let pw = password.unwrap();
+ let password_ptr = pw.as_ptr();
+ let temp_password_ptr = temp_password.as_ptr() as *const i8;
+ return match callback(password_ptr, temp_password_ptr) {
+ 0 => Ok(D::new(self, temp_password)),
+ rv => Err((self, CommandError::from(rv))),
+ };
+ }
+}
+
+impl Authenticate for UnauthenticatedDevice {
+ fn authenticate_user(
+ self,
+ password: &str,
+ ) -> Result<UserAuthenticatedDevice, (Self, CommandError)> {
+ return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe {
+ nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr)
+ });
+ }
+
+ fn authenticate_admin(
self,
password: &str,
- ) -> Result<AdminAuthenticatedDevice, (UnauthenticatedDevice, CommandError)> {
+ ) -> Result<AdminAuthenticatedDevice, (Self, CommandError)> {
return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe {
nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr)
});
@@ -521,7 +542,7 @@ impl GenerateOtp for UserAuthenticatedDevice {
/// # Example
///
/// ```no_run
- /// use nitrokey::{Device, GenerateOtp};
+ /// use nitrokey::{Authenticate, GenerateOtp};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), CommandError> {
@@ -562,7 +583,7 @@ impl GenerateOtp for UserAuthenticatedDevice {
/// # Example
///
/// ```no_run
- /// use nitrokey::{Device, GenerateOtp};
+ /// use nitrokey::{Authenticate, GenerateOtp};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), CommandError> {
@@ -623,7 +644,7 @@ impl AdminAuthenticatedDevice {
/// # Example
///
/// ```no_run
- /// use nitrokey::Config;
+ /// use nitrokey::{Authenticate, Config};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), CommandError> {
diff --git a/src/lib.rs b/src/lib.rs
index 1cfb7fd..cb44ee2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -38,7 +38,7 @@
//! Configure an HOTP slot:
//!
//! ```no_run
-//! use nitrokey::{CommandStatus, ConfigureOtp, Device, OtpMode, OtpSlotData};
+//! use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};
//! # use nitrokey::CommandError;
//!
//! # fn try_main() -> Result<(), (CommandError)> {
@@ -73,8 +73,8 @@
//! # }
//! ```
//!
-//! [`authenticate_admin`]: struct.UnauthenticatedDevice.html#method.authenticate_admin
-//! [`authenticate_user`]: struct.UnauthenticatedDevice.html#method.authenticate_user
+//! [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
+//! [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user
//! [`connect`]: fn.connect.html
//! [`connect_model`]: fn.connect_model.html
//! [`device`]: struct.AuthenticatedDevice.html#method.device
@@ -96,7 +96,7 @@ mod util;
mod tests;
pub use config::Config;
-pub use device::{AdminAuthenticatedDevice, Device, Model, UnauthenticatedDevice,
+pub use device::{AdminAuthenticatedDevice, Authenticate, Device, Model, UnauthenticatedDevice,
UserAuthenticatedDevice};
pub use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData};
pub use util::{CommandError, CommandStatus, LogLevel};
diff --git a/src/otp.rs b/src/otp.rs
index 0451c5f..7145b6c 100644
--- a/src/otp.rs
+++ b/src/otp.rs
@@ -25,7 +25,7 @@ pub trait ConfigureOtp {
/// # Example
///
/// ```no_run
- /// use nitrokey::{CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};
+ /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), (CommandError)> {
@@ -61,7 +61,7 @@ pub trait ConfigureOtp {
/// # Example
///
/// ```no_run
- /// use nitrokey::{CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};
+ /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), (CommandError)> {
@@ -94,7 +94,7 @@ pub trait ConfigureOtp {
/// # Example
///
/// ```no_run
- /// use nitrokey::{CommandStatus, ConfigureOtp};
+ /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), (CommandError)> {
@@ -124,7 +124,7 @@ pub trait ConfigureOtp {
/// # Example
///
/// ```no_run
- /// use nitrokey::{CommandStatus, ConfigureOtp};
+ /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp};
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), (CommandError)> {
diff --git a/src/tests/pro.rs b/src/tests/pro.rs
index 71daa78..8476451 100644
--- a/src/tests/pro.rs
+++ b/src/tests/pro.rs
@@ -1,5 +1,5 @@
use std::ffi::CStr;
-use {AdminAuthenticatedDevice, CommandError, CommandStatus, Config, ConfigureOtp,
+use {AdminAuthenticatedDevice, Authenticate, CommandError, CommandStatus, Config, ConfigureOtp,
Device, GenerateOtp, Model, OtpMode, OtpSlotData, UnauthenticatedDevice};
static ADMIN_PASSWORD: &str = "12345678";