From 4f95573576cf525aa62fb35224f817deb9c24da3 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 22 Feb 2021 10:57:20 +0000 Subject: [PATCH] Fast path for CrevIDs with empty string as the passphrase #385 --- cargo-crev/src/main.rs | 24 +++++++++++++++------- crev-lib/src/id.rs | 46 +++++++++++++++++++++++++++++++++--------- crev-lib/src/local.rs | 2 +- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/cargo-crev/src/main.rs b/cargo-crev/src/main.rs index 07309673..77ed9479 100644 --- a/cargo-crev/src/main.rs +++ b/cargo-crev/src/main.rs @@ -6,6 +6,7 @@ doc = "See [user documentation module](./doc/user/index.html)." )] #![cfg_attr(feature = "documentation", feature(external_doc))] +use crev_data::UnlockedId; use crev_data::proof::ContentExt; use crate::prelude::*; use crev_lib::id::LockedId; @@ -214,6 +215,7 @@ fn run_command(command: opts::Command) -> Result { fn read_new_passphrase() -> io::Result { println!("CrevID will be protected by a passphrase."); + println!("You can change it later with `cargo crev id passwd`."); println!( "There's no way to recover your CrevID if you forget your passphrase." ); @@ -226,9 +228,11 @@ fn run_command(command: opts::Command) -> Result { print_crev_proof_repo_fork_help(); e })?; - println!("Your CrevID was created and will be printed below in an encrypted form."); - println!("Make sure to back it up on another device, to prevent losing it."); - println!("{}", res); + if !res.has_no_passphrase() { + println!("Your CrevID was created and will be printed below in an encrypted form."); + println!("Make sure to back it up on another device, to prevent losing it."); + println!("{}", res); + } let local = crev_lib::Local::auto_open()?; let _ = ensure_known_owners_list_exists(&local); @@ -238,10 +242,7 @@ fn run_command(command: opts::Command) -> Result { local.switch_id(&args.id)? } opts::Id::Passwd => { - let res = current_id_change_passphrase()?; - println!("Your CrevID has been updated and will be printed below in the reencrypted form."); - println!("Make sure to back it up on another device, to prevent losing it."); - println!("{}", res); + current_id_change_passphrase()?; } opts::Id::Current => { let local = Local::auto_open()?; @@ -687,12 +688,21 @@ fn current_id_change_passphrase() -> Result { eprintln!("Please enter the OLD passphrase. If you don't know it, you will need to create a new Id."); let unlocked_id = local.read_current_unlocked_id(&term::read_passphrase)?; eprintln!("Now please enter the NEW passphrase."); + change_passphrase(&local, &unlocked_id) +} + +fn change_passphrase(local: &Local, unlocked_id: &UnlockedId) -> Result { let passphrase = term::read_new_passphrase()?; let locked_id = LockedId::from_unlocked_id(&unlocked_id, &passphrase)?; local.save_locked_id(&locked_id)?; local.save_current_id(unlocked_id.as_ref())?; eprintln!("Passphrase changed successfully."); + if !locked_id.has_no_passphrase() { + println!("Your CrevID has been updated and will be printed below in the reencrypted form."); + println!("Make sure to back it up on another device, to prevent losing it."); + println!("{}", locked_id); + } Ok(locked_id) } diff --git a/crev-lib/src/id.rs b/crev-lib/src/id.rs index b000ac6c..ee6a59f2 100644 --- a/crev-lib/src/id.rs +++ b/crev-lib/src/id.rs @@ -63,19 +63,23 @@ impl LockedId { pub fn from_unlocked_id(unlocked_id: &UnlockedId, passphrase: &str) -> Result { use miscreant::aead::Aead; - let config = Config { - variant: argon2::Variant::Argon2id, - version: argon2::Version::Version13, + let config = if passphrase != "" { + Config { + variant: argon2::Variant::Argon2id, + version: argon2::Version::Version13, - hash_length: 64, - mem_cost: 4096, - time_cost: 192, + hash_length: 64, + mem_cost: 4096, + time_cost: 192, - lanes: num_cpus::get() as u32, - thread_mode: argon2::ThreadMode::Parallel, + lanes: num_cpus::get() as u32, + thread_mode: argon2::ThreadMode::Parallel, - ad: &[], - secret: &[], + ad: &[], + secret: &[], + } + } else { + Self::weak_passphrase_config() }; let pwsalt = random_vec(32); @@ -182,4 +186,26 @@ impl LockedId { Ok(result) } } + + pub fn has_no_passphrase(&self) -> bool { + self.passphrase_config.iterations == 1 && self.to_unlocked("").is_ok() + } + + /// Config for empty passphrase. User chose no security, so they're getting none. + fn weak_passphrase_config() -> Config<'static> { + Config { + variant: argon2::Variant::Argon2id, + version: argon2::Version::Version13, + + hash_length: 64, + mem_cost: 16, + time_cost: 1, + + lanes: 1, + thread_mode: argon2::ThreadMode::Parallel, + + ad: &[], + secret: &[], + } + } } diff --git a/crev-lib/src/local.rs b/crev-lib/src/local.rs index 809cf827..c8e02fff 100644 --- a/crev-lib/src/local.rs +++ b/crev-lib/src/local.rs @@ -416,7 +416,7 @@ impl Local { let locked = self.read_locked_id(id)?; let mut i = 0; loop { - let passphrase = passphrase_callback()?; + let passphrase = if locked.has_no_passphrase() { String::new() } else { passphrase_callback()? }; match locked.to_unlocked(&passphrase) { Ok(o) => return Ok(o), Err(e) => {