1 /* 2 * EAP-TLS/PEAP/TTLS/FAST server common functions 3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto/sha1.h" 13 #include "crypto/tls.h" 14 #include "eap_i.h" 15 #include "eap_tls_common.h" 16 17 18 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data); 19 20 21 struct wpabuf * eap_tls_msg_alloc(enum eap_type type, size_t payload_len, 22 u8 code, u8 identifier) 23 { 24 if (type == EAP_UNAUTH_TLS_TYPE) 25 return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, 26 EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, 27 code, identifier); 28 else if (type == EAP_WFA_UNAUTH_TLS_TYPE) 29 return eap_msg_alloc(EAP_VENDOR_WFA_NEW, 30 EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, 31 code, identifier); 32 return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, 33 identifier); 34 } 35 36 37 #ifdef CONFIG_TLS_INTERNAL 38 static void eap_server_tls_log_cb(void *ctx, const char *msg) 39 { 40 struct eap_sm *sm = ctx; 41 eap_log_msg(sm, "TLS: %s", msg); 42 } 43 #endif /* CONFIG_TLS_INTERNAL */ 44 45 46 int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 47 int verify_peer, int eap_type) 48 { 49 u8 session_ctx[8]; 50 unsigned int flags = sm->cfg->tls_flags; 51 52 if (!sm->cfg->ssl_ctx) { 53 wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); 54 return -1; 55 } 56 57 data->eap = sm; 58 data->phase2 = sm->init_phase2; 59 60 data->conn = tls_connection_init(sm->cfg->ssl_ctx); 61 if (data->conn == NULL) { 62 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 63 "connection"); 64 return -1; 65 } 66 67 #ifdef CONFIG_TLS_INTERNAL 68 tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm); 69 #ifdef CONFIG_TESTING_OPTIONS 70 tls_connection_set_test_flags(data->conn, sm->tls_test_flags); 71 #endif /* CONFIG_TESTING_OPTIONS */ 72 #endif /* CONFIG_TLS_INTERNAL */ 73 74 if (eap_type != EAP_TYPE_FAST) 75 flags |= TLS_CONN_DISABLE_SESSION_TICKET; 76 os_memcpy(session_ctx, "hostapd", 7); 77 session_ctx[7] = (u8) eap_type; 78 if (tls_connection_set_verify(sm->cfg->ssl_ctx, data->conn, verify_peer, 79 flags, session_ctx, 80 sizeof(session_ctx))) { 81 wpa_printf(MSG_INFO, "SSL: Failed to configure verification " 82 "of TLS peer certificate"); 83 tls_connection_deinit(sm->cfg->ssl_ctx, data->conn); 84 data->conn = NULL; 85 return -1; 86 } 87 88 data->tls_out_limit = sm->cfg->fragment_size > 0 ? 89 sm->cfg->fragment_size : 1398; 90 if (data->phase2) { 91 /* Limit the fragment size in the inner TLS authentication 92 * since the outer authentication with EAP-PEAP does not yet 93 * support fragmentation */ 94 if (data->tls_out_limit > 100) 95 data->tls_out_limit -= 100; 96 } 97 98 #ifdef CONFIG_TESTING_OPTIONS 99 data->skip_prot_success = sm->cfg->skip_prot_success; 100 #endif /* CONFIG_TESTING_OPTIONS */ 101 102 return 0; 103 } 104 105 106 void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 107 { 108 tls_connection_deinit(sm->cfg->ssl_ctx, data->conn); 109 eap_server_tls_free_in_buf(data); 110 wpabuf_free(data->tls_out); 111 data->tls_out = NULL; 112 } 113 114 115 u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 116 const char *label, const u8 *context, 117 size_t context_len, size_t len) 118 { 119 u8 *out; 120 121 out = os_malloc(len); 122 if (out == NULL) 123 return NULL; 124 125 if (tls_connection_export_key(sm->cfg->ssl_ctx, data->conn, label, 126 context, context_len, out, len)) { 127 os_free(out); 128 return NULL; 129 } 130 131 return out; 132 } 133 134 135 /** 136 * eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data 137 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 138 * @data: Data for TLS processing 139 * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 140 * @len: Pointer to length of the session ID generated 141 * Returns: Pointer to allocated Session-Id on success or %NULL on failure 142 * 143 * This function derive the Session-Id based on the TLS session data 144 * (client/server random and method type). 145 * 146 * The caller is responsible for freeing the returned buffer. 147 */ 148 u8 * eap_server_tls_derive_session_id(struct eap_sm *sm, 149 struct eap_ssl_data *data, u8 eap_type, 150 size_t *len) 151 { 152 struct tls_random keys; 153 u8 *out; 154 155 if (data->tls_v13) { 156 u8 *id, *method_id; 157 const u8 context[] = { eap_type }; 158 159 /* Session-Id = <EAP-Type> || Method-Id 160 * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id", 161 * Type-Code, 64) 162 */ 163 *len = 1 + 64; 164 id = os_malloc(*len); 165 if (!id) 166 return NULL; 167 method_id = eap_server_tls_derive_key( 168 sm, data, "EXPORTER_EAP_TLS_Method-Id", context, 1, 64); 169 if (!method_id) { 170 os_free(id); 171 return NULL; 172 } 173 id[0] = eap_type; 174 os_memcpy(id + 1, method_id, 64); 175 os_free(method_id); 176 return id; 177 } 178 179 if (tls_connection_get_random(sm->cfg->ssl_ctx, data->conn, &keys)) 180 return NULL; 181 182 if (keys.client_random == NULL || keys.server_random == NULL) 183 return NULL; 184 185 *len = 1 + keys.client_random_len + keys.server_random_len; 186 out = os_malloc(*len); 187 if (out == NULL) 188 return NULL; 189 190 /* Session-Id = EAP type || client.random || server.random */ 191 out[0] = eap_type; 192 os_memcpy(out + 1, keys.client_random, keys.client_random_len); 193 os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 194 keys.server_random_len); 195 196 return out; 197 } 198 199 200 struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 201 int eap_type, int version, u8 id) 202 { 203 struct wpabuf *req; 204 u8 flags; 205 size_t send_len, plen; 206 207 wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 208 if (data->tls_out == NULL) { 209 wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 210 return NULL; 211 } 212 213 flags = version; 214 send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 215 if (1 + send_len > data->tls_out_limit) { 216 send_len = data->tls_out_limit - 1; 217 flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 218 if (data->tls_out_pos == 0) { 219 flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 220 send_len -= 4; 221 } 222 } 223 224 plen = 1 + send_len; 225 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 226 plen += 4; 227 228 req = eap_tls_msg_alloc(eap_type, plen, EAP_CODE_REQUEST, id); 229 if (req == NULL) 230 return NULL; 231 232 wpabuf_put_u8(req, flags); /* Flags */ 233 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 234 wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 235 236 wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 237 send_len); 238 data->tls_out_pos += send_len; 239 240 if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 241 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 242 "(message sent completely)", 243 (unsigned long) send_len); 244 wpabuf_free(data->tls_out); 245 data->tls_out = NULL; 246 data->tls_out_pos = 0; 247 data->state = MSG; 248 } else { 249 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 250 "(%lu more to send)", (unsigned long) send_len, 251 (unsigned long) wpabuf_len(data->tls_out) - 252 data->tls_out_pos); 253 data->state = WAIT_FRAG_ACK; 254 } 255 256 return req; 257 } 258 259 260 struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 261 { 262 struct wpabuf *req; 263 264 req = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_REQUEST, id); 265 if (req == NULL) 266 return NULL; 267 wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 268 wpabuf_put_u8(req, version); /* Flags */ 269 return req; 270 } 271 272 273 static int eap_server_tls_process_cont(struct eap_ssl_data *data, 274 const u8 *buf, size_t len) 275 { 276 /* Process continuation of a pending message */ 277 if (len > wpabuf_tailroom(data->tls_in)) { 278 wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 279 return -1; 280 } 281 282 wpabuf_put_data(data->tls_in, buf, len); 283 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 284 "bytes more", (unsigned long) len, 285 (unsigned long) wpabuf_tailroom(data->tls_in)); 286 287 return 0; 288 } 289 290 291 static int eap_server_tls_process_fragment(struct eap_ssl_data *data, 292 u8 flags, u32 message_length, 293 const u8 *buf, size_t len) 294 { 295 /* Process a fragment that is not the last one of the message */ 296 if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 297 wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 298 "fragmented packet"); 299 return -1; 300 } 301 302 if (data->tls_in == NULL) { 303 /* First fragment of the message */ 304 305 /* Limit length to avoid rogue peers from causing large 306 * memory allocations. */ 307 if (message_length > 65536) { 308 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 309 " over 64 kB)"); 310 return -1; 311 } 312 313 if (len > message_length) { 314 wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 315 "first fragment of frame (TLS Message " 316 "Length %d bytes)", 317 (int) len, (int) message_length); 318 return -1; 319 } 320 321 data->tls_in = wpabuf_alloc(message_length); 322 if (data->tls_in == NULL) { 323 wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 324 return -1; 325 } 326 wpabuf_put_data(data->tls_in, buf, len); 327 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 328 "fragment, waiting for %lu bytes more", 329 (unsigned long) len, 330 (unsigned long) wpabuf_tailroom(data->tls_in)); 331 } 332 333 return 0; 334 } 335 336 337 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 338 { 339 char buf[20]; 340 341 if (data->tls_out) { 342 /* This should not happen.. */ 343 wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 344 "processing new message"); 345 wpabuf_free(data->tls_out); 346 WPA_ASSERT(data->tls_out == NULL); 347 } 348 349 data->tls_out = tls_connection_server_handshake(sm->cfg->ssl_ctx, 350 data->conn, 351 data->tls_in, NULL); 352 if (data->tls_out == NULL) { 353 wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 354 return -1; 355 } 356 if (tls_connection_get_failed(sm->cfg->ssl_ctx, data->conn)) { 357 /* TLS processing has failed - return error */ 358 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 359 "report error"); 360 return -1; 361 } 362 363 if (tls_get_version(sm->cfg->ssl_ctx, data->conn, 364 buf, sizeof(buf)) == 0) { 365 wpa_printf(MSG_DEBUG, "SSL: Using TLS version %s", buf); 366 data->tls_v13 = os_strcmp(buf, "TLSv1.3") == 0; 367 } 368 369 if (!sm->serial_num && 370 tls_connection_established(sm->cfg->ssl_ctx, data->conn)) 371 sm->serial_num = tls_connection_peer_serial_num( 372 sm->cfg->ssl_ctx, data->conn); 373 374 /* 375 * RFC 9190 Section 2.5 376 * 377 * We need to signal the other end that TLS negotiation is done. We 378 * can't send a zero-length application data message, so we send 379 * application data which is one byte of zero. 380 * 381 * Note this is only done for when there is no application data to be 382 * sent. So this is done always for EAP-TLS but notably not for PEAP 383 * even on resumption. 384 */ 385 if (data->tls_v13 && 386 tls_connection_established(sm->cfg->ssl_ctx, data->conn)) { 387 struct wpabuf *plain, *encr; 388 389 switch (sm->currentMethod) { 390 case EAP_TYPE_PEAP: 391 break; 392 default: 393 if (!tls_connection_resumed(sm->cfg->ssl_ctx, 394 data->conn)) 395 break; 396 /* fallthrough */ 397 case EAP_TYPE_TLS: 398 #ifdef CONFIG_TESTING_OPTIONS 399 if (data->skip_prot_success) { 400 wpa_printf(MSG_INFO, 401 "TESTING: Do not send protected success indication"); 402 break; 403 } 404 #endif /* CONFIG_TESTING_OPTIONS */ 405 wpa_printf(MSG_DEBUG, 406 "EAP-TLS: Send protected success indication (appl data 0x00)"); 407 408 plain = wpabuf_alloc(1); 409 if (!plain) 410 return -1; 411 wpabuf_put_u8(plain, 0); 412 encr = eap_server_tls_encrypt(sm, data, plain); 413 wpabuf_free(plain); 414 if (!encr) 415 return -1; 416 if (wpabuf_resize(&data->tls_out, wpabuf_len(encr)) < 0) 417 { 418 wpa_printf(MSG_INFO, 419 "EAP-TLS: Failed to resize output buffer"); 420 wpabuf_free(encr); 421 return -1; 422 } 423 wpabuf_put_buf(data->tls_out, encr); 424 wpa_hexdump_buf(MSG_DEBUG, 425 "EAP-TLS: Data appended to the message", 426 encr); 427 wpabuf_free(encr); 428 } 429 } 430 431 return 0; 432 } 433 434 435 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 436 const u8 **pos, size_t *left) 437 { 438 unsigned int tls_msg_len = 0; 439 const u8 *end = *pos + *left; 440 441 wpa_hexdump(MSG_MSGDUMP, "SSL: Received data", *pos, *left); 442 443 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 444 if (*left < 4) { 445 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 446 "length"); 447 return -1; 448 } 449 tls_msg_len = WPA_GET_BE32(*pos); 450 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 451 tls_msg_len); 452 *pos += 4; 453 *left -= 4; 454 455 if (*left > tls_msg_len) { 456 wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 457 "bytes) smaller than this fragment (%d " 458 "bytes)", (int) tls_msg_len, (int) *left); 459 return -1; 460 } 461 } 462 463 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 464 "Message Length %u", flags, tls_msg_len); 465 466 if (data->state == WAIT_FRAG_ACK) { 467 if (*left != 0) { 468 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 469 "WAIT_FRAG_ACK state"); 470 return -1; 471 } 472 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 473 return 1; 474 } 475 476 if (data->tls_in && 477 eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 478 return -1; 479 480 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 481 if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 482 *pos, end - *pos) < 0) 483 return -1; 484 485 data->state = FRAG_ACK; 486 return 1; 487 } 488 489 if (data->state == FRAG_ACK) { 490 wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 491 data->state = MSG; 492 } 493 494 if (data->tls_in == NULL) { 495 /* Wrap unfragmented messages as wpabuf without extra copy */ 496 wpabuf_set(&data->tmpbuf, *pos, end - *pos); 497 data->tls_in = &data->tmpbuf; 498 } 499 500 return 0; 501 } 502 503 504 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 505 { 506 if (data->tls_in != &data->tmpbuf) 507 wpabuf_free(data->tls_in); 508 data->tls_in = NULL; 509 } 510 511 512 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 513 struct eap_ssl_data *data, 514 const struct wpabuf *plain) 515 { 516 struct wpabuf *buf; 517 518 buf = tls_connection_encrypt(sm->cfg->ssl_ctx, data->conn, plain); 519 if (buf == NULL) { 520 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 521 return NULL; 522 } 523 524 return buf; 525 } 526 527 528 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 529 struct wpabuf *respData, void *priv, int eap_type, 530 int (*proc_version)(struct eap_sm *sm, void *priv, 531 int peer_version), 532 void (*proc_msg)(struct eap_sm *sm, void *priv, 533 const struct wpabuf *respData)) 534 { 535 const u8 *pos; 536 u8 flags; 537 size_t left; 538 int ret, res = 0; 539 540 if (eap_type == EAP_UNAUTH_TLS_TYPE) 541 pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 542 EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 543 &left); 544 else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 545 pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 546 EAP_VENDOR_WFA_UNAUTH_TLS, respData, 547 &left); 548 else 549 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, 550 &left); 551 if (pos == NULL || left < 1) 552 return 0; /* Should not happen - frame already validated */ 553 flags = *pos++; 554 left--; 555 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 556 (unsigned long) wpabuf_len(respData), flags); 557 558 if (proc_version && 559 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 560 return -1; 561 562 ret = eap_server_tls_reassemble(data, flags, &pos, &left); 563 if (ret < 0) { 564 res = -1; 565 goto done; 566 } else if (ret == 1) 567 return 0; 568 569 if (proc_msg) 570 proc_msg(sm, priv, respData); 571 572 if (tls_connection_get_write_alerts(sm->cfg->ssl_ctx, data->conn) > 1) { 573 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 574 "TLS processing"); 575 res = -1; 576 } 577 578 done: 579 eap_server_tls_free_in_buf(data); 580 581 return res; 582 } 583