diff --git a/src/cmd_external_sign.rs b/src/cmd_external_sign.rs index 45dd7f2..e6fd1b6 100644 --- a/src/cmd_external_sign.rs +++ b/src/cmd_external_sign.rs @@ -1,5 +1,5 @@ use crate::cmd_sign_jwt::digest_by_jwt_algorithm; -use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage}; +use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage, YubikeyPivKey}; use crate::pivutil::ToStr; use crate::util::{base64_decode, base64_encode}; use crate::{cmdutil, pivutil, seutil, util}; @@ -59,40 +59,17 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { return simple_error!("Invalid alg: {}", alg); } if key.usage != KeyUsage::Singing { - simple_error!("Not singing key") - } else { - Ok(seutil::secure_enclave_p256_sign( - &key.private_key, - &message_bytes, - )?) + return simple_error!("Not singing key"); } + seutil::secure_enclave_p256_sign(&key.private_key, &message_bytes) } KeyUri::YubikeyPivKey(key) => { let mut yk = opt_result!(YubiKey::open(), "Find YubiKey failed: {}"); let pin_opt = pivutil::check_read_pin(&mut yk, key.slot, sub_arg_matches); // FIXME Check Yubikey slot algorithm - let jwt_algorithm = match alg { - "ES256" => AlgorithmType::Es256, - "ES384" => AlgorithmType::Es384, - "RS256" => AlgorithmType::Rs256, - _ => return simple_error!("Invalid alg: {}", alg), - }; - - if key.algorithm == AlgorithmId::Rsa1024 { - return simple_error!("Invalid algorithm: RSA1024"); - } - - let is_p256_mismatch = - key.algorithm == AlgorithmId::EccP256 && jwt_algorithm != AlgorithmType::Es256; - let is_p384_mismatch = - key.algorithm == AlgorithmId::EccP384 && jwt_algorithm != AlgorithmType::Es384; - let is_rsa_mismatch = - key.algorithm == AlgorithmId::Rsa2048 && jwt_algorithm != AlgorithmType::Rs256; - - if is_p256_mismatch || is_p384_mismatch || is_rsa_mismatch { - return simple_error!("Invalid algorithm: {} vs {}", key.algorithm.to_str(), alg); - } + let jwt_algorithm = get_jwt_algorithm(alg)?; + check_algorithm(&key, alg, jwt_algorithm)?; let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?; @@ -110,3 +87,29 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { } } } + +fn check_algorithm(key: &YubikeyPivKey, alg: &str, jwt_algorithm: AlgorithmType) -> XResult<()> { + if key.algorithm == AlgorithmId::Rsa1024 { + return simple_error!("Invalid algorithm: RSA1024"); + } + let is_p256_mismatch = + key.algorithm == AlgorithmId::EccP256 && jwt_algorithm != AlgorithmType::Es256; + let is_p384_mismatch = + key.algorithm == AlgorithmId::EccP384 && jwt_algorithm != AlgorithmType::Es384; + let is_rsa_mismatch = + key.algorithm == AlgorithmId::Rsa2048 && jwt_algorithm != AlgorithmType::Rs256; + + if is_p256_mismatch || is_p384_mismatch || is_rsa_mismatch { + return simple_error!("Invalid algorithm: {} vs {}", key.algorithm.to_str(), alg); + } + Ok(()) +} + +fn get_jwt_algorithm(alg: &str) -> XResult { + Ok(match alg { + "ES256" => AlgorithmType::Es256, + "ES384" => AlgorithmType::Es384, + "RS256" => AlgorithmType::Rs256, + _ => return simple_error!("Invalid alg: {}", alg), + }) +}