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 22 #include <uapi/linux/keyctl.h> 23 #include <uapi/linux/handshake.h> 24 #include "handshake.h" 25 26 struct tls_handshake_req { 27 void (*th_consumer_done)(void *data, int status, 28 key_serial_t peerid); 29 void *th_consumer_data; 30 31 int th_type; 32 unsigned int th_timeout_ms; 33 int th_auth_mode; 34 const char *th_peername; 35 key_serial_t th_keyring; 36 key_serial_t th_certificate; 37 key_serial_t th_privkey; 38 39 unsigned int th_num_peerids; 40 key_serial_t th_peerid[5]; 41 }; 42 43 static struct tls_handshake_req * 44 tls_handshake_req_init(struct handshake_req *req, 45 const struct tls_handshake_args *args) 46 { 47 struct tls_handshake_req *treq = handshake_req_private(req); 48 49 treq->th_timeout_ms = args->ta_timeout_ms; 50 treq->th_consumer_done = args->ta_done; 51 treq->th_consumer_data = args->ta_data; 52 treq->th_peername = args->ta_peername; 53 treq->th_keyring = args->ta_keyring; 54 treq->th_num_peerids = 0; 55 treq->th_certificate = TLS_NO_CERT; 56 treq->th_privkey = TLS_NO_PRIVKEY; 57 return treq; 58 } 59 60 static void tls_handshake_remote_peerids(struct tls_handshake_req *treq, 61 struct genl_info *info) 62 { 63 struct nlattr *head = nlmsg_attrdata(info->nlhdr, GENL_HDRLEN); 64 int rem, len = nlmsg_attrlen(info->nlhdr, GENL_HDRLEN); 65 struct nlattr *nla; 66 unsigned int i; 67 68 i = 0; 69 nla_for_each_attr(nla, head, len, rem) { 70 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH) 71 i++; 72 } 73 if (!i) 74 return; 75 treq->th_num_peerids = min_t(unsigned int, i, 76 ARRAY_SIZE(treq->th_peerid)); 77 78 i = 0; 79 nla_for_each_attr(nla, head, len, rem) { 80 if (nla_type(nla) == HANDSHAKE_A_DONE_REMOTE_AUTH) 81 treq->th_peerid[i++] = nla_get_u32(nla); 82 if (i >= treq->th_num_peerids) 83 break; 84 } 85 } 86 87 /** 88 * tls_handshake_done - callback to handle a CMD_DONE request 89 * @req: socket on which the handshake was performed 90 * @status: session status code 91 * @info: full results of session establishment 92 * 93 */ 94 static void tls_handshake_done(struct handshake_req *req, 95 unsigned int status, struct genl_info *info) 96 { 97 struct tls_handshake_req *treq = handshake_req_private(req); 98 99 treq->th_peerid[0] = TLS_NO_PEERID; 100 if (info) 101 tls_handshake_remote_peerids(treq, info); 102 103 treq->th_consumer_done(treq->th_consumer_data, -status, 104 treq->th_peerid[0]); 105 } 106 107 #if IS_ENABLED(CONFIG_KEYS) 108 static int tls_handshake_private_keyring(struct tls_handshake_req *treq) 109 { 110 key_ref_t process_keyring_ref, keyring_ref; 111 int ret; 112 113 if (treq->th_keyring == TLS_NO_KEYRING) 114 return 0; 115 116 process_keyring_ref = lookup_user_key(KEY_SPEC_PROCESS_KEYRING, 117 KEY_LOOKUP_CREATE, 118 KEY_NEED_WRITE); 119 if (IS_ERR(process_keyring_ref)) { 120 ret = PTR_ERR(process_keyring_ref); 121 goto out; 122 } 123 124 keyring_ref = lookup_user_key(treq->th_keyring, KEY_LOOKUP_CREATE, 125 KEY_NEED_LINK); 126 if (IS_ERR(keyring_ref)) { 127 ret = PTR_ERR(keyring_ref); 128 goto out_put_key; 129 } 130 131 ret = key_link(key_ref_to_ptr(process_keyring_ref), 132 key_ref_to_ptr(keyring_ref)); 133 134 key_ref_put(keyring_ref); 135 out_put_key: 136 key_ref_put(process_keyring_ref); 137 out: 138 return ret; 139 } 140 #else 141 static int tls_handshake_private_keyring(struct tls_handshake_req *treq) 142 { 143 return 0; 144 } 145 #endif 146 147 static int tls_handshake_put_peer_identity(struct sk_buff *msg, 148 struct tls_handshake_req *treq) 149 { 150 unsigned int i; 151 152 for (i = 0; i < treq->th_num_peerids; i++) 153 if (nla_put_u32(msg, HANDSHAKE_A_ACCEPT_PEER_IDENTITY, 154 treq->th_peerid[i]) < 0) 155 return -EMSGSIZE; 156 return 0; 157 } 158 159 static int tls_handshake_put_certificate(struct sk_buff *msg, 160 struct tls_handshake_req *treq) 161 { 162 struct nlattr *entry_attr; 163 164 if (treq->th_certificate == TLS_NO_CERT && 165 treq->th_privkey == TLS_NO_PRIVKEY) 166 return 0; 167 168 entry_attr = nla_nest_start(msg, HANDSHAKE_A_ACCEPT_CERTIFICATE); 169 if (!entry_attr) 170 return -EMSGSIZE; 171 172 if (nla_put_u32(msg, HANDSHAKE_A_X509_CERT, 173 treq->th_certificate) || 174 nla_put_u32(msg, HANDSHAKE_A_X509_PRIVKEY, 175 treq->th_privkey)) { 176 nla_nest_cancel(msg, entry_attr); 177 return -EMSGSIZE; 178 } 179 180 nla_nest_end(msg, entry_attr); 181 return 0; 182 } 183 184 /** 185 * tls_handshake_accept - callback to construct a CMD_ACCEPT response 186 * @req: handshake parameters to return 187 * @info: generic netlink message context 188 * @fd: file descriptor to be returned 189 * 190 * Returns zero on success, or a negative errno on failure. 191 */ 192 static int tls_handshake_accept(struct handshake_req *req, 193 struct genl_info *info, int fd) 194 { 195 struct tls_handshake_req *treq = handshake_req_private(req); 196 struct nlmsghdr *hdr; 197 struct sk_buff *msg; 198 int ret; 199 200 ret = tls_handshake_private_keyring(treq); 201 if (ret < 0) 202 goto out; 203 204 ret = -ENOMEM; 205 msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 206 if (!msg) 207 goto out; 208 hdr = handshake_genl_put(msg, info); 209 if (!hdr) 210 goto out_cancel; 211 212 ret = -EMSGSIZE; 213 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_SOCKFD, fd); 214 if (ret < 0) 215 goto out_cancel; 216 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, treq->th_type); 217 if (ret < 0) 218 goto out_cancel; 219 if (treq->th_peername) { 220 ret = nla_put_string(msg, HANDSHAKE_A_ACCEPT_PEERNAME, 221 treq->th_peername); 222 if (ret < 0) 223 goto out_cancel; 224 } 225 if (treq->th_timeout_ms) { 226 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_TIMEOUT, treq->th_timeout_ms); 227 if (ret < 0) 228 goto out_cancel; 229 } 230 231 ret = nla_put_u32(msg, HANDSHAKE_A_ACCEPT_AUTH_MODE, 232 treq->th_auth_mode); 233 if (ret < 0) 234 goto out_cancel; 235 switch (treq->th_auth_mode) { 236 case HANDSHAKE_AUTH_PSK: 237 ret = tls_handshake_put_peer_identity(msg, treq); 238 if (ret < 0) 239 goto out_cancel; 240 break; 241 case HANDSHAKE_AUTH_X509: 242 ret = tls_handshake_put_certificate(msg, treq); 243 if (ret < 0) 244 goto out_cancel; 245 break; 246 } 247 248 genlmsg_end(msg, hdr); 249 return genlmsg_reply(msg, info); 250 251 out_cancel: 252 genlmsg_cancel(msg, hdr); 253 out: 254 return ret; 255 } 256 257 static const struct handshake_proto tls_handshake_proto = { 258 .hp_handler_class = HANDSHAKE_HANDLER_CLASS_TLSHD, 259 .hp_privsize = sizeof(struct tls_handshake_req), 260 .hp_flags = BIT(HANDSHAKE_F_PROTO_NOTIFY), 261 262 .hp_accept = tls_handshake_accept, 263 .hp_done = tls_handshake_done, 264 }; 265 266 /** 267 * tls_client_hello_anon - request an anonymous TLS handshake on a socket 268 * @args: socket and handshake parameters for this request 269 * @flags: memory allocation control flags 270 * 271 * Return values: 272 * %0: Handshake request enqueue; ->done will be called when complete 273 * %-ESRCH: No user agent is available 274 * %-ENOMEM: Memory allocation failed 275 */ 276 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t flags) 277 { 278 struct tls_handshake_req *treq; 279 struct handshake_req *req; 280 281 req = handshake_req_alloc(&tls_handshake_proto, flags); 282 if (!req) 283 return -ENOMEM; 284 treq = tls_handshake_req_init(req, args); 285 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 286 treq->th_auth_mode = HANDSHAKE_AUTH_UNAUTH; 287 288 return handshake_req_submit(args->ta_sock, req, flags); 289 } 290 EXPORT_SYMBOL(tls_client_hello_anon); 291 292 /** 293 * tls_client_hello_x509 - request an x.509-based TLS handshake on a socket 294 * @args: socket and handshake parameters for this request 295 * @flags: memory allocation control flags 296 * 297 * Return values: 298 * %0: Handshake request enqueue; ->done will be called when complete 299 * %-ESRCH: No user agent is available 300 * %-ENOMEM: Memory allocation failed 301 */ 302 int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t flags) 303 { 304 struct tls_handshake_req *treq; 305 struct handshake_req *req; 306 307 req = handshake_req_alloc(&tls_handshake_proto, flags); 308 if (!req) 309 return -ENOMEM; 310 treq = tls_handshake_req_init(req, args); 311 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 312 treq->th_auth_mode = HANDSHAKE_AUTH_X509; 313 treq->th_certificate = args->ta_my_cert; 314 treq->th_privkey = args->ta_my_privkey; 315 316 return handshake_req_submit(args->ta_sock, req, flags); 317 } 318 EXPORT_SYMBOL(tls_client_hello_x509); 319 320 /** 321 * tls_client_hello_psk - request a PSK-based TLS handshake on a socket 322 * @args: socket and handshake parameters for this request 323 * @flags: memory allocation control flags 324 * 325 * Return values: 326 * %0: Handshake request enqueue; ->done will be called when complete 327 * %-EINVAL: Wrong number of local peer IDs 328 * %-ESRCH: No user agent is available 329 * %-ENOMEM: Memory allocation failed 330 */ 331 int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flags) 332 { 333 struct tls_handshake_req *treq; 334 struct handshake_req *req; 335 unsigned int i; 336 337 if (!args->ta_num_peerids || 338 args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid)) 339 return -EINVAL; 340 341 req = handshake_req_alloc(&tls_handshake_proto, flags); 342 if (!req) 343 return -ENOMEM; 344 treq = tls_handshake_req_init(req, args); 345 treq->th_type = HANDSHAKE_MSG_TYPE_CLIENTHELLO; 346 treq->th_auth_mode = HANDSHAKE_AUTH_PSK; 347 treq->th_num_peerids = args->ta_num_peerids; 348 for (i = 0; i < args->ta_num_peerids; i++) 349 treq->th_peerid[i] = args->ta_my_peerids[i]; 350 351 return handshake_req_submit(args->ta_sock, req, flags); 352 } 353 EXPORT_SYMBOL(tls_client_hello_psk); 354 355 /** 356 * tls_server_hello_x509 - request a server TLS handshake on a socket 357 * @args: socket and handshake parameters for this request 358 * @flags: memory allocation control flags 359 * 360 * Return values: 361 * %0: Handshake request enqueue; ->done will be called when complete 362 * %-ESRCH: No user agent is available 363 * %-ENOMEM: Memory allocation failed 364 */ 365 int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags) 366 { 367 struct tls_handshake_req *treq; 368 struct handshake_req *req; 369 370 req = handshake_req_alloc(&tls_handshake_proto, flags); 371 if (!req) 372 return -ENOMEM; 373 treq = tls_handshake_req_init(req, args); 374 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO; 375 treq->th_auth_mode = HANDSHAKE_AUTH_X509; 376 treq->th_certificate = args->ta_my_cert; 377 treq->th_privkey = args->ta_my_privkey; 378 379 return handshake_req_submit(args->ta_sock, req, flags); 380 } 381 EXPORT_SYMBOL(tls_server_hello_x509); 382 383 /** 384 * tls_server_hello_psk - request a server TLS handshake on a socket 385 * @args: socket and handshake parameters for this request 386 * @flags: memory allocation control flags 387 * 388 * Return values: 389 * %0: Handshake request enqueue; ->done will be called when complete 390 * %-ESRCH: No user agent is available 391 * %-ENOMEM: Memory allocation failed 392 */ 393 int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags) 394 { 395 struct tls_handshake_req *treq; 396 struct handshake_req *req; 397 398 req = handshake_req_alloc(&tls_handshake_proto, flags); 399 if (!req) 400 return -ENOMEM; 401 treq = tls_handshake_req_init(req, args); 402 treq->th_type = HANDSHAKE_MSG_TYPE_SERVERHELLO; 403 treq->th_auth_mode = HANDSHAKE_AUTH_PSK; 404 treq->th_num_peerids = 1; 405 treq->th_peerid[0] = args->ta_my_peerids[0]; 406 407 return handshake_req_submit(args->ta_sock, req, flags); 408 } 409 EXPORT_SYMBOL(tls_server_hello_psk); 410 411 /** 412 * tls_handshake_cancel - cancel a pending handshake 413 * @sk: socket on which there is an ongoing handshake 414 * 415 * Request cancellation races with request completion. To determine 416 * who won, callers examine the return value from this function. 417 * 418 * Return values: 419 * %true - Uncompleted handshake request was canceled 420 * %false - Handshake request already completed or not found 421 */ 422 bool tls_handshake_cancel(struct sock *sk) 423 { 424 return handshake_req_cancel(sk); 425 } 426 EXPORT_SYMBOL(tls_handshake_cancel); 427