feat: v1.13.18, external_sign supports --message-type
This commit is contained in:
@@ -13,6 +13,7 @@ use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::XResult;
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use swift_secure_enclave_tool_rs::DigestType;
|
||||
use yubikey::piv::sign_data;
|
||||
|
||||
pub struct CommandImpl;
|
||||
@@ -28,6 +29,7 @@ impl Command for CommandImpl {
|
||||
.arg(cmdutil::build_alg_arg())
|
||||
.arg(cmdutil::build_parameter_arg())
|
||||
.arg(cmdutil::build_message_arg())
|
||||
.arg(cmdutil::build_message_type_arg())
|
||||
.arg(cmdutil::build_pin_arg())
|
||||
.arg(cmdutil::build_serial_arg())
|
||||
}
|
||||
@@ -36,11 +38,12 @@ impl Command for CommandImpl {
|
||||
let alg = sub_arg_matches.value_of("alg").unwrap();
|
||||
let parameter = sub_arg_matches.value_of("parameter").unwrap();
|
||||
let message_base64 = sub_arg_matches.value_of("message-base64").unwrap();
|
||||
let message_type = sub_arg_matches.value_of("message-type");
|
||||
let message_bytes = base64_decode(message_base64)?;
|
||||
|
||||
let mut json = BTreeMap::new();
|
||||
let key_uri = parse_key_uri(parameter)?;
|
||||
match sign(alg, &message_bytes, key_uri, sub_arg_matches) {
|
||||
match sign(alg, &message_bytes, message_type, key_uri, sub_arg_matches) {
|
||||
Ok(signature_bytes) => {
|
||||
json.insert("success", Value::Bool(true));
|
||||
json.insert("signature_base64", base64_encode(&signature_bytes).into());
|
||||
@@ -56,7 +59,14 @@ impl Command for CommandImpl {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
|
||||
pub fn sign(alg: &str, message: &[u8], message_type: Option<&str>, key_uri: KeyUri, sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
|
||||
let digest_type = DigestType::parse(message_type)?;
|
||||
if let Some(bytes_len) = digest_type.bytes() {
|
||||
if message.len() != bytes_len as usize {
|
||||
return simple_error!("Invalid message length, requires: {}, actual: {}", bytes_len, message.len());
|
||||
}
|
||||
}
|
||||
let is_raw = DigestType::Raw == digest_type;
|
||||
match key_uri {
|
||||
KeyUri::SecureEnclave(key) => {
|
||||
if "ES256" != alg {
|
||||
@@ -66,7 +76,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
|
||||
return simple_error!("Not singing key");
|
||||
}
|
||||
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.private_key)?;
|
||||
seutil::secure_enclave_p256_sign(&private_key, message)
|
||||
seutil::secure_enclave_p256_sign(&private_key, message, digest_type)
|
||||
}
|
||||
KeyUri::YubikeyPiv(key) => {
|
||||
let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?;
|
||||
@@ -87,7 +97,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
|
||||
"Yubikey not supported algorithm: {}",
|
||||
key.algorithm.to_str()
|
||||
);
|
||||
let raw_in = digest_by_jwt_algorithm(jwt_algorithm, message)?;
|
||||
let raw_in = iff!(is_raw, digest_by_jwt_algorithm(jwt_algorithm, message)?, message.to_vec());
|
||||
let signed_data = opt_result!(
|
||||
sign_data(&mut yk, &raw_in, algorithm, key.slot),
|
||||
"Sign YubiKey failed: {}"
|
||||
@@ -99,7 +109,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
|
||||
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &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)?;
|
||||
let raw_in = iff!(is_raw, digest_by_jwt_algorithm(jwt_algorithm, message)?, message.to_vec());
|
||||
let ecdsa_algorithm = convert_jwt_algorithm_to_ecdsa_algorithm(jwt_algorithm)?;
|
||||
let signed_data = ecdsautil::ecdsa_sign(
|
||||
ecdsa_algorithm,
|
||||
@@ -117,7 +127,7 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
|
||||
|
||||
let rsa_sign_algorithm =
|
||||
opt_value_result!(RsaSignAlgorithm::from_str(alg), "Invalid --alg: {}", alg);
|
||||
rsautil::sign(&rsa_private_key, rsa_sign_algorithm, message)
|
||||
rsautil::sign(&rsa_private_key, rsa_sign_algorithm, message, is_raw)
|
||||
} else {
|
||||
simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
|
||||
}
|
||||
@@ -125,7 +135,8 @@ pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMat
|
||||
KeyUri::ExternalCommand(key) => {
|
||||
let parameter = cmd_hmac_decrypt::try_decrypt(&mut None, &key.parameter)?;
|
||||
let alg = key.algorithm.as_jwa_name();
|
||||
let signature = external_command_rs::external_sign(&key.external_command, ¶meter, alg, message)?;
|
||||
let signature = external_command_rs::external_sign_digested(
|
||||
&key.external_command, ¶meter, alg, message, digest_type.to_str())?;
|
||||
Ok(signature)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::util::{base64_decode, base64_encode};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use std::collections::BTreeMap;
|
||||
use swift_secure_enclave_tool_rs::DigestType;
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -50,7 +51,7 @@ impl Command for CommandImpl {
|
||||
debugging!("Secure enclave key URI: {:?}", se_key_uri);
|
||||
|
||||
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &se_key_uri.private_key)?;
|
||||
let signature = seutil::secure_enclave_p256_sign(&private_key, &input_bytes)?;
|
||||
let signature = seutil::secure_enclave_p256_sign(&private_key, &input_bytes, DigestType::Raw)?;
|
||||
|
||||
if json_output {
|
||||
let mut json = BTreeMap::<&'_ str, String>::new();
|
||||
|
||||
@@ -69,7 +69,7 @@ fn sign_jwt(
|
||||
let claims = merge_payload_claims(payload, claims)?;
|
||||
let tobe_signed = merge_header_claims(header.as_bytes(), claims.as_bytes());
|
||||
|
||||
let signature = cmd_external_sign::sign(jwt_algorithm.to_str(), &tobe_signed, key_uri, sub_arg_matches)?;
|
||||
let signature = cmd_external_sign::sign(jwt_algorithm.to_str(), &tobe_signed, None, key_uri, sub_arg_matches)?;
|
||||
|
||||
let signed_data = match jwt_algorithm {
|
||||
AlgorithmType::Rs256 => signature,
|
||||
|
||||
@@ -53,6 +53,11 @@ pub fn build_message_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("message-base64").long("message-base64").takes_value(true).required(true).help("Message in base64")
|
||||
}
|
||||
|
||||
|
||||
pub fn build_message_type_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("message-type").long("message-type").takes_value(true).help("Optional, message type, raw, sha256, sha384 or sha512")
|
||||
}
|
||||
|
||||
pub fn build_no_pin_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("no-pin").long("no-pin").help("No PIN")
|
||||
}
|
||||
|
||||
@@ -33,18 +33,18 @@ impl RsaSignAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign(rsa_private_key: &RsaPrivateKey, rsa_sign_algorithm: RsaSignAlgorithm, message: &[u8]) -> XResult<Vec<u8>> {
|
||||
pub fn sign(rsa_private_key: &RsaPrivateKey, rsa_sign_algorithm: RsaSignAlgorithm, message: &[u8], is_raw: bool) -> XResult<Vec<u8>> {
|
||||
match rsa_sign_algorithm {
|
||||
RsaSignAlgorithm::Rs256 => {
|
||||
let raw_in = digestutil::sha256_bytes(message);
|
||||
let raw_in = iff!(is_raw, digestutil::sha256_bytes(message), message.to_vec());
|
||||
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha256>(), &raw_in)?)
|
||||
}
|
||||
RsaSignAlgorithm::Rs384 => {
|
||||
let raw_in = digestutil::sha384_bytes(message);
|
||||
let raw_in = iff!(is_raw, digestutil::sha384_bytes(message), message.to_vec());
|
||||
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha384>(), &raw_in)?)
|
||||
}
|
||||
RsaSignAlgorithm::Rs512 => {
|
||||
let raw_in = digestutil::sha512_bytes(message);
|
||||
let raw_in = iff!(is_raw, digestutil::sha512_bytes(message), message.to_vec());
|
||||
Ok(rsa_private_key.sign(Pkcs1v15Sign::new::<Sha512>(), &raw_in)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::util::{base64_decode, base64_encode};
|
||||
use rust_util::XResult;
|
||||
use se_tool::KeyPurpose;
|
||||
use swift_secure_enclave_tool_rs as se_tool;
|
||||
use swift_secure_enclave_tool_rs::ControlFlag;
|
||||
use swift_secure_enclave_tool_rs::{ControlFlag, DigestType};
|
||||
|
||||
pub fn is_support_se() -> bool {
|
||||
se_tool::is_secure_enclave_supported().unwrap_or_else(|e| {
|
||||
@@ -62,8 +62,8 @@ pub fn secure_enclave_p256_dh(
|
||||
Ok(shared_secret)
|
||||
}
|
||||
|
||||
pub fn secure_enclave_p256_sign(private_key: &str, content: &[u8]) -> XResult<Vec<u8>> {
|
||||
pub fn secure_enclave_p256_sign(private_key: &str, content: &[u8], digest_type: DigestType) -> XResult<Vec<u8>> {
|
||||
let private_key_representation = base64_decode(private_key)?;
|
||||
let signature = se_tool::private_key_sign(&private_key_representation, content)?;
|
||||
let signature = se_tool::private_key_sign_digested(&private_key_representation, content, digest_type)?;
|
||||
Ok(signature)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user