#![cfg(feature = "aws")]
use crate::cmk::CMKTrait;
use crate::error::cmk::CMKError;
use async_trait::async_trait;
use aws_sdk_kms::primitives::Blob;
use aws_sdk_kms::types::EncryptionAlgorithmSpec;
use aws_sdk_kms::Client;
use std::sync::Arc;
pub struct AwsCMK {
pub(crate) client: Arc<Client>,
pub(crate) key_name: String,
pub(crate) encryption_algorithm: EncryptionAlgorithmSpec,
}
impl AwsCMK {
pub fn new(
client: Arc<Client>,
key_name: String,
encryption_algorithm: EncryptionAlgorithmSpec
) -> Self {
Self {
client,
key_name,
encryption_algorithm,
}
}
}
#[async_trait]
impl CMKTrait for AwsCMK {
async fn encrypt(&self, plaintext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
let blob = Blob::new(plaintext);
let encrypted = self.client
.encrypt()
.key_id(&self.key_name)
.encryption_algorithm(self.encryption_algorithm.clone())
.plaintext(blob)
.send();
match encrypted.await {
Ok(encrypted) =>
match encrypted.ciphertext_blob() {
Some(ciphertext) => Ok(ciphertext.clone().into_inner()),
None => Err(CMKError("CMK returned no ciphertext".to_owned())),
}
Err(e) => Err(CMKError(format!("Could not encrypt plaintext, Error: {:?}", e))),
}
}
async fn decrypt(&self, ciphertext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
let blob = Blob::new(ciphertext);
let decrypted = self.client
.decrypt()
.key_id(&self.key_name)
.encryption_algorithm(self.encryption_algorithm.clone())
.ciphertext_blob(blob)
.send();
match decrypted.await {
Ok(decrypted) =>
match decrypted.plaintext() {
Some(plaintext) => Ok(plaintext.clone().into_inner()),
None => Err(CMKError("CMK returned no plaintext".to_string())),
}
Err(e) => Err(CMKError(format!("Could not decrypt ciphertext, Error: {:?}", e))),
}
}
}