From c3f1761ae147e562ec3565c7ba8a9cb1834759c2 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Sun, 20 Jan 2019 09:26:11 -0800 Subject: Implement storage hidden subcommand With this change we implement the storage hidden subcommand. We support creation, opening, and closing of hidden volumes. Note that the opening of a hidden volume automatically closes any opened encrypted volumes and vice versa. To that end, we force file system level caches to disk even from the storage open and storage hidden open commands. --- nitrocli/src/args.rs | 6 +++--- nitrocli/src/commands.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 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) -> 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) -> Result<()> { @@ -323,7 +323,7 @@ fn storage_hidden_open(ctx: &mut ExecCtx<'_>, args: Vec) -> 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) -> Result<()> { @@ -331,7 +331,7 @@ fn storage_hidden_close(ctx: &mut ExecCtx<'_>, args: Vec) -> 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(device: &D) -> crate::Result where D: nitrokey::Device, -- cgit v1.2.3