diff options
-rw-r--r-- | nitrocli/src/args.rs | 6 | ||||
-rw-r--r-- | nitrocli/src/commands.rs | 44 | ||||
-rw-r--r-- | nitrocli/src/pinentry.rs | 2 |
3 files changed, 47 insertions, 5 deletions
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index 4c9ed52..0f4ef4f 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -315,7 +315,7 @@ fn storage_hidden_create(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> parse(ctx, &parser, args)?; drop(parser); - Ok(()) + commands::storage_hidden_create(ctx, slot, start, end) } fn storage_hidden_open(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { @@ -323,7 +323,7 @@ fn storage_hidden_open(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { parser.set_description("Opens a hidden volume on a Nitrokey Storage"); parse(ctx, &parser, args)?; - Ok(()) + commands::storage_hidden_open(ctx) } fn storage_hidden_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { @@ -331,7 +331,7 @@ fn storage_hidden_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> parser.set_description("Closes the hidden volume on a Nitrokey Storage"); parse(ctx, &parser, args)?; - Ok(()) + commands::storage_hidden_close(ctx) } /// Execute a config subcommand. diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 5af2a44..ab70e29 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -296,6 +296,10 @@ pub fn storage_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> { let device = get_storage_device(ctx)?; let pin_entry = pinentry::PinEntry::from(pinentry::PinType::User, &device)?; + // We may forcefully close a hidden volume, if active, so be sure to + // flush caches to disk. + unsafe { sync() }; + try_with_pin(ctx, &pin_entry, "Opening encrypted volume failed", |pin| { device.enable_encrypted_volume(&pin) }) @@ -314,6 +318,46 @@ pub fn storage_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> { .map_err(|err| get_error("Closing encrypted volume failed", err)) } +/// Create a hidden volume. +pub fn storage_hidden_create( + ctx: &mut args::ExecCtx<'_>, + slot: u8, + start: u8, + end: u8, +) -> Result<()> { + let device = get_storage_device(ctx)?; + let pwd_entry = pinentry::PwdEntry::from(&device)?; + let pwd = pinentry::choose(&pwd_entry)?; + + device + .create_hidden_volume(slot, start, end, &pwd) + .map_err(|err| get_error("Creating hidden volume failed", err)) +} + +/// Open a hidden volume. +pub fn storage_hidden_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> { + let device = get_storage_device(ctx)?; + let pwd_entry = pinentry::PwdEntry::from(&device)?; + let pwd = pinentry::inquire(&pwd_entry, pinentry::Mode::Query, None)?; + + // We may forcefully close an encrypted volume, if active, so be sure + // to flush caches to disk. + unsafe { sync() }; + + device + .enable_hidden_volume(&pwd) + .map_err(|err| get_error("Opening hidden volume failed", err)) +} + +/// Close a previously opened hidden volume. +pub fn storage_hidden_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> { + unsafe { sync() }; + + get_storage_device(ctx)? + .disable_hidden_volume() + .map_err(|err| get_error("Closing hidden volume failed", err)) +} + /// Pretty print the status of a Nitrokey Storage. fn print_storage_status( ctx: &mut args::ExecCtx<'_>, diff --git a/nitrocli/src/pinentry.rs b/nitrocli/src/pinentry.rs index f8606ed..8370328 100644 --- a/nitrocli/src/pinentry.rs +++ b/nitrocli/src/pinentry.rs @@ -122,14 +122,12 @@ impl SecretEntry for PinEntry { } #[derive(Debug)] -#[allow(unused)] pub struct PwdEntry { model: nitrokey::Model, serial: String, } impl PwdEntry { - #[allow(unused)] pub fn from<D>(device: &D) -> crate::Result<Self> where D: nitrokey::Device, |