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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.