feat: update ecdsautil
This commit is contained in:
@@ -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)?,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user