1 // SPDX-License-Identifier: GPL-2.0-only
3 * Establish a TLS session for a kernel socket consumer
4 * using the tlshd user space handler.
6 * Author: Chuck Lever <chuck.lever@oracle.com>
8 * Copyright (c) 2021-2023, Oracle and/or its affiliates.
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>
19 #include <net/handshake.h>
20 #include <net/genetlink.h>
21 #include <net/tls_prot.h>
23 #include <uapi/linux/keyctl.h>
24 #include <uapi/linux/handshake.h>
25 #include "handshake.h"
27 struct tls_handshake_req
{
28 void (*th_consumer_done
)(void *data
, int status
,
30 void *th_consumer_data
;
33 unsigned int th_timeout_ms
;
35 const char *th_peername
;
36 key_serial_t th_keyring
;
37 key_serial_t th_certificate
;
38 key_serial_t th_privkey
;
40 unsigned int th_num_peerids
;
41 key_serial_t th_peerid
[5];
44 static struct tls_handshake_req
*
45 tls_handshake_req_init(struct handshake_req
*req
,
46 const struct tls_handshake_args
*args
)
48 struct tls_handshake_req
*treq
= handshake_req_private(req
);
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
;
61 static void tls_handshake_remote_peerids(struct tls_handshake_req
*treq
,
62 struct genl_info
*info
)
64 struct nlattr
*head
= nlmsg_attrdata(info
->nlhdr
, GENL_HDRLEN
);
65 int rem
, len
= nlmsg_attrlen(info
->nlhdr
, GENL_HDRLEN
);
70 nla_for_each_attr(nla
, head
, len
, rem
) {
71 if (nla_type(nla
) == HANDSHAKE_A_DONE_REMOTE_AUTH
)
76 treq
->th_num_peerids
= min_t(unsigned int, i
,
77 ARRAY_SIZE(treq
->th_peerid
));
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
)
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
95 static void tls_handshake_done(struct handshake_req
*req
,
96 unsigned int status
, struct genl_info
*info
)
98 struct tls_handshake_req
*treq
= handshake_req_private(req
);
100 treq
->th_peerid
[0] = TLS_NO_PEERID
;
102 tls_handshake_remote_peerids(treq
, info
);
105 set_bit(HANDSHAKE_F_REQ_SESSION
, &req
->hr_flags
);
107 treq
->th_consumer_done(treq
->th_consumer_data
, -status
,
111 #if IS_ENABLED(CONFIG_KEYS)
112 static int tls_handshake_private_keyring(struct tls_handshake_req
*treq
)
114 key_ref_t process_keyring_ref
, keyring_ref
;
117 if (treq
->th_keyring
== TLS_NO_KEYRING
)
120 process_keyring_ref
= lookup_user_key(KEY_SPEC_PROCESS_KEYRING
,
123 if (IS_ERR(process_keyring_ref
)) {
124 ret
= PTR_ERR(process_keyring_ref
);
128 keyring_ref
= lookup_user_key(treq
->th_keyring
, KEY_LOOKUP_CREATE
,
130 if (IS_ERR(keyring_ref
)) {
131 ret
= PTR_ERR(keyring_ref
);
135 ret
= key_link(key_ref_to_ptr(process_keyring_ref
),
136 key_ref_to_ptr(keyring_ref
));
138 key_ref_put(keyring_ref
);
140 key_ref_put(process_keyring_ref
);
145 static int tls_handshake_private_keyring(struct tls_handshake_req
*treq
)
151 static int tls_handshake_put_peer_identity(struct sk_buff
*msg
,
152 struct tls_handshake_req
*treq
)
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)
163 static int tls_handshake_put_certificate(struct sk_buff
*msg
,
164 struct tls_handshake_req
*treq
)
166 struct nlattr
*entry_attr
;
168 if (treq
->th_certificate
== TLS_NO_CERT
&&
169 treq
->th_privkey
== TLS_NO_PRIVKEY
)
172 entry_attr
= nla_nest_start(msg
, HANDSHAKE_A_ACCEPT_CERTIFICATE
);
176 if (nla_put_s32(msg
, HANDSHAKE_A_X509_CERT
,
177 treq
->th_certificate
) ||
178 nla_put_s32(msg
, HANDSHAKE_A_X509_PRIVKEY
,
180 nla_nest_cancel(msg
, entry_attr
);
184 nla_nest_end(msg
, entry_attr
);
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
194 * Returns zero on success, or a negative errno on failure.
196 static int tls_handshake_accept(struct handshake_req
*req
,
197 struct genl_info
*info
, int fd
)
199 struct tls_handshake_req
*treq
= handshake_req_private(req
);
200 struct nlmsghdr
*hdr
;
204 ret
= tls_handshake_private_keyring(treq
);
209 msg
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
212 hdr
= handshake_genl_put(msg
, info
);
216 ret
= nla_put_s32(msg
, HANDSHAKE_A_ACCEPT_SOCKFD
, fd
);
219 ret
= nla_put_u32(msg
, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE
, treq
->th_type
);
222 if (treq
->th_peername
) {
223 ret
= nla_put_string(msg
, HANDSHAKE_A_ACCEPT_PEERNAME
,
228 if (treq
->th_timeout_ms
) {
229 ret
= nla_put_u32(msg
, HANDSHAKE_A_ACCEPT_TIMEOUT
, treq
->th_timeout_ms
);
234 ret
= nla_put_u32(msg
, HANDSHAKE_A_ACCEPT_AUTH_MODE
,
238 switch (treq
->th_auth_mode
) {
239 case HANDSHAKE_AUTH_PSK
:
240 ret
= tls_handshake_put_peer_identity(msg
, treq
);
244 case HANDSHAKE_AUTH_X509
:
245 ret
= tls_handshake_put_certificate(msg
, treq
);
251 genlmsg_end(msg
, hdr
);
252 return genlmsg_reply(msg
, info
);
255 genlmsg_cancel(msg
, hdr
);
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
),
265 .hp_accept
= tls_handshake_accept
,
266 .hp_done
= tls_handshake_done
,
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
275 * %0: Handshake request enqueue; ->done will be called when complete
276 * %-ESRCH: No user agent is available
277 * %-ENOMEM: Memory allocation failed
279 int tls_client_hello_anon(const struct tls_handshake_args
*args
, gfp_t flags
)
281 struct tls_handshake_req
*treq
;
282 struct handshake_req
*req
;
284 req
= handshake_req_alloc(&tls_handshake_proto
, flags
);
287 treq
= tls_handshake_req_init(req
, args
);
288 treq
->th_type
= HANDSHAKE_MSG_TYPE_CLIENTHELLO
;
289 treq
->th_auth_mode
= HANDSHAKE_AUTH_UNAUTH
;
291 return handshake_req_submit(args
->ta_sock
, req
, flags
);
293 EXPORT_SYMBOL(tls_client_hello_anon
);
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
301 * %0: Handshake request enqueue; ->done will be called when complete
302 * %-ESRCH: No user agent is available
303 * %-ENOMEM: Memory allocation failed
305 int tls_client_hello_x509(const struct tls_handshake_args
*args
, gfp_t flags
)
307 struct tls_handshake_req
*treq
;
308 struct handshake_req
*req
;
310 req
= handshake_req_alloc(&tls_handshake_proto
, flags
);
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
;
319 return handshake_req_submit(args
->ta_sock
, req
, flags
);
321 EXPORT_SYMBOL(tls_client_hello_x509
);
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
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
334 int tls_client_hello_psk(const struct tls_handshake_args
*args
, gfp_t flags
)
336 struct tls_handshake_req
*treq
;
337 struct handshake_req
*req
;
340 if (!args
->ta_num_peerids
||
341 args
->ta_num_peerids
> ARRAY_SIZE(treq
->th_peerid
))
344 req
= handshake_req_alloc(&tls_handshake_proto
, flags
);
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
];
354 return handshake_req_submit(args
->ta_sock
, req
, flags
);
356 EXPORT_SYMBOL(tls_client_hello_psk
);
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
364 * %0: Handshake request enqueue; ->done will be called when complete
365 * %-ESRCH: No user agent is available
366 * %-ENOMEM: Memory allocation failed
368 int tls_server_hello_x509(const struct tls_handshake_args
*args
, gfp_t flags
)
370 struct tls_handshake_req
*treq
;
371 struct handshake_req
*req
;
373 req
= handshake_req_alloc(&tls_handshake_proto
, flags
);
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
;
382 return handshake_req_submit(args
->ta_sock
, req
, flags
);
384 EXPORT_SYMBOL(tls_server_hello_x509
);
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
392 * %0: Handshake request enqueue; ->done will be called when complete
393 * %-ESRCH: No user agent is available
394 * %-ENOMEM: Memory allocation failed
396 int tls_server_hello_psk(const struct tls_handshake_args
*args
, gfp_t flags
)
398 struct tls_handshake_req
*treq
;
399 struct handshake_req
*req
;
401 req
= handshake_req_alloc(&tls_handshake_proto
, flags
);
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];
410 return handshake_req_submit(args
->ta_sock
, req
, flags
);
412 EXPORT_SYMBOL(tls_server_hello_psk
);
415 * tls_handshake_cancel - cancel a pending handshake
416 * @sk: socket on which there is an ongoing handshake
418 * Request cancellation races with request completion. To determine
419 * who won, callers examine the return value from this function.
422 * %true - Uncompleted handshake request was canceled
423 * %false - Handshake request already completed or not found
425 bool tls_handshake_cancel(struct sock
*sk
)
427 return handshake_req_cancel(sk
);
429 EXPORT_SYMBOL(tls_handshake_cancel
);
432 * tls_handshake_close - send a Closure alert
433 * @sock: an open socket
436 void tls_handshake_close(struct socket
*sock
)
438 struct handshake_req
*req
;
440 req
= handshake_req_hash_lookup(sock
->sk
);
443 if (!test_and_clear_bit(HANDSHAKE_F_REQ_SESSION
, &req
->hr_flags
))
445 tls_alert_send(sock
, TLS_ALERT_LEVEL_WARNING
,
446 TLS_ALERT_DESC_CLOSE_NOTIFY
);
448 EXPORT_SYMBOL(tls_handshake_close
);