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