From 972fcd90ebf7afc802c48ea6c4a1140f896dc173 Mon Sep 17 00:00:00 2001 From: lbeder Date: Tue, 10 Dec 2024 21:36:32 +0400 Subject: [PATCH] Add fingerprint to output --- src/main.rs | 71 ++++++++++++++------------------ src/utils/color_hash.rs | 2 +- src/utils/outputs/fingerprint.rs | 35 ++++++++++++++++ src/utils/outputs/mod.rs | 1 + src/utils/outputs/output.rs | 20 +++++---- 5 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 src/utils/outputs/fingerprint.rs diff --git a/src/main.rs b/src/main.rs index 41f44cc..3a980f1 100755 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ use dialoguer::{theme::ColorfulTheme, Confirm, Input, Password}; use humantime::format_duration; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use mimalloc::MiMalloc; -use sha2::{Digest, Sha256, Sha512}; +use sha2::{Digest, Sha512}; use std::{ cmp::Ordering, collections::VecDeque, @@ -41,7 +41,10 @@ use utils::{ version::Version, }, color_hash::color_hash, - outputs::output::{OpenOutputOptions, Output, OutputOptions}, + outputs::{ + fingerprint::Fingerprint, + output::{OpenOutputOptions, Output, OutputOptions}, + }, }; #[global_allocator] @@ -599,21 +602,6 @@ fn show_hint(data: &str, description: &str, hex: bool) { } } -fn print_fingerprint(options: &SlowKeyOptions, salt: &[u8], password: &[u8]) { - let mut data = serde_json::to_string(&options).unwrap().as_bytes().to_vec(); - data.extend_from_slice(salt); - data.extend_from_slice(password); - - let mut sha256 = Sha256::new(); - sha256.update(data); - let hash = sha256.finalize(); - - println!( - "Fingerprint: {}\n", - hex::encode(&hash[0..8]).to_uppercase().with(color_hash(hash.as_ref())) - ); -} - struct DeriveOptions { options: SlowKeyOptions, checkpoint_data: Option, @@ -647,28 +635,6 @@ fn derive(derive_options: DeriveOptions) { let mut checkpointing_interval: usize = 0; - if let Some(dir) = derive_options.checkpoint_dir { - checkpointing_interval = derive_options.checkpoint_interval.unwrap(); - - if output_key.is_none() { - output_key = Some(get_output_key()); - } - - checkpoint = Some(Checkpoint::new(&CheckpointOptions { - iterations: options.iterations, - dir: dir.to_owned(), - key: output_key.clone().unwrap(), - max_checkpoints_to_keep: derive_options.max_checkpoints_to_keep, - slowkey: options.clone(), - })); - - println!( - "Checkpoint will be created every {} iterations and saved to the \"{}\" checkpoints directory\n", - checkpointing_interval.to_string().cyan(), - &dir.to_string_lossy().cyan() - ); - } - if let Some(checkpoint_data) = &derive_options.checkpoint_data { checkpoint_data.print(DisplayOptions::default()); } @@ -699,7 +665,30 @@ fn derive(derive_options: DeriveOptions) { } // Print the colored hash fingerprint of the parameters - print_fingerprint(&options, &salt, &password); + let fingerprint = Fingerprint::from_data(&options, &salt, &password); + fingerprint.print(); + + if let Some(dir) = derive_options.checkpoint_dir { + checkpointing_interval = derive_options.checkpoint_interval.unwrap(); + + if output_key.is_none() { + output_key = Some(get_output_key()); + } + + checkpoint = Some(Checkpoint::new(&CheckpointOptions { + iterations: options.iterations, + dir: dir.to_owned(), + key: output_key.clone().unwrap(), + max_checkpoints_to_keep: derive_options.max_checkpoints_to_keep, + slowkey: options.clone(), + })); + + println!( + "Checkpoint will be created every {} iterations and saved to the \"{}\" checkpoints directory\n", + checkpointing_interval.to_string().cyan(), + &dir.to_string_lossy().cyan() + ); + } let mb = MultiProgress::new(); @@ -841,7 +830,7 @@ fn derive(derive_options: DeriveOptions) { Some(&prev_data_guard[..]) }; - out.save(&key, prev_data_option); + out.save(&key, prev_data_option, &fingerprint); println!("Saved encrypted output to \"{}\"\n", &out.path.to_str().unwrap().cyan(),); } diff --git a/src/utils/color_hash.rs b/src/utils/color_hash.rs index 93d49d9..525f170 100644 --- a/src/utils/color_hash.rs +++ b/src/utils/color_hash.rs @@ -4,7 +4,7 @@ use byteorder::{BigEndian, ReadBytesExt}; use crossterm::style::Color; pub fn color_hash(data: &[u8; 32]) -> Color { - let v = Cursor::new(data).read_u32::().expect("Hash is too small") as usize; + let v = Cursor::new(data).read_u32::().unwrap(); let b = (v & 0xFF) as u8; let g = ((v >> 8) & 0xFF) as u8; diff --git a/src/utils/outputs/fingerprint.rs b/src/utils/outputs/fingerprint.rs new file mode 100644 index 0000000..427b673 --- /dev/null +++ b/src/utils/outputs/fingerprint.rs @@ -0,0 +1,35 @@ +use crate::color_hash; +use crossterm::style::Stylize; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; + +use crate::slowkey::SlowKeyOptions; + +#[derive(Serialize, Deserialize, PartialEq, Clone)] +pub struct Fingerprint { + pub hash: [u8; 32], +} + +impl Fingerprint { + pub fn from_data(options: &SlowKeyOptions, salt: &[u8], password: &[u8]) -> Self { + let mut data = serde_json::to_string(&options).unwrap().as_bytes().to_vec(); + data.extend_from_slice(salt); + data.extend_from_slice(password); + + let mut sha256 = Sha256::new(); + sha256.update(data); + + Self { + hash: sha256.finalize().into(), + } + } + + pub fn print(&self) { + println!( + "Fingerprint: {}\n", + hex::encode(&self.hash[0..8]) + .to_uppercase() + .with(color_hash(&self.hash)) + ); + } +} diff --git a/src/utils/outputs/mod.rs b/src/utils/outputs/mod.rs index 2fc8484..8496261 100644 --- a/src/utils/outputs/mod.rs +++ b/src/utils/outputs/mod.rs @@ -1,2 +1,3 @@ +pub mod fingerprint; pub mod output; pub mod version; diff --git a/src/utils/outputs/output.rs b/src/utils/outputs/output.rs index 21f3a7c..19f90ab 100644 --- a/src/utils/outputs/output.rs +++ b/src/utils/outputs/output.rs @@ -1,3 +1,9 @@ +use super::{fingerprint::Fingerprint, version::Version}; +use crate::{ + slowkey::{SlowKey, SlowKeyOptions}, + utils::chacha20poly1305::{ChaCha20Poly1305, Nonce}, + DisplayOptions, +}; use base64::{engine::general_purpose, Engine as _}; use crossterm::style::Stylize; use serde::{Deserialize, Serialize}; @@ -7,14 +13,6 @@ use std::{ path::PathBuf, }; -use crate::{ - slowkey::{SlowKey, SlowKeyOptions}, - utils::chacha20poly1305::{ChaCha20Poly1305, Nonce}, - DisplayOptions, -}; - -use super::version::Version; - #[derive(PartialEq, Debug, Clone)] pub struct OutputOptions { pub path: PathBuf, @@ -102,6 +100,8 @@ impl OutputData { if display.options { self.data.slowkey.print(); } + + self.data.fingerprint.print(); } } @@ -109,6 +109,7 @@ impl OutputData { pub struct SlowKeyData { pub data: Vec, pub prev_data: Option>, + pub fingerprint: Fingerprint, pub slowkey: SlowKeyOptions, } @@ -162,7 +163,7 @@ impl Output { } } - pub fn save(&self, data: &[u8], prev_data: Option<&[u8]>) { + pub fn save(&self, data: &[u8], prev_data: Option<&[u8]>, fingerprint: &Fingerprint) { let file = File::create(&self.path).unwrap(); let mut writer = BufWriter::new(file); @@ -171,6 +172,7 @@ impl Output { data: SlowKeyData { data: data.to_vec(), prev_data: prev_data.map(|slice| slice.to_vec()), + fingerprint: fingerprint.clone(), slowkey: self.slowkey.clone(), }, };