diff --git a/Cargo.lock b/Cargo.lock index 95b7f82..ccd4537 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1039,7 +1039,7 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "local-mini-kms" -version = "1.0.9" +version = "1.0.10" dependencies = [ "aes-gcm-stream", "aes-kw", diff --git a/Cargo.toml b/Cargo.toml index 22fd963..70d4949 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "local-mini-kms" -version = "1.0.9" +version = "1.0.10" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/cli.rs b/src/cli.rs index bd1445f..84ceece 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -131,6 +131,7 @@ async fn do_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_> let line = { let line = read_line("Input clear(starts with hex: or base64:) or encrypted master key: ", read_from_pinentry)?; + let line = iff!(line.starts_with("hmac_enc:"), card_hmac_decrypt(&line)?, line); if line.starts_with("hex:") || line.starts_with("base64:") { let jwk = opt_result!(serde_json::to_string(&instance_public_key_jwk), "Serialize instance server public key JWK: {} failed"); master_key_encrypt(&line, &jwk)? @@ -151,6 +152,24 @@ async fn do_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_> Ok(Some(0)) } +fn card_hmac_decrypt(ciphertext: &str) -> XResult { + let mut c = std::process::Command::new("card-cli"); + c.args(&["hmac-decrypt", "--ciphertext", &ciphertext, "--json"]); + + debugging!("Run command: {:?}", c); + let output = opt_result!(c.output(), "Call: {:?} failed: {}", c); + if !output.status.success() { + return simple_error!("Call: {:?} exit with error", output); + } + let data: Value = serde_json::from_slice(&output.stdout)?; + if let Value::Object(data_map) = &data { + if let Some(Value::String(plaintext)) = data_map.get("plaintext") { + return Ok(plaintext.to_string()); + } + } + simple_error!("Hmac decrypt without plaintext, data: {:?}", data) +} + async fn send_kms_request_with_ssh_enabled(ssh_remote: &Option, get_request: bool, uri: &str, body: &Option) -> XResult { match ssh_remote { None => {