def __attrs_post_init__(self): """Normalize inputs to crypto material manager.""" options_provided = [option is not None for option in (self.materials_manager, self.keyring, self.key_provider)] provided_count = len([is_set for is_set in options_provided if is_set]) if provided_count != 1: raise TypeError("Exactly one of 'materials_manager', 'keyring', or 'key_provider' must be provided") if self.materials_manager is None: if self.key_provider is not None: self.materials_manager = DefaultCryptoMaterialsManager(master_key_provider=self.key_provider) else: self.materials_manager = DefaultCryptoMaterialsManager(keyring=self.keyring)
def build_cmm(): mock_mkp = MagicMock(__class__=MasterKeyProvider) mock_mkp.decrypt_data_key_from_list.return_value = _DATA_KEY mock_mkp.master_keys_for_encryption.return_value = ( sentinel.primary_mk, {sentinel.primary_mk, sentinel.mk_a, sentinel.mk_b}, ) return DefaultCryptoMaterialsManager(master_key_provider=mock_mkp)
def __attrs_post_init__(self): """Normalize inputs to crypto material manager.""" both_cmm_and_mkp_defined = self.materials_manager is not None and self.key_provider is not None neither_cmm_nor_mkp_defined = self.materials_manager is None and self.key_provider is None if both_cmm_and_mkp_defined or neither_cmm_nor_mkp_defined: raise TypeError("Exactly one of materials_manager or key_provider must be provided") if self.materials_manager is None: self.materials_manager = DefaultCryptoMaterialsManager(master_key_provider=self.key_provider)
def test_get_encryption_materials_uncommitting_algorithm_policy_forbid( patch_for_dcmm_encrypt): """Tests that a Default Crypto Materials Manager request with policy FORBID_ENCRYPT_ALLOW_DECRYPT can successfully encrypt using an algorithm that does not provide commitment.""" mock_alg = MagicMock(__class__=Algorithm) mock_alg.is_committing.return_value = False mock_request = MagicMock(algorithm=mock_alg, encryption_context={}) mock_request.commitment_policy = CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT cmm = DefaultCryptoMaterialsManager(master_key_provider=build_mkp()) test = cmm.get_encryption_materials(request=mock_request) assert test.algorithm is mock_request.algorithm
def test_get_encryption_materials_committing_algorithm_require_encrypt_require_decrypt( patch_for_dcmm_encrypt): """Tests that a Default Crypto Materials Manager request with policy REQUIRE_ENCRYPT_REQUIRE_DECRYPT can successfully encrypt using an algorithm that provides commitment.""" mock_alg = MagicMock(__class__=Algorithm) mock_alg.is_committing.return_value = True mock_request = MagicMock(algorithm=mock_alg, encryption_context={}) mock_request.commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT cmm = DefaultCryptoMaterialsManager(master_key_provider=build_mkp()) test = cmm.get_encryption_materials(request=mock_request) assert test.algorithm is mock_request.algorithm
def __init__(self, keyring): # type: (Keyring) -> None """Set up the inner cryptographic materials manager using the provided keyring. :param Keyring keyring: Keyring to use in the inner cryptographic materials manager """ self._classification_field = "classification" self._classification_error = MissingClassificationError("Encryption context does not contain classification!") # Wrap the provided keyring in the default cryptographic materials manager (CMM). # # This is the same thing that the encrypt and decrypt APIs, as well as the caching CMM, # do if you provide a keyring instead of a CMM. self._cmm = DefaultCryptoMaterialsManager(keyring=keyring)
def test_encrypt_with_keyring_materials_incomplete(algorithm_suite): raw_aes256_keyring = ephemeral_raw_aes_keyring( WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING) encrypt_cmm = DefaultCryptoMaterialsManager( keyring=NoEncryptedDataKeysKeyring(inner_keyring=raw_aes256_keyring)) encryption_materials_request = EncryptionMaterialsRequest( encryption_context={}, frame_length=1024, algorithm=algorithm_suite) with pytest.raises(InvalidCryptographicMaterialsError) as excinfo: encrypt_cmm.get_encryption_materials(encryption_materials_request) excinfo.match("Encryption materials are incomplete!")
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!")
def test_decrypt_materials_uncommitting_alg_require_policy( patch_for_dcmm_decrypt): """Tests that a configuration which requires commitment does not allow decryption of un-committed messages.""" mock_alg = MagicMock(__class__=Algorithm) mock_alg.is_committing.return_value = False mock_request = MagicMock(algorithm=mock_alg, encryption_context={}) mock_request.commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT cmm = DefaultCryptoMaterialsManager(master_key_provider=build_mkp()) with pytest.raises(ActionNotAllowedError) as excinfo: cmm.decrypt_materials(request=mock_request) excinfo.match( "Configuration conflict. Cannot decrypt due to .* requiring only committed messages." )
def test_get_encryption_materials_uncommitting_algorithm_require_encrypt_allow_decrypt( patch_for_dcmm_encrypt): """Tests that a Default Crypto Materials Manager request with policy REQUIRE_ENCRYPT_ALLOW_DECRYPT cannot encrypt using an algorithm that does not provide commitment.""" mock_alg = MagicMock(__class__=Algorithm) mock_alg.is_committing.return_value = False mock_request = MagicMock(algorithm=mock_alg, encryption_context={}) mock_request.commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT cmm = DefaultCryptoMaterialsManager(master_key_provider=build_mkp()) with pytest.raises(ActionNotAllowedError) as excinfo: cmm.get_encryption_materials(request=mock_request) excinfo.match( "Configuration conflict. Cannot encrypt due to .* requiring only committed messages" )
def __init__(self, keyring): # type: (Keyring) -> None """Set up the inner cryptographic materials manager using the provided keyring. :param Keyring keyring: Keyring to use in the inner cryptographic materials manager """ self._allowed_algorithm_suites = { None, # no algorithm suite in the request AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, # the default algorithm suite AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, # the recommended unsigned algorithm suite } # Wrap the provided keyring in the default cryptographic materials manager (CMM). # # This is the same thing that the encrypt and decrypt APIs, as well as the caching CMM, # do if you provide a keyring instead of a CMM. self._cmm = DefaultCryptoMaterialsManager(keyring=keyring)
def run_scenario_with_tampering(self, ciphertext_writer, generation_scenario, plaintext_uri): """ Run a given scenario, tampering with the input or the result. return: a list of (ciphertext, result) pairs """ materials_manager = DefaultCryptoMaterialsManager( generation_scenario.encryption_scenario.master_key_provider_fn() ) ciphertext_to_decrypt = generation_scenario.encryption_scenario.run(materials_manager) if generation_scenario.result: expected_result = generation_scenario.result else: expected_result = MessageDecryptionTestResult.expect_output( plaintext_uri=plaintext_uri, plaintext=generation_scenario.encryption_scenario.plaintext ) return [ generation_scenario.decryption_test_scenario_pair(ciphertext_writer, ciphertext_to_decrypt, expected_result) ]
def test_decrypt_materials_committing_alg(patch_for_dcmm_decrypt, policy): """Tests that all configurations of CommitmentPolicy are able to decrypt when the algorithm provides commitment.""" mock_alg = MagicMock(__class__=Algorithm) mock_alg.is_committing.return_value = True mock_request = MagicMock(algorithm=mock_alg, encryption_context={}) mock_request.commitment_policy = policy cmm = DefaultCryptoMaterialsManager(master_key_provider=build_mkp()) test = cmm.decrypt_materials(request=mock_request) cmm.master_key_provider.decrypt_data_key_from_list.assert_called_once_with( encrypted_data_keys=mock_request.encrypted_data_keys, algorithm=mock_request.algorithm, encryption_context=mock_request.encryption_context, ) cmm._load_verification_key_from_encryption_context.assert_called_once_with( algorithm=mock_request.algorithm, encryption_context=mock_request.encryption_context) assert test.data_key is cmm.master_key_provider.decrypt_data_key_from_list.return_value assert test.verification_key == patch_for_dcmm_decrypt
def test_attributes_fail(): with pytest.raises(TypeError): DefaultCryptoMaterialsManager(master_key_provider=None)
def build_cmm(): mock_mkp = build_mkp() return DefaultCryptoMaterialsManager(master_key_provider=mock_mkp)
def test_attributes_fail(kwargs): with pytest.raises(TypeError): DefaultCryptoMaterialsManager(**kwargs)
def test_attributes_default(): cmm = DefaultCryptoMaterialsManager(master_key_provider=MagicMock( __class__=MasterKeyProvider)) assert cmm.algorithm is ALGORITHM
def __init__(self, master_key_provider): """ Create a new CMM that wraps a new DefaultCryptoMaterialsManager based on the given master key provider. """ self.wrapped_default_cmm = DefaultCryptoMaterialsManager(master_key_provider)