summaryrefslogtreecommitdiff
path: root/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/device.rs')
-rw-r--r--src/device.rs121
1 files changed, 71 insertions, 50 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> {