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