Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyClient: support encrypt operation. #1264

Merged
merged 1 commit into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions sdk/security_keyvault/src/clients/key_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,23 @@ impl KeyClient {
{
DecryptBuilder::new(self.clone(), name.into(), decrypt_parameters)
}

/// Encrypt a single block of data.
///
/// The ENCRYPT operation encrypts an arbitrary sequence of plaintext using
/// the target encryption key and specified algorithm.
//
/// This operation is the reverse of the DECRYPT operation; only a single
/// block of data may be encrypted, the size of this block is dependent on
/// the target key and the algorithm to be used.
///
/// The ENCRYPT operation applies to asymmetric and symmetric keys stored in
/// Vault or HSM since it uses the private portion of the key. This
/// operation requires the keys/encrypt permission.
pub fn encrypt<N>(&self, name: N, encrypt_parameters: EncryptParameters) -> EncryptBuilder
where
N: Into<String>,
{
EncryptBuilder::new(self.clone(), name.into(), encrypt_parameters)
}
}
43 changes: 32 additions & 11 deletions sdk/security_keyvault/src/keys/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,25 +278,32 @@ impl Display for EncryptionAlgorithm {

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DecryptParameters {
pub decrypt_parameters_encryption: DecryptParametersEncryption,
pub decrypt_parameters_encryption: CryptographParamtersEncryption,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub ciphertext: Vec<u8>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum DecryptParametersEncryption {
Rsa(RsaDecryptParameters),
AesGcm(AesGcmDecryptParameters),
AesCbc(AesCbcDecryptParameters),
pub enum CryptographParamtersEncryption {
Rsa(RsaEncryptionParameters),
AesGcm(AesGcmEncryptionParameters),
AesCbc(AesCbcEncryptionParameters),
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RsaDecryptParameters {
pub struct EncryptParameters {
pub encrypt_parameters_encryption: CryptographParamtersEncryption,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub plaintext: Vec<u8>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RsaEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
}

impl RsaDecryptParameters {
impl RsaEncryptionParameters {
pub fn new(algorithm: EncryptionAlgorithm) -> Result<Self, Error> {
match algorithm {
EncryptionAlgorithm::Rsa15
Expand All @@ -310,7 +317,7 @@ impl RsaDecryptParameters {
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AesGcmDecryptParameters {
pub struct AesGcmEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub iv: Vec<u8>,
Expand All @@ -323,7 +330,7 @@ pub struct AesGcmDecryptParameters {
pub additional_authenticated_data: Option<Vec<u8>>,
}

impl AesGcmDecryptParameters {
impl AesGcmEncryptionParameters {
pub fn new(
algorithm: EncryptionAlgorithm,
iv: Vec<u8>,
Expand All @@ -347,13 +354,13 @@ impl AesGcmDecryptParameters {
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AesCbcDecryptParameters {
pub struct AesCbcEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub iv: Vec<u8>,
}

impl AesCbcDecryptParameters {
impl AesCbcEncryptionParameters {
pub fn new(algorithm: EncryptionAlgorithm, iv: Vec<u8>) -> Result<Self, Error> {
match algorithm {
EncryptionAlgorithm::A128Cbc
Expand Down Expand Up @@ -382,3 +389,17 @@ pub struct DecryptResult {
)]
pub result: Vec<u8>,
}

#[derive(Debug, Deserialize)]
pub struct EncryptResult {
#[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<u8>,
}
9 changes: 6 additions & 3 deletions sdk/security_keyvault/src/keys/operations/decrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ impl DecryptBuilder {
);

let algorithm = match self.decrypt_parameters.decrypt_parameters_encryption {
DecryptParametersEncryption::Rsa(RsaDecryptParameters { algorithm }) => {
CryptographParamtersEncryption::Rsa(RsaEncryptionParameters { algorithm }) => {
request_body
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
algorithm
}
DecryptParametersEncryption::AesGcm(AesGcmDecryptParameters {
CryptographParamtersEncryption::AesGcm(AesGcmEncryptionParameters {
algorithm,
iv,
authentication_tag,
Expand All @@ -50,7 +50,10 @@ impl DecryptBuilder {
};
algorithm
}
DecryptParametersEncryption::AesCbc(AesCbcDecryptParameters { algorithm, iv }) => {
CryptographParamtersEncryption::AesCbc(AesCbcEncryptionParameters {
algorithm,
iv,
}) => {
request_body
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
Expand Down
88 changes: 88 additions & 0 deletions sdk/security_keyvault/src/keys/operations/encrypt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::prelude::*;
use azure_core::{base64, headers::Headers, CollectedResponse, Method};
use serde_json::{Map, Value};

operation! {
Encrypt,
client: KeyClient,
name: String,
encrypt_parameters: EncryptParameters,
?version: String
}

impl EncryptBuilder {
pub fn into_future(mut self) -> Encrypt {
Box::pin(async move {
// POST {vaultBaseUrl}/keys/{key-name}/{key-version}/encrypt?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/{}/{}/encrypt", self.name, version);

uri.set_path(&path);

let mut request_body = Map::new();
request_body.insert(
"value".to_owned(),
Value::String(base64::encode(self.encrypt_parameters.plaintext)),
);

let algorithm = match self.encrypt_parameters.encrypt_parameters_encryption {
CryptographParamtersEncryption::Rsa(RsaEncryptionParameters { algorithm }) => {
request_body
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
algorithm
}
CryptographParamtersEncryption::AesGcm(AesGcmEncryptionParameters {
algorithm,
iv,
authentication_tag,
additional_authenticated_data,
}) => {
request_body
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
request_body.insert(
"tag".to_owned(),
serde_json::to_value(authentication_tag).unwrap(),
);
if let Some(aad) = additional_authenticated_data {
request_body.insert("aad".to_owned(), serde_json::to_value(aad).unwrap());
};
algorithm
}
CryptographParamtersEncryption::AesCbc(AesCbcEncryptionParameters {
algorithm,
iv,
}) => {
request_body
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
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::<EncryptResult>(body)?;
result.algorithm = algorithm;
Ok(result)
})
}
}

type EncryptResponse = EncryptResult;
2 changes: 2 additions & 0 deletions sdk/security_keyvault/src/keys/operations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod decrypt;
mod encrypt;
mod get_key;
mod sign;
pub use decrypt::*;
pub use encrypt::*;
pub use get_key::*;
pub use sign::*;