def test_get_entity_invalid_value_kek_wrap(self): # Arrange self.ts.require_encryption = True entity = self._create_default_entity_for_encryption() self.ts.key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key.get_key_wrap_algorithm = None try: self.ts.insert_entity(self.table_name, entity) self.fail() except AttributeError as e: self.assertEqual( str(e), _ERROR_OBJECT_INVALID.format('key encryption key', 'get_key_wrap_algorithm')) self.ts.key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key.get_kid = None with self.assertRaises(AttributeError): self.ts.insert_entity(self.table_name, entity) self.ts.key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key.wrap_key = None with self.assertRaises(AttributeError): self.ts.insert_entity(self.table_name, entity)
def test_invalid_value_kek_wrap(self): # Arrange queue_name = self._create_queue() self.qs.key_encryption_key = KeyWrapper('key1') self.qs.key_encryption_key.get_kid = None try: self.qs.put_message(queue_name, u'message') self.fail() except AttributeError as e: self.assertEqual( str(e), _ERROR_OBJECT_INVALID.format('key encryption key', 'get_kid')) self.qs.key_encryption_key = KeyWrapper('key1') self.qs.key_encryption_key.get_kid = None with self.assertRaises(AttributeError): self.qs.put_message(queue_name, u'message') self.qs.key_encryption_key = KeyWrapper('key1') self.qs.key_encryption_key.wrap_key = None with self.assertRaises(AttributeError): self.qs.put_message(queue_name, u'message')
def test_validate_encryption(self): # Arrange queue_name = self._create_queue() kek = KeyWrapper('key1') self.qs.key_encryption_key = kek self.qs.put_message(queue_name, u'message') # Act self.qs.key_encryption_key = None # Message will not be decrypted li = self.qs.peek_messages(queue_name) message = li[0].content message = loads(message) encryption_data = message['EncryptionData'] wrapped_content_key = encryption_data['WrappedContentKey'] wrapped_content_key = _WrappedContentKey( wrapped_content_key['Algorithm'], b64decode( wrapped_content_key['EncryptedKey'].encode(encoding='utf-8')), wrapped_content_key['KeyId']) encryption_agent = encryption_data['EncryptionAgent'] encryption_agent = _EncryptionAgent( encryption_agent['EncryptionAlgorithm'], encryption_agent['Protocol']) encryption_data = _EncryptionData( b64decode(encryption_data['ContentEncryptionIV'].encode( encoding='utf-8')), encryption_agent, wrapped_content_key, {'EncryptionLibrary': __version__}) message = message['EncryptedMessageContents'] content_encryption_key = kek.unwrap_key( encryption_data.wrapped_content_key.encrypted_key, encryption_data.wrapped_content_key.algorithm) #Create decryption cipher backend = backends.default_backend() algorithm = AES(content_encryption_key) mode = CBC(encryption_data.content_encryption_IV) cipher = Cipher(algorithm, mode, backend) #decode and decrypt data decrypted_data = _decode_base64_to_bytes(message) decryptor = cipher.decryptor() decrypted_data = (decryptor.update(decrypted_data) + decryptor.finalize()) #unpad data unpadder = PKCS7(128).unpadder() decrypted_data = (unpadder.update(decrypted_data) + unpadder.finalize()) decrypted_data = decrypted_data.decode(encoding='utf-8') # Assert self.assertEqual(decrypted_data, u'message')
def test_invalid_value_kek_unwrap(self): # Arrange self.bbs.require_encryption = True self.bbs.key_encryption_key = KeyWrapper('key1') blob_name = self._create_small_blob('block_blob') # Act self.bbs.key_encryption_key = KeyWrapper('key1') self.bbs.key_encryption_key.unwrap_key = None try: self.bbs.get_blob_to_bytes(self.container_name, blob_name) self.fail() except AzureException as e: self.assertEqual(str(e), _ERROR_DECRYPTION_FAILURE)
def test_missing_attribute_kek_wrap(self): # In the shared method _generate_blob_encryption_key # Arrange self.bbs.require_encryption = True valid_key = KeyWrapper('key1') # Act invalid_key_1 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_1.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_1.get_kid = valid_key.get_kid # No attribute wrap_key self.bbs.key_encryption_key = invalid_key_1 with self.assertRaises(AttributeError): self._create_small_blob('block_blob') invalid_key_2 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_2.wrap_key = valid_key.wrap_key invalid_key_2.get_kid = valid_key.get_kid # No attribute get_key_wrap_algorithm self.bbs.key_encryption_key = invalid_key_2 with self.assertRaises(AttributeError): self._create_small_blob('block_blob') invalid_key_3 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_3.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_3.wrap_key = valid_key.wrap_key # No attribute get_kid self.bbs.key_encryption_key = invalid_key_2 with self.assertRaises(AttributeError): self._create_small_blob('block_blob')
def test_validate_swapping_properties_fails(self): # Arrange entity1 = self._create_random_entity_class(rk='entity1') entity2 = self._create_random_entity_class(rk='entity2') kek = KeyWrapper('key1') self.ts.key_encryption_key = kek self.ts.encryption_resolver_function = self._default_encryption_resolver self.ts.insert_entity(self.table_name, entity1) self.ts.insert_entity(self.table_name, entity2) # Act self.ts.key_encryption_key = None new_entity1 = self.ts.get_entity(self.table_name, entity1['PartitionKey'], entity1['RowKey']) new_entity2 = deepcopy(new_entity1) new_entity2['PartitionKey'] = entity2['PartitionKey'] new_entity2['RowKey'] = entity2['RowKey'] self.ts.update_entity(self.table_name, new_entity2) self.ts.key_encryption_key = kek # Assert with self.assertRaises(AzureException): self.ts.get_entity(self.table_name, new_entity2['PartitionKey'], new_entity2['RowKey'])
def test_update_encrypted_json_message(self): # Arrange queue_name = self._create_queue() self.qs.key_encryption_key = KeyWrapper('key1') self.qs.encode_function = QueueMessageFormat.noencode self.qs.decode_function = QueueMessageFormat.nodecode message_dict = {'val1': 1, 'val2': '2'} json_text = dumps(message_dict) self.qs.put_message(queue_name, json_text) list_result1 = self.qs.get_messages(queue_name) # Act message_dict['val1'] = 0 message_dict['val2'] = 'updated' json_text = dumps(message_dict) self.qs.update_message( queue_name, list_result1[0].id, list_result1[0].pop_receipt, 0, content=json_text, ) list_result2 = self.qs.get_messages(queue_name) # Assert message = list_result2[0] self.assertEqual(message_dict, loads(message.content))
def test_batch_entity_inserts_context_manager(self): # Arrange self.ts.require_encryption = True entity1 = self._create_random_entity_class() entity2 = self._create_random_entity_class(rk='Entity2') entity3 = self._create_random_entity_class(rk='Entity3') entity2['PartitionKey'] = entity1['PartitionKey'] entity3['PartitionKey'] = entity1['PartitionKey'] self.ts.key_encryption_key = KeyWrapper('key1') self.ts.require_encryption = True self.ts.encryption_resolver_function = self._default_encryption_resolver self.ts.insert_entity(self.table_name, entity3) entity3['sex'] = 'female' # Act with self.ts.batch(self.table_name) as batch: batch.insert_entity(entity1) batch.insert_or_replace_entity(entity2) batch.update_entity(entity3) new_entity1 = self.ts.get_entity(self.table_name, entity1['PartitionKey'], entity1['RowKey']) new_entity2 = self.ts.get_entity(self.table_name, entity2['PartitionKey'], entity2['RowKey']) new_entity3 = self.ts.get_entity(self.table_name, entity3['PartitionKey'], entity3['RowKey']) # Assert self.assertEqual(new_entity1['sex'], entity1['sex']) self.assertEqual(new_entity2['sex'], entity2['sex']) self.assertEqual(new_entity3['sex'], entity3['sex'])
def test_missing_attribute_kek_wrap(self): # Arrange queue_name = self._create_queue() valid_key = KeyWrapper('key1') # Act invalid_key_1 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_1.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_1.get_kid = valid_key.get_kid #No attribute wrap_key self.qs.key_encryption_key = invalid_key_1 with self.assertRaises(AttributeError): self.qs.put_message(queue_name, u'message') invalid_key_2 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_2.wrap_key = valid_key.wrap_key invalid_key_2.get_kid = valid_key.get_kid #No attribute get_key_wrap_algorithm self.qs.key_encryption_key = invalid_key_2 with self.assertRaises(AttributeError): self.qs.put_message(queue_name, u'message') invalid_key_3 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_3.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_3.wrap_key = valid_key.wrap_key #No attribute get_kid self.qs.key_encryption_key = invalid_key_3 with self.assertRaises(AttributeError): self.qs.put_message(queue_name, u'message')
def test_insert_entity_missing_attribute_kek_wrap(self): # Arrange self.ts.require_encryption = True entity = self._create_default_entity_for_encryption() valid_key = KeyWrapper('key1') # Act invalid_key_1 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_1.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_1.get_kid = valid_key.get_kid #No attribute wrap_key self.ts.key_encryption_key = invalid_key_1 with self.assertRaises(AttributeError): self.ts.insert_entity(self.table_name, entity) invalid_key_2 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_2.wrap_key = valid_key.wrap_key invalid_key_2.get_kid = valid_key.get_kid #No attribute get_key_wrap_algorithm self.ts.key_encryption_key = invalid_key_2 with self.assertRaises(AttributeError): self.ts.insert_entity(self.table_name, entity) invalid_key_3 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_3.get_key_wrap_algorithm = valid_key.get_key_wrap_algorithm invalid_key_3.wrap_key = valid_key.wrap_key #No attribute get_kid self.ts.key_encryption_key = invalid_key_3 with self.assertRaises(AttributeError): self.ts.insert_entity(self.table_name, entity)
def test_validate_encryption(self): # Arrange self.bbs.require_encryption = True kek = KeyWrapper('key1') self.bbs.key_encryption_key = kek blob_name = self._create_small_blob('block_blob') # Act self.bbs.require_encryption = False self.bbs.key_encryption_key = None blob = self.bbs.get_blob_to_bytes(self.container_name, blob_name) encryption_data = _dict_to_encryption_data( loads(blob.metadata['encryptiondata'])) iv = encryption_data.content_encryption_IV content_encryption_key = _validate_and_unwrap_cek( encryption_data, kek, None) cipher = _generate_AES_CBC_cipher(content_encryption_key, iv) decryptor = cipher.decryptor() unpadder = PKCS7(128).unpadder() content = decryptor.update(blob.content) + decryptor.finalize() content = unpadder.update(content) + unpadder.finalize() self.assertEqual(self.bytes, content)
def test_table_ops_ignore_encryption(self): table_name = self.get_resource_name('EncryptionTableOps') try: # Arrange self.ts.require_encryption = True self.ts.key_encryption_key = KeyWrapper('key1') # Act self.assertTrue(self.ts.create_table(table_name)) self.assertTrue(self.ts.exists(table_name)) list_tables = self.ts.list_tables() test_table_exists = False for table in list_tables: if table.name == table_name: test_table_exists = True self.assertTrue(test_table_exists) permissions = self.ts.get_table_acl(table_name) new_policy = AccessPolicy(TablePermissions(_str='r'), expiry=datetime(2017, 9, 9)) permissions['samplePolicy'] = new_policy self.ts.set_table_acl(table_name, permissions) permissions = self.ts.get_table_acl(table_name) permissions['samplePolicy'] self.ts.key_encryption_key = None permissions = self.ts.get_table_acl(table_name) permissions['samplePolicy'] self.ts.delete_table(table_name) self.assertFalse(self.ts.exists(table_name)) finally: self.ts.delete_table(table_name)
def test_get_blob_kek(self): # Arrange self.bbs.require_encryption = True self.bbs.key_encryption_key = KeyWrapper('key1') blob_name = self._create_small_blob('block_blob') # Act blob = self.bbs.get_blob_to_bytes(self.container_name, blob_name) # Assert self.assertEqual(blob.content, self.bytes)
def test_insert_entity_too_many_properties(self): # Arrange self.ts.require_encryption = True entity = self._create_random_base_entity_dict() self.ts.key_encryption_key = KeyWrapper('key1') for i in range(251): entity['key{0}'.format(i)] = 'value{0}'.format(i) # Act with self.assertRaises(ValueError): resp = self.ts.insert_entity(self.table_name, entity)
def test_get_messages_encrypted_kek(self): # Arrange self.qs.key_encryption_key = KeyWrapper('key1') queue_name = self._create_queue() self.qs.put_message(queue_name, u'encrypted_message_2') # Act li = self.qs.get_messages(queue_name) # Assert self.assertEqual(li[0].content, u'encrypted_message_2')
def test_get_with_strict_mode(self): # Arrange queue_name = self._create_queue() self.qs.put_message(queue_name, u'message') self.qs.require_encryption = True self.qs.key_encryption_key = KeyWrapper('key1') try: self.qs.get_messages(queue_name) except ValueError as e: self.assertEqual(str(e), _ERROR_MESSAGE_NOT_ENCRYPTED)
def test_get_blob_strict_mode_unencrypted_blob(self): # Arrange blob_name = self._create_small_blob('block_blob') # Act self.bbs.require_encryption = True self.bbs.key_encryption_key = KeyWrapper('key1') # Assert with self.assertRaises(AzureException): self.bbs.get_blob_to_bytes(self.container_name, blob_name)
def test_get_blob_strict_mode_no_policy(self): # Arrange self.bbs.require_encryption = True self.bbs.key_encryption_key = KeyWrapper('key1') blob_name = self._create_small_blob('block_blob') # Act self.bbs.key_encryption_key = None # Assert with self.assertRaises(ValueError): self.bbs.get_blob_to_bytes(self.container_name, blob_name)
def test_encryption_add_encrypted_64k_message(self): # Arrange queue_name = self._create_queue() message = u'a' * 1024 * 64 # Act self.qs.put_message(queue_name, message) # Assert self.qs.key_encryption_key = KeyWrapper('key1') with self.assertRaises(AzureHttpError): self.qs.put_message(queue_name, message)
def test_get_entity_invalid_value_kek_unwrap(self): # Arrange self.ts.require_encryption = True entity = self._create_default_entity_for_encryption() self.ts.key_encryption_key = KeyWrapper('key1') self.ts.insert_entity(self.table_name, entity) self.ts.key_encryption_key.unwrap_key = None try: self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey']) self.fail() except AzureException as e: self.assertEqual(str(e), _ERROR_DECRYPTION_FAILURE) self.ts.key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key.get_kid = None with self.assertRaises(AzureException): self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey'])
def _create_blob_from_star(self, type, content, create_method, data, **kwargs): self.service_dict[type].key_encryption_key = KeyWrapper('key1') self.service_dict[type].require_encryption = True blob_name = self._get_blob_reference(type) create_method(self.container_name, blob_name, data, **kwargs) blob = self.service_dict[type].get_blob_to_bytes( self.container_name, blob_name) self.assertEqual(content, blob.content)
def test_get_strict_mode_unencrypted_entity(self): # Arrange entity = self._create_random_base_entity_class() self.ts.insert_entity(self.table_name, entity) # Act self.ts.require_encryption = True self.ts.key_encryption_key = KeyWrapper('key1') # Assert with self.assertRaises(AzureException): self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey'])
def test_invalid_value_kek_unwrap(self): # Arrange queue_name = self._create_queue() self.qs.key_encryption_key = KeyWrapper('key1') self.qs.put_message(queue_name, u'message') # Act self.qs.key_encryption_key.unwrap_key = None with self.assertRaises(AzureException): self.qs.peek_messages(queue_name) self.qs.key_encryption_key.get_kid = None with self.assertRaises(AzureException): self.qs.peek_messages(queue_name)
def test_get_strict_mode_no_key(self): # Arrange entity = self._create_default_entity_for_encryption() self.ts.key_encryption_key = KeyWrapper('key1') self.ts.insert_entity(self.table_name, entity) # Act self.ts.key_encryption_key = None self.ts.require_encryption = True # Assert with self.assertRaises(AzureException): self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey'])
def test_query_entities_all_properties(self): # Arrange self.ts.require_encryption = True self.ts.key_encryption_key = KeyWrapper('key1') table_name = self._create_query_table_encrypted(5) default_entity = self._create_random_entity_class() # Act resp = self.ts.query_entities(table_name, num_results=5) # Assert self.assertEqual(len(resp.items), 5) for entity in resp.items: self.assertEqual(default_entity['sex'], entity['sex'])
def test_peek_messages_encrypted_resolver(self): # Arrange self.qs.key_encryption_key = KeyWrapper('key1') queue_name = self._create_queue() self.qs.put_message(queue_name, u'encrypted_message_4') key_resolver = KeyResolver() key_resolver.put_key(self.qs.key_encryption_key) self.resolver = key_resolver.resolve_key # Act li = self.qs.peek_messages(queue_name) # Assert self.assertEqual(li[0].content, u'encrypted_message_4')
def test_put_blob_empty(self): # Arrange self.bbs.key_encryption_key = KeyWrapper('key1') self.bbs.require_encryption = True content = b'' blob_name = self._get_blob_reference('block_blob') # Act self.bbs.create_blob_from_bytes(self.container_name, blob_name, content) blob = self.bbs.get_blob_to_bytes(self.container_name, blob_name) # Assert self.assertEqual(content, blob.content)
def test_get_encrypt_multiple_properties(self): # Arrange self.ts.require_encryption = True entity = self._create_default_entity_for_encryption() self.ts.key_encryption_key = KeyWrapper('key1') self.ts.insert_entity(self.table_name, entity) # Act new_entity = self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey']) # Assert self._assert_default_entity(new_entity)
def test_encryption_nonmatching_kid(self): # Arrange queue_name = self._create_queue() self.qs.key_encryption_key = KeyWrapper('key1') self.qs.put_message(queue_name, u'message') # Act self.qs.key_encryption_key.kid = 'Invalid' # Assert try: self.qs.get_messages(queue_name) self.fail() except AzureException as e: self.assertEqual(str(e), _ERROR_DECRYPTION_FAILURE)
def test_missing_attribute_kek_unrwap(self): # Arrange queue_name = self._create_queue() self.qs.key_encryption_key = KeyWrapper('key1') self.qs.put_message(queue_name, u'message') # Act valid_key = KeyWrapper('key1') invalid_key_1 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_1.unwrap_key = valid_key.unwrap_key #No attribute get_kid self.qs.key_encryption_key = invalid_key_1 try: self.qs.peek_messages(queue_name) self.fail() except AzureException as e: self.assertEqual(str(e), _ERROR_DECRYPTION_FAILURE) invalid_key_2 = lambda: None #functions are objects, so this effectively creates an empty object invalid_key_2.get_kid = valid_key.get_kid #No attribute unwrap_key self.qs.key_encryption_key = invalid_key_2 with self.assertRaises(AzureException): self.qs.peek_messages(queue_name)