use std::path::PathBuf;
use cosmian_kmip::kmip_2_1::{
kmip_operations::Sign,
kmip_types::{CryptographicParameters, UniqueIdentifier},
};
use cosmian_kms_client::{KmsClient, read_bytes_from_file, write_bytes_to_file};
use crate::{
actions::kms::{console, labels::KEY_ID, shared::get_key_uid},
error::result::{KmsCliResult, KmsCliResultHelper},
};
pub(crate) async fn run_sign(
kms_rest_client: KmsClient,
input_file: PathBuf,
key_id: Option<String>,
tags: Option<Vec<String>>,
output_file: Option<PathBuf>,
cryptographic_parameters: Option<CryptographicParameters>,
digested: bool,
) -> KmsCliResult<()> {
let data = read_bytes_from_file(&input_file)
.with_context(|| "Cannot read bytes from the input file")?;
let id = get_key_uid(key_id.as_ref(), tags.as_ref(), KEY_ID)?;
let sign_request = if digested {
Sign {
unique_identifier: Some(UniqueIdentifier::TextString(id)),
cryptographic_parameters,
data: None,
digested_data: Some(data),
correlation_value: None,
init_indicator: None,
final_indicator: None,
}
} else {
Sign {
unique_identifier: Some(UniqueIdentifier::TextString(id)),
cryptographic_parameters,
data: Some(data.into()),
digested_data: None,
correlation_value: None,
init_indicator: None,
final_indicator: None,
}
};
let response = kms_rest_client
.sign(sign_request)
.await
.with_context(|| "Cannot execute the query on the KMS server")?;
let signature = response.signature_data.context("The signature is empty")?;
let output_path = output_file.unwrap_or_else(|| {
let mut p = input_file.clone();
p.set_extension("signed");
p
});
write_bytes_to_file(&signature, &output_path)
.with_context(|| "Cannot write the signature to the output file")?;
let stdout = format!("Signature written to {}", output_path.display());
let mut stdout = console::Stdout::new(&stdout);
stdout.set_tags(tags.as_ref());
stdout.write()?;
Ok(())
}