feat: v1.12.10

This commit is contained in:
2025-05-06 23:47:18 +08:00
parent 81f7a6d77e
commit d6ecdb5ed4
13 changed files with 40 additions and 37 deletions

2
Cargo.lock generated
View File

@@ -508,7 +508,7 @@ dependencies = [
[[package]]
name = "card-cli"
version = "1.12.9"
version = "1.12.10"
dependencies = [
"aes-gcm-stream",
"authenticator 0.3.1",

View File

@@ -1,6 +1,6 @@
[package]
name = "card-cli"
version = "1.12.9"
version = "1.12.10"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"

View File

@@ -72,7 +72,7 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
}
KeyUri::YubikeyHmacEncSoftKey(key) => {
if key.algorithm.is_ecc() {
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(&key.hmac_enc_private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(&key.hmac_enc_private_key)?;
let p256_public_key = ecdsautil::parse_p256_private_key_to_public_key(&private_key).ok();
let p384_public_key = ecdsautil::parse_p384_private_key_to_public_key(&private_key).ok();
let p521_public_key = ecdsautil::parse_p521_private_key_to_public_key(&private_key).ok();
@@ -89,7 +89,7 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
simple_error!("Invalid hmac enc private key")
} else if key.algorithm.is_rsa() {
use rsa::pkcs8::DecodePrivateKey;
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(&key.hmac_enc_private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(&key.hmac_enc_private_key)?;
let private_key_der = base64_decode(&private_key)?;
let rsa_private_key = RsaPrivateKey::from_pkcs8_der(&private_key_der)?;
Ok(rsa_private_key.to_public_key().to_public_key_der()?.to_vec())

View File

@@ -95,7 +95,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
}
KeyUri::YubikeyHmacEncSoftKey(key) => {
if key.algorithm.is_ecc() {
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(&key.hmac_enc_private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(&key.hmac_enc_private_key)?;
let (jwt_algorithm, private_key_d) = parse_ecdsa_private_key(&private_key)?;
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?;
@@ -110,7 +110,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
Ok(signed_data)
} else if key.algorithm.is_rsa() {
use rsa::pkcs8::DecodePrivateKey;
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(&key.hmac_enc_private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(&key.hmac_enc_private_key)?;
let private_key_der = base64_decode(&private_key)?;
let rsa_private_key = RsaPrivateKey::from_pkcs8_der(&private_key_der)?;

View File

@@ -32,7 +32,11 @@ impl Command for CommandImpl {
let ciphertext = sub_arg_matches.value_of("ciphertext").unwrap();
let auto_pbe = sub_arg_matches.is_present("auto-pbe");
let text = hmac_decrypt(ciphertext, auto_pbe)?;
let text = if pbeutil::is_simple_pbe_encrypted(ciphertext) {
pbeutil::simple_pbe_decrypt_with_prompt_to_string(&ciphertext)?
} else {
hmac_decrypt(ciphertext, auto_pbe)?
};
if json_output {
let mut json = BTreeMap::<&'_ str, String>::new();
@@ -47,9 +51,11 @@ impl Command for CommandImpl {
}
}
pub fn try_hmac_decrypt(ciphertext: &str) -> XResult<String> {
pub fn try_decrypt(ciphertext: &str) -> XResult<String> {
if is_hmac_encrypted(ciphertext) {
hmac_decrypt(ciphertext, true)
} else if pbeutil::is_simple_pbe_encrypted(ciphertext) {
pbeutil::simple_pbe_decrypt_with_prompt_to_string(&ciphertext)
} else {
Ok(ciphertext.to_string())
}
@@ -58,7 +64,7 @@ pub fn try_hmac_decrypt(ciphertext: &str) -> XResult<String> {
pub fn hmac_decrypt(ciphertext: &str, auto_pbe: bool) -> XResult<String> {
let text = hmac_decrypt_to_string(ciphertext)?;
if auto_pbe && pbeutil::is_simple_pbe_encrypted(&text) {
Ok(pbeutil::simple_pbe_decrypt_with_prompt_to_string(&text)?)
pbeutil::simple_pbe_decrypt_with_prompt_to_string(&text)
} else {
Ok(text)
}

View File

@@ -31,22 +31,24 @@ impl Command for CommandImpl {
let json_output = cmdutil::check_json_output(sub_arg_matches);
let text = sub_arg_matches.value_of("plaintext").unwrap().to_string();
let hmac_encrypt_ciphertext = hmac_encrypt(&text, &mut None, sub_arg_matches)?;
let ciphertext = do_encrypt(&text, &mut None, sub_arg_matches)?;
let ciphertext = hmacutil::hmac_encrypt_from_string(&ciphertext)?;
if json_output {
let mut json = BTreeMap::<&'_ str, String>::new();
json.insert("ciphertext", hmac_encrypt_ciphertext);
json.insert("ciphertext", ciphertext);
util::print_pretty_json(&json);
} else {
success!("HMAC encrypt ciphertext: {}", hmac_encrypt_ciphertext);
success!("HMAC encrypt ciphertext: {}", ciphertext);
}
Ok(None)
}
}
pub fn hmac_encrypt(text: &str, password_opt: &mut Option<String>, sub_arg_matches: &ArgMatches) -> XResult<String> {
pub fn do_encrypt(text: &str, password_opt: &mut Option<String>, sub_arg_matches: &ArgMatches) -> XResult<String> {
let with_hmac_encrypt = sub_arg_matches.is_present("with-hmac-encrypt");
let with_pbe_encrypt = sub_arg_matches.is_present("with-pbe-encrypt");
let text = if with_pbe_encrypt {
let double_pin_check = sub_arg_matches.is_present("double-pin-check");
@@ -56,5 +58,9 @@ pub fn hmac_encrypt(text: &str, password_opt: &mut Option<String>, sub_arg_match
} else {
text.to_string()
};
if with_hmac_encrypt {
Ok(hmacutil::hmac_encrypt_from_string(&text)?)
} else {
Ok(text)
}
}

View File

@@ -2,7 +2,7 @@ use crate::ecdsautil::EcdsaAlgorithm;
use crate::keychain::{KeychainKey, KeychainKeyValue};
use crate::keyutil::{KeyAlgorithmId, KeyUri, YubikeyHmacEncSoftKey};
use crate::util::base64_encode;
use crate::{cmd_hmac_encrypt, cmdutil, ecdsautil, rsautil, util, yubikeyutil};
use crate::{cmd_hmac_encrypt, cmdutil, ecdsautil, hmacutil, pbeutil, rsautil, util, yubikeyutil};
use clap::{App, Arg, ArgMatches, SubCommand};
use rust_util::util_clap::{Command, CommandError};
use std::collections::BTreeMap;
@@ -35,7 +35,6 @@ impl Command for CommandImpl {
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let json_output = cmdutil::check_json_output(sub_arg_matches);
let with_hmac_encrypt = sub_arg_matches.is_present("with-hmac-encrypt");
let key_type = sub_arg_matches.value_of("type").unwrap().to_lowercase();
let keychain_name = sub_arg_matches.value_of("keychain-name");
@@ -71,14 +70,10 @@ impl Command for CommandImpl {
};
let mut password_opt = None;
let (pkcs8_base64, secret_key_pem) = if with_hmac_encrypt {
(
cmd_hmac_encrypt::hmac_encrypt(&pkcs8_base64, &mut password_opt, sub_arg_matches)?,
cmd_hmac_encrypt::hmac_encrypt(&secret_key_pem, &mut password_opt, sub_arg_matches)?,
)
} else {
(pkcs8_base64, secret_key_pem)
};
let (pkcs8_base64, secret_key_pem) = (
cmd_hmac_encrypt::do_encrypt(&pkcs8_base64, &mut password_opt, sub_arg_matches)?,
cmd_hmac_encrypt::do_encrypt(&secret_key_pem, &mut password_opt, sub_arg_matches)?,
);
let public_key_base64 = base64_encode(&public_key_der);
let keychain_key_uri = if let Some(keychain_name) = keychain_name {
@@ -114,7 +109,8 @@ impl Command for CommandImpl {
"rsa4096" => Some(KeyAlgorithmId::Rsa4096),
_ => None,
};
if let (true, Some(algorithm_id)) = (with_hmac_encrypt, algorithm_id) {
let with_encrypt = hmacutil::is_hmac_encrypted(&pkcs8_base64) || pbeutil::is_simple_pbe_encrypted(&pkcs8_base64);
if let (true, Some(algorithm_id)) = (with_encrypt, algorithm_id) {
let yk = yubikeyutil::open_yubikey()?;
let yubikey_hmac_enc_soft_key = YubikeyHmacEncSoftKey {
key_name: format!("yubikey{}-{}", yk.version().major, yk.serial().0),

View File

@@ -35,7 +35,7 @@ impl Command for CommandImpl {
let key = sub_arg_matches.value_of("key").unwrap();
let epk = sub_arg_matches.value_of("epk").unwrap();
let key = cmd_hmac_decrypt::try_hmac_decrypt(key)?;
let key = cmd_hmac_decrypt::try_decrypt(key)?;
let key_uri = parse_key_uri(&key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri);

View File

@@ -45,7 +45,7 @@ impl Command for CommandImpl {
Some(input) => input.as_bytes().to_vec(),
};
let key = cmd_hmac_decrypt::try_hmac_decrypt(key)?;
let key = cmd_hmac_decrypt::try_decrypt(key)?;
let key_uri = parse_key_uri(&key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri);

View File

@@ -6,7 +6,7 @@ use p256::PublicKey;
use rust_util::util_clap::{Command, CommandError};
use spki::DecodePublicKey;
use std::collections::BTreeMap;
use crate::cmd_hmac_encrypt::hmac_encrypt;
use crate::cmd_hmac_encrypt;
pub struct CommandImpl;
@@ -67,12 +67,7 @@ impl Command for CommandImpl {
private_key,
);
let with_hmac_encrypt = sub_arg_matches.is_present("with-hmac-encrypt");
let key_uri = if with_hmac_encrypt {
hmac_encrypt(&key_uri, &mut None, sub_arg_matches)?
} else {
key_uri
};
let key_uri = cmd_hmac_encrypt::do_encrypt(&key_uri, &mut None, sub_arg_matches)?;
print_se_key(json_output, &public_key_point, &public_key_der, &key_uri);
Ok(None)

View File

@@ -23,7 +23,7 @@ impl Command for CommandImpl {
seutil::check_se_supported()?;
let key = sub_arg_matches.value_of("key").unwrap();
let key = cmd_hmac_decrypt::try_hmac_decrypt(key)?;
let key = cmd_hmac_decrypt::try_decrypt(key)?;
let key_uri = parse_key_uri(&key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri);

View File

@@ -34,7 +34,7 @@ impl Command for CommandImpl {
sub_arg_matches.value_of("key"),
"Private key PKCS#8 DER base64 encoded or PEM"
);
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(private_key)?;
let key_uri = parse_key_uri(&private_key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri);

View File

@@ -33,7 +33,7 @@ impl Command for CommandImpl {
"Private key PKCS#8 DER base64 encoded or PEM"
);
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(private_key)?;
let private_key = cmd_hmac_decrypt::try_decrypt(private_key)?;
let private_key = if keychain::is_keychain_key_uri(&private_key) {
debugging!("Private key keychain key URI: {}", &private_key);