xref: /linux/net/handshake/tlshd.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Establish a TLS session for a kernel socket consumer
4  * using the tlshd user space handler.
5  *
6  * Author: Chuck Lever <chuck.lever@oracle.com>
7  *
8  * Copyright (c) 2021-2023, Oracle and/or its affiliates.
9  */
10 
11 #include <linux/types.h>
12 #include <linux/socket.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/key.h>
17 
18 #include <net/sock.h>
19 #include <net/handshake.h>
20 #include <net/genetlink.h>
21 #include <net/tls_prot.h>
22 
23 #include <uapi/linux/keyctl.h>
24 #include <uapi/linux/handshake.h>
25 #include "handshake.h"
26 
27 struct tls_handshake_req {
28 	void			(*th_consumer_done)(void *data, int status,
29 						    key_serial_t peerid);
30 	void			*th_consumer_data;
31 
32 	int			th_type;
33 	unsigned int		th_timeout_ms;
34 	int			th_auth_mode;
35 	const char		*th_peername;
36 	key_serial_t		th_keyring;
37 	key_serial_t		th_certificate;
38 	key_serial_t		th_privkey;
39 
40 	unsigned int		th_num_peerids;
41 	key_serial_t		th_peerid[5];
42 };
43 
44 static struct tls_handshake_req *
45 tls_handshake_req_init(struct handshake_req *req,
46 		       const struct tls_handshake_args *args)
47 {
48 	struct tls_handshake_req *treq = handshake_req_private(req);
49 
50 	treq->th_timeout_ms = args->ta_timeout_ms;
51 	treq->th_consumer_done = args->ta_done;
52 	treq->th_consumer_data = args->ta_data;
53 	treq->th_peername = args->ta_peername;
54 	treq->th_keyring = args->ta_keyring;
55 	treq->th_num_peerids = 0;
56 	treq->th_certificate = TLS_NO_CERT;
57 	treq->th_privkey = TLS_NO_PRIVKEY;
58 	return treq;
59 }
60 
61 static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
62 					 struct genl_info *info)
63 {
64 	struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN);
65 	int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN);
66 	struct nlattr *nla;
67 	unsigned int i;
68 
69 	i = 0;
70 	nla_for_each_attr(nla, head, len, rem) {
71 		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
72 			i++;
73 	}
74 	if (!i)
75 		return;
76 	treq->th_num_peerids = min_t(unsigned int, i,
77 				     ARRAY_SIZE(treq->th_peerid));
78 
79 	i = 0;
80 	nla_for_each_attr(nla, head, len, rem) {
81 		if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH)
82 			treq->th_peerid[i++] = nla_get_u32(nla);
83 		if (i >= treq->th_num_peerids)
84 			break;
85 	}
86 }
87 
88 /**
89  * tls_handshake_done - callback to handle a CMD_DONE request
90  * @req: socket on which the handshake was performed
91  * @status: session status code
92  * @info: full results of session establishment
93  *
94  */
95 static void tls_handshake_done(struct handshake_req *req,
96 			       unsigned int status, struct genl_info *info)
97 {
98 	struct tls_handshake_req *treq = handshake_req_private(req);
99 
100 	treq->th_peerid[0] = TLS_NO_PEERID;
101 	if (info)
102 		tls_handshake_remote_peerids(treq, info);
103 
104 	if (!status)
105 		set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);
106 
107 	treq->th_consumer_done(treq->th_consumer_data, -status,
108 			       treq->th_peerid[0]);
109 }
110 
111 #if IS_ENABLED(CONFIG_KEYS)
112 static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
113 {
114 	key_ref_t process_keyring_ref, keyring_ref;
115 	int ret;
116 
117 	if (treq->th_keyring == TLS_NO_KEYRING)
118 		return 0;
119 
120 	process_keyring_ref = lookup_user_key(KEY_SPEC_PROCESS_KEYRING,
121 					      KEY_LOOKUP_CREATE,
122 					      KEY_NEED_WRITE);
123 	if (IS_ERR(process_keyring_ref)) {
124 		ret = PTR_ERR(process_keyring_ref);
125 		goto out;
126 	}
127 
128 	keyring_ref = lookup_user_key(treq->th_keyring, KEY_LOOKUP_CREATE,
129 				      KEY_NEED_LINK);
130 	if (IS_ERR(keyring_ref)) {
131 		ret = PTR_ERR(keyring_ref);
132 		goto out_put_key;
133 	}
134 
135 	ret = key_link(key_ref_to_ptr(process_keyring_ref),
136 		       key_ref_to_ptr(keyring_ref));
137 
138 	key_ref_put(keyring_ref);
139 out_put_key:
140 	key_ref_put(process_keyring_ref);
141 out:
142 	return ret;
143 }
144 #else
145 static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
146 {
147 	return 0;
148 }
149 #endif
150 
151 static int tls_handshake_put_peer_identity(struct sk_buff *msg,
152 					   struct tls_handshake_req *treq)
153 {
154 	unsigned int i;
155 
156 	for (i = 0; i < treq->th_num_peerids; i++)
157 		if (nla_put_u32(msg, HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
158 				treq->th_peerid[i]) < 0)
159 			return -EMSGSIZE;
160 	return 0;
161 }
162 
163 static int tls_handshake_put_certificate(struct sk_buff *msg,
164 					 struct tls_handshake_req *treq)
165 {
166 	struct nlattr *entry_attr;
167 
168 	if (treq->th_certificate == TLS_NO_CERT &&
169 	    treq->th_privkey == TLS_NO_PRIVKEY)
170 		return 0;
171 
172 	entry_attr = nla_nest_start(msg, HANDSHAKE_A_ACCEPT_CERTIFICATE);
173 	if (!entry_attr)
174 		return -EMSGSIZE;
175 
176 	if (nla_put_s32(msg, HANDSHAKE_A_X509_CERT,
177 			treq->th_certificate) ||
178 	    nla_put_s32(msg, HANDSHAKE_A_X509_PRIVKEY,
179 			treq->th_privkey)) {
180 		nla_nest_cancel(msg, entry_attr);
181 		return -EMSGSIZE;
182 	}
183 
184 	nla_nest_end(msg, entry_attr);
185 	return 0;
186 }
187 
188 /**
189  * tls_handshake_accept - callback to construct a CMD_ACCEPT response
190  * @req: handshake parameters to return
191  * @info: generic netlink message context
192  * @fd: file descriptor to be returned
193  *
194  * Returns zero on success, or a negative errno on failure.
195  */
196 static int tls_handshake_accept(struct handshake_req *req,
197 				struct genl_info *info, int fd)
198 {
199 	struct tls_handshake_req *treq = handshake_req_private(req);
200 	struct nlmsghdr *hdr;
201 	struct sk_buff *msg;
202 	int ret;
203 
204 	ret = tls_handshake_private_keyring(treq);
205 	if (ret < 0)
206 		goto out;
207 
208 	ret = -ENOMEM;
209 	msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
210 	if (!msg)
211 		goto out;
212 	hdr = handshake_genl_put(msg, info);
213 	if (!hdr)
214 		goto out_cancel;
215 
216 	ret = nla_put_s32(msg, HANDSHAKE_A_ACCEPT_SOCKFD, fd);
217 	if (ret < 0)
218 		goto out_cancel;
219 	ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, treq->th_type);
220 	if (ret < 0)
221 		goto out_cancel;
222 	if (treq->th_peername) {
223 		ret = nla_put_string(msg, HANDSHAKE_A_ACCEPT_PEERNAME,
224 				     treq->th_peername);
225 		if (ret < 0)
226 			goto out_cancel;
227 	}
228 	if (treq->th_timeout_ms) {
229 		ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_TIMEOUT, treq->th_timeout_ms);
230 		if (ret < 0)
231 			goto out_cancel;
232 	}
233 
234 	ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE,
235 			  treq->th_auth_mode);
236 	if (ret < 0)
237 		goto out_cancel;
238 	switch (treq->th_auth_mode) {
239 	case HANDSHAKE_AUTH_PSK:
240 		ret = tls_handshake_put_peer_identity(msg, treq);
241 		if (ret < 0)
242 			goto out_cancel;
243 		break;
244 	case HANDSHAKE_AUTH_X509:
245 		ret = tls_handshake_put_certificate(msg, treq);
246 		if (ret < 0)
247 			goto out_cancel;
248 		break;
249 	}
250 
251 	genlmsg_end(msg, hdr);
252 	return genlmsg_reply(msg, info);
253 
254 out_cancel:
255 	genlmsg_cancel(msg, hdr);
256 out:
257 	return ret;
258 }
259 
260 static const struct handshake_proto tls_handshake_proto = {
261 	.hp_handler_class	= HANDSHAKE_HANDLER_CLASS_TLSHD,
262 	.hp_privsize		= sizeof(struct tls_handshake_req),
263 	.hp_flags		= BIT(HANDSHAKE_F_PROTO_NOTIFY),
264 
265 	.hp_accept		= tls_handshake_accept,
266 	.hp_done		= tls_handshake_done,
267 };
268 
269 /**
270  * tls_client_hello_anon - request an anonymous TLS handshake on a socket
271  * @args: socket and handshake parameters for this request
272  * @flags: memory allocation control flags
273  *
274  * Return values:
275  *   %0: Handshake request enqueue; ->done will be called when complete
276  *   %-ESRCH: No user agent is available
277  *   %-ENOMEM: Memory allocation failed
278  */
279 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags)
280 {
281 	struct tls_handshake_req *treq;
282 	struct handshake_req *req;
283 
284 	req = handshake_req_alloc(&tls_handshake_proto, flags);
285 	if (!req)
286 		return -ENOMEM;
287 	treq = tls_handshake_req_init(req, args);
288 	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
289 	treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH;
290 
291 	return handshake_req_submit(args->ta_sock, req, flags);
292 }
293 EXPORT_SYMBOL(tls_client_hello_anon);
294 
295 /**
296  * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket
297  * @args: socket and handshake parameters for this request
298  * @flags: memory allocation control flags
299  *
300  * Return values:
301  *   %0: Handshake request enqueue; ->done will be called when complete
302  *   %-ESRCH: No user agent is available
303  *   %-ENOMEM: Memory allocation failed
304  */
305 int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
306 {
307 	struct tls_handshake_req *treq;
308 	struct handshake_req *req;
309 
310 	req = handshake_req_alloc(&tls_handshake_proto, flags);
311 	if (!req)
312 		return -ENOMEM;
313 	treq = tls_handshake_req_init(req, args);
314 	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
315 	treq->th_auth_mode = HANDSHAKE_AUTH_X509;
316 	treq->th_certificate = args->ta_my_cert;
317 	treq->th_privkey = args->ta_my_privkey;
318 
319 	return handshake_req_submit(args->ta_sock, req, flags);
320 }
321 EXPORT_SYMBOL(tls_client_hello_x509);
322 
323 /**
324  * tls_client_hello_psk - request a PSK-based TLS handshake on a socket
325  * @args: socket and handshake parameters for this request
326  * @flags: memory allocation control flags
327  *
328  * Return values:
329  *   %0: Handshake request enqueue; ->done will be called when complete
330  *   %-EINVAL: Wrong number of local peer IDs
331  *   %-ESRCH: No user agent is available
332  *   %-ENOMEM: Memory allocation failed
333  */
334 int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
335 {
336 	struct tls_handshake_req *treq;
337 	struct handshake_req *req;
338 	unsigned int i;
339 
340 	if (!args->ta_num_peerids ||
341 	    args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid))
342 		return -EINVAL;
343 
344 	req = handshake_req_alloc(&tls_handshake_proto, flags);
345 	if (!req)
346 		return -ENOMEM;
347 	treq = tls_handshake_req_init(req, args);
348 	treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
349 	treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
350 	treq->th_num_peerids = args->ta_num_peerids;
351 	for (i = 0; i < args->ta_num_peerids; i++)
352 		treq->th_peerid[i] = args->ta_my_peerids[i];
353 
354 	return handshake_req_submit(args->ta_sock, req, flags);
355 }
356 EXPORT_SYMBOL(tls_client_hello_psk);
357 
358 /**
359  * tls_server_hello_x509 - request a server TLS handshake on a socket
360  * @args: socket and handshake parameters for this request
361  * @flags: memory allocation control flags
362  *
363  * Return values:
364  *   %0: Handshake request enqueue; ->done will be called when complete
365  *   %-ESRCH: No user agent is available
366  *   %-ENOMEM: Memory allocation failed
367  */
368 int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
369 {
370 	struct tls_handshake_req *treq;
371 	struct handshake_req *req;
372 
373 	req = handshake_req_alloc(&tls_handshake_proto, flags);
374 	if (!req)
375 		return -ENOMEM;
376 	treq = tls_handshake_req_init(req, args);
377 	treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
378 	treq->th_auth_mode = HANDSHAKE_AUTH_X509;
379 	treq->th_certificate = args->ta_my_cert;
380 	treq->th_privkey = args->ta_my_privkey;
381 
382 	return handshake_req_submit(args->ta_sock, req, flags);
383 }
384 EXPORT_SYMBOL(tls_server_hello_x509);
385 
386 /**
387  * tls_server_hello_psk - request a server TLS handshake on a socket
388  * @args: socket and handshake parameters for this request
389  * @flags: memory allocation control flags
390  *
391  * Return values:
392  *   %0: Handshake request enqueue; ->done will be called when complete
393  *   %-ESRCH: No user agent is available
394  *   %-ENOMEM: Memory allocation failed
395  */
396 int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
397 {
398 	struct tls_handshake_req *treq;
399 	struct handshake_req *req;
400 
401 	req = handshake_req_alloc(&tls_handshake_proto, flags);
402 	if (!req)
403 		return -ENOMEM;
404 	treq = tls_handshake_req_init(req, args);
405 	treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
406 	treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
407 	treq->th_num_peerids = 1;
408 	treq->th_peerid[0] = args->ta_my_peerids[0];
409 
410 	return handshake_req_submit(args->ta_sock, req, flags);
411 }
412 EXPORT_SYMBOL(tls_server_hello_psk);
413 
414 /**
415  * tls_handshake_cancel - cancel a pending handshake
416  * @sk: socket on which there is an ongoing handshake
417  *
418  * Request cancellation races with request completion. To determine
419  * who won, callers examine the return value from this function.
420  *
421  * Return values:
422  *   %true - Uncompleted handshake request was canceled
423  *   %false - Handshake request already completed or not found
424  */
425 bool tls_handshake_cancel(struct sock *sk)
426 {
427 	return handshake_req_cancel(sk);
428 }
429 EXPORT_SYMBOL(tls_handshake_cancel);
430 
431 /**
432  * tls_handshake_close - send a Closure alert
433  * @sock: an open socket
434  *
435  */
436 void tls_handshake_close(struct socket *sock)
437 {
438 	struct handshake_req *req;
439 
440 	req = handshake_req_hash_lookup(sock->sk);
441 	if (!req)
442 		return;
443 	if (!test_and_clear_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags))
444 		return;
445 	tls_alert_send(sock, TLS_ALERT_LEVEL_WARNING,
446 		       TLS_ALERT_DESC_CLOSE_NOTIFY);
447 }
448 EXPORT_SYMBOL(tls_handshake_close);
449