fat: v0.1.1

This commit is contained in:
2025-10-24 23:32:35 +08:00
parent 7a96d533bd
commit 197b8df2ed
3 changed files with 26 additions and 17 deletions

4
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "aes" name = "aes"
@@ -325,7 +325,7 @@ dependencies = [
[[package]] [[package]]
name = "pinentry-cli" name = "pinentry-cli"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"clap", "clap",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "pinentry-cli" name = "pinentry-cli"
version = "0.1.0" version = "0.1.1"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@@ -1,5 +1,5 @@
use std::{env, fs};
use std::process::exit; use std::process::exit;
use std::{env, fs};
use aes_gcm_stream::Aes256GcmStreamEncryptor; use aes_gcm_stream::Aes256GcmStreamEncryptor;
use clap::Parser; use clap::Parser;
@@ -23,7 +23,7 @@ struct Cli {
/// Prompt in pinentry /// Prompt in pinentry
#[arg(long)] #[arg(long)]
pub prompt: Option<String>, pub prompt: Option<String>,
/// Encryption key, must be 32 bytes and in HEX format /// Encryption key, must be 32 bytes and in HEX format, '-' do not encrypt
#[arg(long, short = 'k')] #[arg(long, short = 'k')]
pub encryption_key: String, pub encryption_key: String,
/// Disable fallback to rpassword, default false /// Disable fallback to rpassword, default false
@@ -88,14 +88,22 @@ fn get_pin_entry(args: &Cli) -> String {
fn get_encryption_key(args: &Cli) -> Result<[u8; 32], PinResult> { fn get_encryption_key(args: &Cli) -> Result<[u8; 32], PinResult> {
let mut encryption_key = [0_u8; 32]; let mut encryption_key = [0_u8; 32];
if &args.encryption_key == "-" || &args.encryption_key == "--" {
// all 0 key, do not encrypt
return Ok(encryption_key);
}
match hex::decode(&args.encryption_key) { match hex::decode(&args.encryption_key) {
Ok(key) => { Ok(key) => {
if key.len() != 32 { if key.len() != 32 {
return Err(PinResult::new_error(format!("Bad encryption key length, expected 32, actual: {}", key.len()))); return Err(PinResult::new_error(format!(
"Bad encryption key length, expected 32, actual: {}",
key.len()
)));
} }
encryption_key.copy_from_slice(&key[..32]); encryption_key.copy_from_slice(&key[..32]);
} }
Err(e) => return Err(PinResult::new_error(format!("{}", e))) Err(e) => return Err(PinResult::new_error(format!("{}", e))),
}; };
Ok(encryption_key) Ok(encryption_key)
} }
@@ -120,25 +128,26 @@ fn get_pin(args: Cli) -> PinResult {
Ok(secret_string) => { Ok(secret_string) => {
PinResult::new_pin(&encryption_key, secret_string.expose_secret().to_string()) PinResult::new_pin(&encryption_key, secret_string.expose_secret().to_string())
} }
Err(e) => { Err(e) => PinResult::new_error(format!("{}", e)),
PinResult::new_error(format!("{}", e))
}
} }
} else if fallback_cli { } else if fallback_cli {
match rpassword::prompt_password(format!("{}: ", description)) { match rpassword::prompt_password(format!("{}: ", description)) {
Ok(pin) => { Ok(pin) => PinResult::new_pin(&encryption_key, pin),
PinResult::new_pin(&encryption_key, pin) Err(e) => PinResult::new_error(format!("{}", e)),
}
Err(e) => {
PinResult::new_error(format!("{}", e))
}
} }
} else { } else {
PinResult::new_error(String::from("pinentry not found and --disable-fallback-cli is turned on.")) PinResult::new_error(String::from(
"pinentry not found and --disable-fallback-cli is turned on.",
))
} }
} }
fn encrypt(key: &[u8; 32], pin: String) -> String { fn encrypt(key: &[u8; 32], pin: String) -> String {
if key == &[0_u8; 32] {
// DO NOT encrypt when key is all 0
return pin;
}
let nonce = random::<[u8; 12]>(); let nonce = random::<[u8; 12]>();
let mut encrypted = vec![]; let mut encrypted = vec![];
let mut encryptor = Aes256GcmStreamEncryptor::new(*key, &nonce); let mut encryptor = Aes256GcmStreamEncryptor::new(*key, &nonce);