use aws_config::Region;
use aws_esdk::client as esdk_client;
use aws_esdk::material_providers::client as mpl_client;
use aws_esdk::material_providers::types::material_providers_config::MaterialProvidersConfig;
use aws_esdk::types::aws_encryption_sdk_config::AwsEncryptionSdkConfig;
use std::collections::HashMap;
pub async fn encrypt_and_decrypt_with_keyring(
example_data: &str,
default_region_kms_key_id: &str,
second_region_kms_key_id: &str,
default_region: String,
second_region: String,
) -> Result<(), crate::BoxError> {
let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
let encryption_context = HashMap::from([
("encryption".to_string(), "context".to_string()),
("is not".to_string(), "secret".to_string()),
("but adds".to_string(), "useful metadata".to_string()),
(
"that can help you".to_string(),
"be confident that".to_string(),
),
(
"the data you are handling".to_string(),
"is what you think it is".to_string(),
),
]);
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
let kms_multi_keyring = mpl
.create_aws_kms_multi_keyring()
.generator(default_region_kms_key_id)
.kms_key_ids(vec![second_region_kms_key_id.to_string()])
.send()
.await?;
let plaintext = example_data.as_bytes();
let encryption_response = esdk_client
.encrypt()
.plaintext(plaintext)
.keyring(kms_multi_keyring.clone())
.encryption_context(encryption_context.clone())
.send()
.await?;
let ciphertext = encryption_response
.ciphertext
.expect("Unable to unwrap ciphertext from encryption response");
assert_ne!(
ciphertext,
aws_smithy_types::Blob::new(plaintext),
"Ciphertext and plaintext data are the same. Invalid encryption"
);
let decryption_response_multi_keyring = esdk_client
.decrypt()
.ciphertext(ciphertext.clone())
.keyring(kms_multi_keyring)
.encryption_context(encryption_context.clone())
.send()
.await?;
let decrypted_plaintext_multi_keyring = decryption_response_multi_keyring
.plaintext
.expect("Unable to unwrap plaintext from decryption response");
assert_eq!(
decrypted_plaintext_multi_keyring,
aws_smithy_types::Blob::new(plaintext),
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
);
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let default_region_kms_config = aws_sdk_kms::config::Builder::from(&sdk_config)
.region(Region::new(default_region))
.build();
let default_region_kms_client = aws_sdk_kms::Client::from_conf(default_region_kms_config);
let default_region_kms_keyring = mpl
.create_aws_kms_keyring()
.kms_key_id(default_region_kms_key_id)
.kms_client(default_region_kms_client)
.send()
.await?;
let decryption_response_default_region_kms_keyring = esdk_client
.decrypt()
.ciphertext(ciphertext.clone())
.keyring(default_region_kms_keyring)
.encryption_context(encryption_context.clone())
.send()
.await?;
let decrypted_plaintext_default_region_kms_keyring =
decryption_response_default_region_kms_keyring
.plaintext
.expect("Unable to unwrap plaintext from decryption response");
assert_eq!(
decrypted_plaintext_default_region_kms_keyring,
aws_smithy_types::Blob::new(plaintext),
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
);
let second_region_kms_config = aws_sdk_kms::config::Builder::from(&sdk_config)
.region(Region::new(second_region))
.build();
let second_region_kms_client = aws_sdk_kms::Client::from_conf(second_region_kms_config);
let second_region_kms_keyring = mpl
.create_aws_kms_keyring()
.kms_key_id(second_region_kms_key_id)
.kms_client(second_region_kms_client)
.send()
.await?;
let decryption_response_second_region_kms_keyring = esdk_client
.decrypt()
.ciphertext(ciphertext)
.keyring(second_region_kms_keyring)
.encryption_context(encryption_context)
.send()
.await?;
let decrypted_plaintext_second_region_kms_keyring =
decryption_response_second_region_kms_keyring
.plaintext
.expect("Unable to unwrap plaintext from decryption response");
assert_eq!(
decrypted_plaintext_second_region_kms_keyring,
aws_smithy_types::Blob::new(plaintext),
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
);
println!("KMS Multi Keyring Example Completed Successfully");
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
pub async fn test_encrypt_and_decrypt_with_keyring() -> Result<(), crate::BoxError2> {
use crate::example_utils::utils;
let default_region: String = "us-west-2".to_string();
let second_region: String = "eu-central-1".to_string();
encrypt_and_decrypt_with_keyring(
utils::TEST_EXAMPLE_DATA,
utils::TEST_DEFAULT_KMS_KEY_ID,
utils::TEST_SECOND_REGION_KMS_KEY_ID,
default_region,
second_region,
)
.await?;
Ok(())
}