def send_to_concent(msg: message.base.Message, signing_key: bytes, concent_variant: dict) -> typing.Optional[bytes]: """Sends a message to the concent server :return: Raw reply message, None or exception :rtype: Bytes|None """ logger.debug('send_to_concent(): Updating timestamp msg %r', msg) # Delayed messages are prepared before they're needed # and only sent to Concent if they're not cancelled # before. This can cause a situation where previously # prepared message will be too old to send when enqueued. # Also messages with no delay could have stayed in queue # long enough to eat significant amount of Message Transport Time # SEE: golem_messages.constants header = msg_datastructures.MessageHeader( msg.header.type_, # Using this tricky approach instead of time.time() # because of AppVeyor issues. calendar.timegm(time.gmtime()), msg.header.encrypted, ) msg.header = header logger.debug('send_to_concent(): Encrypting msg %r', msg) # if signature already exists, it must be set to None explicitly if msg.sig is not None: msg.sig = None data = golem_messages.dump(msg, signing_key, concent_variant['pubkey']) logger.debug('send_to_concent(): data: %r', data) concent_post_url = urljoin(concent_variant['url'], '/api/v1/send/') headers = { 'Content-Type': 'application/octet-stream', 'X-Golem-Messages': golem_messages.__version__, } try: logger.debug( 'send_to_concent(): POST %r hdr: %r', concent_post_url, headers, ) response = requests.post( concent_post_url, data=data, headers=headers, **ssl_kwargs(concent_variant), ) except requests.exceptions.RequestException as e: logger.warning('Concent RequestException %r', e) response = e.response verify_response(response) return response.content or None
def is_golem_message_signed_with_key( public_key: bytes, golem_message: message.base.Message, ) -> bool: """ Validates if given Golem message is signed with given public key. :param golem_message: Instance of golem_messages.base.Message object. :param public_key: Client public key in bytes. :return: True if given Golem message is signed with given public key, otherwise False. """ assert isinstance(golem_message, message.base.Message) validate_bytes_public_key(public_key, 'public_key') try: is_valid = golem_message.verify_signature(public_key) except MessageError as exception: is_valid = False log_error_message( logger, f'There was an exception when validating if golem_message {golem_message.__class__.__name__} is signed ' f'with public key {public_key}, exception: {exception}.' ) return is_valid
def validate_golem_message_signed_with_key( golem_message: message.base.Message, public_key: bytes, ): assert isinstance(golem_message, message.base.Message) validate_bytes_public_key(public_key, 'public_key') try: golem_message.verify_signature(public_key) except MessageError as exception: error_message = join_messages( 'There was an exception when validating if golem_message {} is signed with public key {}.' .format( golem_message.TYPE, public_key, ), str(exception)) raise Http400( error_message, error_code=ErrorCode.MESSAGE_SIGNATURE_WRONG, )
def get_validated_client_public_key_from_client_message(golem_message: message.base.Message): if isinstance(golem_message, message.concents.ForcePayment): if ( isinstance(golem_message.subtask_results_accepted_list, list) and len(golem_message.subtask_results_accepted_list) > 0 ): task_to_compute = golem_message.subtask_results_accepted_list[0].task_to_compute else: raise ConcentValidationError( "subtask_results_accepted_list must be a list type and contains at least one message", error_code=ErrorCode.MESSAGE_VALUE_WRONG_LENGTH, ) elif isinstance(golem_message, message.tasks.TaskMessage): if not golem_message.is_valid(): raise GolemMessageValidationError( "Golem message invalid", error_code=ErrorCode.MESSAGE_INVALID ) task_to_compute = golem_message.task_to_compute else: raise ConcentValidationError( "Unknown message type", error_code=ErrorCode.MESSAGE_UNKNOWN, ) if task_to_compute is not None: if isinstance(golem_message, ( message.ForceReportComputedTask, message.concents.ForceSubtaskResults, message.concents.ForcePayment, message.concents.SubtaskResultsVerify, )): client_public_key = task_to_compute.provider_public_key validate_hex_public_key(client_public_key, 'provider_public_key') elif isinstance(golem_message, ( message.AckReportComputedTask, message.RejectReportComputedTask, message.concents.ForceGetTaskResult, message.concents.ForceSubtaskResultsResponse, )): client_public_key = task_to_compute.requestor_public_key validate_hex_public_key(client_public_key, 'requestor_public_key') else: raise ConcentValidationError( "Unknown message type", error_code=ErrorCode.MESSAGE_UNKNOWN, ) return hex_to_bytes_convert(client_public_key) return None