// SPDX-License-Identifier: GPL-2.0-only
/*
 * Establish a TLS session for a kernel socket consumer
 * using the tlshd user space handler.
 *
 * Author: Chuck Lever <chuck.lever@oracle.com>
 *
 * Copyright (c) 2021-2023, Oracle and/or its affiliates.
 */

#include <linux/types.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/key.h>

#include <net/sock.h>
#include <net/handshake.h>
#include <net/genetlink.h>
#include <net/tls_prot.h>

#include <uapi/linux/keyctl.h>
#include <uapi/linux/handshake.h>
#include "handshake.h"

struct tls_handshake_req {
	void			(*th_consumer_done)(void *data, int status,
						    key_serial_t peerid);
	void			*th_consumer_data;

	int			th_type;
	unsigned int		th_timeout_ms;
	int			th_auth_mode;
	const char		*th_peername;
	key_serial_t		th_keyring;
	key_serial_t		th_certificate;
	key_serial_t		th_privkey;

	unsigned int		th_num_peerids;
	key_serial_t		th_peerid[5];
};

static struct tls_handshake_req *
tls_handshake_req_init(struct handshake_req *req,
		       const struct tls_handshake_args *args)
{
	struct tls_handshake_req *treq = handshake_req_private(req);

	treq->th_timeout_ms = args->ta_timeout_ms;
	treq->th_consumer_done = args->ta_done;
	treq->th_consumer_data = args->ta_data;
	treq->th_peername = args->ta_peername;
	treq->th_keyring = args->ta_keyring;
	treq->th_num_peerids = 0;
	treq->th_certificate = TLS_NO_CERT;
	treq->th_privkey = TLS_NO_PRIVKEY;
	return treq;
}

static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
					 struct genl_info *info)
{
	struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN);
	int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN);
	struct nlattr *nla;
	unsigned int i;

	i = 0;
	nla_for_each_attr(nla, head, len, rem) {
		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
			i++;
	}
	if (!i)
		return;
	treq->th_num_peerids = min_t(unsigned int, i,
				     ARRAY_SIZE(treq->th_peerid));

	i = 0;
	nla_for_each_attr(nla, head, len, rem) {
		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
			treq->th_peerid[i++] = nla_get_u32(nla);
		if (i >= treq->th_num_peerids)
			break;
	}
}

/**
 * tls_handshake_done - callback to handle a CMD_DONE request
 * @req: socket on which the handshake was performed
 * @status: session status code
 * @info: full results of session establishment
 *
 */
static void tls_handshake_done(struct handshake_req *req,
			       unsigned int status, struct genl_info *info)
{
	struct tls_handshake_req *treq = handshake_req_private(req);

	treq->th_peerid[0] = TLS_NO_PEERID;
	if (info)
		tls_handshake_remote_peerids(treq, info);

	if (!status)
		set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);

	treq->th_consumer_done(treq->th_consumer_data, -status,
			       treq->th_peerid[0]);
}

#if IS_ENABLED(CONFIG_KEYS)
static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
{
	key_ref_t process_keyring_ref, keyring_ref;
	int ret;

	if (treq->th_keyring == TLS_NO_KEYRING)
		return 0;

	process_keyring_ref = lookup_user_key(KEY_SPEC_PROCESS_KEYRING,
					      KEY_LOOKUP_CREATE,
					      KEY_NEED_WRITE);
	if (IS_ERR(process_keyring_ref)) {
		ret = PTR_ERR(process_keyring_ref);
		goto out;
	}

	keyring_ref = lookup_user_key(treq->th_keyring, KEY_LOOKUP_CREATE,
				      KEY_NEED_LINK);
	if (IS_ERR(keyring_ref)) {
		ret = PTR_ERR(keyring_ref);
		goto out_put_key;
	}

	ret = key_link(key_ref_to_ptr(process_keyring_ref),
		       key_ref_to_ptr(keyring_ref));

	key_ref_put(keyring_ref);
out_put_key:
	key_ref_put(process_keyring_ref);
out:
	return ret;
}
#else
static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
{
	return 0;
}
#endif

static int tls_handshake_put_peer_identity(struct sk_buff *msg,
					   struct tls_handshake_req *treq)
{
	unsigned int i;

	for (i = 0; i < treq->th_num_peerids; i++)
		if (nla_put_u32(msg, HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
				treq->th_peerid[i]) < 0)
			return -EMSGSIZE;
	return 0;
}

static int tls_handshake_put_certificate(struct sk_buff *msg,
					 struct tls_handshake_req *treq)
{
	struct nlattr *entry_attr;

	if (treq->th_certificate == TLS_NO_CERT &&
	    treq->th_privkey == TLS_NO_PRIVKEY)
		return 0;

	entry_attr = nla_nest_start(msg, HANDSHAKE_A_ACCEPT_CERTIFICATE);
	if (!entry_attr)
		return -EMSGSIZE;

	if (nla_put_s32(msg, HANDSHAKE_A_X509_CERT,
			treq->th_certificate) ||
	    nla_put_s32(msg, HANDSHAKE_A_X509_PRIVKEY,
			treq->th_privkey)) {
		nla_nest_cancel(msg, entry_attr);
		return -EMSGSIZE;
	}

	nla_nest_end(msg, entry_attr);
	return 0;
}

/**
 * tls_handshake_accept - callback to construct a CMD_ACCEPT response
 * @req: handshake parameters to return
 * @info: generic netlink message context
 * @fd: file descriptor to be returned
 *
 * Returns zero on success, or a negative errno on failure.
 */
static int tls_handshake_accept(struct handshake_req *req,
				struct genl_info *info, int fd)
{
	struct tls_handshake_req *treq = handshake_req_private(req);
	struct nlmsghdr *hdr;
	struct sk_buff *msg;
	int ret;

	ret = tls_handshake_private_keyring(treq);
	if (ret < 0)
		goto out;

	ret = -ENOMEM;
	msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		goto out;
	hdr = handshake_genl_put(msg, info);
	if (!hdr)
		goto out_cancel;

	ret = -EMSGSIZE;
	ret = nla_put_s32(msg, HANDSHAKE_A_ACCEPT_SOCKFD, fd);
	if (ret < 0)
		goto out_cancel;
	ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, treq->th_type);
	if (ret < 0)
		goto out_cancel;
	if (treq->th_peername) {
		ret = nla_put_string(msg, HANDSHAKE_A_ACCEPT_PEERNAME,
				     treq->th_peername);
		if (ret < 0)
			goto out_cancel;
	}
	if (treq->th_timeout_ms) {
		ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_TIMEOUT, treq->th_timeout_ms);
		if (ret < 0)
			goto out_cancel;
	}

	ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE,
			  treq->th_auth_mode);
	if (ret < 0)
		goto out_cancel;
	switch (treq->th_auth_mode) {
	case HANDSHAKE_AUTH_PSK:
		ret = tls_handshake_put_peer_identity(msg, treq);
		if (ret < 0)
			goto out_cancel;
		break;
	case HANDSHAKE_AUTH_X509:
		ret = tls_handshake_put_certificate(msg, treq);
		if (ret < 0)
			goto out_cancel;
		break;
	}

	genlmsg_end(msg, hdr);
	return genlmsg_reply(msg, info);

out_cancel:
	genlmsg_cancel(msg, hdr);
out:
	return ret;
}

static const struct handshake_proto tls_handshake_proto = {
	.hp_handler_class	= HANDSHAKE_HANDLER_CLASS_TLSHD,
	.hp_privsize		= sizeof(struct tls_handshake_req),
	.hp_flags		= BIT(HANDSHAKE_F_PROTO_NOTIFY),

	.hp_accept		= tls_handshake_accept,
	.hp_done		= tls_handshake_done,
};

/**
 * tls_client_hello_anon - request an anonymous TLS handshake on a socket
 * @args: socket and handshake parameters for this request
 * @flags: memory allocation control flags
 *
 * Return values:
 *   %0: Handshake request enqueue; ->done will be called when complete
 *   %-ESRCH: No user agent is available
 *   %-ENOMEM: Memory allocation failed
 */
int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags)
{
	struct tls_handshake_req *treq;
	struct handshake_req *req;

	req = handshake_req_alloc(&tls_handshake_proto, flags);
	if (!req)
		return -ENOMEM;
	treq = tls_handshake_req_init(req, args);
	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
	treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH;

	return handshake_req_submit(args->ta_sock, req, flags);
}
EXPORT_SYMBOL(tls_client_hello_anon);

/**
 * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket
 * @args: socket and handshake parameters for this request
 * @flags: memory allocation control flags
 *
 * Return values:
 *   %0: Handshake request enqueue; ->done will be called when complete
 *   %-ESRCH: No user agent is available
 *   %-ENOMEM: Memory allocation failed
 */
int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
{
	struct tls_handshake_req *treq;
	struct handshake_req *req;

	req = handshake_req_alloc(&tls_handshake_proto, flags);
	if (!req)
		return -ENOMEM;
	treq = tls_handshake_req_init(req, args);
	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
	treq->th_auth_mode = HANDSHAKE_AUTH_X509;
	treq->th_certificate = args->ta_my_cert;
	treq->th_privkey = args->ta_my_privkey;

	return handshake_req_submit(args->ta_sock, req, flags);
}
EXPORT_SYMBOL(tls_client_hello_x509);

/**
 * tls_client_hello_psk - request a PSK-based TLS handshake on a socket
 * @args: socket and handshake parameters for this request
 * @flags: memory allocation control flags
 *
 * Return values:
 *   %0: Handshake request enqueue; ->done will be called when complete
 *   %-EINVAL: Wrong number of local peer IDs
 *   %-ESRCH: No user agent is available
 *   %-ENOMEM: Memory allocation failed
 */
int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
{
	struct tls_handshake_req *treq;
	struct handshake_req *req;
	unsigned int i;

	if (!args->ta_num_peerids ||
	    args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid))
		return -EINVAL;

	req = handshake_req_alloc(&tls_handshake_proto, flags);
	if (!req)
		return -ENOMEM;
	treq = tls_handshake_req_init(req, args);
	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
	treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
	treq->th_num_peerids = args->ta_num_peerids;
	for (i = 0; i < args->ta_num_peerids; i++)
		treq->th_peerid[i] = args->ta_my_peerids[i];

	return handshake_req_submit(args->ta_sock, req, flags);
}
EXPORT_SYMBOL(tls_client_hello_psk);

/**
 * tls_server_hello_x509 - request a server TLS handshake on a socket
 * @args: socket and handshake parameters for this request
 * @flags: memory allocation control flags
 *
 * Return values:
 *   %0: Handshake request enqueue; ->done will be called when complete
 *   %-ESRCH: No user agent is available
 *   %-ENOMEM: Memory allocation failed
 */
int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
{
	struct tls_handshake_req *treq;
	struct handshake_req *req;

	req = handshake_req_alloc(&tls_handshake_proto, flags);
	if (!req)
		return -ENOMEM;
	treq = tls_handshake_req_init(req, args);
	treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
	treq->th_auth_mode = HANDSHAKE_AUTH_X509;
	treq->th_certificate = args->ta_my_cert;
	treq->th_privkey = args->ta_my_privkey;

	return handshake_req_submit(args->ta_sock, req, flags);
}
EXPORT_SYMBOL(tls_server_hello_x509);

/**
 * tls_server_hello_psk - request a server TLS handshake on a socket
 * @args: socket and handshake parameters for this request
 * @flags: memory allocation control flags
 *
 * Return values:
 *   %0: Handshake request enqueue; ->done will be called when complete
 *   %-ESRCH: No user agent is available
 *   %-ENOMEM: Memory allocation failed
 */
int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
{
	struct tls_handshake_req *treq;
	struct handshake_req *req;

	req = handshake_req_alloc(&tls_handshake_proto, flags);
	if (!req)
		return -ENOMEM;
	treq = tls_handshake_req_init(req, args);
	treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
	treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
	treq->th_num_peerids = 1;
	treq->th_peerid[0] = args->ta_my_peerids[0];

	return handshake_req_submit(args->ta_sock, req, flags);
}
EXPORT_SYMBOL(tls_server_hello_psk);

/**
 * tls_handshake_cancel - cancel a pending handshake
 * @sk: socket on which there is an ongoing handshake
 *
 * Request cancellation races with request completion. To determine
 * who won, callers examine the return value from this function.
 *
 * Return values:
 *   %true - Uncompleted handshake request was canceled
 *   %false - Handshake request already completed or not found
 */
bool tls_handshake_cancel(struct sock *sk)
{
	return handshake_req_cancel(sk);
}
EXPORT_SYMBOL(tls_handshake_cancel);

/**
 * tls_handshake_close - send a Closure alert
 * @sock: an open socket
 *
 */
void tls_handshake_close(struct socket *sock)
{
	struct handshake_req *req;

	req = handshake_req_hash_lookup(sock->sk);
	if (!req)
		return;
	if (!test_and_clear_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags))
		return;
	tls_alert_send(sock, TLS_ALERT_LEVEL_WARNING,
		       TLS_ALERT_DESC_CLOSE_NOTIFY);
}
EXPORT_SYMBOL(tls_handshake_close);
