feat: keychain-name, but tests not passed
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1753,7 +1753,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-encrypt"
|
name = "tiny-encrypt"
|
||||||
version = "1.7.0"
|
version = "1.7.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm-stream",
|
"aes-gcm-stream",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tiny-encrypt"
|
name = "tiny-encrypt"
|
||||||
version = "1.7.0"
|
version = "1.7.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "A simple and tiny file encrypt tool"
|
description = "A simple and tiny file encrypt tool"
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ pub struct CmdInitKeychain {
|
|||||||
#[arg(long, short = 'E')]
|
#[arg(long, short = 'E')]
|
||||||
pub expose_secure_enclave_private_key: bool,
|
pub expose_secure_enclave_private_key: bool,
|
||||||
|
|
||||||
// /// Keychain name, or default
|
/// Keychain name, or default [--keychain-name not works yet]
|
||||||
// #[arg(long, short = 'c')]
|
#[arg(long, short = 'c')]
|
||||||
// pub keychain_name: Option<String>,
|
pub keychain_name: Option<String>,
|
||||||
|
|
||||||
/// Service name, or default: tiny-encrypt
|
/// Service name, or default: tiny-encrypt
|
||||||
#[arg(long, short = 's')]
|
#[arg(long, short = 's')]
|
||||||
@@ -55,6 +55,7 @@ pub fn keychain_key_se(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
|
|||||||
return simple_error!("Secure enclave is not supported.");
|
return simple_error!("Secure enclave is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let keychain_name = cmd_init_keychain.keychain_name.as_ref().map(String::as_str).unwrap_or("");
|
||||||
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 key_name = &cmd_init_keychain.key_name;
|
let key_name = &cmd_init_keychain.key_name;
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ pub fn keychain_key_se(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
|
|||||||
let saved_arg0 = if cmd_init_keychain.expose_secure_enclave_private_key {
|
let saved_arg0 = if cmd_init_keychain.expose_secure_enclave_private_key {
|
||||||
private_key_base64
|
private_key_base64
|
||||||
} else {
|
} else {
|
||||||
let keychain_key = KeychainKey::from_default_keychain(service_name, key_name);
|
let keychain_key = KeychainKey::from(keychain_name, service_name, key_name);
|
||||||
keychain_key.set_password(private_key_base64.as_bytes())?;
|
keychain_key.set_password(private_key_base64.as_bytes())?;
|
||||||
keychain_key.to_str()
|
keychain_key.to_str()
|
||||||
};
|
};
|
||||||
@@ -84,9 +85,10 @@ pub fn keychain_key_se(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn keychain_key_static(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
|
pub fn keychain_key_static(cmd_init_keychain: CmdInitKeychain) -> XResult<()> {
|
||||||
|
let keychain_name = cmd_init_keychain.keychain_name.as_ref().map(String::as_str).unwrap_or("");
|
||||||
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 key_name = &cmd_init_keychain.key_name;
|
let key_name = &cmd_init_keychain.key_name;
|
||||||
let keychain_key = KeychainKey::from_default_keychain(service_name, key_name);
|
let keychain_key = KeychainKey::from(keychain_name, service_name, key_name);
|
||||||
|
|
||||||
let mut envelop_type = match &cmd_init_keychain.algorithm {
|
let mut envelop_type = match &cmd_init_keychain.algorithm {
|
||||||
None => TinyEncryptEnvelopType::StaticX25519,
|
None => TinyEncryptEnvelopType::StaticX25519,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use pqcrypto_kyber::kyber1024::Ciphertext as Kyber1024Ciphertext;
|
|||||||
use pqcrypto_kyber::kyber1024::PublicKey as Kyber1024PublicKey;
|
use pqcrypto_kyber::kyber1024::PublicKey as Kyber1024PublicKey;
|
||||||
use pqcrypto_kyber::kyber1024::SecretKey as Kyber1024SecretKey;
|
use pqcrypto_kyber::kyber1024::SecretKey as Kyber1024SecretKey;
|
||||||
use rust_util::{debugging, opt_result, opt_value_result, simple_error, XResult};
|
use rust_util::{debugging, opt_result, opt_value_result, simple_error, XResult};
|
||||||
use security_framework::os::macos::keychain::SecKeychain;
|
use security_framework::os::macos::keychain::{CreateOptions, SecKeychain};
|
||||||
use x25519_dalek::{PublicKey, StaticSecret};
|
use x25519_dalek::{PublicKey, StaticSecret};
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
@@ -138,11 +138,8 @@ impl KeychainStaticSecret {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeychainKey {
|
impl KeychainKey {
|
||||||
pub fn from_default_keychain(service_name: &str, key_name: &str) -> Self {
|
|
||||||
Self::from("", service_name, key_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from(keychain_name: &str, service_name: &str, key_name: &str) -> Self {
|
pub fn from(keychain_name: &str, service_name: &str, key_name: &str) -> Self {
|
||||||
|
debugging!("Keychain key: {} - {} - {}", keychain_name, service_name, key_name);
|
||||||
Self {
|
Self {
|
||||||
keychain_name: keychain_name.to_string(),
|
keychain_name: keychain_name.to_string(),
|
||||||
service_name: service_name.to_string(),
|
service_name: service_name.to_string(),
|
||||||
@@ -179,6 +176,7 @@ impl KeychainKey {
|
|||||||
|
|
||||||
pub fn get_password(&self) -> XResult<Option<Vec<u8>>> {
|
pub fn get_password(&self) -> XResult<Option<Vec<u8>>> {
|
||||||
let sec_keychain = self.get_keychain()?;
|
let sec_keychain = self.get_keychain()?;
|
||||||
|
debugging!("Try find generic password: {}.{}", &self.service_name, &self.key_name);
|
||||||
match sec_keychain.find_generic_password(&self.service_name, &self.key_name) {
|
match sec_keychain.find_generic_password(&self.service_name, &self.key_name) {
|
||||||
Ok((item_password, _keychain_item)) => {
|
Ok((item_password, _keychain_item)) => {
|
||||||
Ok(Some(item_password.as_ref().to_vec()))
|
Ok(Some(item_password.as_ref().to_vec()))
|
||||||
@@ -204,10 +202,21 @@ impl KeychainKey {
|
|||||||
|
|
||||||
fn get_keychain(&self) -> XResult<SecKeychain> {
|
fn get_keychain(&self) -> XResult<SecKeychain> {
|
||||||
if !self.keychain_name.is_empty() {
|
if !self.keychain_name.is_empty() {
|
||||||
return simple_error!("Keychain name must be empty.");
|
// TODO --keychain-name test failed
|
||||||
|
debugging!("Open or create keychain: {}", &self.keychain_name);
|
||||||
|
let keychain_path = format!("{}.keychain", &self.keychain_name);
|
||||||
|
debugging!("Keychain path: {}", &keychain_path);
|
||||||
|
match SecKeychain::open(&keychain_path) {
|
||||||
|
Ok(sec_keychain) => Ok(sec_keychain),
|
||||||
|
Err(e) => match CreateOptions::new().prompt_user(true).create(&keychain_path) {
|
||||||
|
Ok(sec_keychain) => Ok(sec_keychain),
|
||||||
|
Err(ce) => simple_error!("Open keychain: {}, failed: {}, create also failed: {}", &self.keychain_name, e, ce)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Ok(opt_result!(SecKeychain::default(), "Get keychain failed: {}"))
|
Ok(opt_result!(SecKeychain::default(), "Get keychain failed: {}"))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrypt_x25519_data(keychain_key: &KeychainKey, ephemeral_public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
|
pub fn decrypt_x25519_data(keychain_key: &KeychainKey, ephemeral_public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
|
||||||
|
|||||||
Reference in New Issue
Block a user