feat: v1.12.9
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage};
|
||||
use crate::util::{base64_decode, base64_encode};
|
||||
use crate::yubikeyutil::find_key_or_error;
|
||||
use crate::{cmdutil, ecdsautil, hmacutil, seutil, util, yubikeyutil};
|
||||
use crate::{cmd_hmac_decrypt, cmdutil, ecdsautil, seutil, util, yubikeyutil};
|
||||
use clap::{App, ArgMatches, SubCommand};
|
||||
use ecdsa::elliptic_curve::pkcs8::der::Encode;
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
@@ -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 = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_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 = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_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())
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::keyutil::{parse_key_uri, KeyAlgorithmId, KeyUri, KeyUsage, YubikeyPiv
|
||||
use crate::pivutil::ToStr;
|
||||
use crate::rsautil::RsaSignAlgorithm;
|
||||
use crate::util::{base64_decode, base64_encode};
|
||||
use crate::{cmdutil, ecdsautil, hmacutil, pivutil, rsautil, seutil, util, yubikeyutil};
|
||||
use crate::{cmd_hmac_decrypt, cmdutil, ecdsautil, pivutil, rsautil, seutil, util, yubikeyutil};
|
||||
use clap::{App, ArgMatches, SubCommand};
|
||||
use jwt::AlgorithmType;
|
||||
use rsa::RsaPrivateKey;
|
||||
@@ -95,7 +95,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
|
||||
}
|
||||
KeyUri::YubikeyHmacEncSoftKey(key) => {
|
||||
if key.algorithm.is_ecc() {
|
||||
let private_key = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_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 = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_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)?;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::{cmdutil, hmacutil, pbeutil, util};
|
||||
use rust_util::XResult;
|
||||
use crate::{cmdutil, pbeutil, util};
|
||||
use crate::hmacutil::{hmac_decrypt_to_string, is_hmac_encrypted};
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -29,12 +30,9 @@ impl Command for CommandImpl {
|
||||
let json_output = cmdutil::check_json_output(sub_arg_matches);
|
||||
|
||||
let ciphertext = sub_arg_matches.value_of("ciphertext").unwrap();
|
||||
let mut text = hmacutil::hmac_decrypt_to_string(ciphertext)?;
|
||||
|
||||
let auto_pbe = sub_arg_matches.is_present("auto-pbe");
|
||||
if auto_pbe && pbeutil::is_simple_pbe_encrypted(&text) {
|
||||
text = pbeutil::simple_pbe_decrypt_with_prompt_to_string(&text)?;
|
||||
}
|
||||
|
||||
let text = hmac_decrypt(ciphertext, auto_pbe)?;
|
||||
|
||||
if json_output {
|
||||
let mut json = BTreeMap::<&'_ str, String>::new();
|
||||
@@ -48,3 +46,20 @@ impl Command for CommandImpl {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_hmac_decrypt(ciphertext: &str) -> XResult<String> {
|
||||
if is_hmac_encrypted(ciphertext) {
|
||||
hmac_decrypt(ciphertext, true)
|
||||
} else {
|
||||
Ok(ciphertext.to_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)?)
|
||||
} else {
|
||||
Ok(text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use rust_util::XResult;
|
||||
use crate::{cmdutil, hmacutil, pbeutil, util};
|
||||
|
||||
pub struct CommandImpl;
|
||||
@@ -21,24 +21,17 @@ impl Command for CommandImpl {
|
||||
.required(true)
|
||||
.help("Plaintext"),
|
||||
)
|
||||
.arg(Arg::with_name("with-pbe").long("with-pbe").help("With PBE encryption"))
|
||||
.arg(Arg::with_name("double-pin-check").long("double-pin-check").help("Double PIN check"))
|
||||
.arg(Arg::with_name("pbe-iteration").long("pbe-iteration").takes_value(true).help("PBE iteration, default 100000"))
|
||||
.arg(cmdutil::build_with_pbe_encrypt_arg())
|
||||
.arg(cmdutil::build_double_pin_check_arg())
|
||||
.arg(cmdutil::build_pbe_iteration_arg())
|
||||
.arg(cmdutil::build_json_arg())
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let json_output = cmdutil::check_json_output(sub_arg_matches);
|
||||
|
||||
let mut text = sub_arg_matches.value_of("plaintext").unwrap().to_string();
|
||||
let with_pbe = sub_arg_matches.is_present("with-pbe");
|
||||
if with_pbe {
|
||||
let double_pin_check = sub_arg_matches.is_present("double-pin-check");
|
||||
let iteration = sub_arg_matches.value_of("pbe-iteration")
|
||||
.map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000);
|
||||
text = pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, &text, double_pin_check)?;
|
||||
}
|
||||
let hmac_encrypt_ciphertext = hmacutil::hmac_encrypt_from_string(&text)?;
|
||||
let text = sub_arg_matches.value_of("plaintext").unwrap().to_string();
|
||||
let hmac_encrypt_ciphertext = hmac_encrypt(&text, &mut None, sub_arg_matches)?;
|
||||
|
||||
if json_output {
|
||||
let mut json = BTreeMap::<&'_ str, String>::new();
|
||||
@@ -52,3 +45,16 @@ impl Command for CommandImpl {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hmac_encrypt(text: &str, password_opt: &mut Option<String>, sub_arg_matches: &ArgMatches) -> XResult<String> {
|
||||
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");
|
||||
let iteration = sub_arg_matches.value_of("pbe-iteration")
|
||||
.map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000);
|
||||
pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, &text, password_opt, double_pin_check)?
|
||||
} else {
|
||||
text.to_string()
|
||||
};
|
||||
Ok(hmacutil::hmac_encrypt_from_string(&text)?)
|
||||
}
|
||||
|
||||
@@ -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::{cmdutil, ecdsautil, hmacutil, rsautil, util, yubikeyutil};
|
||||
use crate::{cmd_hmac_encrypt, cmdutil, ecdsautil, rsautil, util, yubikeyutil};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use std::collections::BTreeMap;
|
||||
@@ -24,11 +24,10 @@ impl Command for CommandImpl {
|
||||
.takes_value(true)
|
||||
.help("Key type (e.g. p256, p384, p521, rsa1024, rsa2048, rsa3072, rsa4096)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("with-hmac-encrypt")
|
||||
.long("with-hmac-encrypt")
|
||||
.help("With HMAC encrypt"),
|
||||
)
|
||||
.arg(cmdutil::build_with_hmac_encrypt_arg())
|
||||
.arg(cmdutil::build_with_pbe_encrypt_arg())
|
||||
.arg(cmdutil::build_double_pin_check_arg())
|
||||
.arg(cmdutil::build_pbe_iteration_arg())
|
||||
.arg(cmdutil::build_keychain_name_arg())
|
||||
.arg(cmdutil::build_json_arg())
|
||||
}
|
||||
@@ -71,10 +70,11 @@ impl Command for CommandImpl {
|
||||
return simple_error!("Unsupported key type: {}", key_type);
|
||||
};
|
||||
|
||||
let mut password_opt = None;
|
||||
let (pkcs8_base64, secret_key_pem) = if with_hmac_encrypt {
|
||||
(
|
||||
hmacutil::hmac_encrypt_from_string(&pkcs8_base64)?,
|
||||
hmacutil::hmac_encrypt_from_string(&secret_key_pem)?,
|
||||
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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::keyutil::parse_key_uri;
|
||||
use crate::{cmdutil, seutil, util};
|
||||
use crate::{cmd_hmac_decrypt, cmdutil, seutil, util};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use p256::elliptic_curve::sec1::FromEncodedPoint;
|
||||
use p256::{EncodedPoint, PublicKey};
|
||||
@@ -41,7 +41,8 @@ impl Command for CommandImpl {
|
||||
let key = sub_arg_matches.value_of("key").unwrap();
|
||||
let epk = sub_arg_matches.value_of("epk").unwrap();
|
||||
|
||||
let key_uri = parse_key_uri(key)?;
|
||||
let key = cmd_hmac_decrypt::try_hmac_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);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::keyutil::parse_key_uri;
|
||||
use crate::{cmdutil, seutil, util};
|
||||
use crate::{cmd_hmac_decrypt, cmdutil, seutil, util};
|
||||
use crate::util::{base64_decode, base64_encode};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
@@ -51,7 +51,8 @@ impl Command for CommandImpl {
|
||||
Some(input) => input.as_bytes().to_vec(),
|
||||
};
|
||||
|
||||
let key_uri = parse_key_uri(key)?;
|
||||
let key = cmd_hmac_decrypt::try_hmac_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);
|
||||
|
||||
|
||||
@@ -6,6 +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;
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -36,6 +37,10 @@ impl Command for CommandImpl {
|
||||
.long("disable-bio")
|
||||
.help("Disable bio"),
|
||||
)
|
||||
.arg(cmdutil::build_with_hmac_encrypt_arg())
|
||||
.arg(cmdutil::build_with_pbe_encrypt_arg())
|
||||
.arg(cmdutil::build_double_pin_check_arg())
|
||||
.arg(cmdutil::build_pbe_iteration_arg())
|
||||
.arg(cmdutil::build_json_arg())
|
||||
}
|
||||
|
||||
@@ -62,6 +67,13 @@ 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
|
||||
};
|
||||
|
||||
print_se_key(json_output, &public_key_point, &public_key_der, &key_uri);
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use serde_json::{Map, Value};
|
||||
use crate::cmd_sign_jwt::{build_jwt_parts, merge_header_claims, merge_payload_claims, print_jwt_token};
|
||||
use crate::ecdsautil::parse_ecdsa_to_rs;
|
||||
use crate::keyutil::parse_key_uri;
|
||||
use crate::{cmd_sign_jwt, cmdutil, hmacutil, util};
|
||||
use crate::{cmd_hmac_decrypt, cmd_sign_jwt, cmdutil, util};
|
||||
use crate::util::base64_decode;
|
||||
|
||||
const SEPARATOR: &str = ".";
|
||||
@@ -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 = hmacutil::try_hmac_decrypt_to_string(private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_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);
|
||||
|
||||
@@ -6,7 +6,7 @@ use serde_json::{Map, Value};
|
||||
|
||||
use crate::cmd_sign_jwt::{build_jwt_parts, digest_by_jwt_algorithm, merge_header_claims, merge_payload_claims, print_jwt_token};
|
||||
use crate::keychain::{KeychainKey, KeychainKeyValue};
|
||||
use crate::{cmd_sign_jwt, cmdutil, ecdsautil, hmacutil, keychain, util};
|
||||
use crate::{cmd_hmac_decrypt, cmd_sign_jwt, cmdutil, ecdsautil, keychain, util};
|
||||
use crate::ecdsautil::{EcdsaAlgorithm, EcdsaSignType};
|
||||
|
||||
const SEPARATOR: &str = ".";
|
||||
@@ -33,7 +33,7 @@ impl Command for CommandImpl {
|
||||
"Private key PKCS#8 DER base64 encoded or PEM"
|
||||
);
|
||||
|
||||
let private_key = hmacutil::try_hmac_decrypt_to_string(private_key)?;
|
||||
let private_key = cmd_hmac_decrypt::try_hmac_decrypt(private_key)?;
|
||||
|
||||
let private_key = if keychain::is_keychain_key_uri(&private_key) {
|
||||
debugging!("Private key keychain key URI: {}", &private_key);
|
||||
|
||||
@@ -9,6 +9,22 @@ pub fn build_slot_arg() -> Arg<'static, 'static> {
|
||||
.help("PIV slot, e.g. 82, 83 ... 95, 9a, 9c, 9d, 9e")
|
||||
}
|
||||
|
||||
pub fn build_with_hmac_encrypt_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("with-hmac-encrypt").long("with-hmac-encrypt").help("With HMAC encrypt")
|
||||
}
|
||||
|
||||
pub fn build_with_pbe_encrypt_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("with-pbe-encrypt").long("with-pbe-encrypt").help("With PBE encryption")
|
||||
}
|
||||
|
||||
pub fn build_double_pin_check_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("double-pin-check").long("double-pin-check").help("Double PIN check")
|
||||
}
|
||||
|
||||
pub fn build_pbe_iteration_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("pbe-iteration").long("pbe-iteration").takes_value(true).help("PBE iteration, default 100000")
|
||||
}
|
||||
|
||||
pub fn build_serial_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("serial").long("serial").takes_value(true).help("Serial number")
|
||||
}
|
||||
|
||||
@@ -44,14 +44,6 @@ pub fn is_hmac_encrypted(ciphertext: &str) -> bool {
|
||||
ciphertext.starts_with(HMAC_ENC_PREFIX)
|
||||
}
|
||||
|
||||
pub fn try_hmac_decrypt_to_string(ciphertext: &str) -> XResult<String> {
|
||||
if is_hmac_encrypted(ciphertext) {
|
||||
hmac_decrypt_to_string(ciphertext)
|
||||
} else {
|
||||
Ok(ciphertext.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hmac_decrypt_to_string(ciphertext: &str) -> XResult<String> {
|
||||
let plaintext = hmac_decrypt(ciphertext)?;
|
||||
Ok(String::from_utf8(plaintext)?)
|
||||
|
||||
@@ -7,8 +7,8 @@ use rust_util::XResult;
|
||||
|
||||
const PBE_ENC_PREFIX: &str = "pbe_enc:";
|
||||
|
||||
pub fn simple_pbe_encrypt_with_prompt_from_string(iteration: u32, plaintext: &str, password_double_check: bool) -> XResult<String> {
|
||||
simple_pbe_encrypt_with_prompt(iteration, plaintext.as_bytes(), password_double_check)
|
||||
pub fn simple_pbe_encrypt_with_prompt_from_string(iteration: u32, plaintext: &str, passowrd: &mut Option<String>, password_double_check: bool) -> XResult<String> {
|
||||
simple_pbe_encrypt_with_prompt(iteration, plaintext.as_bytes(), passowrd, password_double_check)
|
||||
}
|
||||
|
||||
pub fn simple_pbe_decrypt_with_prompt_to_string(ciphertext: &str) -> XResult<String> {
|
||||
@@ -16,15 +16,22 @@ pub fn simple_pbe_decrypt_with_prompt_to_string(ciphertext: &str) -> XResult<Str
|
||||
Ok(String::from_utf8(plaintext)?)
|
||||
}
|
||||
|
||||
pub fn simple_pbe_encrypt_with_prompt(iteration: u32, plaintext: &[u8], password_double_check: bool) -> XResult<String> {
|
||||
let pin1 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
|
||||
if password_double_check {
|
||||
let pin2 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
|
||||
if pin1 != pin2 {
|
||||
return simple_error!("Two PINs mismatch");
|
||||
pub fn simple_pbe_encrypt_with_prompt(iteration: u32, plaintext: &[u8], password_opt: &mut Option<String>, password_double_check: bool) -> XResult<String> {
|
||||
let pin = match password_opt {
|
||||
None => {
|
||||
let pin1 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
|
||||
if password_double_check {
|
||||
let pin2 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
|
||||
if pin1 != pin2 {
|
||||
return simple_error!("Two PINs mismatch");
|
||||
}
|
||||
}
|
||||
*password_opt = Some(pin1.clone());
|
||||
pin1
|
||||
}
|
||||
}
|
||||
simple_pbe_encrypt(&pin1, iteration, plaintext)
|
||||
Some(pin) => pin.clone(),
|
||||
};
|
||||
simple_pbe_encrypt(&pin, iteration, plaintext)
|
||||
}
|
||||
|
||||
pub fn simple_pbe_decrypt_with_prompt(ciphertext: &str) -> XResult<Vec<u8>> {
|
||||
|
||||
Reference in New Issue
Block a user