main/keyring/ecdh/
kms_ecdh_discovery_keyring_example.rs1use crate::example_utils::utils::generate_kms_ecc_public_key;
31use crate::example_utils::utils::TEST_KMS_ECDH_KEY_ID_P256_SENDER;
32use aws_esdk::aws_cryptography_primitives::types::EcdhCurveSpec;
33use aws_esdk::client as esdk_client;
34use aws_esdk::material_providers::client as mpl_client;
35use aws_esdk::material_providers::types::material_providers_config::MaterialProvidersConfig;
36use aws_esdk::material_providers::types::KmsEcdhStaticConfigurations;
37use aws_esdk::material_providers::types::KmsPrivateKeyToStaticPublicKeyInput;
38use aws_esdk::material_providers::types::KmsPublicKeyDiscoveryInput;
39use aws_esdk::types::aws_encryption_sdk_config::AwsEncryptionSdkConfig;
40use aws_smithy_types::Blob;
41use std::collections::HashMap;
42
43pub async fn decrypt_with_keyring(
44 example_data: &str,
45 ecdh_curve_spec: EcdhCurveSpec,
46 ecc_recipient_key_arn: &str,
47) -> Result<(), crate::BoxError> {
48 let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
54 let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
55
56 let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
58 let kms_client = aws_sdk_kms::Client::new(&sdk_config);
59
60 let encryption_context = HashMap::from([
65 ("encryption".to_string(), "context".to_string()),
66 ("is not".to_string(), "secret".to_string()),
67 ("but adds".to_string(), "useful metadata".to_string()),
68 (
69 "that can help you".to_string(),
70 "be confident that".to_string(),
71 ),
72 (
73 "the data you are handling".to_string(),
74 "is what you think it is".to_string(),
75 ),
76 ]);
77
78 let kms_ecdh_discovery_static_configuration_input = KmsPublicKeyDiscoveryInput::builder()
80 .recipient_kms_identifier(ecc_recipient_key_arn)
81 .build()?;
82
83 let kms_ecdh_discovery_static_configuration =
84 KmsEcdhStaticConfigurations::KmsPublicKeyDiscovery(
85 kms_ecdh_discovery_static_configuration_input,
86 );
87
88 let mpl_config = MaterialProvidersConfig::builder().build()?;
90 let mpl = mpl_client::Client::from_conf(mpl_config)?;
91
92 let kms_ecdh_discovery_keyring = mpl
104 .create_aws_kms_ecdh_keyring()
105 .kms_client(kms_client.clone())
106 .curve_spec(ecdh_curve_spec)
107 .key_agreement_scheme(kms_ecdh_discovery_static_configuration)
108 .send()
109 .await?;
110
111 let plaintext = example_data.as_bytes();
114
115 let ciphertext = get_ciphertext(
121 example_data,
122 encryption_context.clone(),
123 ecc_recipient_key_arn,
124 ecdh_curve_spec,
125 kms_client,
126 esdk_client.clone(),
127 )
128 .await?;
129
130 let decryption_response = esdk_client
132 .decrypt()
133 .ciphertext(ciphertext)
134 .keyring(kms_ecdh_discovery_keyring)
135 .encryption_context(encryption_context)
137 .send()
138 .await?;
139
140 let decrypted_plaintext = decryption_response
141 .plaintext
142 .expect("Unable to unwrap plaintext from decryption response");
143
144 assert_eq!(
147 decrypted_plaintext,
148 aws_smithy_types::Blob::new(plaintext),
149 "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
150 );
151
152 println!("KMS ECDH Discovery Keyring Example Completed Successfully");
153
154 Ok(())
155}
156
157async fn get_ciphertext(
158 example_data: &str,
159 encryption_context: HashMap<String, String>,
160 ecc_recipient_key_arn: &str,
161 ecdh_curve_spec: EcdhCurveSpec,
162 kms_client: aws_sdk_kms::Client,
163 esdk_client: esdk_client::Client,
164) -> Result<Blob, crate::BoxError> {
165 let public_key_sender_utf8_bytes =
169 generate_kms_ecc_public_key(TEST_KMS_ECDH_KEY_ID_P256_SENDER).await?;
170 let public_key_recipient_utf8_bytes =
171 generate_kms_ecc_public_key(ecc_recipient_key_arn).await?;
172
173 let kms_ecdh_static_configuration_input = KmsPrivateKeyToStaticPublicKeyInput::builder()
175 .sender_kms_identifier(TEST_KMS_ECDH_KEY_ID_P256_SENDER)
176 .sender_public_key(public_key_sender_utf8_bytes)
178 .recipient_public_key(public_key_recipient_utf8_bytes)
180 .build()?;
181
182 let kms_ecdh_static_configuration = KmsEcdhStaticConfigurations::KmsPrivateKeyToStaticPublicKey(
183 kms_ecdh_static_configuration_input,
184 );
185
186 let mpl_config = MaterialProvidersConfig::builder().build()?;
188 let mpl = mpl_client::Client::from_conf(mpl_config)?;
189
190 let kms_ecdh_keyring = mpl
191 .create_aws_kms_ecdh_keyring()
192 .kms_client(kms_client)
193 .curve_spec(ecdh_curve_spec)
194 .key_agreement_scheme(kms_ecdh_static_configuration)
195 .send()
196 .await?;
197
198 let plaintext = example_data.as_bytes();
200
201 let encryption_response = esdk_client
202 .encrypt()
203 .plaintext(plaintext)
204 .keyring(kms_ecdh_keyring.clone())
205 .encryption_context(encryption_context.clone())
206 .send()
207 .await?;
208
209 let ciphertext = encryption_response
210 .ciphertext
211 .expect("Unable to unwrap ciphertext from encryption response");
212
213 assert_ne!(
216 ciphertext,
217 aws_smithy_types::Blob::new(plaintext),
218 "Ciphertext and plaintext data are the same. Invalid encryption"
219 );
220
221 Ok(ciphertext)
222}
223
224#[tokio::test(flavor = "multi_thread")]
225pub async fn test_decrypt_with_keyring() -> Result<(), crate::BoxError2> {
226 use crate::example_utils::utils;
228
229 decrypt_with_keyring(
230 utils::TEST_EXAMPLE_DATA,
231 EcdhCurveSpec::EccNistP256,
232 utils::TEST_KMS_ECDH_KEY_ID_P256_RECIPIENT,
233 )
234 .await?;
235
236 Ok(())
237}