#[cfg(feature = "non-fips")]
use cosmian_kms_client::reexport::cosmian_kms_client_utils::export_utils::ExportKeyFormat;
use cosmian_kms_client::reexport::cosmian_kms_client_utils::{
create_utils::SymmetricAlgorithm, symmetric_utils::DataEncryptionAlgorithm,
};
use cosmian_logger::{info, log_init};
use tempfile::TempDir;
use test_kms_server::TestsContext;
use uuid::Uuid;
use crate::{
actions::kms::{
shared::{ExportSecretDataOrKeyAction, UnwrapSecretDataOrKeyAction},
symmetric::{KeyEncryptionAlgorithm, keys::create_key::CreateKeyAction},
},
error::result::KmsCliResult,
tests::kms::symmetric::encrypt_decrypt::run_encrypt_decrypt_test,
};
pub(super) async fn test_wrap_with_aes_gcm(ctx: &TestsContext) -> KmsCliResult<()> {
log_init(option_env!("RUST_LOG"));
let wrapping_key_id = CreateKeyAction {
key_id: Some("hsm::0::".to_owned() + &Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
sensitive: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("Created wrapping key: {wrapping_key_id}");
let dek = CreateKeyAction {
key_id: Some(Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
wrapping_key_id: Some(wrapping_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("Created DEK: {dek}");
run_encrypt_decrypt_test(
&ctx.get_owner_client(),
&dek,
DataEncryptionAlgorithm::AesGcm,
Some(KeyEncryptionAlgorithm::AesGcm),
12 + 32 + 16
+ 1
+ 12 + 16, )
.await?;
run_encrypt_decrypt_test(
&ctx.get_owner_client(),
&dek,
DataEncryptionAlgorithm::AesGcm,
Some(KeyEncryptionAlgorithm::AesGcm),
12 + 32 + 16
+ 1
+ 12 + 16, )
.await
}
#[cfg(feature = "non-fips")]
pub(super) async fn test_wrap_with_rsa_oaep(ctx: &TestsContext) -> KmsCliResult<()> {
use crate::{
actions::kms::rsa::keys::create_key_pair::CreateKeyPairAction,
tests::kms::symmetric::encrypt_decrypt::run_encrypt_decrypt_test,
};
log_init(None);
let (_private_key_id, public_key_id) = CreateKeyPairAction {
key_size: 2048,
private_key_id: Some("hsm::0::".to_string() + &Uuid::new_v4().to_string()),
sensitive: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("Wrapping key id: {public_key_id}");
let dek = CreateKeyAction {
key_id: Some(Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
wrapping_key_id: Some(public_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
run_encrypt_decrypt_test(
&ctx.get_owner_client(),
&dek,
DataEncryptionAlgorithm::AesGcm,
Some(KeyEncryptionAlgorithm::AesGcm),
12 + 32 + 16
+ 1
+ 12 + 16, )
.await?;
run_encrypt_decrypt_test(
&ctx.get_owner_client(),
&dek,
DataEncryptionAlgorithm::AesGcm,
Some(KeyEncryptionAlgorithm::AesGcm),
12 + 32 + 16
+ 1
+ 12 + 16, )
.await
}
#[cfg(feature = "non-fips")]
pub(super) async fn test_unwrap_on_export(ctx: &TestsContext) -> KmsCliResult<()> {
use crate::actions::kms::{
rsa::keys::create_key_pair::CreateKeyPairAction, shared::ExportSecretDataOrKeyAction,
};
log_init(option_env!("RUST_LOG"));
let (_private_key_id, public_key_id) = CreateKeyPairAction {
key_size: 2048,
private_key_id: Some("hsm::0::".to_string() + &Uuid::new_v4().to_string()),
sensitive: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("===> Wrapping key id: {public_key_id}");
let dek = CreateKeyAction {
key_id: Some(Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
wrapping_key_id: Some(public_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("===> DEK id: {dek}");
let tmp_dir = TempDir::new()?;
let tmp_path = tmp_dir.path();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("dek.pem"),
key_id: Some(dek.to_string()),
export_format: ExportKeyFormat::Raw,
unwrap: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
Ok(())
}
pub(super) async fn test_unwrap_with_hsm_key(ctx: &TestsContext) -> KmsCliResult<()> {
log_init(option_env!("RUST_LOG"));
let wrapping_key_id = CreateKeyAction {
key_id: Some("hsm::0::".to_owned() + &Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
sensitive: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("===> Wrapping key id: {wrapping_key_id}");
let dek_id = CreateKeyAction {
key_id: Some(Uuid::new_v4().to_string()),
number_of_bits: Some(256),
algorithm: SymmetricAlgorithm::Aes,
wrapping_key_id: Some(wrapping_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
info!("===> DEK id: {dek_id}");
let tmp_dir = TempDir::new()?;
let wrapped_file = tmp_dir.path().join("dek_wrapped.json");
let unwrapped_file = tmp_dir.path().join("dek_unwrapped.json");
ExportSecretDataOrKeyAction {
key_file: wrapped_file.clone(),
key_id: Some(dek_id.to_string()),
export_format: cosmian_kms_client::reexport::cosmian_kms_client_utils::export_utils::ExportKeyFormat::JsonTtlv,
unwrap: false,
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
Box::pin(
UnwrapSecretDataOrKeyAction {
key_file_in: wrapped_file,
key_file_out: Some(unwrapped_file.clone()),
unwrap_key_id: Some(wrapping_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client()),
)
.await?;
assert!(
unwrapped_file.exists(),
"unwrapped key file must be written to disk"
);
let unwrapped = cosmian_kms_client::read_object_from_json_ttlv_file(&unwrapped_file)?;
assert!(
!unwrapped.is_wrapped(),
"key material in output file must not be wrapped"
);
Ok(())
}