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 *
tls_handshake_req_init(struct handshake_req * req,const struct tls_handshake_args * args)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
tls_handshake_remote_peerids(struct tls_handshake_req * treq,struct genl_info * info)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 */
tls_handshake_done(struct handshake_req * req,unsigned int status,struct genl_info * info)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)
tls_handshake_private_keyring(struct tls_handshake_req * treq)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
tls_handshake_private_keyring(struct tls_handshake_req * treq)145 static int tls_handshake_private_keyring(struct tls_handshake_req *treq)
146 {
147 return 0;
148 }
149 #endif
150
tls_handshake_put_peer_identity(struct sk_buff * msg,struct tls_handshake_req * treq)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
tls_handshake_put_certificate(struct sk_buff * msg,struct tls_handshake_req * treq)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 */
tls_handshake_accept(struct handshake_req * req,struct genl_info * info,int fd)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 if (treq->th_keyring) {
234 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_KEYRING,
235 treq->th_keyring);
236 if (ret < 0)
237 goto out_cancel;
238 }
239
240 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE,
241 treq->th_auth_mode);
242 if (ret < 0)
243 goto out_cancel;
244 switch (treq->th_auth_mode) {
245 case HANDSHAKE_AUTH_PSK:
246 ret = tls_handshake_put_peer_identity(msg, treq);
247 if (ret < 0)
248 goto out_cancel;
249 break;
250 case HANDSHAKE_AUTH_X509:
251 ret = tls_handshake_put_certificate(msg, treq);
252 if (ret < 0)
253 goto out_cancel;
254 break;
255 }
256
257 genlmsg_end(msg, hdr);
258 return genlmsg_reply(msg, info);
259
260 out_cancel:
261 genlmsg_cancel(msg, hdr);
262 nlmsg_free(msg);
263 out:
264 return ret;
265 }
266
267 static const struct handshake_proto tls_handshake_proto = {
268 .hp_handler_class = HANDSHAKE_HANDLER_CLASS_TLSHD,
269 .hp_privsize = sizeof(struct tls_handshake_req),
270 .hp_flags = BIT(HANDSHAKE_F_PROTO_NOTIFY),
271
272 .hp_accept = tls_handshake_accept,
273 .hp_done = tls_handshake_done,
274 };
275
276 /**
277 * tls_client_hello_anon - request an anonymous TLS handshake on a socket
278 * @args: socket and handshake parameters for this request
279 * @flags: memory allocation control flags
280 *
281 * Return values:
282 * %0: Handshake request enqueue; ->done will be called when complete
283 * %-ESRCH: No user agent is available
284 * %-ENOMEM: Memory allocation failed
285 */
tls_client_hello_anon(const struct tls_handshake_args * args,gfp_t flags)286 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags)
287 {
288 struct tls_handshake_req *treq;
289 struct handshake_req *req;
290
291 req = handshake_req_alloc(&tls_handshake_proto, flags);
292 if (!req)
293 return -ENOMEM;
294 treq = tls_handshake_req_init(req, args);
295 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
296 treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH;
297
298 return handshake_req_submit(args->ta_sock, req, flags);
299 }
300 EXPORT_SYMBOL(tls_client_hello_anon);
301
302 /**
303 * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket
304 * @args: socket and handshake parameters for this request
305 * @flags: memory allocation control flags
306 *
307 * Return values:
308 * %0: Handshake request enqueue; ->done will be called when complete
309 * %-ESRCH: No user agent is available
310 * %-ENOMEM: Memory allocation failed
311 */
tls_client_hello_x509(const struct tls_handshake_args * args,gfp_t flags)312 int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
313 {
314 struct tls_handshake_req *treq;
315 struct handshake_req *req;
316
317 req = handshake_req_alloc(&tls_handshake_proto, flags);
318 if (!req)
319 return -ENOMEM;
320 treq = tls_handshake_req_init(req, args);
321 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
322 treq->th_auth_mode = HANDSHAKE_AUTH_X509;
323 treq->th_certificate = args->ta_my_cert;
324 treq->th_privkey = args->ta_my_privkey;
325
326 return handshake_req_submit(args->ta_sock, req, flags);
327 }
328 EXPORT_SYMBOL(tls_client_hello_x509);
329
330 /**
331 * tls_client_hello_psk - request a PSK-based TLS handshake on a socket
332 * @args: socket and handshake parameters for this request
333 * @flags: memory allocation control flags
334 *
335 * Return values:
336 * %0: Handshake request enqueue; ->done will be called when complete
337 * %-EINVAL: Wrong number of local peer IDs
338 * %-ESRCH: No user agent is available
339 * %-ENOMEM: Memory allocation failed
340 */
tls_client_hello_psk(const struct tls_handshake_args * args,gfp_t flags)341 int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
342 {
343 struct tls_handshake_req *treq;
344 struct handshake_req *req;
345 unsigned int i;
346
347 if (!args->ta_num_peerids ||
348 args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid))
349 return -EINVAL;
350
351 req = handshake_req_alloc(&tls_handshake_proto, flags);
352 if (!req)
353 return -ENOMEM;
354 treq = tls_handshake_req_init(req, args);
355 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO;
356 treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
357 treq->th_num_peerids = args->ta_num_peerids;
358 for (i = 0; i < args->ta_num_peerids; i++)
359 treq->th_peerid[i] = args->ta_my_peerids[i];
360
361 return handshake_req_submit(args->ta_sock, req, flags);
362 }
363 EXPORT_SYMBOL(tls_client_hello_psk);
364
365 /**
366 * tls_server_hello_x509 - request a server TLS handshake on a socket
367 * @args: socket and handshake parameters for this request
368 * @flags: memory allocation control flags
369 *
370 * Return values:
371 * %0: Handshake request enqueue; ->done will be called when complete
372 * %-ESRCH: No user agent is available
373 * %-ENOMEM: Memory allocation failed
374 */
tls_server_hello_x509(const struct tls_handshake_args * args,gfp_t flags)375 int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags)
376 {
377 struct tls_handshake_req *treq;
378 struct handshake_req *req;
379
380 req = handshake_req_alloc(&tls_handshake_proto, flags);
381 if (!req)
382 return -ENOMEM;
383 treq = tls_handshake_req_init(req, args);
384 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
385 treq->th_auth_mode = HANDSHAKE_AUTH_X509;
386 treq->th_certificate = args->ta_my_cert;
387 treq->th_privkey = args->ta_my_privkey;
388
389 return handshake_req_submit(args->ta_sock, req, flags);
390 }
391 EXPORT_SYMBOL(tls_server_hello_x509);
392
393 /**
394 * tls_server_hello_psk - request a server TLS handshake on a socket
395 * @args: socket and handshake parameters for this request
396 * @flags: memory allocation control flags
397 *
398 * Return values:
399 * %0: Handshake request enqueue; ->done will be called when complete
400 * %-ESRCH: No user agent is available
401 * %-ENOMEM: Memory allocation failed
402 */
tls_server_hello_psk(const struct tls_handshake_args * args,gfp_t flags)403 int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags)
404 {
405 struct tls_handshake_req *treq;
406 struct handshake_req *req;
407
408 req = handshake_req_alloc(&tls_handshake_proto, flags);
409 if (!req)
410 return -ENOMEM;
411 treq = tls_handshake_req_init(req, args);
412 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO;
413 treq->th_auth_mode = HANDSHAKE_AUTH_PSK;
414 treq->th_num_peerids = 1;
415 treq->th_peerid[0] = args->ta_my_peerids[0];
416
417 return handshake_req_submit(args->ta_sock, req, flags);
418 }
419 EXPORT_SYMBOL(tls_server_hello_psk);
420
421 /**
422 * tls_handshake_cancel - cancel a pending handshake
423 * @sk: socket on which there is an ongoing handshake
424 *
425 * Request cancellation races with request completion. To determine
426 * who won, callers examine the return value from this function.
427 *
428 * Return values:
429 * %true - Uncompleted handshake request was canceled
430 * %false - Handshake request already completed or not found
431 */
tls_handshake_cancel(struct sock * sk)432 bool tls_handshake_cancel(struct sock *sk)
433 {
434 return handshake_req_cancel(sk);
435 }
436 EXPORT_SYMBOL(tls_handshake_cancel);
437
438 /**
439 * tls_handshake_close - send a Closure alert
440 * @sock: an open socket
441 *
442 */
tls_handshake_close(struct socket * sock)443 void tls_handshake_close(struct socket *sock)
444 {
445 struct handshake_req *req;
446
447 req = handshake_req_hash_lookup(sock->sk);
448 if (!req)
449 return;
450 if (!test_and_clear_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags))
451 return;
452 tls_alert_send(sock, TLS_ALERT_LEVEL_WARNING,
453 TLS_ALERT_DESC_CLOSE_NOTIFY);
454 }
455 EXPORT_SYMBOL(tls_handshake_close);
456