def test_prepare_data_keys(self): mock_encryption_dk = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_raw_data_key_1_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes, ) mock_primary_mk = MagicMock() mock_primary_mk.generate_data_key.return_value = mock_encryption_dk mock_mk_1 = MagicMock() mock_mk_1.encrypt_data_key.return_value = sentinel.encrypted_data_key_1 mock_mk_2 = MagicMock() mock_mk_2.encrypt_data_key.return_value = sentinel.encrypted_data_key_2 test_data_encryption_key, test_encrypted_data_keys = aws_encryption_sdk.internal.utils.prepare_data_keys( primary_master_key=mock_primary_mk, master_keys=[mock_primary_mk, mock_mk_1, mock_mk_2], algorithm=sentinel.algorithm, encryption_context=sentinel.encryption_context, ) mock_primary_mk.generate_data_key.assert_called_once_with(sentinel.algorithm, sentinel.encryption_context) assert not mock_primary_mk.encrypt_data_key.called mock_mk_1.encrypt_data_key.assert_called_once_with( data_key=mock_encryption_dk, algorithm=sentinel.algorithm, encryption_context=sentinel.encryption_context ) mock_mk_2.encrypt_data_key.assert_called_once_with( data_key=mock_encryption_dk, algorithm=sentinel.algorithm, encryption_context=sentinel.encryption_context ) mock_encrypted_data_encryption_key = EncryptedDataKey( key_provider=self.mock_key_provider_1, encrypted_data_key=self.mock_encrypted_data_key_1_bytes ) assert test_data_encryption_key is mock_encryption_dk assert test_encrypted_data_keys == set( [mock_encrypted_data_encryption_key, sentinel.encrypted_data_key_1, sentinel.encrypted_data_key_2] )
def _generate_data_key(self, algorithm, encryption_context=None): """Generates data key and returns plaintext and ciphertext of key. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to pass to KMS :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey """ kms_params = { "KeyId": self._key_id, "NumberOfBytes": algorithm.kdf_input_len } if encryption_context is not None: kms_params["EncryptionContext"] = encryption_context if self.config.grant_tokens: kms_params["GrantTokens"] = self.config.grant_tokens # Catch any boto3 errors and normalize to expected EncryptKeyError try: response = self.config.client.generate_data_key(**kms_params) plaintext = response["Plaintext"] ciphertext = response["CiphertextBlob"] key_id = response["KeyId"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to generate data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise GenerateKeyError(error_message) return DataKey( key_provider=MasterKeyInfo(provider_id=self.provider_id, key_info=key_id), data_key=plaintext, encrypted_data_key=ciphertext, )
def _decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context): """Decrypts an encrypted data key and returns the plaintext. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in decryption :returns: Data key containing decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if Master Key is unable to decrypt data key """ # Wrapped EncryptedDataKey to deserialized EncryptedData encrypted_wrapped_key = aws_encryption_sdk.internal.formatting.deserialize.deserialize_wrapped_key( wrapping_algorithm=self.config.wrapping_key.wrapping_algorithm, wrapping_key_id=self.key_id, wrapped_encrypted_key=encrypted_data_key, ) # EncryptedData to raw key string plaintext_data_key = self.config.wrapping_key.decrypt( encrypted_wrapped_data_key=encrypted_wrapped_key, encryption_context=encryption_context ) # Raw key string to DataKey return DataKey( key_provider=encrypted_data_key.key_provider, data_key=plaintext_data_key, encrypted_data_key=encrypted_data_key.encrypted_data_key, )
def test_decrypt_data_key(self, config_class, key_class, key_id): config = config_class(key_id=key_id, client=self.mock_client) test = key_class(config=config) self.mock_encrypted_data_key.key_provider.key_info = key_id self.mock_client.decrypt.return_value["KeyId"] = key_id.decode("ascii") # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.9 # //= type=test # //# The inputs MUST be the same as the Master Key Decrypt Data Key # //# (../master-key-interface.md#decrypt-data-key) interface. decrypted_key = test._decrypt_data_key( encrypted_data_key=self.mock_encrypted_data_key, algorithm=self.mock_algorithm) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.9 # //= type=test # //# To decrypt the encrypted data key this master key MUST use the # //# configured AWS KMS client to make an AWS KMS Decrypt # //# (https://docs.aws.amazon.com/kms/latest/APIReference/ # //# API_Decrypt.html) request constructed as follows: self.mock_client.decrypt.assert_called_once_with( CiphertextBlob=VALUES["encrypted_data_key"], KeyId=key_id.decode("ascii")) assert decrypted_key == DataKey( key_provider=test.key_provider, data_key=VALUES["data_key"], encrypted_data_key=VALUES["encrypted_data_key"])
def _decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context=None): """Decrypts an encrypted data key and returns the plaintext. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :type algorithm: `aws_encryption_sdk.identifiers.Algorithm` (not used for KMS) :param dict encryption_context: Encryption context to use in decryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if Master Key is unable to decrypt data key """ kms_params = {"CiphertextBlob": encrypted_data_key.encrypted_data_key} if encryption_context: kms_params["EncryptionContext"] = encryption_context if self.config.grant_tokens: kms_params["GrantTokens"] = self.config.grant_tokens # Catch any boto3 errors and normalize to expected DecryptKeyError try: response = self.config.client.decrypt(**kms_params) plaintext = response["Plaintext"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to decrypt data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise DecryptKeyError(error_message) return DataKey( key_provider=self.key_provider, data_key=plaintext, encrypted_data_key=encrypted_data_key.encrypted_data_key)
def test_generate_data_key(self, config_class, key_class, key_id): # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The inputs MUST be the same as the Master Key Generate Data Key # //# (../master-key-interface.md#generate-data-key) interface. config = config_class(key_id=key_id, client=self.mock_client) test = key_class(config=config) generated_key = test._generate_data_key(self.mock_algorithm) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# This master key MUST use the configured AWS KMS client to make an AWS KMS # //# GenerateDatakey (https://docs.aws.amazon.com/kms/latest/APIReference/ # //# API_GenerateDataKey.html) request constructed as follows: self.mock_client.generate_data_key.assert_called_once_with( KeyId=key_id.decode("ascii"), NumberOfBytes=sentinel.kdf_input_len) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The output MUST be the same as the Master Key Generate Data Key # //# (../master-key-interface.md#generate-data-key) interface. # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The response's cipher text blob MUST be used as the returned as the # //# ciphertext for the encrypted data key in the output. # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The response's "Plaintext" MUST be the plaintext in the output. assert generated_key == DataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=VALUES["arn"]), data_key=VALUES["data_key"], encrypted_data_key=VALUES["encrypted_data_key"], )
def _generate_data_key(self, algorithm, encryption_context=None): data_key, encrypted_data_key = self._main_key.generate_data_key() return DataKey( key_provider=MasterKeyInfo( provider_id=self.provider_id, key_info=self._main_key.key_id, ), data_key=data_key, encrypted_data_key=encrypted_data_key, )
def test_generate_data_key(self): test = KMSMasterKey(config=self.mock_kms_mkc_3) generated_key = test._generate_data_key(self.mock_algorithm) self.mock_client.generate_data_key.assert_called_once_with( KeyId='ex_key_info', NumberOfBytes=sentinel.kdf_input_len) assert generated_key == DataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=VALUES['arn']), data_key=VALUES['data_key'], encrypted_data_key=VALUES['encrypted_data_key'])
def _generate_data_key(self, algorithm: AlgorithmSuite, encryption_context: Dict[Text, Text]) -> DataKey: """Perform the provider-specific data key generation task. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey """ data_key = b"".join([chr(i).encode("utf-8") for i in range(1, algorithm.data_key_len + 1)]) return DataKey(key_provider=self.key_provider, data_key=data_key, encrypted_data_key=self._encrypted_data_key)
def test_decrypt_data_key(self): test = KMSMasterKey(config=self.mock_kms_mkc_1) decrypted_key = test._decrypt_data_key( encrypted_data_key=self.mock_encrypted_data_key, algorithm=sentinel.algorithm) self.mock_client.decrypt.assert_called_once_with( CiphertextBlob=VALUES['encrypted_data_key']) assert decrypted_key == DataKey( key_provider=test.key_provider, data_key=VALUES['data_key'], encrypted_data_key=VALUES['encrypted_data_key'])
def _generate_data_key(self, algorithm: AlgorithmSuite, encryption_context: Dict[Text, Text]) -> DataKey: """NullMasterKey does not support generate_data_key :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :raises NotImplementedError: when called """ return DataKey( key_provider=self.key_provider, data_key=self._null_plaintext_data_key(algorithm), encrypted_data_key=b"" )
def test_owns_data_key_owned_symmetric(self, mock_prefix): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING test_master_key = RawMasterKey( key_id=VALUES['wrapped_keys']['raw']['key_info'], provider_id=VALUES['provider_id'], wrapping_key=self.mock_wrapping_key) assert test_master_key.owns_data_key( data_key=DataKey(key_provider=MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['wrapped_keys']['serialized']['key_info']), encrypted_data_key=VALUES['encrypted_data_key'], data_key=VALUES['data_key']))
def test_owns_data_key_not_owned_asymmetric_checking_symmetric(self): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.RSA_OAEP_SHA1_MGF1 test_master_key = RawMasterKey( key_id=VALUES['wrapped_keys']['raw']['key_info'], provider_id=VALUES['provider_id'], wrapping_key=self.mock_wrapping_key) assert not test_master_key.owns_data_key( data_key=DataKey(key_provider=MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['wrapped_keys']['serialized']['key_info']), encrypted_data_key=VALUES['encrypted_data_key'], data_key=VALUES['data_key']))
def test_owns_data_key_owned_symmetric(self, mock_prefix): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING test_master_key = RawMasterKey( key_id=VALUES["wrapped_keys"]["raw"]["key_info"], provider_id=VALUES["provider_id"], wrapping_key=self.mock_wrapping_key, ) assert test_master_key.owns_data_key(data_key=DataKey( key_provider=MasterKeyInfo(provider_id=VALUES["provider_id"], key_info=VALUES["wrapped_keys"] ["serialized"]["key_info"]), encrypted_data_key=VALUES["encrypted_data_key"], data_key=VALUES["data_key"], ))
def test_owns_data_key_not_owned_asymmetric_checking_symmetric(self): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.RSA_OAEP_SHA1_MGF1 test_master_key = RawMasterKey( key_id=VALUES["wrapped_keys"]["raw"]["key_info"], provider_id=VALUES["provider_id"], wrapping_key=self.mock_wrapping_key, ) assert not test_master_key.owns_data_key(data_key=DataKey( key_provider=MasterKeyInfo(provider_id=VALUES["provider_id"], key_info=VALUES["wrapped_keys"] ["serialized"]["key_info"]), encrypted_data_key=VALUES["encrypted_data_key"], data_key=VALUES["data_key"], ))
def _decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context=None): """Decrypts an encrypted data key and returns the plaintext. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :type algorithm: `aws_encryption_sdk.identifiers.Algorithm` (not used for KMS) :param dict encryption_context: Encryption context to use in decryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if Master Key is unable to decrypt data key """ edk_key_id = to_str(encrypted_data_key.key_provider.key_info) if edk_key_id != self._key_id: raise DecryptKeyError( "Cannot decrypt EDK wrapped by key_id={}, because it does not match this " "provider's key_id={}".format(edk_key_id, self._key_id)) kms_params = { "CiphertextBlob": encrypted_data_key.encrypted_data_key, "KeyId": edk_key_id } if encryption_context: kms_params["EncryptionContext"] = encryption_context if self.config.grant_tokens: kms_params["GrantTokens"] = self.config.grant_tokens # Catch any boto3 errors and normalize to expected DecryptKeyError try: response = self.config.client.decrypt(**kms_params) returned_key_id = response["KeyId"] if returned_key_id != edk_key_id: error_message = "AWS KMS returned unexpected key_id {returned} (expected {key_id})".format( returned=returned_key_id, key_id=edk_key_id) _LOGGER.exception(error_message) raise DecryptKeyError(error_message) plaintext = response["Plaintext"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to decrypt data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise DecryptKeyError(error_message) return DataKey( key_provider=self.key_provider, data_key=plaintext, encrypted_data_key=encrypted_data_key.encrypted_data_key)
def test_prepare_data_keys_raw_data_key(self): """Validate that the prepare_data_keys function behaves as expected when called with a RawDataKey. """ test_encryption_data_key, _ = aws_encryption_sdk.internal.utils.prepare_data_keys( key_provider=self.mock_master_key_provider, algorithm=sentinel.algorithm, encryption_context=sentinel.encryption_context, plaintext_rostream=sentinel.plaintext_rostream, plaintext_length=sentinel.plaintext_length, data_key=self.mock_raw_data_key_1) assert not self.mock_master_key_1.generate_data_key.called assert test_encryption_data_key == DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_raw_data_key_1_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes)
def _generate_data_key(self, algorithm, encryption_context=None): """Generates data key and returns plaintext and ciphertext of key. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to pass to KMS :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey """ kms_params = self._build_generate_data_key_request( algorithm, encryption_context) # Catch any boto3 errors and normalize to expected EncryptKeyError try: response = self.config.client.generate_data_key(**kms_params) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //# The response's "Plaintext" MUST be the plaintext in the output. plaintext = response["Plaintext"] # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //# The response's cipher text blob MUST be used as the returned as the # //# ciphertext for the encrypted data key in the output. ciphertext = response["CiphertextBlob"] key_id = response["KeyId"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to generate data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise GenerateKeyError(error_message) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //# The response's "KeyId" MUST be valid. # arn_from_str will error if given an invalid key ARN try: key_id_str = to_str(key_id) arn_from_str(key_id_str) except MalformedArnError: error_message = "Retrieved an unexpected KeyID in response from KMS: {key_id}".format( key_id=key_id) _LOGGER.exception(error_message) raise GenerateKeyError(error_message) return DataKey( key_provider=MasterKeyInfo(provider_id=self.provider_id, key_info=key_id), data_key=plaintext, encrypted_data_key=ciphertext, )
def _decrypt_data_key(self, encrypted_data_key: EncryptedDataKey, algorithm: AlgorithmSuite, encryption_context: Dict[Text, Text]) -> DataKey: """Decrypt an encrypted data key and return the plaintext. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in decryption :returns: Data key containing decrypted data key :rtype: aws_encryption_sdk.structures.DataKey """ return DataKey( key_provider=self.key_provider, data_key=self._null_plaintext_data_key(algorithm), encrypted_data_key=encrypted_data_key.encrypted_data_key, )
def _generate_data_key(self, algorithm, encryption_context): """Generates data key and returns :class:`aws_encryption_sdk.structure.DataKey`. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Generated data key :rtype: aws_encryption_sdk.structure.DataKey """ plaintext_data_key = os.urandom(algorithm.kdf_input_len) encrypted_data_key = self._encrypt_data_key( data_key=RawDataKey(key_provider=self.key_provider, data_key=plaintext_data_key), algorithm=algorithm, encryption_context=encryption_context) return DataKey( key_provider=encrypted_data_key.key_provider, data_key=plaintext_data_key, encrypted_data_key=encrypted_data_key.encrypted_data_key)
def setUp(self): self.mock_algorithm = MagicMock() self.mock_algorithm.__class__ = Algorithm self.mock_algorithm.data_key_len = sentinel.data_key_len self.mock_algorithm.kdf_input_len = sentinel.kdf_input_len self.mock_encrypted_data_key = EncryptedDataKey( key_provider=VALUES['key_provider'], encrypted_data_key=VALUES['encrypted_data_key']) self.mock_data_key = DataKey( key_provider=VALUES['key_provider'], data_key=VALUES['data_key'], encrypted_data_key=VALUES['encrypted_data_key']) self.mock_wrapping_algorithm = MagicMock() self.mock_wrapping_algorithm.__class__ = WrappingAlgorithm self.mock_wrapping_algorithm.encryption_type = sentinel.encryption_type self.mock_wrapping_key = MagicMock() self.mock_wrapping_key.__class__ = WrappingKey self.mock_wrapping_key.wrapping_algorithm = self.mock_wrapping_algorithm self.mock_wrapping_key.encrypt.return_value = sentinel.encrypted_data self.mock_wrapping_key.decrypt.return_value = VALUES['data_key']
VALUES['final_frame_base'].iv, struct.pack('>I', VALUES['small_frame_length'] + 1), VALUES['final_frame_base'].ciphertext, VALUES['final_frame_base'].tag ]) VALUES['serialized_footer'] = b''.join([ VALUES['signature_len'], VALUES['signature'] ]) VALUES['key_provider'] = MasterKeyInfo( 'aws-kms', VALUES['arn'] ) VALUES['data_key_obj'] = DataKey( VALUES['key_provider'], VALUES['data_key'], VALUES['encrypted_data_key'] ) VALUES['encrypted_data_key_obj'] = EncryptedDataKey( VALUES['key_provider'], VALUES['encrypted_data_key'] ) VALUES['data_keys'] = [ VALUES['data_key_obj'] ] VALUES['message_non_framed'] = b''.join([ VALUES['header'], VALUES['header_auth'], VALUES['body_non_framed'], VALUES['footer'] ])
def test_data_key_attributes_succeeds(): DataKey(key_provider=MagicMock(__class__=MasterKeyInfo), data_key=b'', encrypted_data_key=b'')
"raw": { "this": "is", "a": "non-empty", "encryption": "context" }, "hash": b"BPo+2YlnLPXnDxikPiNjCAQdS5Mz829EAn69cRSW81y8OIBPpwlyXVO9kqgHveWu50S42UISPN82fw0H5k+BSQ==", }, }, "encrypted_data_keys": [ { "key": DataKey( key_provider=MasterKeyInfo( provider_id="this is a provider ID", key_info=b"this is some key info"), data_key=b"super secret key!", encrypted_data_key= b"super secret key, now with encryption!", ), "hash": b"TYoFeYuxns/FBlaw4dsRDOv25OCEKuZG9iXt5iEdJ8LU7n5glgkDAVxWUEYC4JKKykJdHkaVpxcDvNqS6UswiQ==", }, { "key": DataKey( key_provider=MasterKeyInfo( provider_id="another provider ID!", key_info=b"this is some different key info"), data_key=b"better super secret key!", encrypted_data_key= b"better super secret key, now with encryption!",
def apply_fixtures(self): # Set up mock key provider and keys self.mock_key_provider_1 = MasterKeyInfo(provider_id="adijoasijfoi", key_info=b"asoiwef8q34") self.mock_raw_data_key_1_bytes = b"asioufhaw9eruhtg" self.mock_generated_data_key_1_bytes = b"df2hj9348r9824" self.mock_encrypted_data_key_1_bytes = b"asioufhaw9eruhtg" self.mock_raw_data_key_1 = RawDataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_raw_data_key_1_bytes) self.mock_generated_data_key_1 = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_generated_data_key_1_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes, ) self.mock_encrypted_data_key_1 = EncryptedDataKey( key_provider=self.mock_key_provider_1, encrypted_data_key=self.mock_encrypted_data_key_1_bytes) self.mock_key_provider_2 = MasterKeyInfo(provider_id="9heui5349gh38", key_info=b"fj98349yhsfd") self.mock_raw_data_key_2_bytes = b"ane4856ht9w87y5" self.mock_generated_data_key_2_bytes = b"fih94587ty3t58yh5tg" self.mock_encrypted_data_key_2_bytes = b"ane4856ht9w87y5" self.mock_generated_data_key_2 = DataKey( key_provider=self.mock_key_provider_2, data_key=self.mock_generated_data_key_2_bytes, encrypted_data_key=self.mock_encrypted_data_key_2_bytes, ) self.mock_encrypted_data_key_2 = EncryptedDataKey( key_provider=self.mock_key_provider_2, encrypted_data_key=self.mock_encrypted_data_key_2_bytes) self.mock_key_provider_3 = MasterKeyInfo( provider_id="sdfiwehjf9384u", key_info=b"evih5874yh587tyhu5") self.mock_raw_data_key_3_bytes = b"f839u459t83uh5rugh" self.mock_generated_data_key_3_bytes = b"sjhfuiehw498gfyu34098upoi" self.mock_encrypted_data_key_3_bytes = b"f839u459t83uh5rugh" self.mock_generated_data_key_3 = DataKey( key_provider=self.mock_key_provider_3, data_key=self.mock_generated_data_key_3_bytes, encrypted_data_key=self.mock_encrypted_data_key_3_bytes, ) self.mock_encrypted_data_key_3 = EncryptedDataKey( key_provider=self.mock_key_provider_3, encrypted_data_key=self.mock_encrypted_data_key_3_bytes) self.mock_master_key_provider = MagicMock() self.mock_master_key_1 = MagicMock() self.mock_master_key_1.encrypt_data_key.return_value = self.mock_encrypted_data_key_1 self.mock_master_key_1.generate_data_key.return_value = self.mock_generated_data_key_1 self.mock_master_key_2 = MagicMock() self.mock_master_key_2.encrypt_data_key.return_value = self.mock_encrypted_data_key_2 self.mock_master_key_2.generate_data_key.return_value = self.mock_generated_data_key_2 self.mock_master_key_3 = MagicMock() self.mock_master_key_3.encrypt_data_key.return_value = self.mock_encrypted_data_key_3 self.mock_master_key_3.generate_data_key.return_value = self.mock_generated_data_key_3 self.mock_master_key_provider.master_keys_for_encryption.return_value = ( self.mock_master_key_1, [ self.mock_master_key_1, self.mock_master_key_2, self.mock_master_key_3 ], ) self.mock_decrypted_data_key_bytes = b"sehf98w34y987y9uierfh" self.mock_encrypted_data_key_bytes = b"sdhf4w398hfwea98ihfr0w8" self.mock_data_key = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_decrypted_data_key_bytes, encrypted_data_key=self.mock_encrypted_data_key_bytes, ) self.mock_encrypted_data_key = EncryptedDataKey( key_provider=self.mock_key_provider_1, encrypted_data_key=self.mock_encrypted_data_key_bytes) self.mock_decrypted_data_key = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_decrypted_data_key_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes, ) self.mock_master_key_provider.decrypt_data_key.return_value = self.mock_decrypted_data_key # Set up mock algorithm self.mock_algorithm = MagicMock() self.mock_algorithm.encryption_algorithm.block_size = VALUES[ "block_size"] self.mock_algorithm.algorithm_id = VALUES["algorithm_id"] self.mock_algorithm.iv_len = VALUES["iv_len"] self.mock_algorithm.tag_len = self.mock_algorithm.auth_len = VALUES[ "tag_len"] self.mock_algorithm.data_key_len = VALUES["data_key_len"] # Set up mock objects self.mock_bad_encrypted_key = MagicMock() self.mock_bad_encrypted_key.encrypted_data_key = sentinel.bad_encrypted_data_key self.mock_aws_encryption_sdk = MagicMock() # Set up os.urandom patch self.mock_urandom_patcher = patch( "aws_encryption_sdk.internal.utils.os.urandom") self.mock_urandom = self.mock_urandom_patcher.start() self.mock_urandom.return_value = sentinel.random # Set up KMSClient patch self.mock_aws_encryption_sdk_instance = MagicMock() self.mock_aws_encryption_sdk_instance.generate_data_key.return_value = ( VALUES["data_key"], VALUES["encrypted_data_key"], ) self.mock_aws_encryption_sdk_instance.decrypt.return_value = VALUES[ "data_key"] self.mock_aws_encryption_sdk_instance.encrypt.return_value = VALUES[ "encrypted_data_key"] yield # Run tearDown self.mock_urandom_patcher.stop()
}, 'full': { 'raw': { 'this': 'is', 'a': 'non-empty', 'encryption': 'context' }, 'hash': b'BPo+2YlnLPXnDxikPiNjCAQdS5Mz829EAn69cRSW81y8OIBPpwlyXVO9kqgHveWu50S42UISPN82fw0H5k+BSQ==' } }, 'encrypted_data_keys': [{ 'key': DataKey( key_provider=MasterKeyInfo(provider_id='this is a provider ID', key_info=b'this is some key info'), data_key=b'super secret key!', encrypted_data_key=b'super secret key, now with encryption!'), 'hash': b'TYoFeYuxns/FBlaw4dsRDOv25OCEKuZG9iXt5iEdJ8LU7n5glgkDAVxWUEYC4JKKykJdHkaVpxcDvNqS6UswiQ==' }, { 'key': DataKey(key_provider=MasterKeyInfo( provider_id='another provider ID!', key_info=b'this is some different key info'), data_key=b'better super secret key!', encrypted_data_key= b'better super secret key, now with encryption!'), 'hash': b'wSrDlPM2ocIj9MAtD94ULSR0Qrt1muBovBDRL+DsSTNphJEM3CZ/h3OyvYL8BR2EIXx0m7GYwv8dGtyZL2D87w==' }]
def test_data_key_attributes_fails(key_provider, data_key, encrypted_data_key): with pytest.raises(TypeError): DataKey(key_provider=key_provider, data_key=data_key, encryted_data_key=encrypted_data_key)
VALUES["ciphertext_len"], VALUES["final_frame_base"].ciphertext, VALUES["final_frame_base"].tag, ]) VALUES["serialized_final_frame_bad_length"] = b"".join([ b"\xff\xff\xff\xff", b"\x00\x00\x00\x01", VALUES["final_frame_base"].iv, struct.pack(">I", VALUES["small_frame_length"] + 1), VALUES["final_frame_base"].ciphertext, VALUES["final_frame_base"].tag, ]) VALUES["serialized_footer"] = b"".join( [VALUES["signature_len"], VALUES["signature"]]) VALUES["key_provider"] = MasterKeyInfo("aws-kms", VALUES["arn"]) VALUES["data_key_obj"] = DataKey(VALUES["key_provider"], VALUES["data_key"], VALUES["encrypted_data_key"]) VALUES["encrypted_data_key_obj"] = EncryptedDataKey( VALUES["key_provider"], VALUES["encrypted_data_key"]) VALUES["data_keys"] = [VALUES["data_key_obj"]] VALUES["message_non_framed"] = b"".join([ VALUES["header"], VALUES["header_auth"], VALUES["body_non_framed"], VALUES["footer"] ]) VALUES["message_single_frame"] = b"".join([ VALUES["header"], VALUES["header_auth"], VALUES["body_final_frame"], VALUES["footer"] ]) VALUES["message_multi_frame"] = b"".join([ VALUES["header"], VALUES["header_auth"], VALUES["body_frame"],
) from aws_encryption_sdk.materials_managers.default import DefaultCryptoMaterialsManager from aws_encryption_sdk.structures import DataKey, EncryptedDataKey, MasterKeyInfo, RawDataKey from ..unit_test_utils import ( BrokenKeyring, NoEncryptedDataKeysKeyring, ephemeral_raw_aes_keyring, ephemeral_raw_aes_master_key, ) pytestmark = [pytest.mark.unit, pytest.mark.local] _DATA_KEY = DataKey( key_provider=MasterKeyInfo(provider_id="Provider", key_info=b"Info"), data_key=b"1234567890123456789012", encrypted_data_key=b"asdf", ) _ENCRYPTED_DATA_KEY = EncryptedDataKey.from_data_key(_DATA_KEY) @pytest.fixture def patch_for_dcmm_encrypt(mocker): mocker.patch.object(DefaultCryptoMaterialsManager, "_generate_signing_key_and_update_encryption_context") mock_signing_key = b"ex_signing_key" DefaultCryptoMaterialsManager._generate_signing_key_and_update_encryption_context.return_value = mock_signing_key mocker.patch.object(aws_encryption_sdk.materials_managers.default, "prepare_data_keys") mock_data_encryption_key = _DATA_KEY mock_encrypted_data_keys = (_ENCRYPTED_DATA_KEY, )
def setUp(self): # Set up mock key provider and keys self.mock_key_provider_1 = MasterKeyInfo(provider_id='adijoasijfoi', key_info=b'asoiwef8q34') self.mock_raw_data_key_1_bytes = b'asioufhaw9eruhtg' self.mock_generated_data_key_1_bytes = b'df2hj9348r9824' self.mock_encrypted_data_key_1_bytes = b'asioufhaw9eruhtg' self.mock_raw_data_key_1 = RawDataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_raw_data_key_1_bytes) self.mock_generated_data_key_1 = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_generated_data_key_1_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes) self.mock_encrypted_data_key_1 = EncryptedDataKey( key_provider=self.mock_key_provider_1, encrypted_data_key=self.mock_encrypted_data_key_1_bytes) self.mock_key_provider_2 = MasterKeyInfo(provider_id='9heui5349gh38', key_info=b'fj98349yhsfd') self.mock_raw_data_key_2_bytes = b'ane4856ht9w87y5' self.mock_generated_data_key_2_bytes = b'fih94587ty3t58yh5tg' self.mock_encrypted_data_key_2_bytes = b'ane4856ht9w87y5' self.mock_generated_data_key_2 = DataKey( key_provider=self.mock_key_provider_2, data_key=self.mock_generated_data_key_2_bytes, encrypted_data_key=self.mock_encrypted_data_key_2_bytes) self.mock_encrypted_data_key_2 = EncryptedDataKey( key_provider=self.mock_key_provider_2, encrypted_data_key=self.mock_encrypted_data_key_2_bytes) self.mock_key_provider_3 = MasterKeyInfo( provider_id='sdfiwehjf9384u', key_info=b'evih5874yh587tyhu5') self.mock_raw_data_key_3_bytes = b'f839u459t83uh5rugh' self.mock_generated_data_key_3_bytes = b'sjhfuiehw498gfyu34098upoi' self.mock_encrypted_data_key_3_bytes = b'f839u459t83uh5rugh' self.mock_generated_data_key_3 = DataKey( key_provider=self.mock_key_provider_3, data_key=self.mock_generated_data_key_3_bytes, encrypted_data_key=self.mock_encrypted_data_key_3_bytes) self.mock_encrypted_data_key_3 = EncryptedDataKey( key_provider=self.mock_key_provider_3, encrypted_data_key=self.mock_encrypted_data_key_3_bytes) self.mock_master_key_provider = MagicMock() self.mock_master_key_1 = MagicMock() self.mock_master_key_1.encrypt_data_key.return_value = self.mock_encrypted_data_key_1 self.mock_master_key_1.generate_data_key.return_value = self.mock_generated_data_key_1 self.mock_master_key_2 = MagicMock() self.mock_master_key_2.encrypt_data_key.return_value = self.mock_encrypted_data_key_2 self.mock_master_key_2.generate_data_key.return_value = self.mock_generated_data_key_2 self.mock_master_key_3 = MagicMock() self.mock_master_key_3.encrypt_data_key.return_value = self.mock_encrypted_data_key_3 self.mock_master_key_3.generate_data_key.return_value = self.mock_generated_data_key_3 self.mock_master_key_provider.master_keys_for_encryption.return_value = ( self.mock_master_key_1, [ self.mock_master_key_1, self.mock_master_key_2, self.mock_master_key_3 ]) self.mock_decrypted_data_key_bytes = b'sehf98w34y987y9uierfh' self.mock_encrypted_data_key_bytes = b'sdhf4w398hfwea98ihfr0w8' self.mock_data_key = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_decrypted_data_key_bytes, encrypted_data_key=self.mock_encrypted_data_key_bytes) self.mock_encrypted_data_key = EncryptedDataKey( key_provider=self.mock_key_provider_1, encrypted_data_key=self.mock_encrypted_data_key_bytes) self.mock_decrypted_data_key = DataKey( key_provider=self.mock_key_provider_1, data_key=self.mock_decrypted_data_key_bytes, encrypted_data_key=self.mock_encrypted_data_key_1_bytes) self.mock_master_key_provider.decrypt_data_key.return_value = self.mock_decrypted_data_key # Set up mock algorithm self.mock_algorithm = MagicMock() self.mock_algorithm.encryption_algorithm.block_size = VALUES[ 'block_size'] self.mock_algorithm.algorithm_id = VALUES['algorithm_id'] self.mock_algorithm.iv_len = VALUES['iv_len'] self.mock_algorithm.tag_len = self.mock_algorithm.auth_len = VALUES[ 'tag_len'] self.mock_algorithm.data_key_len = VALUES['data_key_len'] # Set up mock objects self.mock_bad_encrypted_key = MagicMock() self.mock_bad_encrypted_key.encrypted_data_key = sentinel.bad_encrypted_data_key self.mock_aws_encryption_sdk = MagicMock() # Set up os.urandom patch self.mock_urandom_patcher = patch( 'aws_encryption_sdk.internal.utils.os.urandom') self.mock_urandom = self.mock_urandom_patcher.start() self.mock_urandom.return_value = sentinel.random # Set up KMSClient patch self.mock_aws_encryption_sdk_instance = MagicMock() self.mock_aws_encryption_sdk_instance.generate_data_key.return_value = ( VALUES['data_key'], VALUES['encrypted_data_key']) self.mock_aws_encryption_sdk_instance.decrypt.return_value = VALUES[ 'data_key'] self.mock_aws_encryption_sdk_instance.encrypt.return_value = VALUES[ 'encrypted_data_key']