def test_publishing_profile(self, mock_validator, mock_vault_profile, mock_signature, Change=Change): from cis.libs import encryption o = encryption.Operation(boto_session=None) test_kms_data = { 'Plaintext': base64.b64decode(self.test_artifacts['Plaintext']), 'CiphertextBlob': base64.b64decode(self.test_artifacts['CiphertextBlob']) } test_iv = base64.b64decode(self.test_artifacts['IV']) # Set attrs on object to test data. Not patching boto3 now! o.data_key = test_kms_data o.iv = test_iv mock_vault_profile.return_value = None mock_validator.return_value = True mock_signature.return_value = self.good_signatures p = Change(publisher={'id': 'mozilliansorg'}, signature={}, profile_data=self.test_profile_good) p.encryptor = o p.boto_session = "I am a real session I swear" result = p.send() assert result is True
def test_decryption(self): from cis.libs import encryption o = encryption.Operation( boto_session=None ) test_kms_data = { 'Plaintext': base64.b64decode(self.test_artifacts['Plaintext']), 'CiphertextBlob': base64.b64decode(self.test_artifacts['CiphertextBlob']) } test_iv = base64.b64decode(self.test_artifacts['IV']) # Set attrs on object to test data. Not patching boto3 now! o.data_key = test_kms_data o.iv = test_iv o.plaintext_key = test_kms_data['Plaintext'] kwargs = { 'ciphertext': base64.b64decode(self.test_artifacts['expected_ciphertext']), 'ciphertext_key': test_kms_data['CiphertextBlob'], 'iv': test_iv, 'tag': base64.b64decode(self.test_artifacts['expected_tag']) } operation_result = o.decrypt(**kwargs) self.assertEqual(operation_result, b'foobar')
def test_processor_decrypt(self, mock_verification): mock_verification.return_value = True kc = boto3.client('kinesis') self.dummy_stream = kc.create_stream(StreamName='dummy_cis_stream', ShardCount=1) self.dummy_stream = kc.describe_stream(StreamName='dummy_cis_stream', ) os.environ["CIS_KINESIS_STREAM_ARN"] = self.dummy_stream['StreamDescription']['StreamARN'] + \ '/dummy_cis_stream' from cis.libs import encryption o = encryption.Operation(boto_session=None) test_kms_data = { 'Plaintext': base64.b64decode(self.test_artifacts['Plaintext']), 'CiphertextBlob': base64.b64decode(self.test_artifacts['CiphertextBlob']) } test_iv = base64.b64decode(self.test_artifacts['IV']) # Set attrs on object to test data. Not patching boto3 now! o.data_key = test_kms_data o.iv = test_iv o.plaintext_key = base64.b64decode(self.test_artifacts['Plaintext']) encrypted_profile = o.encrypt( json.dumps(self.test_profile_good).encode()) base64_payload = dict() for key in ['ciphertext', 'ciphertext_key', 'iv', 'tag']: base64_payload[key] = base64.b64encode(encrypted_profile[key]) encrypted_profile = base64_payload publisher = {'id': 'mozilliansorg'} from cis import processor p = processor.Operation(boto_session=None, publisher=publisher, signature=self.good_signatures, encrypted_profile_data=encrypted_profile) p.kinesis_client = boto3.client('kinesis') p.user = self.test_profile_good p.decryptor = o p.run() dump_a = json.dumps(self.test_profile_good, sort_keys=True, indent=2) dump_b = json.dumps(p.decrypted_profile, sort_keys=True, indent=2) assert dump_a == dump_b
def test_processor_validator_with_bad_sig(self, mock_verification): mock_verification.return_value = False kc = boto3.client('kinesis') self.dummy_stream = kc.create_stream(StreamName='dummy_cis_stream', ShardCount=1) self.dummy_stream = kc.describe_stream(StreamName='dummy_cis_stream', ) os.environ["CIS_KINESIS_STREAM_NAME"] = 'dummy_cis_stream' from cis.libs import encryption o = encryption.Operation(boto_session=None) test_kms_data = { 'Plaintext': base64.b64decode(self.test_artifacts['Plaintext']), 'CiphertextBlob': base64.b64decode(self.test_artifacts['CiphertextBlob']) } test_iv = base64.b64decode(self.test_artifacts['IV']) # Set attrs on object to test data. Not patching boto3 now! o.data_key = test_kms_data o.iv = test_iv o.plaintext_key = base64.b64decode(self.test_artifacts['Plaintext']) encrypted_profile = o.encrypt( json.dumps(self.test_profile_good).encode()) base64_payload = dict() for key in ['ciphertext', 'ciphertext_key', 'iv', 'tag']: base64_payload[key] = base64.b64encode(encrypted_profile[key]) encrypted_profile = base64_payload publisher = {'id': 'mozillians.org'} from cis import processor p = processor.ValidatorOperation( boto_session=None, publisher=publisher, signature=self.good_signatures, encrypted_profile_data=encrypted_profile) p.kinesis_client = boto3.client('kinesis') # Fake like the user returned from dynamo by returning same profile. p.user = self.test_profile_good # Decrypt with fake key material. p.decryptor = o res = p.run() assert res is False
def test_object_init(self): from cis.libs import encryption o = encryption.Operation( boto_session=None ) assert o is not None
def test_vault_storage(self, mock_table): mock_table.dynamodb_table.get_item.return_value = { 'ResponseMetadata': { 'HTTPStatusCode': 200, } } from cis.libs import encryption o = encryption.Operation(boto_session=None) test_kms_data = { 'Plaintext': base64.b64decode(self.test_artifacts['Plaintext']), 'CiphertextBlob': base64.b64decode(self.test_artifacts['CiphertextBlob']) } test_iv = base64.b64decode(self.test_artifacts['IV']) # Set attrs on object to test data. Not patching boto3 now! o.data_key = test_kms_data o.iv = test_iv o.plaintext_key = base64.b64decode(self.test_artifacts['Plaintext']) encrypted_profile = o.encrypt( json.dumps(self.test_profile_good).encode()) base64_payload = dict() for key in ['ciphertext', 'ciphertext_key', 'iv', 'tag']: base64_payload[key] = base64.b64encode(encrypted_profile[key]) encrypted_profile = base64_payload publisher = {'id': 'mozilliansorg'} from cis import processor p = processor.StreamtoVaultOperation( boto_session=None, publisher=publisher, signature=self.good_signatures, encrypted_profile_data=encrypted_profile) p.kinesis_client = boto3.client('kinesis') p.decryptor = o from cis import user u = user.Profile(boto_session=None, profile_data=self.test_profile_good) p.user = u p.run()
def __init__(self, boto_session=None, publisher=None, signature=None, encrypted_profile_data=None): self.boto_session = boto_session self.dry_run = True self.decryptor = encryption.Operation(boto_session=boto_session) self.encrypted_profile_data = encrypted_profile_data self.kinesis_client = None self.publisher = publisher self.signature = signature self.stage = self._get_stage() self.user = None
def _prepare_profile_data(self): # Performing encryption and encoding on the user data and set on the object # Encode to base64 all payload fields if not self.encryptor: logger.info( 'Encryptor not present on object. Intializing encryptor for change for user: {}' .format(self.profile_data.get('user_id'))) self.encryptor = encryption.Operation( boto_session=self.boto_session) logger.info( 'Preparing profile data and encrypting profile for user_id: {}.'. format(self.profile_data.get('user_id'))) # Reintegrate groups this publisher is not authoritative for. self._reintegrate_profile_with_api() # DynamoDB workaround self.profile_data = self._nullify_empty_values(self.profile_data) # Actually encrypt the profile encrypted_profile = self.encryptor.encrypt( json.dumps(self.profile_data).encode('utf-8')) base64_payload = dict() # Build up our encryption envelope for key in ['ciphertext', 'ciphertext_key', 'iv', 'tag']: base64_payload[key] = base64.b64encode( encrypted_profile[key]).decode('utf-8') # Dump that out to a string encrypted_profile = json.dumps(base64_payload) logger.info( 'Encryption process complete for change for user_id: {}.'.format( self.profile_data.get('user_id'))) return encrypted_profile