def _string_to_sign(item, table_name, attribute_actions):
    # type: (dynamodb_types.ITEM, Text, AttributeActions) -> bytes
    """Generate the string to sign from an encrypted item and configuration.

    :param dict item: Encrypted DynamoDB item
    :param str table_name: Table name to use when generating the string to sign
    :param AttributeActions attribute_actions: Actions to take for item
    """
    hasher = hashes.Hash(hashes.SHA256(), backend=default_backend())
    data_to_sign = bytearray()
    data_to_sign.extend(
        _hash_data(
            hasher=hasher,
            data="TABLE>{}<TABLE".format(table_name).encode(TEXT_ENCODING)))
    for key in sorted(item.keys()):
        action = attribute_actions.action(key)
        if action is CryptoAction.DO_NOTHING:
            continue

        data_to_sign.extend(
            _hash_data(hasher=hasher, data=key.encode(TEXT_ENCODING)))

        # for some reason pylint can't follow the Enum member attributes
        if action is CryptoAction.SIGN_ONLY:
            data_to_sign.extend(SignatureValues.PLAINTEXT.sha256)  # pylint: disable=no-member
        else:
            data_to_sign.extend(SignatureValues.ENCRYPTED.sha256)  # pylint: disable=no-member

        data_to_sign.extend(
            _hash_data(hasher=hasher, data=serialize_attribute(item[key])))
    return bytes(data_to_sign)
Example #2
0
def test_transformable_item(item):
    ddb_json = dict_to_ddb(item)
    serialized = {}
    for key, value in ddb_json.items():
        serialized[key] = serialize_attribute(value)
    deserialized = {}
    for key, value in serialized.items():
        deserialized[key] = deserialize_attribute(value)
    end_result = ddb_to_dict(deserialized)
    assert end_result == item
Example #3
0
def encrypt_attribute(attribute_name, attribute, encryption_key, algorithm):
    # type: (Text, dynamodb_types.RAW_ATTRIBUTE, DelegatedKey, Text) -> dynamodb_types.BINARY_ATTRIBUTE
    """Encrypt a single DynamoDB attribute.

    :param str attribute_name: DynamoDB attribute name
    :param dict attribute: Plaintext DynamoDB attribute
    :param DelegatedKey encryption_key: DelegatedKey to use to encrypt the attribute
    :param str algorithm: Encryption algorithm descriptor (passed to encryption_key as algorithm)
    :returns: Encrypted DynamoDB binary attribute
    :rtype: dict
    """
    serialized_attribute = serialize_attribute(attribute)
    encrypted_attribute = encryption_key.encrypt(
        algorithm=algorithm, name=attribute_name, plaintext=serialized_attribute
    )
    # for some reason pylint can't follow the Enum member attributes
    return {Tag.BINARY.dynamodb_tag: encrypted_attribute}  # pylint: disable=no-member
Example #4
0
def _serialize_deserialize_cycle(attribute):
    raw_attribute = TypeSerializer().serialize(attribute)
    serialized_attribute = serialize_attribute(raw_attribute)
    cycled_attribute = deserialize_attribute(serialized_attribute)
    deserialized_attribute = TypeDeserializer().deserialize(cycled_attribute)
    assert deserialized_attribute == attribute
Example #5
0
def test_serialize_attribute_errors(attribute, expected_type, expected_message):
    with pytest.raises(expected_type) as excinfo:
        serialize_attribute(attribute)

    excinfo.match(expected_message)
Example #6
0
def test_serialize_attribute(attribute, serialized):
    serialized_attribute = serialize_attribute(attribute)
    assert serialized_attribute == serialized