def serialize(self, private_key: bytes) -> bytes: """ Parses payload into bytes message. """ serialized_payload = self._serialize_payload(self.payload) assert isinstance(serialized_payload, bytes) frame_format = self.get_frame_format() # Create and build part of the frame which will be signed signed_part_of_the_frame = Container( request_id=self.request_id, payload_type=self.payload_type, # type: ignore # pylint: disable=no-member payload=serialized_payload, ) raw_signed_part_of_the_frame = frame_format.signed_part_of_the_frame.build( signed_part_of_the_frame ) # Create signature of part of the frame frame_signature = ecdsa_sign(privkey=private_key, msghash=raw_signed_part_of_the_frame) # Create frame with signature frame = Container( frame_signature=frame_signature, signed_part_of_the_frame=signed_part_of_the_frame, ) raw_frame = frame_format.build(frame) return raw_frame
def test_that_serializing_and_deserializing_message_with_wrong_payload_type_should_raise_exception( self): middleman_message = GolemMessageFrame(Ping(), self.request_id) raw_message = middleman_message.serialize( private_key=CONCENT_PRIVATE_KEY) payload_type_position = FRAME_SIGNATURE_BYTES_LENGTH + FRAME_REQUEST_ID_BYTES_LENGTH invalid_payload_type = 100 # Sanity check for payload type in this case to be between expected bytes assert raw_message[payload_type_position:payload_type_position + 1] == b'\x00' assert invalid_payload_type not in PAYLOAD_TYPE_TO_MIDDLEMAN_MESSAGE_CLASS # Replace bytes with payload length raw_message = ( raw_message[:payload_type_position] + bytes(bytearray([invalid_payload_type])) + raw_message[payload_type_position + FRAME_PAYLOAD_TYPE_LENGTH:]) # Replace message signature new_signature = ecdsa_sign(CONCENT_PRIVATE_KEY, raw_message[FRAME_SIGNATURE_BYTES_LENGTH:]) raw_message_with_new_signature = new_signature + raw_message[ FRAME_SIGNATURE_BYTES_LENGTH:] with pytest.raises(PayloadTypeInvalidMiddlemanProtocolError): AbstractFrame.deserialize(raw_message_with_new_signature, CONCENT_PUBLIC_KEY)
def _get_authentication_challenge_signature(self, authentication_challenge: bytes) -> bytes: """ Returns signed authentication challenge with SigningService private key. """ assert isinstance(authentication_challenge, bytes) return ecdsa_sign( self.signing_service_private_key, authentication_challenge, )
def sign_message(self, private_key: bytes, msg_hash: bytes = None) -> None: """ Calculate and set message signature using the provided private key. :param private_key: sender's private key :param msg_hash: if provided, a call to `get_short_hash()` will be skipped and the provided hash used instead """ self.sig = cryptography.ecdsa_sign(privkey=private_key, msghash=msg_hash or self.get_short_hash())
def test_that__handle_connection_should_send_error_frame_if_payload_type_is_invalid( self): # Prepare frame with malformed payload_type. middleman_message = GolemMessageFrame( payload=self._get_deserialized_transaction_signing_request(), request_id=99, ) raw_message = middleman_message.serialize( private_key=CONCENT_PRIVATE_KEY) payload_type_position = FRAME_SIGNATURE_BYTES_LENGTH + FRAME_REQUEST_ID_BYTES_LENGTH invalid_payload_type = 100 # Replace bytes with payload length. malformed_raw_message = ( raw_message[:payload_type_position] + bytes(bytearray([invalid_payload_type])) + raw_message[payload_type_position + FRAME_PAYLOAD_TYPE_LENGTH:]) # Replace message signature new_signature = ecdsa_sign( CONCENT_PRIVATE_KEY, malformed_raw_message[FRAME_SIGNATURE_BYTES_LENGTH:]) malformed_raw_message_with_new_signature = new_signature + malformed_raw_message[ FRAME_SIGNATURE_BYTES_LENGTH:] raw_message_received = self._prepare_and_execute_handle_connection( malformed_raw_message_with_new_signature) deserialized_message = AbstractFrame.deserialize( raw_message=raw_message_received, public_key=SIGNING_SERVICE_PUBLIC_KEY, ) assertpy.assert_that( deserialized_message.payload).is_instance_of(tuple) assertpy.assert_that(deserialized_message.payload).is_length(2) assertpy.assert_that(deserialized_message.payload[0]).is_equal_to( ErrorCode.InvalidFrame) assertpy.assert_that(deserialized_message.request_id).is_equal_to( REQUEST_ID_FOR_RESPONSE_FOR_INVALID_FRAME)
async def test_that_if_received_frame_has_wrong_request_id_then_function_returns_false(self): with override_settings( SIGNING_SERVICE_PRIVATE_KEY=SIGNING_SERVICE_PRIVATE_KEY, SIGNING_SERVICE_PUBLIC_KEY=SIGNING_SERVICE_PUBLIC_KEY, CONCENT_PRIVATE_KEY=CONCENT_PRIVATE_KEY, CONCENT_PUBLIC_KEY=CONCENT_PUBLIC_KEY, ): with patch("middleman.asynchronous_operations.RequestIDGenerator.generate_request_id", return_value=self.request_id): frame_with_wrong_request_id = AuthenticationResponseFrame( payload=ecdsa_sign( WRONG_SIGNING_SERVICE_PRIVATE_KEY, self.mocked_challenge, ), request_id=self.wrong_request_id, ) mocked_reader = self._prepare_mocked_reader(frame_with_wrong_request_id) authentication_successful = await is_authenticated(mocked_reader, self.mocked_writer) self.mocked_writer.write.assert_called_once() assert_that(authentication_successful).is_false()
def test_that__handle_connection_should_send_error_frame_if_payload_is_invalid( self): # Prepare frame payload which is not Golem message. middleman_message = GolemMessageFrame( payload=Ping(), request_id=99, ) raw_message = middleman_message.serialize( private_key=CONCENT_PRIVATE_KEY) malformed_raw_message = ( raw_message[:FRAME_PAYLOAD_STARTING_BYTE] + AbstractFrame.get_frame_format( ).signed_part_of_the_frame.payload.build(b'\x00' * 100)) # Replace message signature new_signature = ecdsa_sign( CONCENT_PRIVATE_KEY, malformed_raw_message[FRAME_SIGNATURE_BYTES_LENGTH:]) malformed_raw_message_with_new_signature = new_signature + malformed_raw_message[ FRAME_SIGNATURE_BYTES_LENGTH:] raw_message_received = self._prepare_and_execute_handle_connection( malformed_raw_message_with_new_signature) deserialized_message = AbstractFrame.deserialize( raw_message=raw_message_received, public_key=SIGNING_SERVICE_PUBLIC_KEY, ) assertpy.assert_that( deserialized_message.payload).is_instance_of(tuple) assertpy.assert_that(deserialized_message.payload).is_length(2) assertpy.assert_that(deserialized_message.payload[0]).is_equal_to( ErrorCode.InvalidPayload) assertpy.assert_that(deserialized_message.request_id).is_equal_to( REQUEST_ID_FOR_RESPONSE_FOR_INVALID_FRAME)