use std::{ fs::File, io::{Read, Write}, }; use aws_manager::{ self, kms::{self, envelope::Manager}, sts, }; use tokio::time::{sleep, Duration}; /// cargo run --example kms --features="kms,sts" #[tokio::main] async fn main() { // ref. https://github.com/env-logger-rs/env_logger/issues/47 env_logger::init_from_env( env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); let shared_config = aws_manager::load_config(Some(String::from("us-east-1")), None, None).await; log::info!("region {:?}", shared_config.region().unwrap()); let sts_manager = sts::Manager::new(&shared_config); let identity = sts_manager.get_identity().await.unwrap(); log::info!("STS identity: {:?}", identity); let kms_manager = kms::Manager::new(&shared_config); let mut key_desc = id_manager::time::with_prefix("test"); key_desc.push_str("-cmk"); // error should be ignored if it does not exist kms_manager .schedule_to_delete("invalid_id", 7) .await .unwrap(); let encrypt_key = kms_manager .create_symmetric_default_key(&key_desc, false) .await .unwrap(); let (grant_id, _grant_token) = kms_manager .create_grant_for_encrypt_decrypt(&encrypt_key.id, &identity.role_arn) .await .unwrap(); let dek = kms_manager .generate_data_key(&encrypt_key.id, None) .await .unwrap(); let dek_ciphertext_decrypted = kms_manager .decrypt(&encrypt_key.id, None, dek.ciphertext) .await .unwrap(); assert_eq!(dek.plaintext, dek_ciphertext_decrypted); let dek_plaintext_encrypted = kms_manager .encrypt(&encrypt_key.id, None, dek.plaintext.clone()) .await .unwrap(); let dek_plaintext_encrypted_decrypted = kms_manager .decrypt(&encrypt_key.id, None, dek_plaintext_encrypted) .await .unwrap(); assert_eq!(dek.plaintext, dek_plaintext_encrypted_decrypted); assert_eq!(dek_ciphertext_decrypted, dek_plaintext_encrypted_decrypted); let plaintext = "Hello World!"; let mut plaintext_file = tempfile::NamedTempFile::new().unwrap(); plaintext_file.write_all(plaintext.as_bytes()).unwrap(); let plaintext_file_path = plaintext_file.path().to_str().unwrap(); let encrypted_file_path = random_manager::tmp_path(10, Some(".encrypted")).unwrap(); let decrypted_file_path = random_manager::tmp_path(10, Some(".encrypted")).unwrap(); kms_manager .encrypt_file( &encrypt_key.id, None, plaintext_file_path, &encrypted_file_path, ) .await .unwrap(); kms_manager .decrypt_file( &encrypt_key.id, None, &encrypted_file_path, &decrypted_file_path, ) .await .unwrap(); let mut encrypted_file = File::open(encrypted_file_path).unwrap(); let mut encrypted_file_contents = Vec::new(); encrypted_file .read_to_end(&mut encrypted_file_contents) .unwrap(); let mut decrypted_file = File::open(decrypted_file_path).unwrap(); let mut decrypted_file_contents = Vec::new(); decrypted_file .read_to_end(&mut decrypted_file_contents) .unwrap(); log::info!("encrypted_file_contents: {:?}", encrypted_file_contents); log::info!("decrypted_file_contents: {:?}", decrypted_file_contents); assert_eq!(&decrypted_file_contents, plaintext.as_bytes()); assert!(cmp_manager::eq_vectors( &decrypted_file_contents, plaintext.as_bytes() )); let envelope_manager = Manager::new( &kms_manager, encrypt_key.id.clone(), "test-aad-tag".to_string(), // AAD tag ); let sealed_aes_256_file_path = random_manager::tmp_path(10, Some(".encrypted")).unwrap(); let unsealed_aes_256_file_path = random_manager::tmp_path(10, None).unwrap(); envelope_manager .seal_aes_256_file(plaintext_file_path, &sealed_aes_256_file_path) .await .unwrap(); envelope_manager .unseal_aes_256_file(&sealed_aes_256_file_path, &unsealed_aes_256_file_path) .await .unwrap(); let mut sealed_aes_256_file = File::open(sealed_aes_256_file_path).unwrap(); let mut sealed_aes_256_file_contents = Vec::new(); sealed_aes_256_file .read_to_end(&mut sealed_aes_256_file_contents) .unwrap(); let mut unsealed_aes_256_file = File::open(unsealed_aes_256_file_path).unwrap(); let mut unsealed_aes_256_file_contents = Vec::new(); unsealed_aes_256_file .read_to_end(&mut unsealed_aes_256_file_contents) .unwrap(); log::info!( "sealed_aes_256_file_contents: {:?}", sealed_aes_256_file_contents ); log::info!( "unsealed_aes_256_file_contents: {:?}", unsealed_aes_256_file_contents ); assert_eq!(&unsealed_aes_256_file_contents, plaintext.as_bytes()); assert!(cmp_manager::eq_vectors( &unsealed_aes_256_file_contents, plaintext.as_bytes() )); sleep(Duration::from_secs(2)).await; // envelope encryption with "AES_256" (32-byte) let plaintext_sealed = envelope_manager .seal_aes_256(plaintext.as_bytes()) .await .unwrap(); sleep(Duration::from_secs(2)).await; let plaintext_sealed_unsealed = envelope_manager .unseal_aes_256(&plaintext_sealed) .await .unwrap(); log::info!("plaintext_sealed: {:?}", plaintext_sealed); log::info!("plaintext_sealed_unsealed: {:?}", plaintext_sealed_unsealed); assert_eq!(&plaintext_sealed_unsealed, plaintext.as_bytes()); assert!(cmp_manager::eq_vectors( &plaintext_sealed_unsealed, plaintext.as_bytes() )); kms_manager .revoke_grant(&encrypt_key.id, &grant_id) .await .unwrap(); kms_manager .schedule_to_delete(&encrypt_key.id, 7) .await .unwrap(); sleep(Duration::from_secs(2)).await; // error should be ignored if it's already scheduled for delete kms_manager .schedule_to_delete(&encrypt_key.id, 7) .await .unwrap(); }