feat: v1.12.6

This commit is contained in:
2025-05-05 11:22:28 +08:00
parent e52e42d48c
commit 8894a2156a
11 changed files with 302 additions and 76 deletions

View File

@@ -1,17 +1,19 @@
use crate::cmd_sign_jwt::digest_by_jwt_algorithm;
use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage, YubikeyPivKey};
use crate::cmd_sign_jwt_soft::{convert_jwt_algorithm_to_ecdsa_algorithm, parse_ecdsa_private_key};
use crate::ecdsautil::EcdsaSignType;
use crate::keyutil::{parse_key_uri, KeyAlgorithmId, KeyUri, KeyUsage, YubikeyPivKey};
use crate::pivutil::ToStr;
use crate::rsautil::RsaSignAlgorithm;
use crate::util::{base64_decode, base64_encode};
use crate::{cmdutil, ecdsautil, hmacutil, pivutil, seutil, util, yubikeyutil};
use crate::{cmdutil, ecdsautil, hmacutil, pivutil, rsautil, seutil, util, yubikeyutil};
use clap::{App, ArgMatches, SubCommand};
use jwt::AlgorithmType;
use rsa::RsaPrivateKey;
use rust_util::util_clap::{Command, CommandError};
use rust_util::XResult;
use serde_json::Value;
use std::collections::BTreeMap;
use yubikey::piv::{sign_data, AlgorithmId};
use crate::cmd_sign_jwt_soft::{convert_jwt_algorithm_to_ecdsa_algorithm, parse_ecdsa_private_key};
use crate::ecdsautil::EcdsaSignType;
use yubikey::piv::sign_data;
pub struct CommandImpl;
@@ -79,22 +81,45 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
);
}
let algorithm = opt_value_result!(
KeyAlgorithmId::to_algorithm_id(key.algorithm),
"Yubikey not supported algorithm: {}",
key.algorithm.to_str()
);
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?;
let signed_data = opt_result!(
sign_data(&mut yk, &raw_in, key.algorithm, key.slot),
sign_data(&mut yk, &raw_in, algorithm, key.slot),
"Sign YubiKey failed: {}"
);
Ok(signed_data.to_vec())
}
KeyUri::YubikeyHmacEncSoftKey(key) => {
let private_key = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
let (jwt_algorithm, private_key_d) = parse_ecdsa_private_key(&private_key)?;
if key.algorithm.is_ecc() {
let private_key = hmacutil::try_hmac_decrypt_to_string(&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)?;
let ecdsa_algorithm = convert_jwt_algorithm_to_ecdsa_algorithm(jwt_algorithm)?;
let signed_data = ecdsautil::ecdsa_sign(ecdsa_algorithm, &private_key_d, &raw_in, EcdsaSignType::Der)?;
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?;
let ecdsa_algorithm = convert_jwt_algorithm_to_ecdsa_algorithm(jwt_algorithm)?;
let signed_data = ecdsautil::ecdsa_sign(
ecdsa_algorithm,
&private_key_d,
&raw_in,
EcdsaSignType::Der,
)?;
Ok(signed_data)
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_der = base64_decode(&private_key)?;
let rsa_private_key = RsaPrivateKey::from_pkcs8_der(&private_key_der)?;
let rsa_sign_algorithm =
opt_value_result!(RsaSignAlgorithm::from_str(alg), "Invalid --alg: {}", alg);
rsautil::sign(&rsa_private_key, rsa_sign_algorithm, &message_bytes)
} else {
simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
}
}
}
}
@@ -103,20 +128,23 @@ fn get_jwt_algorithm(key: &YubikeyPivKey, alg: &str) -> XResult<AlgorithmType> {
let jwt_algorithm = match alg {
"ES256" => AlgorithmType::Es256,
"ES384" => AlgorithmType::Es384,
"ES512" => AlgorithmType::Es512,
"RS256" => AlgorithmType::Rs256,
_ => return simple_error!("Invalid alg: {}", alg),
};
if key.algorithm == AlgorithmId::Rsa1024 {
if key.algorithm == KeyAlgorithmId::Rsa1024 {
return simple_error!("Invalid algorithm: RSA1024");
}
let is_p256_mismatch =
key.algorithm == AlgorithmId::EccP256 && jwt_algorithm != AlgorithmType::Es256;
key.algorithm == KeyAlgorithmId::EccP256 && jwt_algorithm != AlgorithmType::Es256;
let is_p384_mismatch =
key.algorithm == AlgorithmId::EccP384 && jwt_algorithm != AlgorithmType::Es384;
key.algorithm == KeyAlgorithmId::EccP384 && jwt_algorithm != AlgorithmType::Es384;
let is_p521_mismatch =
key.algorithm == KeyAlgorithmId::EccP521 && jwt_algorithm != AlgorithmType::Es512;
let is_rsa_mismatch =
key.algorithm == AlgorithmId::Rsa2048 && jwt_algorithm != AlgorithmType::Rs256;
key.algorithm == KeyAlgorithmId::Rsa2048 && jwt_algorithm != AlgorithmType::Rs256;
if is_p256_mismatch || is_p384_mismatch || is_rsa_mismatch {
if is_p256_mismatch || is_p384_mismatch || is_p521_mismatch || is_rsa_mismatch {
return simple_error!("Invalid algorithm: {} vs {}", key.algorithm.to_str(), alg);
}
Ok(jwt_algorithm)