Ejemplo n.º 1
0
def test_encryption_cycle_with_caching():
    algorithm = Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384
    frame_length = 1024
    key_provider = fake_kms_key_provider(algorithm.kdf_input_len)
    cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=10)
    ccmm = aws_encryption_sdk.CachingCryptoMaterialsManager(
        master_key_provider=key_provider, cache=cache, max_age=3600.0, max_messages_encrypted=5
    )
    encrypt_kwargs = dict(
        source=VALUES["plaintext_128"],
        materials_manager=ccmm,
        encryption_context=VALUES["encryption_context"],
        frame_length=frame_length,
        algorithm=algorithm,
    )
    encrypt_cache_key = build_encryption_materials_cache_key(
        partition=ccmm.partition_name,
        request=EncryptionMaterialsRequest(
            encryption_context=VALUES["encryption_context"],
            frame_length=frame_length,
            algorithm=algorithm,
            plaintext_length=len(VALUES["plaintext_128"]),
        ),
    )
    ciphertext, header = aws_encryption_sdk.encrypt(**encrypt_kwargs)
    decrypt_cache_key = build_decryption_materials_cache_key(
        partition=ccmm.partition_name,
        request=DecryptionMaterialsRequest(
            algorithm=algorithm,
            encrypted_data_keys=header.encrypted_data_keys,
            encryption_context=header.encryption_context,
        ),
    )

    assert len(cache._cache) == 1
    assert cache._cache[encrypt_cache_key].messages_encrypted == 1
    assert cache._cache[encrypt_cache_key].bytes_encrypted == 128

    _, _ = aws_encryption_sdk.decrypt(source=ciphertext, materials_manager=ccmm)

    assert len(cache._cache) == 2
    assert decrypt_cache_key in cache._cache

    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)
    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)
    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)

    assert len(cache._cache) == 2
    assert cache._cache[encrypt_cache_key].messages_encrypted == 4
    assert cache._cache[encrypt_cache_key].bytes_encrypted == 512

    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)
    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)
    _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs)

    assert len(cache._cache) == 2
    assert cache._cache[encrypt_cache_key].messages_encrypted == 2
    assert cache._cache[encrypt_cache_key].bytes_encrypted == 256
Ejemplo n.º 2
0
    def _read_header(self):
        """Reads the message header from the input stream.

        :returns: tuple containing deserialized header and header_auth objects
        :rtype: tuple of aws_encryption_sdk.structures.MessageHeader
            and aws_encryption_sdk.internal.structures.MessageHeaderAuthentication
        :raises CustomMaximumValueExceeded: if frame length is greater than the custom max value
        """
        header, raw_header = aws_encryption_sdk.internal.formatting.deserialize.deserialize_header(self.source_stream)

        if (
                self.config.max_body_length is not None
                and header.content_type == ContentType.FRAMED_DATA
                and header.frame_length > self.config.max_body_length
        ):
            raise CustomMaximumValueExceeded(
                'Frame Size in header found larger than custom value: {found} > {custom}'.format(
                    found=header.frame_length,
                    custom=self.config.max_body_length
                )
            )

        decrypt_materials_request = DecryptionMaterialsRequest(
            encrypted_data_keys=header.encrypted_data_keys,
            algorithm=header.algorithm,
            encryption_context=header.encryption_context
        )
        decryption_materials = self.config.materials_manager.decrypt_materials(request=decrypt_materials_request)
        if decryption_materials.verification_key is None:
            self.verifier = None
        else:
            self.verifier = Verifier.from_key_bytes(
                algorithm=header.algorithm,
                key_bytes=decryption_materials.verification_key
            )
        if self.verifier is not None:
            self.verifier.update(raw_header)

        header_auth = aws_encryption_sdk.internal.formatting.deserialize.deserialize_header_auth(
            stream=self.source_stream,
            algorithm=header.algorithm,
            verifier=self.verifier
        )
        self._derived_data_key = derive_data_encryption_key(
            source_key=decryption_materials.data_key.data_key,
            algorithm=header.algorithm,
            message_id=header.message_id
        )
        aws_encryption_sdk.internal.formatting.deserialize.validate_header(
            header=header,
            header_auth=header_auth,
            raw_header=raw_header,
            data_key=self._derived_data_key
        )
        return header, header_auth
def test_decrypt_with_keyring_materials_do_not_match_request(
        kwargs, algorithm_suite):
    raw_aes256_keyring = ephemeral_raw_aes_keyring(
        WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING)

    encrypt_cmm = DefaultCryptoMaterialsManager(keyring=raw_aes256_keyring)
    decrypt_cmm = DefaultCryptoMaterialsManager(
        keyring=BrokenKeyring(inner_keyring=raw_aes256_keyring, **kwargs))

    encryption_materials_request = EncryptionMaterialsRequest(
        encryption_context={}, frame_length=1024, algorithm=algorithm_suite)
    encryption_materials = encrypt_cmm.get_encryption_materials(
        encryption_materials_request)

    decryption_materials_request = DecryptionMaterialsRequest(
        algorithm=encryption_materials.algorithm,
        encrypted_data_keys=encryption_materials.encrypted_data_keys,
        encryption_context=encryption_materials.encryption_context,
    )

    with pytest.raises(InvalidCryptographicMaterialsError) as excinfo:
        decrypt_cmm.decrypt_materials(decryption_materials_request)

    excinfo.match("Decryption materials do not match request!")
Ejemplo n.º 4
0
     (set([VALUES['basic']['encrypted_data_keys'][1]['key']
           ]), [VALUES['basic']['encrypted_data_keys'][1]['hash']]), ([
               VALUES['basic']['encrypted_data_keys'][1]['key'],
               VALUES['basic']['encrypted_data_keys'][0]['key']
           ], [
               VALUES['basic']['encrypted_data_keys'][0]['hash'],
               VALUES['basic']['encrypted_data_keys'][1]['hash']
           ])))
def test_encrypted_data_keys_hash(encrypted_data_keys, result):
    hasher = hashes.Hash(hashes.SHA512(), backend=default_backend())
    assert _encrypted_data_keys_hash(hasher, encrypted_data_keys) == b''.join(
        [b64decode(each) for each in result])


@pytest.mark.parametrize(
    'inner_request, result', [(dict(
        partition=scenario['components']['partition_name'],
        request=DecryptionMaterialsRequest(
            algorithm=scenario['components']['algorithm'],
            encrypted_data_keys=scenario['components']['encrypted_data_keys'],
            encryption_context=scenario['components']['encryption_context'])),
                               scenario['id'])
                              for scenario in VALUES['cache_ids']['decrypt']])
def test_build_decryption_materials_cache_key(inner_request, result):
    assert build_decryption_materials_cache_key(
        **inner_request) == b64decode(result)


def test_512_bit_pad():
    assert _512_BIT_PAD == struct.pack('>64x')
Ejemplo n.º 5
0
)
def test_encrypted_data_keys_hash(encrypted_data_keys, result):
    hasher = hashes.Hash(hashes.SHA512(), backend=default_backend())
    assert _encrypted_data_keys_hash(hasher, encrypted_data_keys) == b"".join(
        [b64decode(each) for each in result])


@pytest.mark.parametrize(
    "inner_request, result",
    [(
        dict(
            partition=scenario["components"]["partition_name"],
            request=DecryptionMaterialsRequest(
                algorithm=scenario["components"]["algorithm"],
                encrypted_data_keys=scenario["components"]
                ["encrypted_data_keys"],
                encryption_context=scenario["components"]
                ["encryption_context"],
                commitment_policy=scenario["components"]["commitment_policy"],
            ),
        ),
        scenario["id"],
    ) for scenario in VALUES["cache_ids"]["decrypt"]],
)
def test_build_decryption_materials_cache_key(inner_request, result):
    assert build_decryption_materials_cache_key(
        **inner_request) == b64decode(result)


def test_512_bit_pad():
    assert _512_BIT_PAD == struct.pack(">64x")
Ejemplo n.º 6
0
    def _read_header(self):
        """Reads the message header from the input stream.

        :returns: tuple containing deserialized header and header_auth objects
        :rtype: tuple of aws_encryption_sdk.structures.MessageHeader
            and aws_encryption_sdk.internal.structures.MessageHeaderAuthentication
        :raises CustomMaximumValueExceeded: if frame length is greater than the custom max value
        """
        header, raw_header = deserialize_header(self.source_stream)
        self.__unframed_bytes_read += len(raw_header)

        validate_commitment_policy_on_decrypt(self.config.commitment_policy,
                                              header.algorithm)

        if (self.config.max_body_length is not None
                and header.content_type == ContentType.FRAMED_DATA
                and header.frame_length > self.config.max_body_length):
            raise CustomMaximumValueExceeded(
                "Frame Size in header found larger than custom value: {found:d} > {custom:d}"
                .format(found=header.frame_length,
                        custom=self.config.max_body_length))

        decrypt_materials_request = DecryptionMaterialsRequest(
            encrypted_data_keys=header.encrypted_data_keys,
            algorithm=header.algorithm,
            encryption_context=header.encryption_context,
            commitment_policy=self.config.commitment_policy,
        )
        decryption_materials = self.config.materials_manager.decrypt_materials(
            request=decrypt_materials_request)
        if decryption_materials.verification_key is None:
            self.verifier = None
        else:
            self.verifier = Verifier.from_key_bytes(
                algorithm=header.algorithm,
                key_bytes=decryption_materials.verification_key)
        if self.verifier is not None:
            self.verifier.update(raw_header)

        header_auth = deserialize_header_auth(version=header.version,
                                              stream=self.source_stream,
                                              algorithm=header.algorithm,
                                              verifier=self.verifier)
        self._derived_data_key = derive_data_encryption_key(
            source_key=decryption_materials.data_key.data_key,
            algorithm=header.algorithm,
            message_id=header.message_id)

        if header.algorithm.is_committing():
            expected_commitment_key = calculate_commitment_key(
                source_key=decryption_materials.data_key.data_key,
                algorithm=header.algorithm,
                message_id=header.message_id,
            )

            if not hmac.compare_digest(expected_commitment_key,
                                       header.commitment_key):
                raise MasterKeyProviderError(
                    "Key commitment validation failed. Key identity does not match the identity asserted in the "
                    "message. Halting processing of this message.")

        validate_header(header=header,
                        header_auth=header_auth,
                        raw_header=raw_header,
                        data_key=self._derived_data_key)

        return header, header_auth