feat: v1.13.19
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -593,7 +593,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "card-cli"
|
||||
version = "1.13.18"
|
||||
version = "1.13.19"
|
||||
dependencies = [
|
||||
"aes-gcm-stream",
|
||||
"authenticator 0.3.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "card-cli"
|
||||
version = "1.13.18"
|
||||
version = "1.13.19"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -122,7 +122,6 @@ pub fn ecdh(
|
||||
if let Ok(shared_secret) = ecdhutil::parse_p521_private_and_ecdh(&private_key_bytes, ephemeral_public_key_bytes) {
|
||||
return Ok(shared_secret.to_vec());
|
||||
}
|
||||
|
||||
simple_error!("Invalid EC private key and/or ephemeral public key")
|
||||
} else if key.algorithm.is_mlkem() {
|
||||
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?;
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage};
|
||||
use crate::util::{base64_decode, base64_encode};
|
||||
use crate::yubikeyutil::find_key_or_error;
|
||||
use crate::{cmd_hmac_decrypt, cmdutil, ecdsautil, seutil, util, yubikeyutil};
|
||||
use clap::{App, ArgMatches, SubCommand};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use ecdsa::elliptic_curve::pkcs8::der::Encode;
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::XResult;
|
||||
@@ -11,7 +11,7 @@ use std::collections::BTreeMap;
|
||||
use rsa::RsaPrivateKey;
|
||||
use spki::EncodePublicKey;
|
||||
use x509_parser::parse_x509_certificate;
|
||||
use crate::mlkemutil::try_parse_decapsulate_key_private_get_encapsulate;
|
||||
use crate::mlkemutil::{try_parse_decapsulate_key_private_get_encapsulate, try_parse_encapsulation_key_public_then_encapsulate};
|
||||
use crate::pivutil::ToStr;
|
||||
|
||||
pub struct CommandImpl;
|
||||
@@ -26,14 +26,16 @@ impl Command for CommandImpl {
|
||||
.about("External public key subcommand")
|
||||
.arg(cmdutil::build_parameter_arg())
|
||||
.arg(cmdutil::build_serial_arg())
|
||||
.arg(Arg::with_name("x-generate-shared-secret").long("x-generate-shared-secret").help("Generate a shared secret"))
|
||||
}
|
||||
|
||||
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 generate_shared_secret = sub_arg_matches.is_present("x-generate-shared-secret");
|
||||
|
||||
let mut json = BTreeMap::new();
|
||||
match fetch_public_key(parameter, &serial_opt) {
|
||||
match fetch_public_key(parameter, &serial_opt, generate_shared_secret, &mut json) {
|
||||
Ok(public_key_bytes) => {
|
||||
json.insert("success", Value::Bool(true));
|
||||
json.insert("public_key_base64", base64_encode(&public_key_bytes).into());
|
||||
@@ -49,7 +51,7 @@ impl Command for CommandImpl {
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u8>> {
|
||||
fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>, generate_shared_secret: bool, json: &mut BTreeMap<&str, Value>) -> XResult<Vec<u8>> {
|
||||
let key_uri = parse_key_uri(parameter)?;
|
||||
match key_uri {
|
||||
KeyUri::SecureEnclave(key) => {
|
||||
@@ -99,6 +101,13 @@ fn fetch_public_key(parameter: &str, serial_opt: &Option<&str>) -> XResult<Vec<u
|
||||
let private_key = cmd_hmac_decrypt::try_decrypt(&mut None, &key.hmac_enc_private_key)?;
|
||||
let private_key_der = base64_decode(&private_key)?;
|
||||
let (_, ek_public) = try_parse_decapsulate_key_private_get_encapsulate(&private_key_der)?;
|
||||
if generate_shared_secret {
|
||||
if let Ok((mlkem_len, ciphertext, shared_secret)) = try_parse_encapsulation_key_public_then_encapsulate(&ek_public) {
|
||||
json.insert("algorithm", mlkem_len.to_str().into());
|
||||
json.insert("ciphertext", base64_encode(ciphertext).into());
|
||||
json.insert("shared_secret", hex::encode(&shared_secret).into());
|
||||
}
|
||||
}
|
||||
Ok(ek_public)
|
||||
} else {
|
||||
simple_error!("Invalid algorithm: {}", key.algorithm.to_str())
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use crate::rsautil::rsa_public_key_to_jwk;
|
||||
use crate::util::{base64_encode, to_pem};
|
||||
use ecdsa::elliptic_curve::pkcs8::LineEnding;
|
||||
use ml_kem::kem::{Decapsulate, Encapsulate};
|
||||
use ml_kem::{EncodedSizeUser, KemCore, MlKem1024, MlKem512, MlKem768};
|
||||
use rust_util::XResult;
|
||||
use std::convert::TryInto;
|
||||
use crate::pivutil::ToStr;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum MlKemLen {
|
||||
@@ -13,6 +12,16 @@ pub enum MlKemLen {
|
||||
Len1024,
|
||||
}
|
||||
|
||||
impl ToStr for MlKemLen {
|
||||
fn to_str(&self) -> &str {
|
||||
match self {
|
||||
MlKemLen::Len512 => "mlkem512",
|
||||
MlKemLen::Len768 => "mlkem768",
|
||||
MlKemLen::Len1024 => "mlkem1024",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_mlkem_keypair(len: usize) -> XResult<(String, String, String, Vec<u8>, String)> {
|
||||
let (dk_private, ek_public) = match len {
|
||||
512 => generate_ml_kem_512(),
|
||||
@@ -98,6 +107,19 @@ pub fn generate_ml_kem_1024() -> (Vec<u8>, Vec<u8>) {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn try_parse_encapsulation_key_public_then_encapsulate(bytes: &[u8]) -> XResult<(MlKemLen, Vec<u8>, Vec<u8>)> {
|
||||
if let Ok((ciphertext, shared_key)) = parse_encapsulation_key_512_public_then_encapsulate(bytes) {
|
||||
return Ok((MlKemLen::Len512, ciphertext, shared_key));
|
||||
}
|
||||
if let Ok((ciphertext, shared_key)) = parse_encapsulation_key_768_public_then_encapsulate(bytes) {
|
||||
return Ok((MlKemLen::Len768, ciphertext, shared_key));
|
||||
}
|
||||
if let Ok((ciphertext, shared_key)) = parse_encapsulation_key_1024_public_then_encapsulate(bytes) {
|
||||
return Ok((MlKemLen::Len1024, ciphertext, shared_key));
|
||||
}
|
||||
simple_error!("Invalid encapsulation key, only allow MK-KEM-512, ML-KEM-768, ML-KEM-1024")
|
||||
}
|
||||
|
||||
pub fn parse_encapsulation_key_512_public_then_encapsulate(
|
||||
bytes: &[u8],
|
||||
) -> XResult<(Vec<u8>, Vec<u8>)> {
|
||||
|
||||
Reference in New Issue
Block a user