/*
 * SSL/TLS interface functions for NSS
 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <nspr/prtypes.h>
#include <nspr/plarenas.h>
#include <nspr/plhash.h>
#include <nspr/prio.h>
#include <nspr/prclist.h>
#include <nspr/prlock.h>
#include <nspr/prinit.h>
#include <nspr/prerror.h>
#include <nspr/prmem.h>
#include <nss/nss.h>
#include <nss/nssilckt.h>
#include <nss/ssl.h>
#include <nss/pk11func.h>
#include <nss/secerr.h>

#include "common.h"
#include "tls.h"

static int tls_nss_ref_count = 0;

static PRDescIdentity nss_layer_id;


struct tls_connection {
	PRFileDesc *fd;

	int established;
	int verify_peer;
	u8 *push_buf, *pull_buf, *pull_buf_offset;
	size_t push_buf_len, pull_buf_len;
};


static PRStatus nss_io_close(PRFileDesc *fd)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O close");
	return PR_SUCCESS;
}


static PRInt32 nss_io_read(PRFileDesc *fd, void *buf, PRInt32 amount)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O read(%d)", amount);
	return PR_FAILURE;
}


static PRInt32 nss_io_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O write(%d)", amount);
	return PR_FAILURE;
}


static PRInt32 nss_io_writev(PRFileDesc *fd, const PRIOVec *iov,
			     PRInt32 iov_size, PRIntervalTime timeout)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O writev(%d)", iov_size);
	return PR_FAILURE;
}


static PRInt32 nss_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
			   PRIntn flags, PRIntervalTime timeout)
{
	struct tls_connection *conn = (struct tls_connection *) fd->secret;
	u8 *end;

	wpa_printf(MSG_DEBUG, "NSS: I/O recv(%d)", amount);

	if (conn->pull_buf == NULL) {
		wpa_printf(MSG_DEBUG, "NSS: No data available to be read yet");
		return PR_FAILURE;
	}

	end = conn->pull_buf + conn->pull_buf_len;
	if (end - conn->pull_buf_offset < amount)
		amount = end - conn->pull_buf_offset;
	os_memcpy(buf, conn->pull_buf_offset, amount);
	conn->pull_buf_offset += amount;
	if (conn->pull_buf_offset == end) {
		wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
		os_free(conn->pull_buf);
		conn->pull_buf = conn->pull_buf_offset = NULL;
		conn->pull_buf_len = 0;
	} else {
		wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
			   __func__,
			   (unsigned long) (end - conn->pull_buf_offset));
	}
	return amount;
}


static PRInt32 nss_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
			   PRIntn flags, PRIntervalTime timeout)
{
	struct tls_connection *conn = (struct tls_connection *) fd->secret;
	u8 *nbuf;

	wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
	wpa_hexdump(MSG_MSGDUMP, "NSS: I/O send data", buf, amount);

	nbuf = os_realloc(conn->push_buf, conn->push_buf_len + amount);
	if (nbuf == NULL) {
		wpa_printf(MSG_ERROR, "NSS: Failed to allocate memory for the "
			   "data to be sent");
		return PR_FAILURE;
	}
	os_memcpy(nbuf + conn->push_buf_len, buf, amount);
	conn->push_buf = nbuf;
	conn->push_buf_len += amount;

	return amount;
}


static PRInt32 nss_io_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
			       PRIntn flags, PRNetAddr *addr,
			       PRIntervalTime timeout)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
	return PR_FAILURE;
}


static PRInt32 nss_io_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
			     PRIntn flags, const PRNetAddr *addr,
			     PRIntervalTime timeout)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
	return PR_FAILURE;
}


static PRStatus nss_io_getpeername(PRFileDesc *fd, PRNetAddr *addr)
{
	wpa_printf(MSG_DEBUG, "NSS: I/O getpeername");

	/*
	 * It Looks like NSS only supports IPv4 and IPv6 TCP sockets. Provide a
	 * fake IPv4 address to work around this even though we are not really
	 * using TCP.
	 */
	os_memset(addr, 0, sizeof(*addr));
	addr->inet.family = PR_AF_INET;

	return PR_SUCCESS;
}


static PRStatus nss_io_getsocketoption(PRFileDesc *fd,
				       PRSocketOptionData *data)
{
	switch (data->option) {
	case PR_SockOpt_Nonblocking:
		wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(Nonblocking)");
		data->value.non_blocking = PR_TRUE;
		return PR_SUCCESS;
	default:
		wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(%d)",
			   data->option);
		return PR_FAILURE;
	}
}


static const PRIOMethods nss_io = {
	PR_DESC_LAYERED,
	nss_io_close,
	nss_io_read,
	nss_io_write,
	NULL /* available */,
	NULL /* available64 */,
	NULL /* fsync */,
	NULL /* fseek */,
	NULL /* fseek64 */,
	NULL /* fileinfo */,
	NULL /* fileinfo64 */,
	nss_io_writev,
	NULL /* connect */,
	NULL /* accept */,
	NULL /* bind */,
	NULL /* listen */,
	NULL /* shutdown */,
	nss_io_recv,
	nss_io_send,
	nss_io_recvfrom,
	nss_io_sendto,
	NULL /* poll */,
	NULL /* acceptread */,
	NULL /* transmitfile */,
	NULL /* getsockname */,
	nss_io_getpeername,
	NULL /* reserved_fn_6 */,
	NULL /* reserved_fn_5 */,
	nss_io_getsocketoption,
	NULL /* setsocketoption */,
	NULL /* sendfile */,
	NULL /* connectcontinue */,
	NULL /* reserved_fn_3 */,
	NULL /* reserved_fn_2 */,
	NULL /* reserved_fn_1 */,
	NULL /* reserved_fn_0 */
};


static char * nss_password_cb(PK11SlotInfo *slot, PRBool retry, void *arg)
{
	wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
	return NULL;
}


void * tls_init(const struct tls_config *conf)
{
	char *dir;

	tls_nss_ref_count++;
	if (tls_nss_ref_count > 1)
		return (void *) 1;

	PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

	nss_layer_id = PR_GetUniqueIdentity("wpa_supplicant");

	PK11_SetPasswordFunc(nss_password_cb);

	dir = getenv("SSL_DIR");
	if (dir) {
		if (NSS_Init(dir) != SECSuccess) {
			wpa_printf(MSG_ERROR, "NSS: NSS_Init(cert_dir=%s) "
				   "failed", dir);
			return NULL;
		}
	} else {
		if (NSS_NoDB_Init(NULL) != SECSuccess) {
			wpa_printf(MSG_ERROR, "NSS: NSS_NoDB_Init(NULL) "
				   "failed");
			return NULL;
		}
	}

	if (SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, PR_FALSE) !=
	    SECSuccess ||
	    SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess ||
	    SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess ||
	    SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE) != SECSuccess) {
		wpa_printf(MSG_ERROR, "NSS: SSL_OptionSetDefault failed");
		return NULL;
	}

	if (NSS_SetDomesticPolicy() != SECSuccess) {
		wpa_printf(MSG_ERROR, "NSS: NSS_SetDomesticPolicy() failed");
		return NULL;
	}

	return (void *) 1;
}

void tls_deinit(void *ssl_ctx)
{
	tls_nss_ref_count--;
	if (tls_nss_ref_count == 0) {
		if (NSS_Shutdown() != SECSuccess)
			wpa_printf(MSG_ERROR, "NSS: NSS_Shutdown() failed");
	}
}


int tls_get_errors(void *tls_ctx)
{
	return 0;
}


static SECStatus nss_bad_cert_cb(void *arg, PRFileDesc *fd)
{
	struct tls_connection *conn = arg;
	SECStatus res = SECSuccess;
	PRErrorCode err;
	CERTCertificate *cert;
	char *subject, *issuer;

	err = PR_GetError();
	if (IS_SEC_ERROR(err))
		wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (sec err "
			   "%d)", err - SEC_ERROR_BASE);
	else
		wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (err %d)",
			   err);
	cert = SSL_PeerCertificate(fd);
	subject = CERT_NameToAscii(&cert->subject);
	issuer = CERT_NameToAscii(&cert->issuer);
	wpa_printf(MSG_DEBUG, "NSS: Peer certificate subject='%s' issuer='%s'",
		   subject, issuer);
	CERT_DestroyCertificate(cert);
	PR_Free(subject);
	PR_Free(issuer);
	if (conn->verify_peer)
		res = SECFailure;

	return res;
}


static void nss_handshake_cb(PRFileDesc *fd, void *client_data)
{
	struct tls_connection *conn = client_data;
	wpa_printf(MSG_DEBUG, "NSS: Handshake completed");
	conn->established = 1;
}


struct tls_connection * tls_connection_init(void *tls_ctx)
{
	struct tls_connection *conn;

	conn = os_zalloc(sizeof(*conn));
	if (conn == NULL)
		return NULL;

	conn->fd = PR_CreateIOLayerStub(nss_layer_id, &nss_io);
	if (conn->fd == NULL) {
		os_free(conn);
		return NULL;
	}
	conn->fd->secret = (void *) conn;

	conn->fd = SSL_ImportFD(NULL, conn->fd);
	if (conn->fd == NULL) {
		os_free(conn);
		return NULL;
	}

	if (SSL_OptionSet(conn->fd, SSL_SECURITY, PR_TRUE) != SECSuccess ||
	    SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) !=
	    SECSuccess ||
	    SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) !=
	    SECSuccess ||
	    SSL_OptionSet(conn->fd, SSL_ENABLE_TLS, PR_TRUE) != SECSuccess ||
	    SSL_BadCertHook(conn->fd, nss_bad_cert_cb, conn) != SECSuccess ||
	    SSL_HandshakeCallback(conn->fd, nss_handshake_cb, conn) !=
	    SECSuccess) {
		wpa_printf(MSG_ERROR, "NSS: Failed to set options");
		PR_Close(conn->fd);
		os_free(conn);
		return NULL;
	}

	SSL_ResetHandshake(conn->fd, PR_FALSE);

	return conn;
}


void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
{
	PR_Close(conn->fd);
	os_free(conn->push_buf);
	os_free(conn->pull_buf);
	os_free(conn);
}


int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
{
	return conn->established;
}


int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
{
	return -1;
}


int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
			      const struct tls_connection_params *params)
{
	wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
	return 0;
}


int tls_global_set_params(void *tls_ctx,
			  const struct tls_connection_params *params)
{
	return -1;
}


int tls_global_set_verify(void *tls_ctx, int check_crl)
{
	return -1;
}


int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
			      int verify_peer)
{
	conn->verify_peer = verify_peer;
	return 0;
}


int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
			    struct tls_keys *keys)
{
	/* NSS does not export master secret or client/server random. */
	return -1;
}


int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
		       const char *label, int server_random_first,
		       u8 *out, size_t out_len)
{
	if (conn == NULL || server_random_first) {
		wpa_printf(MSG_INFO, "NSS: Unsupported PRF request "
			   "(server_random_first=%d)",
			   server_random_first);
		return -1;
	}

	if (SSL_ExportKeyingMaterial(conn->fd, label, NULL, 0, out, out_len) !=
	    SECSuccess) {
		wpa_printf(MSG_INFO, "NSS: Failed to use TLS extractor "
			   "(label='%s' out_len=%d", label, (int) out_len);
		return -1;
	}

	return 0;
}


struct wpabuf * tls_connection_handshake(void *tls_ctx,
					 struct tls_connection *conn,
					 const struct wpabuf *in_data,
					 struct wpabuf **appl_data)
{
	struct wpabuf *out_data;

	wpa_printf(MSG_DEBUG, "NSS: handshake: in_len=%u",
		   in_data ? (unsigned int) wpabuf_len(in_data) : 0);

	if (appl_data)
		*appl_data = NULL;

	if (in_data && wpabuf_len(in_data) > 0) {
		if (conn->pull_buf) {
			wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
				   "pull_buf", __func__,
				   (unsigned long) conn->pull_buf_len);
			os_free(conn->pull_buf);
		}
		conn->pull_buf = os_malloc(wpabuf_len(in_data));
		if (conn->pull_buf == NULL)
			return NULL;
		os_memcpy(conn->pull_buf, wpabuf_head(in_data),
			  wpabuf_len(in_data));
		conn->pull_buf_offset = conn->pull_buf;
		conn->pull_buf_len = wpabuf_len(in_data);
	}

	SSL_ForceHandshake(conn->fd);

	if (conn->established && conn->push_buf == NULL) {
		/* Need to return something to get final TLS ACK. */
		conn->push_buf = os_malloc(1);
	}

	if (conn->push_buf == NULL)
		return NULL;
	out_data = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
	if (out_data == NULL)
		os_free(conn->push_buf);
	conn->push_buf = NULL;
	conn->push_buf_len = 0;
	return out_data;
}


struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
						struct tls_connection *conn,
						const struct wpabuf *in_data,
						struct wpabuf **appl_data)
{
	return NULL;
}


struct wpabuf * tls_connection_encrypt(void *tls_ctx,
				       struct tls_connection *conn,
				       const struct wpabuf *in_data)
{
	PRInt32 res;
	struct wpabuf *buf;

	wpa_printf(MSG_DEBUG, "NSS: encrypt %d bytes",
		   (int) wpabuf_len(in_data));
	res = PR_Send(conn->fd, wpabuf_head(in_data), wpabuf_len(in_data), 0,
		      0);
	if (res < 0) {
		wpa_printf(MSG_ERROR, "NSS: Encryption failed");
		return NULL;
	}
	if (conn->push_buf == NULL)
		return NULL;
	buf = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
	if (buf == NULL)
		os_free(conn->push_buf);
	conn->push_buf = NULL;
	conn->push_buf_len = 0;
	return buf;
}


struct wpabuf * tls_connection_decrypt(void *tls_ctx,
				       struct tls_connection *conn,
				       const struct wpabuf *in_data)
{
	PRInt32 res;
	struct wpabuf *out;

	wpa_printf(MSG_DEBUG, "NSS: decrypt %d bytes",
		   (int) wpabuf_len(in_data));
	if (conn->pull_buf) {
		wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
			   "pull_buf", __func__,
			   (unsigned long) conn->pull_buf_len);
		os_free(conn->pull_buf);
	}
	conn->pull_buf = os_malloc(wpabuf_len(in_data));
	if (conn->pull_buf == NULL)
		return NULL;
	os_memcpy(conn->pull_buf, wpabuf_head(in_data), wpabuf_len(in_data));
	conn->pull_buf_offset = conn->pull_buf;
	conn->pull_buf_len = wpabuf_len(in_data);

	/*
	 * Even though we try to disable TLS compression, it is possible that
	 * this cannot be done with all TLS libraries. Add extra buffer space
	 * to handle the possibility of the decrypted data being longer than
	 * input data.
	 */
	out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
	if (out == NULL)
		return NULL;

	res = PR_Recv(conn->fd, wpabuf_mhead(out), wpabuf_size(out), 0, 0);
	wpa_printf(MSG_DEBUG, "NSS: PR_Recv: %d", res);
	if (res < 0) {
		wpabuf_free(out);
		return NULL;
	}
	wpabuf_put(out, res);

	return out;
}


int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
{
	return 0;
}


int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
				   u8 *ciphers)
{
	return -1;
}


int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
		   char *buf, size_t buflen)
{
	return -1;
}


int tls_connection_enable_workaround(void *tls_ctx,
				     struct tls_connection *conn)
{
	return -1;
}


int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
				    int ext_type, const u8 *data,
				    size_t data_len)
{
	return -1;
}


int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
{
	return 0;
}


int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
{
	return 0;
}


int tls_connection_get_write_alerts(void *tls_ctx,
				    struct tls_connection *conn)
{
	return 0;
}


int tls_connection_get_keyblock_size(void *tls_ctx,
				     struct tls_connection *conn)
{
	return -1;
}


unsigned int tls_capabilities(void *tls_ctx)
{
	return 0;
}


int tls_connection_set_session_ticket_cb(void *tls_ctx,
					 struct tls_connection *conn,
					 tls_session_ticket_cb cb,
					 void *ctx)
{
	return -1;
}
