Skip to content

Commit e21e2ec

Browse files
KeyClient: support encrypt operation. (#1264)
1 parent d9eb5de commit e21e2ec

File tree

5 files changed

+147
-14
lines changed

5 files changed

+147
-14
lines changed

sdk/security_keyvault/src/clients/key_client.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,23 @@ impl KeyClient {
6666
{
6767
DecryptBuilder::new(self.clone(), name.into(), decrypt_parameters)
6868
}
69+
70+
/// Encrypt a single block of data.
71+
///
72+
/// The ENCRYPT operation encrypts an arbitrary sequence of plaintext using
73+
/// the target encryption key and specified algorithm.
74+
//
75+
/// This operation is the reverse of the DECRYPT operation; only a single
76+
/// block of data may be encrypted, the size of this block is dependent on
77+
/// the target key and the algorithm to be used.
78+
///
79+
/// The ENCRYPT operation applies to asymmetric and symmetric keys stored in
80+
/// Vault or HSM since it uses the private portion of the key. This
81+
/// operation requires the keys/encrypt permission.
82+
pub fn encrypt<N>(&self, name: N, encrypt_parameters: EncryptParameters) -> EncryptBuilder
83+
where
84+
N: Into<String>,
85+
{
86+
EncryptBuilder::new(self.clone(), name.into(), encrypt_parameters)
87+
}
6988
}

sdk/security_keyvault/src/keys/models.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -278,25 +278,32 @@ impl Display for EncryptionAlgorithm {
278278

279279
#[derive(Debug, Serialize, Deserialize, Clone)]
280280
pub struct DecryptParameters {
281-
pub decrypt_parameters_encryption: DecryptParametersEncryption,
281+
pub decrypt_parameters_encryption: CryptographParamtersEncryption,
282282
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
283283
pub ciphertext: Vec<u8>,
284284
}
285285

286286
#[derive(Debug, Serialize, Deserialize, Clone)]
287287
#[serde(untagged)]
288-
pub enum DecryptParametersEncryption {
289-
Rsa(RsaDecryptParameters),
290-
AesGcm(AesGcmDecryptParameters),
291-
AesCbc(AesCbcDecryptParameters),
288+
pub enum CryptographParamtersEncryption {
289+
Rsa(RsaEncryptionParameters),
290+
AesGcm(AesGcmEncryptionParameters),
291+
AesCbc(AesCbcEncryptionParameters),
292292
}
293293

294294
#[derive(Debug, Serialize, Deserialize, Clone)]
295-
pub struct RsaDecryptParameters {
295+
pub struct EncryptParameters {
296+
pub encrypt_parameters_encryption: CryptographParamtersEncryption,
297+
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
298+
pub plaintext: Vec<u8>,
299+
}
300+
301+
#[derive(Debug, Serialize, Deserialize, Clone)]
302+
pub struct RsaEncryptionParameters {
296303
pub algorithm: EncryptionAlgorithm,
297304
}
298305

299-
impl RsaDecryptParameters {
306+
impl RsaEncryptionParameters {
300307
pub fn new(algorithm: EncryptionAlgorithm) -> Result<Self, Error> {
301308
match algorithm {
302309
EncryptionAlgorithm::Rsa15
@@ -310,7 +317,7 @@ impl RsaDecryptParameters {
310317
}
311318

312319
#[derive(Debug, Serialize, Deserialize, Clone)]
313-
pub struct AesGcmDecryptParameters {
320+
pub struct AesGcmEncryptionParameters {
314321
pub algorithm: EncryptionAlgorithm,
315322
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
316323
pub iv: Vec<u8>,
@@ -323,7 +330,7 @@ pub struct AesGcmDecryptParameters {
323330
pub additional_authenticated_data: Option<Vec<u8>>,
324331
}
325332

326-
impl AesGcmDecryptParameters {
333+
impl AesGcmEncryptionParameters {
327334
pub fn new(
328335
algorithm: EncryptionAlgorithm,
329336
iv: Vec<u8>,
@@ -347,13 +354,13 @@ impl AesGcmDecryptParameters {
347354
}
348355

349356
#[derive(Debug, Serialize, Deserialize, Clone)]
350-
pub struct AesCbcDecryptParameters {
357+
pub struct AesCbcEncryptionParameters {
351358
pub algorithm: EncryptionAlgorithm,
352359
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
353360
pub iv: Vec<u8>,
354361
}
355362

356-
impl AesCbcDecryptParameters {
363+
impl AesCbcEncryptionParameters {
357364
pub fn new(algorithm: EncryptionAlgorithm, iv: Vec<u8>) -> Result<Self, Error> {
358365
match algorithm {
359366
EncryptionAlgorithm::A128Cbc
@@ -382,3 +389,17 @@ pub struct DecryptResult {
382389
)]
383390
pub result: Vec<u8>,
384391
}
392+
393+
#[derive(Debug, Deserialize)]
394+
pub struct EncryptResult {
395+
#[serde(skip)]
396+
pub algorithm: EncryptionAlgorithm,
397+
#[serde(rename = "kid")]
398+
pub key_id: String,
399+
#[serde(
400+
rename = "value",
401+
serialize_with = "ser_base64",
402+
deserialize_with = "deser_base64"
403+
)]
404+
pub result: Vec<u8>,
405+
}

sdk/security_keyvault/src/keys/operations/decrypt.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ impl DecryptBuilder {
2727
);
2828

2929
let algorithm = match self.decrypt_parameters.decrypt_parameters_encryption {
30-
DecryptParametersEncryption::Rsa(RsaDecryptParameters { algorithm }) => {
30+
CryptographParamtersEncryption::Rsa(RsaEncryptionParameters { algorithm }) => {
3131
request_body
3232
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
3333
algorithm
3434
}
35-
DecryptParametersEncryption::AesGcm(AesGcmDecryptParameters {
35+
CryptographParamtersEncryption::AesGcm(AesGcmEncryptionParameters {
3636
algorithm,
3737
iv,
3838
authentication_tag,
@@ -50,7 +50,10 @@ impl DecryptBuilder {
5050
};
5151
algorithm
5252
}
53-
DecryptParametersEncryption::AesCbc(AesCbcDecryptParameters { algorithm, iv }) => {
53+
CryptographParamtersEncryption::AesCbc(AesCbcEncryptionParameters {
54+
algorithm,
55+
iv,
56+
}) => {
5457
request_body
5558
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
5659
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use crate::prelude::*;
2+
use azure_core::{base64, headers::Headers, CollectedResponse, Method};
3+
use serde_json::{Map, Value};
4+
5+
operation! {
6+
Encrypt,
7+
client: KeyClient,
8+
name: String,
9+
encrypt_parameters: EncryptParameters,
10+
?version: String
11+
}
12+
13+
impl EncryptBuilder {
14+
pub fn into_future(mut self) -> Encrypt {
15+
Box::pin(async move {
16+
// POST {vaultBaseUrl}/keys/{key-name}/{key-version}/encrypt?api-version=7.2
17+
let version = self.version.unwrap_or_default();
18+
let mut uri = self.client.keyvault_client.vault_url.clone();
19+
let path = format!("keys/{}/{}/encrypt", self.name, version);
20+
21+
uri.set_path(&path);
22+
23+
let mut request_body = Map::new();
24+
request_body.insert(
25+
"value".to_owned(),
26+
Value::String(base64::encode(self.encrypt_parameters.plaintext)),
27+
);
28+
29+
let algorithm = match self.encrypt_parameters.encrypt_parameters_encryption {
30+
CryptographParamtersEncryption::Rsa(RsaEncryptionParameters { algorithm }) => {
31+
request_body
32+
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
33+
algorithm
34+
}
35+
CryptographParamtersEncryption::AesGcm(AesGcmEncryptionParameters {
36+
algorithm,
37+
iv,
38+
authentication_tag,
39+
additional_authenticated_data,
40+
}) => {
41+
request_body
42+
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
43+
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
44+
request_body.insert(
45+
"tag".to_owned(),
46+
serde_json::to_value(authentication_tag).unwrap(),
47+
);
48+
if let Some(aad) = additional_authenticated_data {
49+
request_body.insert("aad".to_owned(), serde_json::to_value(aad).unwrap());
50+
};
51+
algorithm
52+
}
53+
CryptographParamtersEncryption::AesCbc(AesCbcEncryptionParameters {
54+
algorithm,
55+
iv,
56+
}) => {
57+
request_body
58+
.insert("alg".to_owned(), serde_json::to_value(&algorithm).unwrap());
59+
request_body.insert("iv".to_owned(), serde_json::to_value(iv).unwrap());
60+
algorithm
61+
}
62+
};
63+
64+
let headers = Headers::new();
65+
let mut request = self.client.keyvault_client.finalize_request(
66+
uri,
67+
Method::Post,
68+
headers,
69+
Some(Value::Object(request_body).to_string().into()),
70+
)?;
71+
72+
let response = self
73+
.client
74+
.keyvault_client
75+
.send(&mut self.context, &mut request)
76+
.await?;
77+
78+
let response = CollectedResponse::from_response(response).await?;
79+
let body = response.body();
80+
81+
let mut result = serde_json::from_slice::<EncryptResult>(body)?;
82+
result.algorithm = algorithm;
83+
Ok(result)
84+
})
85+
}
86+
}
87+
88+
type EncryptResponse = EncryptResult;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
mod decrypt;
2+
mod encrypt;
23
mod get_key;
34
mod sign;
45
pub use decrypt::*;
6+
pub use encrypt::*;
57
pub use get_key::*;
68
pub use sign::*;

0 commit comments

Comments
 (0)