feat: v1.12.3

This commit is contained in:
2025-05-01 23:38:36 +08:00
parent 86489c5d29
commit 3dae02e090
8 changed files with 79 additions and 49 deletions

View File

@@ -53,7 +53,7 @@ impl Command for CommandImpl {
json.insert("signature_hex", hex::encode(&signature));
}
match ecdsautil::ecdsaverify(ecdsa_algorithm, &public_key, &hash_bytes, &signature) {
match ecdsautil::ecdsa_verify(ecdsa_algorithm, &public_key, &hash_bytes, &signature) {
Ok(_) => {
success!("Verify ECDSA succeed.");
if json_output {

View File

@@ -10,7 +10,8 @@ use rust_util::XResult;
use serde_json::Value;
use std::collections::BTreeMap;
use yubikey::piv::{sign_data, AlgorithmId};
use crate::cmd_sign_jwt_soft::parse_ecdsa_private_key;
use crate::cmd_sign_jwt_soft::{convert_jwt_algorithm_to_ecdsa_algorithm, parse_ecdsa_private_key};
use crate::ecdsautil::EcdsaSignType;
pub struct CommandImpl;
@@ -68,7 +69,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
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);
// FIXME Check Yubikey slot algorithm
// FIXME Check YubiKey slot algorithm
let jwt_algorithm = get_jwt_algorithm(&key, alg)?;
if let Some(pin) = pin_opt {
@@ -90,11 +91,9 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
let (jwt_algorithm, private_key_d) = parse_ecdsa_private_key(&private_key)?;
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?;
let signed_data = match jwt_algorithm {
AlgorithmType::Es256 => ecdsautil::sign_p256_der(&private_key_d, &raw_in)?,
AlgorithmType::Es384 => ecdsautil::sign_p384_der(&private_key_d, &raw_in)?,
_ => return simple_error!("SHOULD NOT HAPPEN: {:?}", jwt_algorithm),
};
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)
}
}

View File

@@ -58,7 +58,7 @@ impl Command for CommandImpl {
}
let algorithm = iff!(algorithm_id == AlgorithmId::EccP256, EcdsaAlgorithm::P256, EcdsaAlgorithm::P384);
match ecdsautil::ecdsaverify(algorithm, pk_point, &hash_bytes, &signature) {
match ecdsautil::ecdsa_verify(algorithm, pk_point, &hash_bytes, &signature) {
Ok(_) => {
success!("Verify ECDSA succeed.");
if json_output {

View File

@@ -19,6 +19,10 @@ impl Command for CommandImpl {
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let json_output = cmdutil::check_json_output(sub_arg_matches);
if let Err(_) = which::which("swift-secure-enclave-tool") {
failure!("Secure Enclave tool not found.");
}
if json_output {
let mut json = BTreeMap::new();
json.insert("se_supported", seutil::is_support_se());

View File

@@ -7,6 +7,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::ecdsautil::{EcdsaAlgorithm, EcdsaSignType};
const SEPARATOR: &str = ".";
@@ -76,18 +77,22 @@ fn sign_jwt(
let tobe_signed = merge_header_claims(header.as_bytes(), claims.as_bytes());
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &tobe_signed)?;
let signed_data = match jwt_algorithm {
AlgorithmType::Es256 => ecdsautil::sign_p256_rs(&private_key_d, &raw_in)?,
AlgorithmType::Es384 => ecdsautil::sign_p384_rs(&private_key_d, &raw_in)?,
_ => return simple_error!("SHOULD NOT HAPPEN: {:?}", jwt_algorithm),
};
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::Rs)?;
let signature = util::base64_encode_url_safe_no_pad(&signed_data);
Ok([&*header, &*claims, &signature].join(SEPARATOR))
}
pub fn convert_jwt_algorithm_to_ecdsa_algorithm(jwt_algorithm: AlgorithmType) -> XResult<EcdsaAlgorithm> {
match jwt_algorithm {
AlgorithmType::Es256 => Ok(EcdsaAlgorithm::P256),
AlgorithmType::Es384 => Ok(EcdsaAlgorithm::P384),
_ => simple_error!("SHOULD NOT HAPPEN: {:?}", jwt_algorithm),
}
}
pub fn parse_ecdsa_private_key(private_key: &str) -> XResult<(AlgorithmType, Vec<u8>)> {
let p256_private_key_d = ecdsautil::parse_p256_private_key(private_key).ok();
let p384_private_key_d = ecdsautil::parse_p384_private_key(private_key).ok();

View File

@@ -16,6 +16,11 @@ pub enum EcdsaAlgorithm {
P384,
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum EcdsaSignType {
Der, Rs,
}
pub fn parse_ecdsa_to_rs(signature_der: &[u8]) -> XResult<Vec<u8>> {
let (mut r, s)= parse_ecdsa_r_and_s(signature_der)?;
r.extend_from_slice(&s);
@@ -132,44 +137,35 @@ pub fn parse_p384_private_key(private_key_pkcs8: &str) -> XResult<Vec<u8>> {
parse_ecdsa_private_key!(p384, private_key_pkcs8)
}
pub fn sign_p256_rs(private_key_d: &[u8], pre_hash: &[u8]) -> XResult<Vec<u8>> {
use p256::ecdsa::{SigningKey, Signature};
use p256::ecdsa::signature::hazmat::PrehashSigner;
macro_rules! sign_ecdsa_rs_or_der {
($algo: tt, $private_key_d: tt, $pre_hash: tt, $is_rs: tt) => ({
use $algo::ecdsa::{SigningKey, Signature};
use $algo::ecdsa::signature::hazmat::PrehashSigner;
let signing_key = SigningKey::from_slice(private_key_d)?;
let signature: Signature = signing_key.sign_prehash(pre_hash)?;
let signing_key = SigningKey::from_slice($private_key_d)?;
let signature: Signature = signing_key.sign_prehash($pre_hash)?;
Ok(signature.to_bytes().to_vec())
if $is_rs {
Ok(signature.to_bytes().to_vec())
} else {
Ok(signature.to_der().as_bytes().to_vec())
}
})
}
pub fn sign_p256_der(private_key_d: &[u8], pre_hash: &[u8]) -> XResult<Vec<u8>> {
use p256::ecdsa::{SigningKey, Signature};
use p256::ecdsa::signature::hazmat::PrehashSigner;
let signing_key = SigningKey::from_slice(private_key_d)?;
let signature: Signature = signing_key.sign_prehash(pre_hash)?;
Ok(signature.to_der().as_bytes().to_vec())
pub fn ecdsa_sign(algo: EcdsaAlgorithm, private_key_d: &[u8], pre_hash: &[u8], sign_type: EcdsaSignType) -> XResult<Vec<u8>> {
match algo {
EcdsaAlgorithm::P256 => sign_p256_rs_or_der(private_key_d, pre_hash, sign_type == EcdsaSignType::Rs),
EcdsaAlgorithm::P384 => sign_p384_rs_or_der(private_key_d, pre_hash, sign_type == EcdsaSignType::Rs),
}
}
pub fn sign_p384_rs(private_key_d: &[u8], pre_hash: &[u8]) -> XResult<Vec<u8>> {
use p384::ecdsa::{SigningKey, Signature};
use p384::ecdsa::signature::hazmat::PrehashSigner;
let signing_key = SigningKey::from_slice(private_key_d)?;
let signature: Signature = signing_key.sign_prehash(pre_hash)?;
Ok(signature.to_bytes().to_vec())
pub fn sign_p256_rs_or_der(private_key_d: &[u8], pre_hash: &[u8], is_rs: bool) -> XResult<Vec<u8>> {
sign_ecdsa_rs_or_der!(p256, private_key_d, pre_hash, is_rs)
}
pub fn sign_p384_der(private_key_d: &[u8], pre_hash: &[u8]) -> XResult<Vec<u8>> {
use p384::ecdsa::{SigningKey, Signature};
use p384::ecdsa::signature::hazmat::PrehashSigner;
let signing_key = SigningKey::from_slice(private_key_d)?;
let signature: Signature = signing_key.sign_prehash(pre_hash)?;
Ok(signature.to_der().as_bytes().to_vec())
pub fn sign_p384_rs_or_der(private_key_d: &[u8], pre_hash: &[u8], is_rs: bool) -> XResult<Vec<u8>> {
sign_ecdsa_rs_or_der!(p384, private_key_d, pre_hash, is_rs)
}
macro_rules! ecdsa_verify_signature {
@@ -187,7 +183,7 @@ macro_rules! ecdsa_verify_signature {
})
}
pub fn ecdsaverify(algo: EcdsaAlgorithm, pk_point: &[u8], prehash: &[u8], signature: &[u8]) -> XResult<()> {
pub fn ecdsa_verify(algo: EcdsaAlgorithm, pk_point: &[u8], prehash: &[u8], signature: &[u8]) -> XResult<()> {
match algo {
EcdsaAlgorithm::P256 => ecdsa_verify_signature!(NistP256, pk_point, prehash, signature),
EcdsaAlgorithm::P384 => ecdsa_verify_signature!(NistP384, pk_point, prehash, signature),