def test_process_rekey_key_pair_batch_item(self): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.REKEY_KEY_PAIR), response_payload=payloads.RekeyKeyPairResponsePayload()) result = self.client._process_rekey_key_pair_batch_item(batch_item) msg = "expected {0}, received {1}".format(RekeyKeyPairResult, result) self.assertIsInstance(result, RekeyKeyPairResult, msg)
def test_encrypt(self, send_mock, build_mock): """ Test that the client can encrypt data. """ payload = payloads.EncryptResponsePayload( unique_identifier='1', data=( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ) ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.ENCRYPT), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.encrypt( ( b'\x37\x36\x35\x34\x33\x32\x31\x20' b'\x4E\x6F\x77\x20\x69\x73\x20\x74' b'\x68\x65\x20\x74\x69\x6D\x65\x20' b'\x66\x6F\x72\x20\x00' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.BLOWFISH ), iv_counter_nonce=b'\xFE\xDC\xBA\x98\x76\x54\x32\x10' ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), result.get('data') ) self.assertEqual(None, result.get('iv_counter_nonce')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def test_process_get_attribute_list_batch_item(self): uid = '00000000-1111-2222-3333-444444444444' names = ['Cryptographic Algorithm', 'Cryptographic Length'] payload = payloads.GetAttributeListResponsePayload( unique_identifier=uid, attribute_names=names) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.GET_ATTRIBUTE_LIST), response_payload=payload) result = self.client._process_get_attribute_list_batch_item(batch_item) self.assertIsInstance(result, GetAttributeListResult) self.assertEqual(uid, result.uid) self.assertEqual(names, result.names)
def test_process_get_attributes_batch_item(self): uuid = '00000000-1111-2222-3333-444444444444' attributes = [] payload = get_attributes.GetAttributesResponsePayload( unique_identifier=uuid, attributes=attributes) batch_item = ResponseBatchItem(operation=Operation( OperationEnum.GET_ATTRIBUTES), response_payload=payload) result = self.client._process_get_attributes_batch_item(batch_item) self.assertIsInstance(result, GetAttributesResult) self.assertEqual(uuid, result.uuid) self.assertEqual(attributes, result.attributes)
def test_derive_key(self, send_mock, build_mock): """ Test that the client can derive a key. """ payload = payloads.DeriveKeyResponsePayload( unique_identifier='1', ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DERIVE_KEY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.derive_key( object_type=enums.ObjectType.SYMMETRIC_KEY, unique_identifiers=['2', '3'], derivation_method=enums.DerivationMethod.ENCRYPT, derivation_parameters=DerivationParameters( cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.AES ), initialization_vector=b'\x01\x02\x03\x04', derivation_data=b'\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8' ), template_attribute=TemplateAttribute( attributes=[ self.attr_factory.create_attribute( 'Cryptographic Length', 128 ), self.attr_factory.create_attribute( 'Cryptographic Algorithm', enums.CryptographicAlgorithm.AES ) ] ), ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def test_signature_verify(self, send_mock, build_mock): """ Test that the client can verify a signature. """ payload = payloads.SignatureVerifyResponsePayload( unique_identifier='1', validity_indicator=enums.ValidityIndicator.INVALID ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGNATURE_VERIFY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.signature_verify( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), ( b'\x11\x11\x11\x11\x11\x11\x11\x11' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( enums.ValidityIndicator.INVALID, result.get('validity_indicator') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def _test_process_discover_versions_batch_item(self, protocol_versions): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DISCOVER_VERSIONS), response_payload=payloads.DiscoverVersionsResponsePayload( protocol_versions)) result = self.client._process_discover_versions_batch_item(batch_item) base = "expected {0}, received {1}" msg = base.format(DiscoverVersionsResult, result) self.assertIsInstance(result, DiscoverVersionsResult, msg) # The payload maps protocol_versions to an empty list on None if protocol_versions is None: protocol_versions = list() msg = base.format(protocol_versions, result.protocol_versions) self.assertEqual(protocol_versions, result.protocol_versions, msg)
def test_process_batch_items(self): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.CREATE_KEY_PAIR), response_payload=payloads.CreateKeyPairResponsePayload()) response = ResponseMessage(batch_items=[batch_item, batch_item]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = base.format(list, results) self.assertIsInstance(results, list, msg) msg = "number of results " + base.format(2, len(results)) self.assertEqual(2, len(results), msg) for result in results: msg = base.format(CreateKeyPairResult, result) self.assertIsInstance(result, CreateKeyPairResult, msg)
def _test_process_query_batch_item( self, operations, object_types, vendor_identification, server_information, application_namespaces, extension_information): payload = payloads.QueryResponsePayload( operations, object_types, vendor_identification, server_information, application_namespaces, extension_information) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.QUERY), response_payload=payload) result = self.client._process_query_batch_item(batch_item) base = "expected {0}, observed {1}" msg = base.format(QueryResult, result) self.assertIsInstance(result, QueryResult, msg) # The payload maps the following inputs to empty lists on None. if operations is None: operations = list() if object_types is None: object_types = list() if application_namespaces is None: application_namespaces = list() if extension_information is None: extension_information = list() self._test_equality(operations, result.operations) self._test_equality(object_types, result.object_types) self._test_equality( vendor_identification, result.vendor_identification) self._test_equality(server_information, result.server_information) self._test_equality( application_namespaces, result.application_namespaces) self._test_equality( extension_information, result.extension_information)
def test_process_batch_item_with_error(self): result_status = ResultStatus(ResultStatusEnum.OPERATION_FAILED) result_reason = ResultReason(ResultReasonEnum.INVALID_MESSAGE) result_message = ResultMessage("message") batch_item = ResponseBatchItem(result_status=result_status, result_reason=result_reason, result_message=result_message) response = ResponseMessage(batch_items=[batch_item]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = "number of results " + base.format(1, len(results)) self.assertEqual(1, len(results), msg) result = results[0] self.assertIsInstance(result, OperationResult) self.assertEqual(result.result_status, result_status) self.assertEqual(result.result_reason, result_reason) self.assertEqual(result.result_message.value, "message")
def test_sign(self, send_mock, build_mock): """ Test that the client can sign data """ payload = payloads.SignResponsePayload( unique_identifier='1', signature_data=b'aaaaaaaaaaaaaaaa' ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGN), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.sign( b'\x11\x11\x11\x11\x11\x11\x11\x11', unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( b'aaaaaaaaaaaaaaaa', result.get('signature') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def _process_request(self, message): header = message.request_header protocol_version = header.protocol_version # maximum_response_size = header.maximum_response_size asynchronous_indicator = header.asynchronous_indicator # authentication = header.authentication batch_error_cont_option = header.batch_error_cont_option # batch_order_option = header.batch_order_option # time_stamp = header.time_stamp request_batch_count = header.batch_count.value # TODO (peter-hamilton) Log receipt of message with time stamp if asynchronous_indicator is None: asynchronous_indicator = AsynchronousIndicator(False) if batch_error_cont_option is None: batch_error_cont_option = BatchErrorContinuationOption(BECO.STOP) request_batch_items = message.batch_items response_batch_items = [] for i in range(request_batch_count): request_batch_item = request_batch_items[i] failure_occurred = False operation = request_batch_item.operation ubi_id = request_batch_item.unique_batch_item_id payload = request_batch_item.request_payload message_extension = request_batch_item.message_extension result = self._process_operation(operation, payload) result_status = result[0] result_reason = result[1] result_message = result[2] asyn_cv = None response_payload = None message_extension = None if result_status.value is RS.SUCCESS: response_payload = result[3] elif result_status.value is RS.OPERATION_FAILED: failure_occurred = True result_reason = result[1] elif result_status.value is RS.OPERATION_PENDING: # TODO (peter-hamilton) Need to add a way to track async # TODO (peter-hamilton) operations. asyn_cv = b'\x00' elif result_status.value is RS.OPERATION_UNDONE: result_reason = result[1] else: msg = 'Unrecognized operation result status: {0}' raise RuntimeError(msg.format(result_status)) resp_bi = ResponseBatchItem(operation=operation, unique_batch_item_id=ubi_id, result_status=result_status, result_reason=result_reason, result_message=result_message, async_correlation_value=asyn_cv, response_payload=response_payload, message_extension=message_extension) response_batch_items.append(resp_bi) if failure_occurred: if batch_error_cont_option.value is BECO.STOP: break elif batch_error_cont_option.value is BECO.UNDO: # TODO (peter-hamilton) Tell client to undo operations. # TODO (peter-hamilton) Unclear what response should be. break elif batch_error_cont_option.value is BECO.CONTINUE: continue else: msg = 'Unrecognized batch error continuation option: {0}' raise RuntimeError(msg.format(batch_error_cont_option)) response_batch_count = BatchCount(len(response_batch_items)) response_time_stamp = TimeStamp(int(time.time())) response_header = ResponseHeader(protocol_version=protocol_version, time_stamp=response_time_stamp, batch_count=response_batch_count) response_message = ResponseMessage(response_header=response_header, batch_items=response_batch_items) return response_message