use cosmian_kms_client::kmip_2_1::kmip_types::UniqueIdentifier;
use tempfile::TempDir;
use test_kms_server::{
TestsContext, start_default_test_kms_server,
start_default_test_kms_server_with_non_revocable_key_ids,
};
use uuid::Uuid;
use crate::{
actions::kms::{
elliptic_curves::keys::create_key_pair::CreateKeyPairAction,
shared::ExportSecretDataOrKeyAction,
symmetric::keys::{create_key::CreateKeyAction, revoke_key::RevokeKeyAction},
},
error::result::KmsCliResult,
};
pub(crate) async fn assert_revoked(
ctx: &TestsContext,
key_id: &UniqueIdentifier,
) -> KmsCliResult<()> {
let tmp_dir = TempDir::new()?;
let tmp_path = tmp_dir.path();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap_err();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(key_id.to_string()),
allow_revoked: true,
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap();
Ok(())
}
#[tokio::test]
async fn test_revoke_symmetric_key() -> KmsCliResult<()> {
let ctx = start_default_test_kms_server().await;
let key_id = CreateKeyAction::default()
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(key_id.to_string()),
revocation_reason: "revocation test".to_owned(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &key_id).await?;
Ok(())
}
#[tokio::test]
async fn test_revoke_ec_key() -> KmsCliResult<()> {
let ctx = start_default_test_kms_server().await;
{
let (private_key_id, public_key_id) = CreateKeyPairAction::default()
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(private_key_id.to_string()),
revocation_reason: "revocation test".to_owned(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &private_key_id).await?;
assert_revoked(ctx, &public_key_id).await?;
};
{
let (private_key_id, public_key_id) = CreateKeyPairAction::default()
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(public_key_id.to_string()),
revocation_reason: "revocation test".to_owned(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &private_key_id).await?;
assert_revoked(ctx, &public_key_id).await?;
};
Ok(())
}
#[cfg(feature = "non-fips")]
#[tokio::test]
async fn test_revoke_cover_crypt() -> KmsCliResult<()> {
use std::path::PathBuf;
use crate::actions::kms::cover_crypt::keys::{
create_key_pair::CreateMasterKeyPairAction, create_user_key::CreateUserKeyAction,
};
let ctx = start_default_test_kms_server().await;
{
let (master_secret_key_id, master_public_key_id) = Box::pin(
CreateMasterKeyPairAction {
specification: PathBuf::from(
"../../test_data/access_structure_specifications.json",
),
..Default::default()
}
.run(ctx.get_owner_client()),
)
.await?;
let user_key_id_1 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
let user_key_id_2 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(master_secret_key_id.to_string()),
revocation_reason: "revocation test".to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &master_secret_key_id).await?;
assert_revoked(ctx, &master_public_key_id).await?;
assert_revoked(ctx, &user_key_id_1).await?;
assert_revoked(ctx, &user_key_id_2).await?;
};
{
let (master_secret_key_id, master_public_key_id) = Box::pin(
CreateMasterKeyPairAction {
specification: PathBuf::from(
"../../test_data/access_structure_specifications.json",
),
..Default::default()
}
.run(ctx.get_owner_client()),
)
.await?;
let user_key_id_1 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
let user_key_id_2 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(master_public_key_id.to_string()),
revocation_reason: "revocation test".to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &master_secret_key_id).await?;
assert_revoked(ctx, &master_public_key_id).await?;
assert_revoked(ctx, &user_key_id_1).await?;
assert_revoked(ctx, &user_key_id_2).await?;
};
{
let (master_secret_key_id, master_public_key_id) = Box::pin(
CreateMasterKeyPairAction {
specification: PathBuf::from(
"../../test_data/access_structure_specifications.json",
),
..Default::default()
}
.run(ctx.get_owner_client()),
)
.await?;
let user_key_id_1 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
let user_key_id_2 = CreateUserKeyAction {
master_secret_key_id: master_secret_key_id.to_string(),
access_policy: "(Department::MKG || Department::FIN) && Security Level::Top Secret"
.to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(user_key_id_1.to_string()),
revocation_reason: "revocation test".to_string(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &user_key_id_1).await?;
let tmp_dir = TempDir::new()?;
let tmp_path = tmp_dir.path();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(master_secret_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(master_public_key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(user_key_id_2.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap();
};
Ok(())
}
#[tokio::test]
async fn test_non_revocable_symmetric_key() -> KmsCliResult<()> {
let non_revocable_key = Uuid::new_v4().to_string();
let ctx = start_default_test_kms_server_with_non_revocable_key_ids(Some(vec![
non_revocable_key.clone(),
Uuid::new_v4().to_string(),
]))
.await;
let key_id = CreateKeyAction {
key_id: Some(non_revocable_key.clone()),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_eq!(key_id.to_string(), non_revocable_key);
RevokeKeyAction {
key_id: Some(key_id.to_string()),
revocation_reason: "revocation test".to_owned(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
let tmp_dir = TempDir::new()?;
let tmp_path = tmp_dir.path();
ExportSecretDataOrKeyAction {
key_file: tmp_path.join("output.export"),
key_id: Some(key_id.to_string()),
..Default::default()
}
.run(ctx.get_owner_client())
.await
.unwrap();
Ok(())
}
#[tokio::test]
async fn test_revoke_secret_data() -> KmsCliResult<()> {
let ctx = start_default_test_kms_server().await;
let secret_id =
crate::actions::kms::secret_data::create_secret::CreateSecretDataAction::default()
.run(ctx.get_owner_client())
.await?;
RevokeKeyAction {
key_id: Some(secret_id.to_string()),
revocation_reason: "revocation test".to_owned(),
..Default::default()
}
.run(ctx.get_owner_client())
.await?;
assert_revoked(ctx, &secret_id).await?;
Ok(())
}