feat: v1.4.3, init static x25519 when exists

This commit is contained in:
2023-12-10 12:32:46 +08:00
parent c393302d6c
commit 7ee38b8ac5
4 changed files with 32 additions and 15 deletions

2
Cargo.lock generated
View File

@@ -1700,7 +1700,7 @@ dependencies = [
[[package]] [[package]]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "1.4.2" version = "1.4.3"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"base64", "base64",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "1.4.2" version = "1.4.3"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
description = "A simple and tiny file encrypt tool" description = "A simple and tiny file encrypt tool"

View File

@@ -1,5 +1,5 @@
use clap::Args; use clap::Args;
use rust_util::{debugging, information, opt_result, opt_value_result, simple_error, success, XResult}; use rust_util::{debugging, information, opt_result, opt_value_result, simple_error, success, warning, XResult};
use security_framework::os::macos::keychain::SecKeychain; use security_framework::os::macos::keychain::SecKeychain;
use crate::config::TinyEncryptConfigEnvelop; use crate::config::TinyEncryptConfigEnvelop;
@@ -7,6 +7,7 @@ use crate::spec::TinyEncryptEnvelopType;
#[cfg(feature = "secure-enclave")] #[cfg(feature = "secure-enclave")]
use crate::util_keychainkey; use crate::util_keychainkey;
use crate::util_keychainstatic; use crate::util_keychainstatic;
use crate::util_keychainstatic::X25519StaticSecret;
#[derive(Debug, Args)] #[derive(Debug, Args)]
pub struct CmdInitKeychain { pub struct CmdInitKeychain {
@@ -66,18 +67,25 @@ pub fn keychain_key_static(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
let service_name = cmd_init_keychain.server_name.as_deref().unwrap_or(DEFAULT_SERVICE_NAME); let service_name = cmd_init_keychain.server_name.as_deref().unwrap_or(DEFAULT_SERVICE_NAME);
let sec_keychain = opt_result!(SecKeychain::default(), "Get keychain failed: {}"); let sec_keychain = opt_result!(SecKeychain::default(), "Get keychain failed: {}");
let key_name = opt_value_result!(&cmd_init_keychain.key_name, "Key name is required."); let key_name = opt_value_result!(&cmd_init_keychain.key_name, "Key name is required.");
if sec_keychain.find_generic_password(service_name, key_name).is_ok() {
return simple_error!("Static x25519 exists: {}.{}", service_name, &key_name);
}
let (keychain_key, public_key) = util_keychainstatic::generate_static_x25519_secret(); let public_key = match sec_keychain.find_generic_password(service_name, key_name) {
opt_result!( Ok((static_x25519, _)) => {
sec_keychain.set_generic_password(service_name, key_name, keychain_key.as_bytes()), warning!("Key already exists: {}.{}", service_name, key_name);
"Write static x25519 failed: {}" let x25519_static_secret = X25519StaticSecret::parse_bytes(&static_x25519.as_ref())?;
); x25519_static_secret.to_public_key()?
}
Err(_) => {
let (keychain_key, public_key) = util_keychainstatic::generate_static_x25519_secret();
debugging!("Keychain key : {}", keychain_key);
opt_result!(
sec_keychain.set_generic_password(service_name, key_name, keychain_key.as_bytes()),
"Write static x25519 failed: {}"
);
public_key
}
};
let public_key_hex = hex::encode(public_key.as_bytes()); let public_key_hex = hex::encode(public_key.as_bytes());
debugging!("Keychain key : {}", keychain_key);
success!("Keychain name: {}", &key_name); success!("Keychain name: {}", &key_name);
success!("Public key : {}", &public_key_hex); success!("Public key : {}", &public_key_hex);

View File

@@ -16,6 +16,11 @@ impl Zeroize for X25519StaticSecret {
} }
impl X25519StaticSecret { impl X25519StaticSecret {
pub fn parse_bytes(bs: &[u8]) -> XResult<Self> {
let key_str = opt_result!(String::from_utf8(bs.to_vec()), "Parse static x25519 failed: {}");
Self::parse(&key_str)
}
pub fn parse(key: &str) -> XResult<Self> { pub fn parse(key: &str) -> XResult<Self> {
if !key.starts_with(X2559_PLAIN_PREFIX) { if !key.starts_with(X2559_PLAIN_PREFIX) {
return simple_error!("Not X25519 plain key"); return simple_error!("Not X25519 plain key");
@@ -47,16 +52,20 @@ impl X25519StaticSecret {
inner_secret.zeroize(); inner_secret.zeroize();
Ok(static_secret) Ok(static_secret)
} }
pub fn to_public_key(&self) -> XResult<PublicKey> {
let static_secret = self.to_static_secret()?;
let public_key: PublicKey = (&static_secret).into();
Ok(public_key)
}
} }
pub fn decrypt_data(service_name: &str, key_name: &str, ephemeral_public_key_bytes: &[u8]) -> XResult<Vec<u8>> { pub fn decrypt_data(service_name: &str, key_name: &str, ephemeral_public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
let sec_keychain = opt_result!(SecKeychain::default(), "Get keychain failed: {}"); let sec_keychain = opt_result!(SecKeychain::default(), "Get keychain failed: {}");
let (static_x25519, _) = opt_result!(sec_keychain.find_generic_password(service_name, key_name), let (static_x25519, _) = opt_result!(sec_keychain.find_generic_password(service_name, key_name),
"Cannot find static x25519 {}.{}: {}", service_name, key_name); "Cannot find static x25519 {}.{}: {}", service_name, key_name);
let static_x25519_bytes = static_x25519.as_ref();
let static_x25519_str = opt_result!(String::from_utf8(static_x25519_bytes.to_vec()), "Parse static x25519 failed: {}");
let x25519_static_secret = X25519StaticSecret::parse(&static_x25519_str)?; let x25519_static_secret = X25519StaticSecret::parse_bytes(static_x25519.as_ref())?;
let static_secret = x25519_static_secret.to_static_secret()?; let static_secret = x25519_static_secret.to_static_secret()?;
let inner_ephemeral_public_key: [u8; 32] = opt_result!( let inner_ephemeral_public_key: [u8; 32] = opt_result!(
ephemeral_public_key_bytes.try_into(), "X25519 public key error: {}"); ephemeral_public_key_bytes.try_into(), "X25519 public key error: {}");