From a1ae0ff4dcdddd45ceb8bdd3f10f825cef55f7ef Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Wed, 7 May 2025 23:54:20 +0800 Subject: [PATCH] feat: v1.13.0 --- Cargo.lock | 90 ++++++++++++++++++++-------------------- Cargo.toml | 2 +- src/cmd_external_sign.rs | 24 +++++------ src/cmd_sign_jwt.rs | 85 +++++++++++++++++++++++++++++++++++++ src/cmd_sign_jwt_piv.rs | 4 +- src/cmd_sign_jwt_se.rs | 2 +- src/cmd_sign_jwt_soft.rs | 2 +- src/ecdsautil.rs | 8 +++- src/keyutil.rs | 16 +++++++ src/main.rs | 4 +- src/pivutil.rs | 21 ++++++++++ 11 files changed, 193 insertions(+), 65 deletions(-) create mode 100644 src/cmd_sign_jwt.rs diff --git a/Cargo.lock b/Cargo.lock index 26a4d57..a9c3ca1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "syn 2.0.101", - "synstructure 0.13.1", + "synstructure 0.13.2", ] [[package]] @@ -242,7 +242,7 @@ dependencies = [ "serde_bytes", "serde_cbor", "serde_json", - "sha2 0.10.8", + "sha2 0.10.9", "winapi 0.3.9", ] @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "card-cli" -version = "1.12.10" +version = "1.13.0" dependencies = [ "aes-gcm-stream", "authenticator 0.3.1", @@ -544,7 +544,7 @@ dependencies = [ "serde", "serde_json", "sha1", - "sha2 0.10.8", + "sha2 0.10.9", "simpledateformat", "spki 0.7.3", "ssh-agent", @@ -561,9 +561,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.20" +version = "1.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" dependencies = [ "shlex", ] @@ -1442,7 +1442,7 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.44.2", + "tokio 1.45.0", "tokio-util", "tracing", ] @@ -1455,9 +1455,9 @@ checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" [[package]] name = "heck" @@ -1482,9 +1482,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hermit-abi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "hex" @@ -1593,7 +1593,7 @@ dependencies = [ "itoa", "pin-project-lite", "socket2", - "tokio 1.44.2", + "tokio 1.45.0", "tower-service", "tracing", "want", @@ -1608,7 +1608,7 @@ dependencies = [ "bytes 1.10.1", "hyper", "native-tls", - "tokio 1.44.2", + "tokio 1.45.0", "tokio-native-tls", ] @@ -1815,7 +1815,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.0", + "hermit-abi 0.5.1", "libc", "windows-sys 0.59.0", ] @@ -1866,7 +1866,7 @@ dependencies = [ "hmac 0.12.1", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -1952,9 +1952,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" @@ -2427,9 +2427,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.107" +version = "0.9.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" dependencies = [ "cc", "libc", @@ -2445,7 +2445,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2457,7 +2457,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2468,7 +2468,7 @@ checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2480,7 +2480,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2494,7 +2494,7 @@ dependencies = [ "elliptic-curve 0.13.8", "primeorder", "rand_core 0.6.4", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2552,7 +2552,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.11", + "redox_syscall 0.5.12", "smallvec 1.15.0", "windows-targets 0.52.6", ] @@ -2952,9 +2952,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags 2.9.0", ] @@ -3023,7 +3023,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "system-configuration", - "tokio 1.44.2", + "tokio 1.45.0", "tokio-native-tls", "tower-service", "url", @@ -3149,7 +3149,7 @@ dependencies = [ "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", - "sha2 0.10.8", + "sha2 0.10.9", "signature 2.2.0", "spki 0.7.3", "subtle", @@ -3249,9 +3249,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags 2.9.0", "errno", @@ -3545,9 +3545,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3823,9 +3823,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -3892,7 +3892,7 @@ dependencies = [ "fastrand", "getrandom 0.3.2", "once_cell", - "rustix 1.0.5", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -4063,9 +4063,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.2" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes 1.10.1", @@ -4136,7 +4136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.44.2", + "tokio 1.45.0", ] [[package]] @@ -4254,7 +4254,7 @@ dependencies = [ "futures-core", "futures-sink", "pin-project-lite", - "tokio 1.44.2", + "tokio 1.45.0", ] [[package]] @@ -4548,7 +4548,7 @@ checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762" dependencies = [ "either", "env_home", - "rustix 1.0.5", + "rustix 1.0.7", "winsafe", ] @@ -4951,7 +4951,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "syn 2.0.101", - "synstructure 0.13.1", + "synstructure 0.13.2", ] [[package]] @@ -4996,7 +4996,7 @@ dependencies = [ "rsa 0.7.2", "secrecy", "sha1", - "sha2 0.10.8", + "sha2 0.10.9", "subtle", "uuid", "x509", @@ -5029,7 +5029,7 @@ dependencies = [ "rsa 0.9.8", "secrecy", "sha1", - "sha2 0.10.8", + "sha2 0.10.9", "signature 2.2.0", "subtle", "uuid", @@ -5075,7 +5075,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "syn 2.0.101", - "synstructure 0.13.1", + "synstructure 0.13.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index dd57420..197f673 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.12.10" +version = "1.13.0" authors = ["Hatter Jiang "] edition = "2018" diff --git a/src/cmd_external_sign.rs b/src/cmd_external_sign.rs index 2aa2450..644e1c1 100644 --- a/src/cmd_external_sign.rs +++ b/src/cmd_external_sign.rs @@ -33,8 +33,14 @@ impl Command for CommandImpl { } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + 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_bytes = base64_decode(message_base64)?; + let mut json = BTreeMap::new(); - match sign(sub_arg_matches) { + let key_uri = parse_key_uri(parameter)?; + match sign(alg, &message_bytes, key_uri, sub_arg_matches) { Ok(signature_bytes) => { json.insert("success", Value::Bool(true)); json.insert("signature_base64", base64_encode(&signature_bytes).into()); @@ -50,13 +56,7 @@ impl Command for CommandImpl { } } -fn sign(sub_arg_matches: &ArgMatches) -> XResult> { - 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 key_uri = parse_key_uri(parameter)?; - let message_bytes = base64_decode(message_base64)?; +pub fn sign(alg: &str, message: &[u8], key_uri: KeyUri, sub_arg_matches: &ArgMatches) -> XResult> { match key_uri { KeyUri::SecureEnclaveKey(key) => { if "ES256" != alg { @@ -65,7 +65,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { if key.usage != KeyUsage::Singing { return simple_error!("Not singing key"); } - seutil::secure_enclave_p256_sign(&key.private_key, &message_bytes) + seutil::secure_enclave_p256_sign(&key.private_key, message) } KeyUri::YubikeyPivKey(key) => { let mut yk = yubikeyutil::open_yubikey_with_args(sub_arg_matches)?; @@ -86,7 +86,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { "Yubikey not supported algorithm: {}", key.algorithm.to_str() ); - let raw_in = digest_by_jwt_algorithm(jwt_algorithm, &message_bytes)?; + let raw_in = digest_by_jwt_algorithm(jwt_algorithm, message)?; let signed_data = opt_result!( sign_data(&mut yk, &raw_in, algorithm, key.slot), "Sign YubiKey failed: {}" @@ -98,7 +98,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { let private_key = cmd_hmac_decrypt::try_decrypt(&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 raw_in = digest_by_jwt_algorithm(jwt_algorithm, message)?; let ecdsa_algorithm = convert_jwt_algorithm_to_ecdsa_algorithm(jwt_algorithm)?; let signed_data = ecdsautil::ecdsa_sign( ecdsa_algorithm, @@ -116,7 +116,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult> { let rsa_sign_algorithm = opt_value_result!(RsaSignAlgorithm::from_str(alg), "Invalid --alg: {}", alg); - rsautil::sign(&rsa_private_key, rsa_sign_algorithm, &message_bytes) + rsautil::sign(&rsa_private_key, rsa_sign_algorithm, message) } else { simple_error!("Invalid algorithm: {}", key.algorithm.to_str()) } diff --git a/src/cmd_sign_jwt.rs b/src/cmd_sign_jwt.rs new file mode 100644 index 0000000..8813a1a --- /dev/null +++ b/src/cmd_sign_jwt.rs @@ -0,0 +1,85 @@ +use crate::cmd_sign_jwt_piv::{ + build_jwt_parts, fill_sign_jwt_app_args, merge_header_claims, + merge_payload_claims, print_jwt_token, +}; +use crate::ecdsautil::parse_ecdsa_to_rs; +use crate::keyutil::parse_key_uri; +use crate::{cmd_external_sign, cmdutil, util}; +use clap::{App, ArgMatches, SubCommand}; +use jwt::ToBase64; +use jwt::{AlgorithmType, Header}; +use rust_util::util_clap::{Command, CommandError}; +use rust_util::XResult; +use serde_json::{Map, Value}; +use crate::pivutil::ToStr; + +const SEPARATOR: &str = "."; + +pub struct CommandImpl; + +impl Command for CommandImpl { + fn name(&self) -> &str { + "sign-jwt" + } + + fn subcommand<'a>(&self) -> App<'a, 'a> { + let app = SubCommand::with_name(self.name()) + .about("Sign JWT subcommand") + .arg(cmdutil::build_key_uri_arg().required(false)) + .arg(cmdutil::build_parameter_arg().required(false)) + .arg(cmdutil::build_pin_arg()) + .arg(cmdutil::build_serial_arg()) + .arg(cmdutil::build_json_arg()); + fill_sign_jwt_app_args(app) + } + + fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + let json_output = cmdutil::check_json_output(sub_arg_matches); + + let (header, payload, jwt_claims) = build_jwt_parts(sub_arg_matches)?; + let token_string = sign_jwt(header, &payload, &jwt_claims, sub_arg_matches)?; + print_jwt_token(json_output, token_string); + + Ok(None) + } +} + +fn sign_jwt( + mut header: Header, + payload: &Option, + claims: &Map, + sub_arg_matches: &ArgMatches, +) -> XResult { + let key = match sub_arg_matches.value_of("key") { + Some(key) => key, + None => match sub_arg_matches.value_of("parameter") { + Some(parameter) => parameter, + None => return simple_error!("Parameter --key or --parameter required"), + } + }; + let key_uri = parse_key_uri(key)?; + + let jwt_algorithm = key_uri.get_preferred_algorithm_type(); + + header.algorithm = jwt_algorithm; + debugging!("Header: {:?}", header); + debugging!("Claims: {:?}", claims); + + let header = opt_result!(header.to_base64(), "Header to base64 failed: {}"); + 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 signed_data = match jwt_algorithm { + AlgorithmType::Rs256 => signature, + AlgorithmType::Es256 | AlgorithmType::Es384 | AlgorithmType::Es512 => { + parse_ecdsa_to_rs(signature.as_slice())? + } + _ => return simple_error!("SHOULD NOT HAPPEN: {:?}", jwt_algorithm), + }; + + let signature = util::base64_encode_url_safe_no_pad(&signed_data); + + Ok([&*header, &*claims, &signature].join(SEPARATOR)) +} diff --git a/src/cmd_sign_jwt_piv.rs b/src/cmd_sign_jwt_piv.rs index f165180..808c3a6 100644 --- a/src/cmd_sign_jwt_piv.rs +++ b/src/cmd_sign_jwt_piv.rs @@ -19,11 +19,11 @@ pub struct CommandImpl; impl Command for CommandImpl { fn name(&self) -> &str { - "sign-jwt" + "sign-jwt-piv" } fn subcommand<'a>(&self) -> App<'a, 'a> { - let app = SubCommand::with_name(self.name()).about("Sign JWT subcommand") + let app = SubCommand::with_name(self.name()).about("Sign JWT(PIV) subcommand") .arg(cmdutil::build_slot_arg()) .arg(cmdutil::build_pin_arg()) .arg(cmdutil::build_no_pin_arg()) diff --git a/src/cmd_sign_jwt_se.rs b/src/cmd_sign_jwt_se.rs index 9af7a9d..8038b88 100644 --- a/src/cmd_sign_jwt_se.rs +++ b/src/cmd_sign_jwt_se.rs @@ -21,7 +21,7 @@ impl Command for CommandImpl { } fn subcommand<'a>(&self) -> App<'a, 'a> { - let app = SubCommand::with_name(self.name()).about("Sign JWT subcommand") + let app = SubCommand::with_name(self.name()).about("Sign JWT(SE) subcommand") .arg(cmdutil::build_key_uri_arg()) .arg(cmdutil::build_json_arg()); cmd_sign_jwt_piv::fill_sign_jwt_app_args(app) diff --git a/src/cmd_sign_jwt_soft.rs b/src/cmd_sign_jwt_soft.rs index 8f65fe9..c45b625 100644 --- a/src/cmd_sign_jwt_soft.rs +++ b/src/cmd_sign_jwt_soft.rs @@ -19,7 +19,7 @@ impl Command for CommandImpl { } fn subcommand<'a>(&self) -> App<'a, 'a> { - let app = SubCommand::with_name(self.name()).about("Sign JWT subcommand") + let app = SubCommand::with_name(self.name()).about("Sign JWT(Soft EC) subcommand") .arg(Arg::with_name("private-key").short("k").long("private-key").takes_value(true).help("Private key PKCS#8")) .arg(cmdutil::build_json_arg()); cmd_sign_jwt_piv::fill_sign_jwt_app_args(app) diff --git a/src/ecdsautil.rs b/src/ecdsautil.rs index f857049..049bd26 100644 --- a/src/ecdsautil.rs +++ b/src/ecdsautil.rs @@ -54,10 +54,14 @@ pub fn parse_ecdsa_r_and_s(signature_der: &[u8]) -> XResult<(Vec, Vec)> Ok((vec_r, vec_s)) } +const P256_LEN: usize = 32; +const P384_LEN: usize = 48; +const P521_LEN: usize = 66; + fn trim_ecdsa_point_coord(p: &[u8]) -> Vec { - if p.len() == ((256 / 8) + 1) || p.len() == ((384 / 8) + 1) { + if p.len() == (P256_LEN + 1) || p.len() == (P384_LEN + 1) || p.len() == (P521_LEN + 1) { p[1..].to_vec() - } else if p.len() == ((256 / 8) - 1) || p.len() == ((384 / 8) - 1) { + } else if p.len() == (P256_LEN - 1) || p.len() == (P384_LEN - 1) || p.len() == (P521_LEN - 1) { let mut v = vec![]; v.push(0_u8); v.extend_from_slice(p); diff --git a/src/keyutil.rs b/src/keyutil.rs index d073216..79f037e 100644 --- a/src/keyutil.rs +++ b/src/keyutil.rs @@ -1,3 +1,4 @@ +use jwt::AlgorithmType; use crate::pivutil::{FromStr, ToStr}; use regex::Regex; use rust_util::XResult; @@ -18,6 +19,21 @@ impl KeyUri { _ => simple_error!("Not a secure enclave key."), } } + + pub fn get_preferred_algorithm_type(&self) -> AlgorithmType { + let algorithm_id = match &self { + KeyUri::SecureEnclaveKey(_) => return AlgorithmType::Es256, + KeyUri::YubikeyPivKey(key) => key.algorithm, + KeyUri::YubikeyHmacEncSoftKey(key) => key.algorithm, + }; + match algorithm_id { + KeyAlgorithmId::Rsa1024 | KeyAlgorithmId::Rsa2048 + | KeyAlgorithmId::Rsa3072 | KeyAlgorithmId::Rsa4096 => AlgorithmType::Rs256, + KeyAlgorithmId::EccP256 => AlgorithmType::Es256, + KeyAlgorithmId::EccP384 => AlgorithmType::Es384, + KeyAlgorithmId::EccP521 => AlgorithmType::Es512, + } + } } impl ToString for KeyUri { diff --git a/src/main.rs b/src/main.rs index b29b797..c34c586 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,6 +49,7 @@ mod cmd_se_ecdh; mod cmd_se_ecsign; mod cmd_se_generate; mod cmd_se_recover; +mod cmd_sign_jwt; mod cmd_sign_jwt_piv; mod cmd_sign_jwt_se; mod cmd_sign_jwt_soft; @@ -69,6 +70,7 @@ mod fidoutil; mod hmacutil; mod keychain; mod keyutil; +mod pbeutil; mod pgpcardutil; mod pinutil; mod pivutil; @@ -79,7 +81,6 @@ mod signfile; mod sshutil; mod util; mod yubikeyutil; -mod pbeutil; pub struct DefaultCommandImpl; @@ -145,6 +146,7 @@ fn inner_main() -> CommandError { Box::new(cmd_sign_jwt_piv::CommandImpl), Box::new(cmd_sign_jwt_soft::CommandImpl), Box::new(cmd_sign_jwt_se::CommandImpl), + Box::new(cmd_sign_jwt::CommandImpl), Box::new(cmd_file_sign::CommandImpl), Box::new(cmd_file_verify::CommandImpl), Box::new(cmd_se::CommandImpl), diff --git a/src/pivutil.rs b/src/pivutil.rs index 608b5dd..f98df08 100644 --- a/src/pivutil.rs +++ b/src/pivutil.rs @@ -1,4 +1,5 @@ use clap::ArgMatches; +use jwt::AlgorithmType; use rust_util::XResult; use spki::{ObjectIdentifier, SubjectPublicKeyInfoOwned}; use spki::der::{Decode, Encode}; @@ -62,6 +63,26 @@ pub trait FromStr { Self: Sized; } +impl ToStr for AlgorithmType { + fn to_str(&self) -> &str { + match self { + AlgorithmType::Hs256 => "HS256", + AlgorithmType::Hs384 => "HS384", + AlgorithmType::Hs512 => "HS512", + AlgorithmType::Rs256 => "RS256", + AlgorithmType::Rs384 => "RS384", + AlgorithmType::Rs512 => "RS512", + AlgorithmType::Es256 => "ES256", + AlgorithmType::Es384 => "ES384", + AlgorithmType::Es512 => "ES512", + AlgorithmType::Ps256 => "PS256", + AlgorithmType::Ps384 => "PS384", + AlgorithmType::Ps512 => "PS512", + AlgorithmType::None => "NONE", + } + } +} + impl ToStr for PinPolicy { fn to_str(&self) -> &str { match self {