// 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 <[email protected]> * * 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 { … }; static struct tls_handshake_req * tls_handshake_req_init(struct handshake_req *req, const struct tls_handshake_args *args) { … } static void tls_handshake_remote_peerids(struct tls_handshake_req *treq, struct genl_info *info) { … } /** * 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) { … } #if IS_ENABLED(CONFIG_KEYS) static int tls_handshake_private_keyring(struct tls_handshake_req *treq) { … } #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) { … } static int tls_handshake_put_certificate(struct sk_buff *msg, struct tls_handshake_req *treq) { … } /** * 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) { … } static const struct handshake_proto tls_handshake_proto = …; /** * 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) { … } EXPORT_SYMBOL(…); /** * 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) { … } EXPORT_SYMBOL(…); /** * 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) { … } EXPORT_SYMBOL(…); /** * 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) { … } EXPORT_SYMBOL(…); /** * 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) { … } EXPORT_SYMBOL(…); /** * 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) { … } EXPORT_SYMBOL(…); /** * tls_handshake_close - send a Closure alert * @sock: an open socket * */ void tls_handshake_close(struct socket *sock) { … } EXPORT_SYMBOL(…);