feat: 1.13.12, support external command
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use jwt::AlgorithmType;
|
||||
use crate::pivutil::{FromStr, ToStr};
|
||||
use jwt::AlgorithmType;
|
||||
use percent_encoding::NON_ALPHANUMERIC;
|
||||
use regex::Regex;
|
||||
use rust_util::XResult;
|
||||
use yubikey::piv::{AlgorithmId, SlotId};
|
||||
@@ -10,6 +11,7 @@ pub enum KeyUri {
|
||||
SecureEnclaveKey(SecureEnclaveKey),
|
||||
YubikeyPivKey(YubikeyPivKey),
|
||||
YubikeyHmacEncSoftKey(YubikeyHmacEncSoftKey),
|
||||
ExternalCommandKey(ExternalCommandKey),
|
||||
}
|
||||
|
||||
impl KeyUri {
|
||||
@@ -25,10 +27,13 @@ impl KeyUri {
|
||||
KeyUri::SecureEnclaveKey(_) => return AlgorithmType::Es256,
|
||||
KeyUri::YubikeyPivKey(key) => key.algorithm,
|
||||
KeyUri::YubikeyHmacEncSoftKey(key) => key.algorithm,
|
||||
KeyUri::ExternalCommandKey(key) => key.algorithm,
|
||||
};
|
||||
match algorithm_id {
|
||||
KeyAlgorithmId::Rsa1024 | KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072 | KeyAlgorithmId::Rsa4096 => AlgorithmType::Rs256,
|
||||
KeyAlgorithmId::Rsa1024
|
||||
| KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072
|
||||
| KeyAlgorithmId::Rsa4096 => AlgorithmType::Rs256,
|
||||
KeyAlgorithmId::EccP256 => AlgorithmType::Es256,
|
||||
KeyAlgorithmId::EccP384 => AlgorithmType::Es384,
|
||||
KeyAlgorithmId::EccP521 => AlgorithmType::Es512,
|
||||
@@ -66,6 +71,17 @@ impl ToString for KeyUri {
|
||||
key_uri.push_str("::");
|
||||
key_uri.push_str(key.hmac_enc_private_key.as_str());
|
||||
}
|
||||
// key://external-command-file-name:external_command/p256::parameter
|
||||
KeyUri::ExternalCommandKey(key) => {
|
||||
let encoded_external_command =
|
||||
percent_encoding::utf8_percent_encode(&key.external_command, NON_ALPHANUMERIC)
|
||||
.to_string();
|
||||
key_uri.push_str(&encoded_external_command);
|
||||
key_uri.push_str(":external_command/");
|
||||
key_uri.push_str(key.algorithm.to_str());
|
||||
key_uri.push_str("::");
|
||||
key_uri.push_str(&key.parameter);
|
||||
}
|
||||
}
|
||||
key_uri
|
||||
}
|
||||
@@ -106,19 +122,35 @@ impl KeyAlgorithmId {
|
||||
|
||||
pub fn is_rsa(&self) -> bool {
|
||||
match self {
|
||||
KeyAlgorithmId::Rsa1024 | KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072 | KeyAlgorithmId::Rsa4096 => true,
|
||||
KeyAlgorithmId::Rsa1024
|
||||
| KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072
|
||||
| KeyAlgorithmId::Rsa4096 => true,
|
||||
KeyAlgorithmId::EccP256 | KeyAlgorithmId::EccP384 | KeyAlgorithmId::EccP521 => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_ecc(&self) -> bool {
|
||||
match self {
|
||||
KeyAlgorithmId::Rsa1024 | KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072 | KeyAlgorithmId::Rsa4096 => false,
|
||||
KeyAlgorithmId::Rsa1024
|
||||
| KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072
|
||||
| KeyAlgorithmId::Rsa4096 => false,
|
||||
KeyAlgorithmId::EccP256 | KeyAlgorithmId::EccP384 | KeyAlgorithmId::EccP521 => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_jwa_name(&self) -> &str {
|
||||
match self {
|
||||
KeyAlgorithmId::Rsa1024
|
||||
| KeyAlgorithmId::Rsa2048
|
||||
| KeyAlgorithmId::Rsa3072
|
||||
| KeyAlgorithmId::Rsa4096 => "RS256",
|
||||
KeyAlgorithmId::EccP256 => "ES256,",
|
||||
KeyAlgorithmId::EccP384 => "ES384",
|
||||
KeyAlgorithmId::EccP521 => "ES512",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for KeyAlgorithmId {
|
||||
@@ -206,6 +238,14 @@ pub struct YubikeyHmacEncSoftKey {
|
||||
pub hmac_enc_private_key: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct ExternalCommandKey {
|
||||
pub external_command: String,
|
||||
pub algorithm: KeyAlgorithmId,
|
||||
pub parameter: String,
|
||||
}
|
||||
|
||||
pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
|
||||
let regex = Regex::new(r##"^key://([0-9a-zA-Z\-\._]*):(\w+)/(\w+):((?:\w+)?):(.*)$"##).unwrap();
|
||||
let captures = match regex.captures(key_uri) {
|
||||
@@ -277,6 +317,28 @@ pub fn parse_key_uri(key_uri: &str) -> XResult<KeyUri> {
|
||||
debugging!("Parsed key uri: {:?}", parsed_key_uri);
|
||||
Ok(parsed_key_uri)
|
||||
}
|
||||
"external_command" => {
|
||||
if "" != usage {
|
||||
return simple_error!("Key uri's usage must be empty.");
|
||||
}
|
||||
let external_command = opt_result!(
|
||||
percent_encoding::percent_decode_str(host_or_name).decode_utf8(),
|
||||
"Decode external command failed: {}"
|
||||
);
|
||||
let algorithm = opt_value_result!(
|
||||
KeyAlgorithmId::from_str(algorithm),
|
||||
"Invalid algorithm id: {}",
|
||||
algorithm
|
||||
);
|
||||
let parameter = left_part.to_string();
|
||||
let parsed_key_uri = KeyUri::ExternalCommandKey(ExternalCommandKey {
|
||||
external_command: external_command.to_string(),
|
||||
algorithm,
|
||||
parameter,
|
||||
});
|
||||
debugging!("Parsed key uri: {:?}", parsed_key_uri);
|
||||
Ok(parsed_key_uri)
|
||||
}
|
||||
_ => simple_error!("Key uri's module must be se."),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user