use std::process::Command;
use assert_cmd::prelude::*;
use cosmian_kms_cli_actions::{
actions::symmetric::keys::create_key::CreateKeyAction,
reexport::cosmian_kms_client::read_object_from_json_ttlv_file,
};
use tempfile::TempDir;
use test_kms_server::start_default_test_kms_server;
use super::SUB_COMMAND;
use crate::{
config::CKMS_CONF_ENV,
error::{CosmianError, result::CosmianResult},
tests::{
PROG_NAME, save_kms_cli_config,
shared::{ExportKeyParams, export_key},
symmetric::create_key::create_symmetric_key,
utils::{extract_uids::extract_uid, recover_cmd_logs},
},
};
pub(crate) fn rekey_symmetric_key(
cli_conf_path: &str,
unique_identifier: &str,
) -> CosmianResult<String> {
let mut cmd = Command::cargo_bin(PROG_NAME)?;
cmd.env(CKMS_CONF_ENV, cli_conf_path);
cmd.env("RUST_MIN_STACK", "16777216");
let mut args = vec!["keys", "re-key"];
args.extend(vec!["--key-id", unique_identifier]);
cmd.arg(SUB_COMMAND).args(args);
let output = recover_cmd_logs(&mut cmd);
if output.status.success() {
let output = std::str::from_utf8(&output.stdout)?;
let unique_identifier = extract_uid(output, "Unique identifier").ok_or_else(|| {
CosmianError::Default("failed extracting the unique identifier".to_owned())
})?;
return Ok(unique_identifier.to_string());
}
Err(CosmianError::Default(
std::str::from_utf8(&output.stderr)?.to_owned(),
))
}
const AES_KEY_SIZE: usize = 256;
#[tokio::test]
pub(crate) async fn test_rekey_symmetric_key() -> CosmianResult<()> {
let tmp_dir = TempDir::new()?;
let tmp_path = tmp_dir.path();
let ctx = start_default_test_kms_server().await;
let (owner_client_conf_path, _) = save_kms_cli_config(ctx);
let id = create_symmetric_key(
&owner_client_conf_path,
CreateKeyAction {
number_of_bits: Some(AES_KEY_SIZE),
..Default::default()
},
)?;
export_key(ExportKeyParams {
cli_conf_path: owner_client_conf_path.clone(),
sub_command: "sym".to_owned(),
key_id: id.clone(),
key_file: tmp_path.join("aes_sym").to_str().unwrap().to_owned(),
..Default::default()
})?;
let id_2 = rekey_symmetric_key(&owner_client_conf_path, &id)?;
assert_eq!(id, id_2);
export_key(ExportKeyParams {
cli_conf_path: owner_client_conf_path,
sub_command: "sym".to_owned(),
key_id: id,
key_file: tmp_path.join("aes_sym_2").to_str().unwrap().to_owned(),
..Default::default()
})?;
let old_object = read_object_from_json_ttlv_file(&tmp_path.join("aes_sym"))?;
let new_object = read_object_from_json_ttlv_file(&tmp_path.join("aes_sym_2"))?;
assert_ne!(
old_object.key_block()?.key_bytes()?,
new_object.key_block()?.key_bytes()?
);
assert!(old_object.attributes()? == new_object.attributes()?);
assert_eq!(
new_object.attributes()?.cryptographic_length.unwrap(),
i32::try_from(AES_KEY_SIZE).unwrap()
);
Ok(())
}