feat: 1.13.15, make clippy happy
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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, ¶meter, ephemeral_public_key_bytes)
|
external_command_rs::external_ecdh(&key.external_command, ¶meter, ephemeral_public_key_bytes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, ¶meter)
|
external_command_rs::external_public_key(&key.external_command, ¶meter)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, ¶meter, alg, message)?;
|
let signature = external_command_rs::external_sign(&key.external_command, ¶meter, alg, message)?;
|
||||||
Ok(signature)
|
Ok(signature)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 });
|
||||||
|
|||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()));
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user