Source code for dynamodb_encryption_sdk.material_providers.wrapped

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Cryptographic materials provider to use ephemeral content encryption keys wrapped by delegated keys."""
import attr
import six

from dynamodb_encryption_sdk.delegated_keys import DelegatedKey
from dynamodb_encryption_sdk.exceptions import UnwrappingError, WrappingError
from dynamodb_encryption_sdk.internal.validators import dictionary_validator
from dynamodb_encryption_sdk.materials.wrapped import WrappedCryptographicMaterials
from dynamodb_encryption_sdk.structures import EncryptionContext  # noqa pylint: disable=unused-import

from . import CryptographicMaterialsProvider

try:  # Python 3.5.0 and 3.5.1 have incompatible typing modules
    from typing import Dict, Optional, Text  # noqa pylint: disable=unused-import
except ImportError:  # pragma: no cover
    # We only actually need these imports when running the mypy checks
    pass

try:  # Python 3.5.0 and 3.5.1 have incompatible typing modules
    from typing import Optional  # noqa pylint: disable=unused-import
except ImportError:  # pragma: no cover
    # We only actually need these imports when running the mypy checks
    pass


__all__ = ("WrappedCryptographicMaterialsProvider",)


[docs]@attr.s(init=False) class WrappedCryptographicMaterialsProvider(CryptographicMaterialsProvider): """Cryptographic materials provider to use ephemeral content encryption keys wrapped by delegated keys. :param DelegatedKey signing_key: Delegated key used as signing and verification key :param DelegatedKey wrapping_key: Delegated key used to wrap content key .. note:: ``wrapping_key`` must be provided if providing encryption materials :param DelegatedKey unwrapping_key: Delegated key used to unwrap content key .. note:: ``unwrapping_key`` must be provided if providing decryption materials or loading materials from material description """ _signing_key = attr.ib(validator=attr.validators.instance_of(DelegatedKey)) _wrapping_key = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(DelegatedKey)), default=None) _unwrapping_key = attr.ib( validator=attr.validators.optional(attr.validators.instance_of(DelegatedKey)), default=None ) _material_description = attr.ib( validator=attr.validators.optional(dictionary_validator(six.string_types, six.string_types)), default=attr.Factory(dict), ) def __init__( self, signing_key, # type: DelegatedKey wrapping_key=None, # type: Optional[DelegatedKey] unwrapping_key=None, # type: Optional[DelegatedKey] material_description=None, # type: Optional[Dict[Text, Text]] ): # noqa=D107 # type: (...) -> None # Workaround pending resolution of attrs/mypy interaction. # https://github.com/python/mypy/issues/2088 # https://github.com/python-attrs/attrs/issues/215 if material_description is None: material_description = {} self._signing_key = signing_key self._wrapping_key = wrapping_key self._unwrapping_key = unwrapping_key self._material_description = material_description attr.validate(self) def _build_materials(self, encryption_context): # type: (EncryptionContext) -> WrappedCryptographicMaterials """Construct :param EncryptionContext encryption_context: Encryption context for request :returns: Wrapped cryptographic materials :rtype: WrappedCryptographicMaterials """ material_description = self._material_description.copy() material_description.update(encryption_context.material_description) return WrappedCryptographicMaterials( wrapping_key=self._wrapping_key, unwrapping_key=self._unwrapping_key, signing_key=self._signing_key, material_description=material_description, )
[docs] def encryption_materials(self, encryption_context): # type: (EncryptionContext) -> WrappedCryptographicMaterials """Provide encryption materials. :param EncryptionContext encryption_context: Encryption context for request :returns: Encryption materials :rtype: WrappedCryptographicMaterials :raises WrappingError: if no wrapping key is available """ if self._wrapping_key is None: raise WrappingError("Encryption materials cannot be provided: no wrapping key") return self._build_materials(encryption_context)
[docs] def decryption_materials(self, encryption_context): # type: (EncryptionContext) -> WrappedCryptographicMaterials """Provide decryption materials. :param EncryptionContext encryption_context: Encryption context for request :returns: Decryption materials :rtype: WrappedCryptographicMaterials :raises UnwrappingError: if no unwrapping key is available """ if self._unwrapping_key is None: raise UnwrappingError("Decryption materials cannot be provided: no unwrapping key") return self._build_materials(encryption_context)