def serialize(material_description):
    # type: (Dict[Text, Text]) -> dynamodb_types.BINARY_ATTRIBUTE
    """Serialize a material description dictionary into a DynamodDB attribute.

    :param dict material_description: Material description dictionary
    :returns: Serialized material description as a DynamoDB binary attribute value
    :rtype: dict
    :raises InvalidMaterialDescriptionError: if invalid name or value found in material description
    """
    material_description_bytes = bytearray(_MATERIAL_DESCRIPTION_VERSION)

    # TODO: verify Java sorting order
    for name, value in sorted(material_description.items(), key=lambda x: x[0]):
        try:
            material_description_bytes.extend(encode_value(to_bytes(name)))
            material_description_bytes.extend(encode_value(to_bytes(value)))
        except (TypeError, struct.error):
            raise InvalidMaterialDescriptionError(
                'Invalid name or value in material description: "{name}"="{value}"'.format(
                    name=name,
                    value=value
                )
            )

    return {Tag.BINARY.dynamodb_tag: bytes(material_description_bytes)}
Example #2
0
    def _decrypt_initial_material(self, encryption_context):
        # type: (EncryptionContext) -> bytes
        """Decrypt an encrypted initial cryptographic material value.

        :param encryption_context: Encryption context providing information about request
        :type encryption_context: EncryptionContext
        :returns: Plaintext of initial cryptographic material
        :rtype: bytes
        """
        key_id = self._select_key_id(encryption_context)
        self._validate_key_id(key_id, encryption_context)
        kms_encryption_context = self._kms_encryption_context(
            encryption_context=encryption_context,
            encryption_description=encryption_context.material_description.get(
                MaterialDescriptionKeys.CONTENT_ENCRYPTION_ALGORITHM.value),
            signing_description=encryption_context.material_description.get(
                MaterialDescriptionKeys.ITEM_SIGNATURE_ALGORITHM.value),
        )
        encrypted_initial_material = base64.b64decode(
            to_bytes(
                encryption_context.material_description.get(
                    MaterialDescriptionKeys.WRAPPED_DATA_KEY.value)))
        kms_params = dict(CiphertextBlob=encrypted_initial_material,
                          EncryptionContext=kms_encryption_context)
        if self._grant_tokens:
            kms_params["GrantTokens"] = self._grant_tokens
        # Catch any boto3 errors and normalize to expected UnwrappingError
        try:
            response = self._client(key_id).decrypt(**kms_params)
            return response["Plaintext"]
        except (botocore.exceptions.ClientError, KeyError):
            message = "Failed to unwrap AWS KMS protected materials"
            _LOGGER.exception(message)
            raise UnwrappingError(message)
Example #3
0
 def _transform_string_value(value):
     # type: (dynamodb_types.STRING) -> bytes
     """
     :param value: Input value
     :type value: bytes or str
     :returns: bytes value
     :rtype: bytes
     """
     return to_bytes(value)
def test_to_bytes(data, expected_output):
    test = to_bytes(data)
    assert test == expected_output