/*
 * osmo-pcap TLS code
 *
 * (C) 2016 by Holger Hans Peter Freyther <holger@moiji-mobile.com>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <osmo-pcap/osmo_tls.h>
#include <osmo-pcap/osmo_pcap_client.h>
#include <osmo-pcap/osmo_pcap_server.h>
#include <osmo-pcap/common.h>

#include <osmocom/core/write_queue.h>
#include <osmocom/core/talloc.h>

#include <string.h>

#define CHECK_RC(rc, str) \
		if (rc != 0) { \
			LOGP(DTLS, LOGL_ERROR, "%s with rc=%d\n", str, rc); \
			exit(1); \
		}

static int generate_dh_params(struct osmo_pcap_server *server)
{
	int rc;
	unsigned int bits =  gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,
							GNUTLS_SEC_PARAM_HIGH);

	LOGP(DTLS, LOGL_NOTICE, "Going to create DH params for %d bits\n", bits);

	/* allocate it */
	rc = gnutls_dh_params_init (&server->dh_params);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate DH params rc=%d\n", rc);
		server->dh_params_allocated = false;
		return rc;
	}

	/* generate and check */
	rc = gnutls_dh_params_generate2 (server->dh_params, bits);
	if (rc == GNUTLS_E_SUCCESS)
		server->dh_params_allocated = true;
	else {
		LOGP(DTLS, LOGL_ERROR, "Failed to generate DH params rc=%d\n", rc);
		server->dh_params_allocated = false;
		gnutls_dh_params_deinit(server->dh_params);
	}
	return rc;
}

void osmo_tls_dh_load(struct osmo_pcap_server *server)
{
	gnutls_datum_t data;
	int rc;

	/* free it before we start */
	if (server->dh_params_allocated) {
		gnutls_dh_params_deinit(server->dh_params);
		server->dh_params_allocated = false;
	}
	/* check if we have all data */
	if (!server->tls_dh_pkcs3) {
		LOGP(DTLS, LOGL_ERROR, "Can not generate missing pkcs3=%p\n",
			server->tls_dh_pkcs3);
		return;
	}
	/* initialize it again */
	rc = gnutls_dh_params_init (&server->dh_params);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate DH params rc=%d\n", rc);
		server->dh_params_allocated = false;
		return;
	}
	/* load prime and generator */
	rc = gnutls_load_file(server->tls_dh_pkcs3, &data);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to load DH params from=%s rc=%d\n",
			server->tls_dh_pkcs3, rc);
		gnutls_dh_params_deinit(server->dh_params);
		return;
	}
	rc = gnutls_dh_params_import_pkcs3(server->dh_params, &data, GNUTLS_X509_FMT_PEM);
	gnutls_free(data.data);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to import DH params rc=%d\n", rc);
		gnutls_dh_params_deinit(server->dh_params);
		return;
	}
	/* done */
	server->dh_params_allocated = true;
}

void osmo_tls_dh_generate(struct osmo_pcap_server *server)
{
	if (server->dh_params_allocated)
		gnutls_dh_params_deinit(server->dh_params);
	generate_dh_params(server);
}

static int cert_callback(gnutls_session_t tls_session,
				const gnutls_datum_t * req_ca_rdn, int nreqs,
				const gnutls_pk_algorithm_t * sign_algos,
				int sign_algos_length, gnutls_pcert_st ** pcert,
				unsigned int *pcert_length, gnutls_privkey_t * pkey)
{
	struct osmo_tls_session *sess = gnutls_session_get_ptr(tls_session);
	gnutls_certificate_type_t type;

	LOGP(DTLS, LOGL_DEBUG, "cert callback from server\n");
	type = gnutls_certificate_type_get(tls_session);
	if (type != GNUTLS_CRT_X509)
		return -1;

	*pcert_length = 1;
	*pcert = &sess->pcert;
	*pkey = sess->privk;
	return 0;
}

static void tls_log_func(int level, const char *str)
{
	LOGP(DTLS, LOGL_DEBUG, "GNUtls: |<%d>| %s", level, str);
}

static int verify_cert_cb(gnutls_session_t session)
{
	const char *hostname;
	unsigned int status;
	int ret;

	hostname = gnutls_session_get_ptr(session);
	ret = gnutls_certificate_verify_peers3(session,
				hostname, &status);
	if (ret != 0)
		return GNUTLS_E_CERTIFICATE_ERROR;
	if (status != 0)
		return GNUTLS_E_CERTIFICATE_ERROR;
	return 0;
}

static void release_keys(struct osmo_tls_session *sess)
{
	if (sess->pcert_alloc) {
		gnutls_pcert_deinit(&sess->pcert);
		sess->pcert_alloc = false;
	}
	if (sess->privk_alloc) {
		gnutls_privkey_deinit(sess->privk);
		sess->privk_alloc = false;
	}
}

void osmo_tls_init(void)
{
	int rc;
	rc = gnutls_global_init();
	CHECK_RC(rc, "init failed");
        gnutls_global_set_log_function(tls_log_func);
}

void osmo_tls_server_init(struct osmo_pcap_server *server)
{
	int rc;

	if (server->dh_params_allocated)
		return;
	rc = generate_dh_params(server);
	CHECK_RC(rc, "dh params failed");
}

static int need_handshake(struct osmo_tls_session *tls_session)
{
	int rc;

	rc = gnutls_handshake(tls_session->session);
	if (rc == 0) {
		/* handshake is done. start writing if we are allowed to */
		LOGP(DTLS, LOGL_NOTICE, "TLS handshake done.\n");
		if (!llist_empty(&tls_session->wqueue->msg_queue))
			tls_session->wqueue->bfd.when = BSC_FD_WRITE | BSC_FD_READ;
		else
			tls_session->wqueue->bfd.when = BSC_FD_READ;
		tls_session->need_handshake = false;
		release_keys(tls_session);
		if (tls_session->handshake_done)
			tls_session->handshake_done(tls_session);
	} else if (rc == GNUTLS_E_AGAIN || rc == GNUTLS_E_INTERRUPTED) {
		LOGP(DTLS, LOGL_DEBUG, "rc=%d will wait for writable again.\n", rc);
	} else if (gnutls_error_is_fatal(rc)) {
		/* it failed for good.. */
		LOGP(DTLS, LOGL_ERROR, "handshake failed rc=%d str=%s\n",
			rc, gnutls_strerror(rc));
		tls_session->wqueue->bfd.when = 0;
		tls_session->error(tls_session);
	}
	return 0;
}

static int tls_read(struct osmo_tls_session *sess)
{
	char buf[1024];
	int rc;

	if (sess->read)
		return sess->read(sess);

	memset(buf, 0, sizeof(buf));
	rc = gnutls_record_recv(sess->session, buf, sizeof(buf) - 1);
	return rc;
}

static int tls_write(struct osmo_tls_session *sess)
{
	int rc;
	sess->wqueue->bfd.when &= ~BSC_FD_WRITE;

	if (llist_empty(&sess->wqueue->msg_queue))
		return 0;

	if (sess->need_resend) {
		rc = gnutls_record_send(sess->session, NULL, 0);
	} else {
		struct msgb *msg;
		msg = (struct msgb *) sess->wqueue->msg_queue.next;
		rc = gnutls_record_send(sess->session, msg->data, msg->len);
	}

	if (rc > 0) {
		sess->wqueue->current_length -= 1;
		sess->need_resend = false;
		struct msgb *msg = msgb_dequeue(&sess->wqueue->msg_queue);
		msgb_free(msg);
	} else if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN) {
		sess->need_resend = true;
	} else if (gnutls_error_is_fatal(rc)) {
		return rc;
	}

	if (sess->need_resend || !llist_empty(&sess->wqueue->msg_queue))
		sess->wqueue->bfd.when |= BSC_FD_WRITE;
	return rc;
}

int osmo_tls_client_bfd_cb(struct osmo_fd *fd, unsigned what)
{
	struct osmo_tls_session *sess = fd->data;

	if (sess->need_handshake)
		return need_handshake(sess);

	if (what & BSC_FD_READ) {
		int rc = tls_read(sess);
		if (rc <= 0) {
			sess->error(sess);
			return rc;
		}
	}
	if (what & BSC_FD_WRITE) {
		int rc = tls_write(sess);
		if (rc < 0) {
			sess->error(sess);
			return rc;
		}
	}

	return 0;
}

static int load_keys(struct osmo_pcap_client_conn *conn)
{
	struct osmo_tls_session *sess = &conn->tls_session;
	gnutls_datum_t data;
	int rc;

	if (!conn->tls_client_cert || !conn->tls_client_key) {
		LOGP(DTLS, LOGL_DEBUG, "Skipping x509 client cert %p %p\n",
			conn->tls_client_cert, conn->tls_client_key);
		return 0;
	}


	rc = gnutls_load_file(conn->tls_client_cert, &data);
	if (rc < 0) {
		LOGP(DTLS, LOGL_ERROR, "Failed to load file=%s rc=%d\n",
			conn->tls_client_cert, rc);
		return -1;
	}
	rc = gnutls_pcert_import_x509_raw(&sess->pcert, &data, GNUTLS_X509_FMT_PEM, 0);
	gnutls_free(data.data);
	if (rc < 0) {
		LOGP(DTLS, LOGL_ERROR, "Failed to import file=%s rc=%d\n",
			conn->tls_client_cert, rc);
		return -1;
	}
	sess->pcert_alloc = true;

	/* copied to RAM.. nothing we can do about it */
	rc = gnutls_load_file(conn->tls_client_key, &data);
	if (rc < 0) {
		LOGP(DTLS, LOGL_ERROR, "Failed to load file=%s rc=%d\n",
			conn->tls_client_key, rc);
		return -1;
	}
	gnutls_privkey_init(&sess->privk);
	rc = gnutls_privkey_import_x509_raw(sess->privk, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
	gnutls_free(data.data);
	if (rc < 0) {
		LOGP(DTLS, LOGL_ERROR, "Failed to load file=%s rc=%d\n",
			conn->tls_client_key, rc);
		release_keys(sess);
		return -1;
	}
	sess->privk_alloc = true;
	return 0;
}

size_t osmo_tls_pending(struct osmo_tls_session *sess)
{
	return gnutls_record_check_pending(sess->session);
}

bool osmo_tls_init_server_session(struct osmo_pcap_conn *conn,
					struct osmo_pcap_server *server)
{
	struct osmo_tls_session *sess = &conn->tls_session;
	struct osmo_wqueue *wq = &conn->rem_wq;
	int rc;

	gnutls_global_set_log_level(server->tls_log_level);

	memset(sess, 0, sizeof(*sess));
	sess->in_use = sess->anon_alloc = sess->cert_alloc = false;
	rc = gnutls_init(&sess->session, GNUTLS_SERVER | GNUTLS_NONBLOCK);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "gnutls_init failed with rc=%d\n", rc);
		return false;
	}
	gnutls_session_set_ptr(sess->session, sess);
	sess->in_use = true;

	/* use default or string */
	if (server->tls_priority) {
		const char *err;
		rc = gnutls_priority_set_direct(sess->session, server->tls_priority, &err);
	} else {
		rc = gnutls_set_default_priority(sess->session);
	}

	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "def prio failed with rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}

	/* allow username/password operation */
	rc = gnutls_anon_allocate_server_credentials(&sess->anon_serv_cred);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate anon cred rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}
	sess->anon_serv_alloc = true;

	/* x509 certificate handling */
	rc = gnutls_certificate_allocate_credentials(&sess->cert_cred);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate x509 cred rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}
	sess->cert_alloc = true;

	/* set the credentials now */
	if (server->dh_params_allocated) {
		gnutls_anon_set_server_dh_params(sess->anon_serv_cred, server->dh_params);
		gnutls_certificate_set_dh_params(sess->cert_cred, server->dh_params);
	}

	if (server->tls_allow_anon)
		gnutls_credentials_set(sess->session, GNUTLS_CRD_ANON, sess->anon_serv_cred);
	if (server->tls_allow_x509)
		gnutls_credentials_set(sess->session, GNUTLS_CRD_CERTIFICATE, sess->cert_cred);

	if (server->tls_capath) {
		rc = gnutls_certificate_set_x509_trust_file(
				sess->cert_cred, server->tls_capath, GNUTLS_X509_FMT_PEM);
		if (rc != GNUTLS_E_SUCCESS) {
			LOGP(DTLS, LOGL_ERROR, "Failed to load capath from path=%s rc=%d\n",
				server->tls_capath, rc);
			osmo_tls_release(sess);
			return false;
		}
	}

	if (server->tls_crlfile) {
		rc = gnutls_certificate_set_x509_crl_file(
				sess->cert_cred, server->tls_crlfile, GNUTLS_X509_FMT_PEM);
		if (rc != GNUTLS_E_SUCCESS) {
			LOGP(DTLS, LOGL_ERROR, "Failed to load crlfile from path=%s rc=%d\n",
				server->tls_crlfile, rc);
			osmo_tls_release(sess);
			return false;
		}
	}

	if (server->tls_server_cert && server->tls_server_key) {
		rc = gnutls_certificate_set_x509_key_file(
				sess->cert_cred, server->tls_server_cert, server->tls_server_key,
				GNUTLS_X509_FMT_PEM);
		if (rc != GNUTLS_E_SUCCESS) {
			LOGP(DTLS, LOGL_ERROR, "Failed to load crt/key from path=%s/%s rc=%d\n",
				server->tls_server_cert, server->tls_server_key, rc);
			osmo_tls_release(sess);
			return false;
		}
	}

	#warning "TODO client certificates"

	gnutls_transport_set_int(sess->session, wq->bfd.fd);
	gnutls_handshake_set_timeout(sess->session,
					GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
	wq->bfd.cb = osmo_tls_client_bfd_cb;
	wq->bfd.data = sess;
	wq->bfd.when = BSC_FD_READ | BSC_FD_WRITE;
	sess->need_handshake = true;
	sess->wqueue = wq;
	return true;
}

bool osmo_tls_init_client_session(struct osmo_pcap_client_conn *client)
{
	struct osmo_tls_session *sess = &client->tls_session;
	struct osmo_wqueue *wq = &client->wqueue;
	unsigned int status;
	int rc;

	gnutls_global_set_log_level(client->tls_log_level);

	memset(sess, 0, sizeof(*sess));
	sess->in_use = sess->anon_alloc = sess->cert_alloc = false;
	rc = gnutls_init(&sess->session, GNUTLS_CLIENT | GNUTLS_NONBLOCK);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "gnutls_init failed with rc=%d\n", rc);
		return false;
	}
	gnutls_session_set_ptr(sess->session, sess);
	sess->in_use = true;

	/* use default or string */
	if (client->tls_priority) {
		const char *err;
		rc = gnutls_priority_set_direct(sess->session, client->tls_priority, &err);
	} else {
		rc = gnutls_set_default_priority(sess->session);
	}

	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "def prio failed with rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}

	/* allow username/password operation */
	rc = gnutls_anon_allocate_client_credentials(&sess->anon_cred);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate anon cred rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}
	sess->anon_alloc = true;

	/* x509 certificate handling */
        rc = gnutls_certificate_allocate_credentials(&sess->cert_cred);
	if (rc != GNUTLS_E_SUCCESS) {
		LOGP(DTLS, LOGL_ERROR, "Failed to allocate x509 cred rc=%d\n", rc);
		osmo_tls_release(sess);
		return false;
	}
	sess->cert_alloc = true;

	/* set the credentials now */
	gnutls_credentials_set(sess->session, GNUTLS_CRD_ANON, sess->anon_cred);
	gnutls_credentials_set(sess->session, GNUTLS_CRD_CERTIFICATE, sess->cert_cred);

	if (client->tls_capath) {
		rc = gnutls_certificate_set_x509_trust_file(
				sess->cert_cred, client->tls_capath, GNUTLS_X509_FMT_PEM);
		if (rc != GNUTLS_E_SUCCESS) {
			LOGP(DTLS, LOGL_ERROR, "Failed to load capath from path=%s rc=%d\n",
				client->tls_capath, rc);
			osmo_tls_release(sess);
			return false;
		}
	}

	if (load_keys(client) != 0) {
		osmo_tls_release(sess);
		return false;
	}

	gnutls_certificate_set_retrieve_function2(sess->cert_cred, cert_callback);

	/* set the hostname if we have one */
	if (client->tls_hostname)
		gnutls_server_name_set(sess->session, GNUTLS_NAME_DNS,
				client->tls_hostname, strlen(client->tls_hostname));

	/* do the verification */
	if (client->tls_verify) {
		gnutls_certificate_set_verify_function(sess->cert_cred, verify_cert_cb);
		gnutls_certificate_verify_peers3(sess->session, client->tls_hostname, &status);
	} else
		LOGP(DTLS, LOGL_NOTICE, "Not going to validate certs as configured\n");

	gnutls_transport_set_int(sess->session, wq->bfd.fd);
	gnutls_handshake_set_timeout(sess->session,
					GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
	wq->bfd.cb = osmo_tls_client_bfd_cb;
	wq->bfd.data = sess;
	wq->bfd.when = BSC_FD_READ | BSC_FD_WRITE;
	sess->need_handshake = true;
	sess->wqueue = wq;
	return true;
}

void osmo_tls_release(struct osmo_tls_session *session)
{
	if (!session->in_use)
		return;

	gnutls_deinit(session->session);

	release_keys(session);

	if (session->anon_alloc)
		gnutls_anon_free_client_credentials(session->anon_cred);
	if (session->anon_serv_alloc)
		gnutls_anon_free_server_credentials(session->anon_serv_cred);
	if (session->cert_alloc)
		gnutls_certificate_free_credentials(session->cert_cred);
	session->in_use = false;
}
