Skip to content
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
215 changes: 168 additions & 47 deletions sdk/storage/azure-storage-blob/azure/storage/blob/_shared/encryption.py

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions sdk/storage/azure-storage-queue/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# Release History

## 12.3.1 (Unreleased)
## 12.4.0b1 (Unreleased)

### Features Added

### Breaking Changes

### Bugs Fixed

### Other Changes
- Introduced version 2.0 of client-side encryption for Queue messages which utilizes AES-GCM-256 encryption.
Version 1.0 is now deprecated and no longer considered secure. If you are using client-side encryption, it is
**highly recommended** that you update to version 2.0.
The encryption version can be specified on any client constructor via the `encryption_version`
keyword (i.e. `encryption_version='2.0'`).

## 12.3.0 (2022-05-09)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,27 @@
import six
from azure.core.exceptions import DecodeError

from ._shared.encryption import decrypt_queue_message, encrypt_queue_message
from ._shared.encryption import decrypt_queue_message, encrypt_queue_message, _ENCRYPTION_PROTOCOL_V1


class MessageEncodePolicy(object):

def __init__(self):
self.require_encryption = False
self.encryption_version = None
self.key_encryption_key = None
self.resolver = None

def __call__(self, content):
if content:
content = self.encode(content)
if self.key_encryption_key is not None:
content = encrypt_queue_message(content, self.key_encryption_key)
content = encrypt_queue_message(content, self.key_encryption_key, self.encryption_version)
return content

def configure(self, require_encryption, key_encryption_key, resolver):
def configure(self, require_encryption, key_encryption_key, resolver, encryption_version=_ENCRYPTION_PROTOCOL_V1):
self.require_encryption = require_encryption
self.encryption_version = encryption_version
self.key_encryption_key = key_encryption_key
self.resolver = resolver
if self.require_encryption and not self.key_encryption_key:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
# --------------------------------------------------------------------------

import functools
import warnings
from typing import ( # pylint: disable=unused-import
Union, Optional, Any, IO, Iterable, AnyStr, Dict, List, Tuple,
Optional, Any, Dict, List,
TYPE_CHECKING)
try:
from urllib.parse import urlparse, quote, unquote
Expand Down Expand Up @@ -34,8 +35,6 @@
from ._models import QueueMessage, AccessPolicy, MessagesPaged

if TYPE_CHECKING:
from datetime import datetime
from azure.core.pipeline.policies import HTTPPolicy
from ._models import QueueProperties


Expand Down Expand Up @@ -477,10 +476,23 @@ def send_message(
visibility_timeout = kwargs.pop('visibility_timeout', None)
time_to_live = kwargs.pop('time_to_live', None)
timeout = kwargs.pop('timeout', None)
self._config.message_encode_policy.configure(
require_encryption=self.require_encryption,
key_encryption_key=self.key_encryption_key,
resolver=self.key_resolver_function)
try:
self._config.message_encode_policy.configure(
require_encryption=self.require_encryption,
key_encryption_key=self.key_encryption_key,
resolver=self.key_resolver_function,
encryption_version=self.encryption_version)
except TypeError:
warnings.warn(
"TypeError when calling message_encode_policy.configure. \
It is likely missing the encryption_version parameter. \
Consider updating your encryption information/implementation. \
Retrying without encryption_version."
)
self._config.message_encode_policy.configure(
require_encryption=self.require_encryption,
key_encryption_key=self.key_encryption_key,
resolver=self.key_resolver_function)
encoded_content = self._config.message_encode_policy(content)
new_message = GenQueueMessage(message_text=encoded_content)

Expand Down Expand Up @@ -711,10 +723,23 @@ def update_message(self,
if receipt is None:
raise ValueError("pop_receipt must be present")
if message_text is not None:
self._config.message_encode_policy.configure(
self.require_encryption,
self.key_encryption_key,
self.key_resolver_function)
try:
self._config.message_encode_policy.configure(
self.require_encryption,
self.key_encryption_key,
self.key_resolver_function,
encryption_version=self.encryption_version)
except TypeError:
warnings.warn(
"TypeError when calling message_encode_policy.configure. \
It is likely missing the encryption_version parameter. \
Consider updating your encryption information/implementation. \
Retrying without encryption_version."
)
self._config.message_encode_policy.configure(
self.require_encryption,
self.key_encryption_key,
self.key_resolver_function)
encoded_message_text = self._config.message_encode_policy(message_text)
updated = GenQueueMessage(message_text=encoded_message_text)
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,5 +433,6 @@ def get_queue_client(self,
return QueueClient(
self.url, queue_name=queue_name, credential=self.credential,
key_resolver_function=self.key_resolver_function, require_encryption=self.require_encryption,
key_encryption_key=self.key_encryption_key, api_version=self.api_version, _pipeline=_pipeline,
_configuration=self._config, _location_mode=self._location_mode, _hosts=self._hosts, **kwargs)
encryption_version=self.encryption_version, key_encryption_key=self.key_encryption_key,
api_version=self.api_version, _pipeline=_pipeline, _configuration=self._config,
_location_mode=self._location_mode, _hosts=self._hosts, **kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# --------------------------------------------------------------------------
import logging
import uuid
import warnings
from typing import ( # pylint: disable=unused-import
Optional,
Any,
Expand Down Expand Up @@ -104,8 +105,15 @@ def __init__(
self._hosts = {LocationMode.PRIMARY: primary_hostname, LocationMode.SECONDARY: secondary_hostname}

self.require_encryption = kwargs.get("require_encryption", False)
self.encryption_version = kwargs.get("encryption_version", "1.0")
self.key_encryption_key = kwargs.get("key_encryption_key")
self.key_resolver_function = kwargs.get("key_resolver_function")
if self.key_encryption_key and self.encryption_version == '1.0':
warnings.warn("This client has been configured to use encryption with version 1.0. \
Version 1.0 is deprecated and no longer considered secure. It is highly \
recommended that you switch to using version 2.0. The version can be \
specified using the 'encryption_version' keyword.")

self._config, self._pipeline = self._create_pipeline(self.credential, storage_sdk=service, **kwargs)

def __enter__(self):
Expand Down
Loading