/*
 * Copyright (c) 2026 Andrian Budantsov
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "server.h"
#include "client.h"
#include "stream/stream.h"
#include "auth/auth.h"
#include "auth/des-auth.h"
#include "crypto.h"
#include "crypto/des-rfb.h"

#include <string.h>

bool des_auth_verify(const uint8_t* challenge, const uint8_t* response,
		const char* password)
{
	uint8_t expected[NVNC_AUTH_DES_CHALLENGE_SIZE];
	crypto_des_rfb_encrypt(expected, challenge, password);
	return memcmp(expected, response, NVNC_AUTH_DES_CHALLENGE_SIZE) == 0;
}

int des_auth_send_challenge(struct nvnc_client* client)
{
	crypto_random(client->des_challenge, NVNC_AUTH_DES_CHALLENGE_SIZE);
	return stream_write(client->net_stream, client->des_challenge,
			NVNC_AUTH_DES_CHALLENGE_SIZE);
}

int des_auth_handle_response(struct nvnc_client* client)
{
	if (client->buffer_len - client->buffer_index < NVNC_AUTH_DES_CHALLENGE_SIZE)
		return 0;

	uint8_t* response = client->msg_buffer + client->buffer_index;

	update_min_rtt(client);

	struct nvnc_auth_creds* creds = nvnc_auth_creds_new(NVNC_AUTH_CREDS_DES);
	nvnc_assert(creds, "Out of memory");

	memcpy(creds->des.challenge, client->des_challenge,
			NVNC_AUTH_DES_CHALLENGE_SIZE);
	memcpy(creds->des.response, response, NVNC_AUTH_DES_CHALLENGE_SIZE);

	security_handshake_authenticate(client, creds);
	return NVNC_AUTH_DES_CHALLENGE_SIZE;
}
