aboutsummaryrefslogtreecommitdiff
path: root/nitrocli/src/commands.rs
diff options
context:
space:
mode:
Diffstat (limited to 'nitrocli/src/commands.rs')
-rw-r--r--nitrocli/src/commands.rs26
1 files changed, 26 insertions, 0 deletions
diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs
index 989abbf..aed0319 100644
--- a/nitrocli/src/commands.rs
+++ b/nitrocli/src/commands.rs
@@ -19,6 +19,7 @@
use std::fmt;
use std::result;
+use std::thread;
use std::time;
use std::u8;
@@ -33,6 +34,8 @@ use crate::error::Error;
use crate::pinentry;
use crate::Result;
+const NITROKEY_DEFAULT_ADMIN_PIN: &str = "12345678";
+
/// Create an `error::Error` with an error message of the format `msg: err`.
fn get_error(msg: &'static str, err: nitrokey::CommandError) -> Error {
Error::CommandError(Some(msg), err)
@@ -291,6 +294,29 @@ pub fn status(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
print_status(ctx, model, &device)
}
+/// Perform a factory reset.
+pub fn reset(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
+ let device = get_device(ctx)?;
+ let pin_entry = pinentry::PinEntry::from(pinentry::PinType::Admin, &device)?;
+
+ // To force the user to enter the admin PIN before performing a
+ // factory reset, we clear the pinentry cache for the admin PIN.
+ pinentry::clear(&pin_entry)?;
+
+ try_with_pin(ctx, &pin_entry, "Factory reset failed", |pin| {
+ device.factory_reset(&pin)?;
+ // Work around for a timing issue between factory_reset and
+ // build_aes_key, see
+ // https://github.com/Nitrokey/nitrokey-storage-firmware/issues/80
+ thread::sleep(time::Duration::from_secs(3));
+ // Another work around for spurious WrongPassword returns of
+ // build_aes_key after a factory reset on Pro devices.
+ // https://github.com/Nitrokey/nitrokey-pro-firmware/issues/57
+ let _ = device.get_user_retry_count();
+ device.build_aes_key(NITROKEY_DEFAULT_ADMIN_PIN)
+ })
+}
+
/// Open the encrypted volume on the nitrokey.
pub fn storage_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
let device = get_storage_device(ctx)?;