feat: update ecdsautil

This commit is contained in:
2025-05-02 00:01:11 +08:00
parent 3dae02e090
commit d7f52530df
2 changed files with 47 additions and 20 deletions

View File

@@ -4,6 +4,7 @@ use clap::{App, Arg, ArgMatches, SubCommand};
use rust_util::util_clap::{Command, CommandError};
use std::collections::BTreeMap;
use yubikey::piv::AlgorithmId;
use crate::ecdsautil::EcdsaAlgorithm;
use crate::keyutil::{KeyUri, YubikeyHmacEncSoftKey};
use crate::util::base64_encode;
@@ -47,13 +48,21 @@ impl Command for CommandImpl {
}
}
let (pkcs8_base64, secret_key_pem, public_key_pem, public_key_der, jwk_ec_key) = match key_type.as_str() {
"p256" => ecdsautil::generate_p256_keypair()?,
"p384" => ecdsautil::generate_p384_keypair()?,
let ecdsa_algorithm = match key_type.as_str() {
"p256" => EcdsaAlgorithm::P256,
"p384" => EcdsaAlgorithm::P384,
_ => {
return simple_error!("Key type must be p256 or p384");
}
};
let (pkcs8_base64,
secret_key_pem,
public_key_pem,
public_key_der,
jwk_ec_key
) = ecdsautil::generate_ecdsa_keypair(ecdsa_algorithm)?;
let (pkcs8_base64, secret_key_pem) = if with_hmac_encrypt {
(
hmacutil::hmac_encrypt_from_string(&pkcs8_base64)?,

View File

@@ -36,14 +36,14 @@ pub fn parse_ecdsa_r_and_s(signature_der: &[u8]) -> XResult<(Vec<u8>, Vec<u8>)>
match &seq[0].content {
BerObjectContent::Integer(r) => {
debugging!("Signature r: {}", hex::encode(r));
vec_r = trim_point_leading_zero(r);
vec_r = trim_ecdsa_point_coord(r);
}
_ => return simple_error!("Parse signature failed: [0]not integer"),
}
match &seq[1].content {
BerObjectContent::Integer(s) => {
debugging!("Signature s: {}", hex::encode(s));
vec_s = trim_point_leading_zero(s);
vec_s = trim_ecdsa_point_coord(s);
}
_ => return simple_error!("Parse signature failed: [1]not integer"),
}
@@ -53,32 +53,47 @@ pub fn parse_ecdsa_r_and_s(signature_der: &[u8]) -> XResult<(Vec<u8>, Vec<u8>)>
Ok((vec_r, vec_s))
}
fn trim_point_leading_zero(p: &[u8]) -> Vec<u8> {
fn trim_ecdsa_point_coord(p: &[u8]) -> Vec<u8> {
if p.len() == ((256 / 8) + 1) || p.len() == ((384 / 8) + 1) {
p[1..].to_vec()
} else if p.len() == ((256 / 8) - 1) || p.len() == ((384 / 8) - 1) {
let mut v = vec![];
v.push(0_u8);
v.extend_from_slice(p);
v
} else {
p.to_vec()
}
}
macro_rules! generate_inner_ecdsa_keypair {
($algo: tt) => ({
use $algo::SecretKey;
let secret_key = SecretKey::random(&mut rand::thread_rng());
let secret_key_der_base64 = base64_encode(secret_key.to_pkcs8_der()?.as_bytes());
let secret_key_pem = secret_key.to_pkcs8_pem(LineEnding::LF)?.to_string();
let public_key_pem = secret_key.public_key().to_public_key_pem(LineEnding::LF)?;
let public_key_der = secret_key.public_key().to_public_key_der()?.to_vec();
let jwk_ec_key = secret_key.public_key().to_jwk();
Ok((secret_key_der_base64, secret_key_pem, public_key_pem, public_key_der, jwk_ec_key))
})
}
pub fn generate_ecdsa_keypair(algo: EcdsaAlgorithm) -> XResult<(String, String, String, Vec<u8>, JwkEcKey)> {
match algo {
EcdsaAlgorithm::P256 => generate_p256_keypair(),
EcdsaAlgorithm::P384 => generate_p384_keypair(),
}
}
pub fn generate_p256_keypair() -> XResult<(String, String, String, Vec<u8>, JwkEcKey)> {
let secret_key = p256::SecretKey::random(&mut rand::thread_rng());
let secret_key_der_base64 = base64_encode(secret_key.to_pkcs8_der()?.as_bytes());
let secret_key_pem = secret_key.to_pkcs8_pem(LineEnding::LF)?.to_string();
let public_key_pem = secret_key.public_key().to_public_key_pem(LineEnding::LF)?;
let public_key_der = secret_key.public_key().to_public_key_der()?.to_vec();
let jwk_ec_key = secret_key.public_key().to_jwk();
Ok((secret_key_der_base64, secret_key_pem, public_key_pem, public_key_der, jwk_ec_key))
generate_inner_ecdsa_keypair!(p256)
}
pub fn generate_p384_keypair() -> XResult<(String, String, String, Vec<u8>, JwkEcKey)> {
let secret_key = p384::SecretKey::random(&mut rand::thread_rng());
let secret_key_der_base64 = base64_encode(secret_key.to_pkcs8_der()?.as_bytes());
let secret_key_pem = secret_key.to_pkcs8_pem(LineEnding::LF)?.to_string();
let public_key_pem = secret_key.public_key().to_public_key_pem(LineEnding::LF)?;
let public_key_der = secret_key.public_key().to_public_key_der()?.to_vec();
let jwk_ec_key = secret_key.public_key().to_jwk();
Ok((secret_key_der_base64, secret_key_pem, public_key_pem, public_key_der, jwk_ec_key))
generate_inner_ecdsa_keypair!(p384)
}
@@ -110,6 +125,7 @@ pub fn parse_p384_private_key_to_public_key(private_key_pkcs8: &str) -> XResult<
parse_ecdsa_private_key_to_public_key!(p384, private_key_pkcs8)
}
macro_rules! parse_ecdsa_private_key {
($algo: tt, $parse_ecdsa_private_key: tt) => ({
use $algo::pkcs8::DecodePrivateKey;
@@ -137,6 +153,7 @@ pub fn parse_p384_private_key(private_key_pkcs8: &str) -> XResult<Vec<u8>> {
parse_ecdsa_private_key!(p384, private_key_pkcs8)
}
macro_rules! sign_ecdsa_rs_or_der {
($algo: tt, $private_key_d: tt, $pre_hash: tt, $is_rs: tt) => ({
use $algo::ecdsa::{SigningKey, Signature};
@@ -168,6 +185,7 @@ pub fn sign_p384_rs_or_der(private_key_d: &[u8], pre_hash: &[u8], is_rs: bool) -
sign_ecdsa_rs_or_der!(p384, private_key_d, pre_hash, is_rs)
}
macro_rules! ecdsa_verify_signature {
($algo: tt, $pk_point: tt, $prehash: tt, $signature: tt) => ({
use ecdsa::Signature;