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