feat: v1.12.2
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage};
|
||||
use crate::pivutil::slot_equals;
|
||||
use crate::util::base64_encode;
|
||||
use crate::{cmdutil, seutil, util};
|
||||
use crate::yubikeyutil::find_key_or_error;
|
||||
use crate::{cmdutil, ecdsautil, hmacutil, seutil, util, yubikeyutil};
|
||||
use clap::{App, ArgMatches, SubCommand};
|
||||
use ecdsa::elliptic_curve::pkcs8::der::Encode;
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
@@ -9,7 +9,6 @@ use rust_util::XResult;
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use x509_parser::parse_x509_certificate;
|
||||
use yubikey::{Key, YubiKey};
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -22,13 +21,15 @@ impl Command for CommandImpl {
|
||||
SubCommand::with_name(self.name())
|
||||
.about("External public key subcommand")
|
||||
.arg(cmdutil::build_parameter_arg())
|
||||
.arg(cmdutil::build_serial_arg())
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let parameter = sub_arg_matches.value_of("parameter").unwrap();
|
||||
let serial_opt = sub_arg_matches.value_of("serial");
|
||||
|
||||
let mut json = BTreeMap::new();
|
||||
match fetch_public_key(parameter) {
|
||||
match fetch_public_key(parameter, &serial_opt) {
|
||||
Ok(public_key_bytes) => {
|
||||
json.insert("success", Value::Bool(true));
|
||||
json.insert("public_key_base64", base64_encode(&public_key_bytes).into());
|
||||
@@ -44,7 +45,7 @@ impl Command for CommandImpl {
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_public_key(parameter: &str) -> XResult<Vec<u8>> {
|
||||
fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u8>> {
|
||||
let key_uri = parse_key_uri(parameter)?;
|
||||
match key_uri {
|
||||
KeyUri::SecureEnclaveKey(key) => {
|
||||
@@ -57,18 +58,27 @@ fn fetch_public_key(parameter: &str) -> XResult<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
KeyUri::YubikeyPivKey(key) => {
|
||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||
let keys = opt_result!(Key::list(&mut yk), "List keys failed: {}");
|
||||
for k in &keys {
|
||||
let slot_str = format!("{:x}", Into::<u8>::into(k.slot()));
|
||||
if slot_equals(&key.slot, &slot_str) {
|
||||
let cert_der = k.certificate().cert.to_der()?;
|
||||
let x509_certificate = parse_x509_certificate(cert_der.as_slice()).unwrap().1;
|
||||
let public_key_bytes = x509_certificate.public_key().raw;
|
||||
return Ok(public_key_bytes.to_vec());
|
||||
}
|
||||
let mut yk = yubikeyutil::open_yubikey_with_serial(serial_opt)?;
|
||||
if let Some(key) = find_key_or_error(&mut yk, &key.slot)? {
|
||||
let cert_der = key.certificate().cert.to_der()?;
|
||||
let x509_certificate = parse_x509_certificate(cert_der.as_slice()).unwrap().1;
|
||||
let public_key_bytes = x509_certificate.public_key().raw;
|
||||
return Ok(public_key_bytes.to_vec());
|
||||
}
|
||||
simple_error!("Slot {} not found", key.slot)
|
||||
}
|
||||
KeyUri::YubikeyHmacEncSoftKey(key) => {
|
||||
let private_key = hmacutil::try_hmac_decrypt_to_string(&key.hmac_enc_private_key)?;
|
||||
let p256_public_key = ecdsautil::parse_p256_private_key_to_public_key(&private_key).ok();
|
||||
let p384_public_key = ecdsautil::parse_p384_private_key_to_public_key(&private_key).ok();
|
||||
|
||||
if let Some(p256_public_key) = p256_public_key {
|
||||
return Ok(p256_public_key);
|
||||
}
|
||||
if let Some(p384_public_key) = p384_public_key {
|
||||
return Ok(p384_public_key);
|
||||
}
|
||||
simple_error!("Invalid hmac enc private key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user