diff --git a/sdk/core/src/headers/mod.rs b/sdk/core/src/headers/mod.rs index 10ddcafe33..126edc1cf7 100644 --- a/sdk/core/src/headers/mod.rs +++ b/sdk/core/src/headers/mod.rs @@ -15,23 +15,23 @@ impl AsHeaders for T where T: Header, { - type Iter = std::option::IntoIter<(HeaderName, HeaderValue)>; + type Iter = std::vec::IntoIter<(HeaderName, HeaderValue)>; fn as_headers(&self) -> Self::Iter { - Some((self.name(), self.value())).into_iter() + vec![(self.name(), self.value())].into_iter() } } impl AsHeaders for Option where - T: Header, + T: AsHeaders>, { - type Iter = std::option::IntoIter<(HeaderName, HeaderValue)>; + type Iter = T::Iter; fn as_headers(&self) -> Self::Iter { match self { Some(h) => h.as_headers(), - None => None.into_iter(), + None => vec![].into_iter(), } } } @@ -361,3 +361,6 @@ pub const USER: HeaderName = HeaderName::from_static("x-ms-user"); pub const USER_AGENT: HeaderName = HeaderName::from_static("user-agent"); pub const VERSION: HeaderName = HeaderName::from_static("x-ms-version"); pub const WWW_AUTHENTICATE: HeaderName = HeaderName::from_static("www-authenticate"); +pub const ENCRYPTION_ALGORITHM: HeaderName = HeaderName::from_static("x-ms-encryption-algorithm"); +pub const ENCRYPTION_KEY: HeaderName = HeaderName::from_static("x-ms-encryption-key"); +pub const ENCRYPTION_KEY_SHA256: HeaderName = HeaderName::from_static("x-ms-encryption-key-sha256"); diff --git a/sdk/storage_blobs/src/blob/operations/get_blob.rs b/sdk/storage_blobs/src/blob/operations/get_blob.rs index 5551e70df4..ea197dd074 100644 --- a/sdk/storage_blobs/src/blob/operations/get_blob.rs +++ b/sdk/storage_blobs/src/blob/operations/get_blob.rs @@ -15,6 +15,7 @@ operation! { ?blob_versioning: BlobVersioning, ?lease_id: LeaseId, ?chunk_size: u64, + ?encryption_key: CPKInfo, ?if_modified_since: IfModifiedSinceCondition, ?if_match: IfMatchCondition, ?if_tags: IfTags, @@ -43,6 +44,7 @@ impl GetBlobBuilder { } headers.add(this.lease_id); + headers.add(this.encryption_key.as_ref()); headers.add(this.if_modified_since); headers.add(this.if_match.clone()); headers.add(this.if_tags.clone()); diff --git a/sdk/storage_blobs/src/blob/operations/put_block_blob.rs b/sdk/storage_blobs/src/blob/operations/put_block_blob.rs index 3dabac3e57..ab8864f180 100644 --- a/sdk/storage_blobs/src/blob/operations/put_block_blob.rs +++ b/sdk/storage_blobs/src/blob/operations/put_block_blob.rs @@ -16,6 +16,7 @@ operation! { ?access_tier: AccessTier, ?tags: Tags, ?lease_id: LeaseId, + ?encryption_key: CPKInfo, ?encryption_scope: EncryptionScope, ?if_modified_since: IfModifiedSinceCondition, ?if_match: IfMatchCondition, @@ -42,6 +43,7 @@ impl PutBlockBlobBuilder { } headers.add(self.access_tier); headers.add(self.lease_id); + headers.add(self.encryption_key); headers.add(self.encryption_scope); headers.add(self.if_modified_since); headers.add(self.if_match); diff --git a/sdk/storage_blobs/src/options/encryption_key.rs b/sdk/storage_blobs/src/options/encryption_key.rs new file mode 100644 index 0000000000..79847ae039 --- /dev/null +++ b/sdk/storage_blobs/src/options/encryption_key.rs @@ -0,0 +1,67 @@ +use azure_core::headers::{self, AsHeaders, HeaderName, HeaderValue}; + +const DEFAULT_ENCRYPTION_ALGORITHM: &str = "AES256"; + +#[derive(Clone, Debug)] +pub struct CPKInfo { + encryption_key: String, + encryption_key_sha256: String, + + // only support AES256 + encryption_algorithm: Option, +} + +impl CPKInfo { + pub fn new(key: String, key_sha256: String, algorithm: Option) -> Self { + Self { + encryption_key: key, + encryption_key_sha256: key_sha256, + + encryption_algorithm: algorithm, + } + } +} + +impl From<(String, String)> for CPKInfo { + fn from(s: (String, String)) -> Self { + Self::new(s.0, s.1, None) + } +} + +impl From<(String, String, String)> for CPKInfo { + fn from(s: (String, String, String)) -> Self { + Self::new(s.0, s.1, Some(s.2)) + } +} + +impl AsHeaders for CPKInfo { + type Iter = std::vec::IntoIter<(HeaderName, HeaderValue)>; + + fn as_headers(&self) -> Self::Iter { + let algorithm = self + .encryption_algorithm + .as_deref() + .unwrap_or(DEFAULT_ENCRYPTION_ALGORITHM) + .to_owned(); + let headers = vec![ + (headers::ENCRYPTION_ALGORITHM, algorithm.into()), + ( + headers::ENCRYPTION_KEY, + self.encryption_key.to_owned().into(), + ), + ( + headers::ENCRYPTION_KEY_SHA256, + self.encryption_key_sha256.to_owned().into(), + ), + ]; + headers.into_iter() + } +} + +impl AsHeaders for &CPKInfo { + type Iter = ::Iter; + + fn as_headers(&self) -> Self::Iter { + (*self).as_headers() + } +} diff --git a/sdk/storage_blobs/src/options/mod.rs b/sdk/storage_blobs/src/options/mod.rs index 14077bc265..0f0ccf9845 100644 --- a/sdk/storage_blobs/src/options/mod.rs +++ b/sdk/storage_blobs/src/options/mod.rs @@ -14,6 +14,7 @@ mod block_id; mod condition_append_position; mod condition_max_size; mod delete_snapshot_method; +mod encryption_key; mod encryption_scope; mod hash; mod rehydrate_policy; @@ -33,6 +34,7 @@ pub use block_id::BlockId; pub use condition_append_position::ConditionAppendPosition; pub use condition_max_size::ConditionMaxSize; pub use delete_snapshot_method::DeleteSnapshotsMethod; +pub use encryption_key::CPKInfo; pub use encryption_scope::EncryptionScope; pub use hash::Hash; pub use rehydrate_policy::RehydratePriority;