From 7fe4da3b4388f6be5aa3049cb3e0658425ce3295 Mon Sep 17 00:00:00 2001 From: Felix Marezki Date: Tue, 27 Jun 2023 23:23:03 +0200 Subject: [PATCH] feature: unwrapkey operation for keyvault (#1309) --- .../src/clients/key_client.rs | 11 +++ sdk/security_keyvault/src/keys/models.rs | 21 +++++ .../src/keys/operations/mod.rs | 2 + .../src/keys/operations/unwrap_key.rs | 83 +++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 sdk/security_keyvault/src/keys/operations/unwrap_key.rs diff --git a/sdk/security_keyvault/src/clients/key_client.rs b/sdk/security_keyvault/src/clients/key_client.rs index 758ca0c2f6..0f5618417f 100644 --- a/sdk/security_keyvault/src/clients/key_client.rs +++ b/sdk/security_keyvault/src/clients/key_client.rs @@ -100,4 +100,15 @@ impl KeyClient { { GetRandomBytesBuilder::new(self.clone(), hsm_name.into(), count) } + + pub fn unwrap_key( + &self, + name: N, + unwrap_key_parameters: UnwrapKeyParameters, + ) -> UnwrapKeyBuilder + where + N: Into, + { + UnwrapKeyBuilder::new(self.clone(), name.into(), unwrap_key_parameters) + } } diff --git a/sdk/security_keyvault/src/keys/models.rs b/sdk/security_keyvault/src/keys/models.rs index 10e4a53c35..d525b06d4e 100644 --- a/sdk/security_keyvault/src/keys/models.rs +++ b/sdk/security_keyvault/src/keys/models.rs @@ -410,3 +410,24 @@ pub struct GetRandomBytesResult { #[serde(rename = "value", deserialize_with = "deser_base64")] pub result: Vec, } + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct UnwrapKeyParameters { + pub decrypt_parameters_encryption: CryptographParamtersEncryption, + #[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")] + pub ciphertext: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct UnwrapKeyResult { + #[serde(skip)] + pub algorithm: EncryptionAlgorithm, + #[serde(rename = "kid")] + pub key_id: String, + #[serde( + rename = "value", + serialize_with = "ser_base64", + deserialize_with = "deser_base64" + )] + pub result: Vec, +} diff --git a/sdk/security_keyvault/src/keys/operations/mod.rs b/sdk/security_keyvault/src/keys/operations/mod.rs index 7de4fefa6d..d2f962856d 100644 --- a/sdk/security_keyvault/src/keys/operations/mod.rs +++ b/sdk/security_keyvault/src/keys/operations/mod.rs @@ -3,8 +3,10 @@ mod encrypt; mod get_key; mod get_random_bytes; mod sign; +mod unwrap_key; pub use decrypt::*; pub use encrypt::*; pub use get_key::*; pub use get_random_bytes::*; pub use sign::*; +pub use unwrap_key::*; diff --git a/sdk/security_keyvault/src/keys/operations/unwrap_key.rs b/sdk/security_keyvault/src/keys/operations/unwrap_key.rs new file mode 100644 index 0000000000..7691326291 --- /dev/null +++ b/sdk/security_keyvault/src/keys/operations/unwrap_key.rs @@ -0,0 +1,83 @@ +use crate::prelude::*; +use azure_core::{headers::Headers, CollectedResponse, Method}; +use serde_json::{Map, Value}; + +operation! { + UnwrapKey, + client: KeyClient, + name: String, + unwrap_key_parameters: UnwrapKeyParameters, + ?version: String +} + +impl UnwrapKeyBuilder { + pub fn into_future(mut self) -> UnwrapKey { + Box::pin(async move { + // POST {vaultBaseUrl}/keys/{key-name}/{key-version}/decrypt?api-version=7.2 + let version = self.version.unwrap_or_default(); + let mut uri = self.client.keyvault_client.vault_url.clone(); + let path = format!("keys/{}/{}/unwrapkey", self.name, version); + + uri.set_path(&path); + + let mut request_body = Map::new(); + request_body.insert( + "value".to_owned(), + Value::String(String::from_utf8(self.unwrap_key_parameters.ciphertext)?), + ); + + let algorithm = match self.unwrap_key_parameters.decrypt_parameters_encryption { + CryptographParamtersEncryption::Rsa(RsaEncryptionParameters { algorithm }) => { + request_body.insert("alg".to_owned(), serde_json::to_value(&algorithm)?); + algorithm + } + CryptographParamtersEncryption::AesGcm(AesGcmEncryptionParameters { + algorithm, + iv, + authentication_tag, + additional_authenticated_data, + }) => { + request_body.insert("alg".to_owned(), serde_json::to_value(&algorithm)?); + request_body.insert("iv".to_owned(), serde_json::to_value(iv)?); + request_body + .insert("tag".to_owned(), serde_json::to_value(authentication_tag)?); + if let Some(aad) = additional_authenticated_data { + request_body.insert("aad".to_owned(), serde_json::to_value(aad)?); + }; + algorithm + } + CryptographParamtersEncryption::AesCbc(AesCbcEncryptionParameters { + algorithm, + iv, + }) => { + request_body.insert("alg".to_owned(), serde_json::to_value(&algorithm)?); + request_body.insert("iv".to_owned(), serde_json::to_value(iv)?); + algorithm + } + }; + + let headers = Headers::new(); + let mut request = self.client.keyvault_client.finalize_request( + uri, + Method::Post, + headers, + Some(Value::Object(request_body).to_string().into()), + )?; + + let response = self + .client + .keyvault_client + .send(&mut self.context, &mut request) + .await?; + + let response = CollectedResponse::from_response(response).await?; + let body = response.body(); + + let mut result = serde_json::from_slice::(body)?; + result.algorithm = algorithm; + Ok(result) + }) + } +} + +type UnwrapKeyResponse = UnwrapKeyResult;