feat: v1.13.0

This commit is contained in:
2025-05-07 23:54:20 +08:00
parent 06d2da4ddf
commit a1ae0ff4dc
11 changed files with 193 additions and 65 deletions

90
Cargo.lock generated
View File

@@ -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]]

View File

@@ -1,6 +1,6 @@
[package]
name = "card-cli"
version = "1.12.10"
version = "1.13.0"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"

View File

@@ -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<Vec<u8>> {
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<Vec<u8>> {
match key_uri {
KeyUri::SecureEnclaveKey(key) => {
if "ES256" != alg {
@@ -65,7 +65,7 @@ fn sign(sub_arg_matches: &ArgMatches) -> XResult<Vec<u8>> {
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<Vec<u8>> {
"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<Vec<u8>> {
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<Vec<u8>> {
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())
}

85
src/cmd_sign_jwt.rs Normal file
View File

@@ -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<String>,
claims: &Map<String, Value>,
sub_arg_matches: &ArgMatches,
) -> XResult<String> {
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))
}

View File

@@ -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())

View File

@@ -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)

View File

@@ -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)

View File

@@ -54,10 +54,14 @@ pub fn parse_ecdsa_r_and_s(signature_der: &[u8]) -> XResult<(Vec<u8>, Vec<u8>)>
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<u8> {
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);

View File

@@ -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 {

View File

@@ -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),

View File

@@ -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 {