main/
limit_encrypted_data_keys_example.rs1use aws_esdk::client as esdk_client;
20use aws_esdk::material_providers::client as mpl_client;
21use aws_esdk::material_providers::types::keyring::KeyringRef;
22use aws_esdk::material_providers::types::material_providers_config::MaterialProvidersConfig;
23use aws_esdk::material_providers::types::AesWrappingAlg;
24use aws_esdk::types::aws_encryption_sdk_config::AwsEncryptionSdkConfig;
25use aws_esdk::types::error::Error::AwsEncryptionSdkException;
26use rand::TryRngCore;
27use std::collections::HashMap;
28
29pub async fn encrypt_and_decrypt_with_keyring(
30 example_data: &str,
31 max_encrypted_data_keys: u16,
32) -> Result<(), crate::BoxError> {
33 let esdk_config = AwsEncryptionSdkConfig::builder()
40 .max_encrypted_data_keys(max_encrypted_data_keys)
41 .build()?;
42 let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
43
44 let key_namespace: &str = "my-key-namespace";
50 let key_name: &str = "my-aes-key-name";
51
52 let encryption_context = HashMap::from([
57 ("encryption".to_string(), "context".to_string()),
58 ("is not".to_string(), "secret".to_string()),
59 ("but adds".to_string(), "useful metadata".to_string()),
60 (
61 "that can help you".to_string(),
62 "be confident that".to_string(),
63 ),
64 (
65 "the data you are handling".to_string(),
66 "is what you think it is".to_string(),
67 ),
68 ]);
69
70 let mpl_config = MaterialProvidersConfig::builder().build()?;
73 let mpl = mpl_client::Client::from_conf(mpl_config)?;
74
75 let mut raw_aes_keyrings: Vec<KeyringRef> = vec![];
76
77 assert!(
78 max_encrypted_data_keys > 0,
79 "max_encrypted_data_keys MUST be greater than 0"
80 );
81
82 let mut i = 0;
83 while i < max_encrypted_data_keys {
84 let aes_key_bytes = generate_aes_key_bytes();
85
86 let raw_aes_keyring = mpl
87 .create_raw_aes_keyring()
88 .key_name(key_name)
89 .key_namespace(key_namespace)
90 .wrapping_key(aes_key_bytes)
91 .wrapping_alg(AesWrappingAlg::AlgAes256GcmIv12Tag16)
92 .send()
93 .await?;
94
95 raw_aes_keyrings.push(raw_aes_keyring);
96 i += 1;
97 }
98
99 let generator_keyring = raw_aes_keyrings.remove(0);
101
102 let multi_keyring = mpl
103 .create_multi_keyring()
104 .generator(generator_keyring)
105 .child_keyrings(raw_aes_keyrings)
106 .send()
107 .await?;
108
109 let plaintext = example_data.as_bytes();
111
112 let encryption_response = esdk_client
113 .encrypt()
114 .plaintext(plaintext)
115 .keyring(multi_keyring.clone())
116 .encryption_context(encryption_context.clone())
117 .send()
118 .await?;
119
120 let ciphertext = encryption_response
121 .ciphertext
122 .expect("Unable to unwrap ciphertext from encryption response");
123
124 assert_ne!(
127 ciphertext,
128 aws_smithy_types::Blob::new(plaintext),
129 "Ciphertext and plaintext data are the same. Invalid encryption"
130 );
131
132 let decryption_response = esdk_client
134 .decrypt()
135 .ciphertext(ciphertext.clone())
136 .keyring(multi_keyring.clone())
137 .encryption_context(encryption_context.clone())
139 .send()
140 .await?;
141
142 let decrypted_plaintext = decryption_response
143 .plaintext
144 .expect("Unable to unwrap plaintext from decryption response");
145
146 assert_eq!(
149 decrypted_plaintext,
150 aws_smithy_types::Blob::new(plaintext),
151 "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
152 );
153
154 let esdk_config = AwsEncryptionSdkConfig::builder()
157 .max_encrypted_data_keys(max_encrypted_data_keys - 1)
158 .build()?;
159 let esdk_client_incorrect_max_encrypted_keys = esdk_client::Client::from_conf(esdk_config)?;
160
161 let decryption_response_incorrect_max_encrypted_keys = esdk_client_incorrect_max_encrypted_keys
162 .decrypt()
163 .ciphertext(ciphertext)
164 .keyring(multi_keyring)
165 .encryption_context(encryption_context)
167 .send()
168 .await;
169
170 match decryption_response_incorrect_max_encrypted_keys {
171 Ok(_) => panic!(
172 "Decrypt using discovery keyring with wrong AWS Account ID MUST \
173 raise AwsCryptographicMaterialProvidersError"
174 ),
175 Err(AwsEncryptionSdkException { message: m }) => assert_eq!(
176 m,
177 "Ciphertext encrypted data keys exceed maxEncryptedDataKeys"
178 ),
179 _ => panic!("Unexpected error type"),
180 }
181
182 println!("Limit Encrypted Data Keys Example Completed Successfully");
183
184 Ok(())
185}
186
187fn generate_aes_key_bytes() -> Vec<u8> {
188 let mut random_bytes = [0u8; 32];
193 rand::rngs::OsRng.try_fill_bytes(&mut random_bytes).unwrap();
194
195 random_bytes.to_vec()
196}
197
198#[tokio::test(flavor = "multi_thread")]
199pub async fn test_encrypt_and_decrypt_with_keyring() -> Result<(), crate::BoxError2> {
200 use crate::example_utils::utils;
202
203 let max_encrypted_data_keys: u16 = 3;
205
206 encrypt_and_decrypt_with_keyring(utils::TEST_EXAMPLE_DATA, max_encrypted_data_keys).await?;
207
208 Ok(())
209}