feat: 1.13.15, make clippy happy

This commit is contained in:
2025-06-29 23:23:19 +08:00
parent d272904357
commit 6bd4d0ba57
16 changed files with 69 additions and 57 deletions

2
Cargo.lock generated
View File

@@ -519,7 +519,7 @@ dependencies = [
[[package]] [[package]]
name = "card-cli" name = "card-cli"
version = "1.13.14" version = "1.13.15"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"authenticator 0.3.1", "authenticator 0.3.1",

View File

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

View File

@@ -58,14 +58,14 @@ pub fn ecdh(
sub_arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches,
) -> XResult<Vec<u8>> { ) -> XResult<Vec<u8>> {
match key_uri { match key_uri {
KeyUri::SecureEnclaveKey(key) => { KeyUri::SecureEnclave(key) => {
if key.usage != KeyUsage::Singing { if key.usage != KeyUsage::Singing {
return simple_error!("Not singing key"); return simple_error!("Not singing key");
} }
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.private_key)?; let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.private_key)?;
seutil::secure_enclave_p256_dh(&private_key, ephemeral_public_key_bytes) seutil::secure_enclave_p256_dh(&private_key, ephemeral_public_key_bytes)
} }
KeyUri::YubikeyPivKey(key) => { KeyUri::YubikeyPiv(key) => {
let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?; let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?;
let pin_opt = pivutil::check_read_pin(&mut yk, key.slot, sub_arg_matches); let pin_opt = pivutil::check_read_pin(&mut yk, key.slot, sub_arg_matches);
@@ -108,7 +108,7 @@ pub fn ecdh(
Ok(decrypted_shared_secret.to_vec()) Ok(decrypted_shared_secret.to_vec())
} }
KeyUri::YubikeyHmacEncSoftKey(key) => { KeyUri::YubikeyHmacEncSoft(key) => {
if key.algorithm.is_ecc() { if key.algorithm.is_ecc() {
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?; let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?;
let private_key_bytes = try_decode(&private_key)?; let private_key_bytes = try_decode(&private_key)?;
@@ -128,7 +128,7 @@ pub fn ecdh(
simple_error!("Invalid algorithm: {}", key.algorithm.to_str()) simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
} }
} }
KeyUri::ExternalCommandKey(key) => { KeyUri::ExternalCommand(key) => {
let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?; let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?;
external_command_rs::external_ecdh(&key.external_command, &parameter, ephemeral_public_key_bytes) external_command_rs::external_ecdh(&key.external_command, &parameter, ephemeral_public_key_bytes)
} }

View File

@@ -51,7 +51,7 @@ impl Command for CommandImpl {
fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u8>> { fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u8>> {
let key_uri = parse_key_uri(parameter)?; let key_uri = parse_key_uri(parameter)?;
match key_uri { match key_uri {
KeyUri::SecureEnclaveKey(key) => { KeyUri::SecureEnclave(key) => {
if key.usage != KeyUsage::Singing { if key.usage != KeyUsage::Singing {
simple_error!("Not singing key") simple_error!("Not singing key")
} else { } else {
@@ -61,7 +61,7 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
Ok(public_key_der) Ok(public_key_der)
} }
} }
KeyUri::YubikeyPivKey(key) => { KeyUri::YubikeyPiv(key) => {
let mut yk = yubikeyutil::open_yubikey_with_serial(serial_opt)?; let mut yk = yubikeyutil::open_yubikey_with_serial(serial_opt)?;
if let Some(key) = find_key_or_error(&mut yk, &key.slot)? { if let Some(key) = find_key_or_error(&mut yk, &key.slot)? {
let cert_der = key.certificate().cert.to_der()?; let cert_der = key.certificate().cert.to_der()?;
@@ -71,7 +71,7 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
} }
simple_error!("Slot {} not found", key.slot) simple_error!("Slot {} not found", key.slot)
} }
KeyUri::YubikeyHmacEncSoftKey(key) => { KeyUri::YubikeyHmacEncSoft(key) => {
if key.algorithm.is_ecc() { if key.algorithm.is_ecc() {
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?; let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?;
let p256_public_key = ecdsautil::parse_p256_private_key_to_public_key(&private_key).ok(); let p256_public_key = ecdsautil::parse_p256_private_key_to_public_key(&private_key).ok();
@@ -98,7 +98,7 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
simple_error!("Invalid algorithm: {}", key.algorithm.to_str()) simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
} }
} }
KeyUri::ExternalCommandKey(key) => { KeyUri::ExternalCommand(key) => {
let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?; let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?;
external_command_rs::external_public_key(&key.external_command, &parameter) external_command_rs::external_public_key(&key.external_command, &parameter)
} }

View File

@@ -58,7 +58,7 @@ impl Command for CommandImpl {
pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> { pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
match key_uri { match key_uri {
KeyUri::SecureEnclaveKey(key) => { KeyUri::SecureEnclave(key) => {
if "ES256" != alg { if "ES256" != alg {
return simple_error!("Invalid alg: {}", alg); return simple_error!("Invalid alg: {}", alg);
} }
@@ -68,7 +68,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.private_key)?; let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.private_key)?;
seutil::secure_enclave_p256_sign(&private_key, message) seutil::secure_enclave_p256_sign(&private_key, message)
} }
KeyUri::YubikeyPivKey(key) => { KeyUri::YubikeyPiv(key) => {
let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?; let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?;
let pin_opt = pivutil::check_read_pin(&mut yk, key.slot, sub_arg_matches); let pin_opt = pivutil::check_read_pin(&mut yk, key.slot, sub_arg_matches);
@@ -94,7 +94,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
); );
Ok(signed_data.to_vec()) Ok(signed_data.to_vec())
} }
KeyUri::YubikeyHmacEncSoftKey(key) => { KeyUri::YubikeyHmacEncSoft(key) => {
if key.algorithm.is_ecc() { if key.algorithm.is_ecc() {
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?; let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?;
let (jwt_algorithm, private_key_d) = parse_ecdsa_private_key(&private_key)?; let (jwt_algorithm, private_key_d) = parse_ecdsa_private_key(&private_key)?;
@@ -122,9 +122,9 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
simple_error!("Invalid algorithm: {}", key.algorithm.to_str()) simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
} }
} }
KeyUri::ExternalCommandKey(key) => { KeyUri::ExternalCommand(key) => {
let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?; let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?;
let alg = key.algorithm.to_jwa_name(); let alg = key.algorithm.as_jwa_name();
let signature = external_command_rs::external_sign(&key.external_command, &parameter, alg, message)?; let signature = external_command_rs::external_sign(&key.external_command, &parameter, alg, message)?;
Ok(signature) Ok(signature)
} }

View File

@@ -54,7 +54,7 @@ pub fn try_decrypt_with_pbe_option(pin_opt: &mut Option<String>, ciphertext: &st
if is_hmac_encrypted(ciphertext) { if is_hmac_encrypted(ciphertext) {
hmac_decrypt(pin_opt, ciphertext, auto_pbe) hmac_decrypt(pin_opt, ciphertext, auto_pbe)
} else if pbeutil::is_simple_pbe_encrypted(ciphertext) { } else if pbeutil::is_simple_pbe_encrypted(ciphertext) {
pbeutil::simple_pbe_decrypt_with_prompt_to_string(pin_opt,&ciphertext) pbeutil::simple_pbe_decrypt_with_prompt_to_string(pin_opt, ciphertext)
} else { } else {
Ok(ciphertext.to_string()) Ok(ciphertext.to_string())
} }

View File

@@ -69,7 +69,7 @@ pub fn do_encrypt(text: &str, password_opt: &mut Option<String>, sub_arg_matches
let double_pin_check = sub_arg_matches.is_present("double-pin-check"); let double_pin_check = sub_arg_matches.is_present("double-pin-check");
let iteration = sub_arg_matches.value_of("pbe-iteration") let iteration = sub_arg_matches.value_of("pbe-iteration")
.map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000); .map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000);
pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, &text, password_opt, double_pin_check)? pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, text, password_opt, double_pin_check)?
} else { } else {
text.to_string() text.to_string()
}; };

View File

@@ -108,7 +108,7 @@ impl Command for CommandImpl {
algorithm: algorithm_id, algorithm: algorithm_id,
hmac_enc_private_key: pkcs8_base64.clone(), hmac_enc_private_key: pkcs8_base64.clone(),
}; };
Some(KeyUri::YubikeyHmacEncSoftKey(yubikey_hmac_enc_soft_key).to_string()) Some(KeyUri::YubikeyHmacEncSoft(yubikey_hmac_enc_soft_key).to_string())
} else { } else {
None None
}; };

View File

@@ -109,7 +109,7 @@ impl Command for CommandImpl {
algorithm: KeyAlgorithmId::from_algorithm_id(algorithm_id), algorithm: KeyAlgorithmId::from_algorithm_id(algorithm_id),
slot: slot_id, slot: slot_id,
}; };
json.insert("key_uri", KeyUri::YubikeyPivKey(yubikey_piv_key).to_string()); json.insert("key_uri", KeyUri::YubikeyPiv(yubikey_piv_key).to_string());
} }
let serial_lower = cert.serial_number.to_string().to_lowercase(); let serial_lower = cert.serial_number.to_string().to_lowercase();
json.insert("serial", if serial_lower.starts_with("00:") { serial_lower.chars().skip(3).collect() } else { serial_lower }); json.insert("serial", if serial_lower.starts_with("00:") { serial_lower.chars().skip(3).collect() } else { serial_lower });

View File

@@ -19,7 +19,7 @@ impl Command for CommandImpl {
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let json_output = cmdutil::check_json_output(sub_arg_matches); let json_output = cmdutil::check_json_output(sub_arg_matches);
if let Err(_) = which::which("swift-secure-enclave-tool") { if which::which("swift-secure-enclave-tool").is_err() {
failure!("Secure Enclave tool not found."); failure!("Secure Enclave tool not found.");
} }

View File

@@ -31,7 +31,7 @@ impl Command for CommandImpl {
let key = sub_arg_matches.value_of("key").unwrap(); let key = sub_arg_matches.value_of("key").unwrap();
let epk = sub_arg_matches.value_of("epk").unwrap(); let epk = sub_arg_matches.value_of("epk").unwrap();
let key_uri = parse_key_uri(&key)?; let key_uri = parse_key_uri(key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?; let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri); debugging!("Secure enclave key URI: {:?}", se_key_uri);
@@ -76,7 +76,7 @@ pub fn parse_epk(epk: &str) -> XResult<Vec<u8>> {
} else { } else {
match hex::decode(epk) { match hex::decode(epk) {
Ok(epk_bytes) => Ok(epk_bytes), Ok(epk_bytes) => Ok(epk_bytes),
Err(e) => match base64_decode(&epk) { Err(e) => match base64_decode(epk) {
Ok(epk_bytes) => Ok(epk_bytes), Ok(epk_bytes) => Ok(epk_bytes),
Err(_) => simple_error!("Decode public key from hex failed: {}", e) Err(_) => simple_error!("Decode public key from hex failed: {}", e)
} }

View File

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

View File

@@ -23,7 +23,7 @@ impl Command for CommandImpl {
seutil::check_se_supported()?; seutil::check_se_supported()?;
let key = sub_arg_matches.value_of("key").unwrap(); let key = sub_arg_matches.value_of("key").unwrap();
let key_uri = parse_key_uri(&key)?; let key_uri = parse_key_uri(key)?;
let se_key_uri = key_uri.as_secure_enclave_key()?; let se_key_uri = key_uri.as_secure_enclave_key()?;
debugging!("Secure enclave key URI: {:?}", se_key_uri); debugging!("Secure enclave key URI: {:?}", se_key_uri);
@@ -34,7 +34,7 @@ impl Command for CommandImpl {
se_key_uri.usage == KeyUsage::Singing, se_key_uri.usage == KeyUsage::Singing,
)?; )?;
print_se_key(json_output, &public_key_point, &public_key_der, &key); print_se_key(json_output, &public_key_point, &public_key_der, key);
Ok(None) Ok(None)
} }

View File

@@ -8,26 +8,26 @@ use yubikey::piv::{AlgorithmId, SlotId};
// reference: https://git.hatter.ink/hatter/card-cli/issues/6 // reference: https://git.hatter.ink/hatter/card-cli/issues/6
#[derive(Debug)] #[derive(Debug)]
pub enum KeyUri { pub enum KeyUri {
SecureEnclaveKey(SecureEnclaveKey), SecureEnclave(SecureEnclaveKey),
YubikeyPivKey(YubikeyPivKey), YubikeyPiv(YubikeyPivKey),
YubikeyHmacEncSoftKey(YubikeyHmacEncSoftKey), YubikeyHmacEncSoft(YubikeyHmacEncSoftKey),
ExternalCommandKey(ExternalCommandKey), ExternalCommand(ExternalCommandKey),
} }
impl KeyUri { impl KeyUri {
pub fn as_secure_enclave_key(&self) -> XResult<&SecureEnclaveKey> { pub fn as_secure_enclave_key(&self) -> XResult<&SecureEnclaveKey> {
match self { match self {
KeyUri::SecureEnclaveKey(key) => Ok(key), KeyUri::SecureEnclave(key) => Ok(key),
_ => simple_error!("Not a secure enclave key."), _ => simple_error!("Not a secure enclave key."),
} }
} }
pub fn get_preferred_algorithm_type(&self) -> AlgorithmType { pub fn get_preferred_algorithm_type(&self) -> AlgorithmType {
let algorithm_id = match &self { let algorithm_id = match &self {
KeyUri::SecureEnclaveKey(_) => return AlgorithmType::Es256, KeyUri::SecureEnclave(_) => return AlgorithmType::Es256,
KeyUri::YubikeyPivKey(key) => key.algorithm, KeyUri::YubikeyPiv(key) => key.algorithm,
KeyUri::YubikeyHmacEncSoftKey(key) => key.algorithm, KeyUri::YubikeyHmacEncSoft(key) => key.algorithm,
KeyUri::ExternalCommandKey(key) => key.algorithm, KeyUri::ExternalCommand(key) => key.algorithm,
}; };
match algorithm_id { match algorithm_id {
KeyAlgorithmId::Rsa1024 KeyAlgorithmId::Rsa1024
@@ -41,6 +41,7 @@ impl KeyUri {
} }
} }
#[allow(clippy::to_string_trait_impl)]
impl ToString for KeyUri { impl ToString for KeyUri {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut key_uri = String::with_capacity(64); let mut key_uri = String::with_capacity(64);
@@ -48,15 +49,15 @@ impl ToString for KeyUri {
match self { match self {
// key://hatter-mac-pro:se/p256:signing:BASE64(dataRepresentation) // key://hatter-mac-pro:se/p256:signing:BASE64(dataRepresentation)
// key://hatter-mac-pro:se/p256:key_agreement:BASE64(dataRepresentation) // key://hatter-mac-pro:se/p256:key_agreement:BASE64(dataRepresentation)
KeyUri::SecureEnclaveKey(key) => { KeyUri::SecureEnclave(key) => {
key_uri.push_str(&key.host); key_uri.push_str(&key.host);
key_uri.push_str(":se/p256:"); key_uri.push_str(":se/p256:");
key_uri.push_str(&key.usage.to_string()); key_uri.push_str(&key.usage.to_string());
key_uri.push_str(":"); key_uri.push(':');
key_uri.push_str(&key.private_key); key_uri.push_str(&key.private_key);
} }
// key://yubikey-5n:piv/p256::9a // key://yubikey-5n:piv/p256::9a
KeyUri::YubikeyPivKey(key) => { KeyUri::YubikeyPiv(key) => {
key_uri.push_str(&key.key_name); key_uri.push_str(&key.key_name);
key_uri.push_str(":piv/"); key_uri.push_str(":piv/");
key_uri.push_str(key.algorithm.to_str()); key_uri.push_str(key.algorithm.to_str());
@@ -64,7 +65,7 @@ impl ToString for KeyUri {
key_uri.push_str(key.slot.to_str()); key_uri.push_str(key.slot.to_str());
} }
// key://-:soft/p256::hmac_enc:... // key://-:soft/p256::hmac_enc:...
KeyUri::YubikeyHmacEncSoftKey(key) => { KeyUri::YubikeyHmacEncSoft(key) => {
key_uri.push_str(&key.key_name); key_uri.push_str(&key.key_name);
key_uri.push_str(":soft/"); key_uri.push_str(":soft/");
key_uri.push_str(key.algorithm.to_str()); key_uri.push_str(key.algorithm.to_str());
@@ -72,7 +73,7 @@ impl ToString for KeyUri {
key_uri.push_str(key.hmac_enc_private_key.as_str()); key_uri.push_str(key.hmac_enc_private_key.as_str());
} }
// key://external-command-file-name:external_command/p256::parameter // key://external-command-file-name:external_command/p256::parameter
KeyUri::ExternalCommandKey(key) => { KeyUri::ExternalCommand(key) => {
let encoded_external_command = let encoded_external_command =
percent_encoding::utf8_percent_encode(&key.external_command, NON_ALPHANUMERIC) percent_encoding::utf8_percent_encode(&key.external_command, NON_ALPHANUMERIC)
.to_string(); .to_string();
@@ -140,7 +141,7 @@ impl KeyAlgorithmId {
} }
} }
pub fn to_jwa_name(&self) -> &str { pub fn as_jwa_name(&self) -> &str {
match self { match self {
KeyAlgorithmId::Rsa1024 KeyAlgorithmId::Rsa1024
| KeyAlgorithmId::Rsa2048 | KeyAlgorithmId::Rsa2048
@@ -203,6 +204,7 @@ impl KeyUsage {
} }
} }
#[allow(clippy::to_string_trait_impl)]
impl ToString for KeyUsage { impl ToString for KeyUsage {
fn to_string(&self) -> String { fn to_string(&self) -> String {
match self { match self {
@@ -269,7 +271,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
} }
Some(key_usage) => key_usage, Some(key_usage) => key_usage,
}; };
let parsed_key_uri = KeyUri::SecureEnclaveKey(SecureEnclaveKey { let parsed_key_uri = KeyUri::SecureEnclave(SecureEnclaveKey {
host: host_or_name.to_string(), host: host_or_name.to_string(),
usage: key_usage, usage: key_usage,
private_key: left_part.to_string(), private_key: left_part.to_string(),
@@ -278,7 +280,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
Ok(parsed_key_uri) Ok(parsed_key_uri)
} }
"piv" => { "piv" => {
if "" != usage { if !usage.is_empty() {
return simple_error!("Key uri's usage must be empty."); return simple_error!("Key uri's usage must be empty.");
} }
let algorithm = opt_value_result!( let algorithm = opt_value_result!(
@@ -291,7 +293,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
"Invalid slot id: {}", "Invalid slot id: {}",
left_part left_part
); );
let parsed_key_uri = KeyUri::YubikeyPivKey(YubikeyPivKey { let parsed_key_uri = KeyUri::YubikeyPiv(YubikeyPivKey {
key_name: host_or_name.to_string(), key_name: host_or_name.to_string(),
algorithm, algorithm,
slot, slot,
@@ -300,7 +302,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
Ok(parsed_key_uri) Ok(parsed_key_uri)
} }
"soft" => { "soft" => {
if "" != usage { if !usage.is_empty() {
return simple_error!("Key uri's usage must be empty."); return simple_error!("Key uri's usage must be empty.");
} }
let algorithm = opt_value_result!( let algorithm = opt_value_result!(
@@ -309,7 +311,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
algorithm algorithm
); );
let hmac_enc_private_key = left_part.to_string(); let hmac_enc_private_key = left_part.to_string();
let parsed_key_uri = KeyUri::YubikeyHmacEncSoftKey(YubikeyHmacEncSoftKey { let parsed_key_uri = KeyUri::YubikeyHmacEncSoft(YubikeyHmacEncSoftKey {
key_name: host_or_name.to_string(), key_name: host_or_name.to_string(),
algorithm, algorithm,
hmac_enc_private_key, hmac_enc_private_key,
@@ -318,7 +320,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
Ok(parsed_key_uri) Ok(parsed_key_uri)
} }
"external_command" => { "external_command" => {
if "" != usage { if !usage.is_empty() {
return simple_error!("Key uri's usage must be empty."); return simple_error!("Key uri's usage must be empty.");
} }
let external_command = opt_result!( let external_command = opt_result!(
@@ -331,7 +333,7 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
algorithm algorithm
); );
let parameter = left_part.to_string(); let parameter = left_part.to_string();
let parsed_key_uri = KeyUri::ExternalCommandKey(ExternalCommandKey { let parsed_key_uri = KeyUri::ExternalCommand(ExternalCommandKey {
external_command: external_command.to_string(), external_command: external_command.to_string(),
algorithm, algorithm,
parameter, parameter,
@@ -352,7 +354,7 @@ fn test_parse_key_uri_01() {
se_key_uri.to_string() se_key_uri.to_string()
); );
match se_key_uri { match se_key_uri {
KeyUri::SecureEnclaveKey(se_key_uri) => { KeyUri::SecureEnclave(se_key_uri) => {
assert_eq!("hatter-mac-pro", se_key_uri.host); assert_eq!("hatter-mac-pro", se_key_uri.host);
assert_eq!(KeyUsage::Singing, se_key_uri.usage); assert_eq!(KeyUsage::Singing, se_key_uri.usage);
assert_eq!("BASE64(dataRepresentation)", se_key_uri.private_key); assert_eq!("BASE64(dataRepresentation)", se_key_uri.private_key);
@@ -373,7 +375,7 @@ fn test_parse_key_uri_02() {
se_key_uri.to_string() se_key_uri.to_string()
); );
match se_key_uri { match se_key_uri {
KeyUri::SecureEnclaveKey(se_key_uri) => { KeyUri::SecureEnclave(se_key_uri) => {
assert_eq!("hatter-mac-m1", se_key_uri.host); assert_eq!("hatter-mac-m1", se_key_uri.host);
assert_eq!(KeyUsage::KeyAgreement, se_key_uri.usage); assert_eq!(KeyUsage::KeyAgreement, se_key_uri.usage);
assert_eq!("BASE64(dataRepresentation)", se_key_uri.private_key); assert_eq!("BASE64(dataRepresentation)", se_key_uri.private_key);
@@ -392,7 +394,7 @@ fn test_parse_key_uri_03() {
se_key_uri.to_string() se_key_uri.to_string()
); );
match se_key_uri { match se_key_uri {
KeyUri::YubikeyPivKey(piv_key_uri) => { KeyUri::YubikeyPiv(piv_key_uri) => {
assert_eq!("yubikey-5n", piv_key_uri.key_name); assert_eq!("yubikey-5n", piv_key_uri.key_name);
assert_eq!(KeyAlgorithmId::EccP256, piv_key_uri.algorithm); assert_eq!(KeyAlgorithmId::EccP256, piv_key_uri.algorithm);
assert_eq!(SlotId::Authentication, piv_key_uri.slot); assert_eq!(SlotId::Authentication, piv_key_uri.slot);

View File

@@ -94,16 +94,26 @@ pub fn is_simple_pbe_encrypted(ciphertext: &str) -> bool {
fn simple_pbe_kdf(password: &str, pbe_salt: &[u8], iteration: u32) -> XResult<[u8; 32]> { fn simple_pbe_kdf(password: &str, pbe_salt: &[u8], iteration: u32) -> XResult<[u8; 32]> {
let mut init_data = password.as_bytes().to_vec(); let mut init_data = password.as_bytes().to_vec();
init_data.extend_from_slice(&pbe_salt); init_data.extend_from_slice(pbe_salt);
let mut loop_hash = sha256_bytes(&init_data); let mut loop_hash = sha256_bytes(&init_data);
for i in 0..iteration { for i in 0..iteration {
let i_to_bytes = i.to_be_bytes(); let i_to_bytes = i.to_be_bytes();
for x in 0..4 { loop_hash[..4].copy_from_slice(&i_to_bytes);
loop_hash[x] = i_to_bytes[x];
}
loop_hash = sha256_bytes(&loop_hash); loop_hash = sha256_bytes(&loop_hash);
} }
let key = copy_sha256(&sha256_bytes(&loop_hash))?; let key = copy_sha256(&sha256_bytes(&loop_hash))?;
Ok(key) Ok(key)
} }
#[test]
fn test_simple_pbe_kdf() {
assert_eq!("cea7eb6424132aa4d6b1880c3cb570df17c41d766826e144088fd16b334c80c5",
hex::encode(simple_pbe_kdf("hello_world", b"salt", 1).unwrap()));
assert_eq!("e3ed4a0a2f451180cfa4a0f8f3e1181d8863fc192d161e4c1480e3612135ca27",
hex::encode(simple_pbe_kdf("hello_world", b"salt", 2).unwrap()));
assert_eq!("e552900ad3f14a96629c8056bd7bc4b2431250ef4a47e78856626f45807cd87e",
hex::encode(simple_pbe_kdf("hello_world 2", b"salt", 2).unwrap()));
assert_eq!("37e71484f00033c99db444c77553364b31614d5145e38aad5bd5caa6676d40f9",
hex::encode(simple_pbe_kdf("hello_world", b"salt 2", 2).unwrap()));
}

View File

@@ -36,15 +36,15 @@ impl RsaSignAlgorithm {
pub fn sign(rsa_private_key: &RsaPrivateKey, rsa_sign_algorithm: RsaSignAlgorithm, message: &[u8]) -> XResult<Vec<u8>> { pub fn sign(rsa_private_key: &RsaPrivateKey, rsa_sign_algorithm: RsaSignAlgorithm, message: &[u8]) -> XResult<Vec<u8>> {
match rsa_sign_algorithm { match rsa_sign_algorithm {
RsaSignAlgorithm::Rs256 => { RsaSignAlgorithm::Rs256 => {
let raw_in = digestutil::sha256_bytes(&message); let raw_in = digestutil::sha256_bytes(message);
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha256>(), &raw_in)?) Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha256>(), &raw_in)?)
} }
RsaSignAlgorithm::Rs384 => { RsaSignAlgorithm::Rs384 => {
let raw_in = digestutil::sha384_bytes(&message); let raw_in = digestutil::sha384_bytes(message);
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha384>(), &raw_in)?) Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha384>(), &raw_in)?)
} }
RsaSignAlgorithm::Rs512 => { RsaSignAlgorithm::Rs512 => {
let raw_in = digestutil::sha512_bytes(&message); let raw_in = digestutil::sha512_bytes(message);
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha512>(), &raw_in)?) Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha512>(), &raw_in)?)
} }
} }