1 /* 2 * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions 3 * Copyright (c) 2004-2013, 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 #include "eap_config.h" 17 18 19 static struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, 20 u8 code, u8 identifier) 21 { 22 if (type == EAP_UNAUTH_TLS_TYPE) 23 return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, 24 EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, 25 code, identifier); 26 if (type == EAP_WFA_UNAUTH_TLS_TYPE) 27 return eap_msg_alloc(EAP_VENDOR_WFA_NEW, 28 EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, 29 code, identifier); 30 return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, 31 identifier); 32 } 33 34 35 static int eap_tls_check_blob(struct eap_sm *sm, const char **name, 36 const u8 **data, size_t *data_len) 37 { 38 const struct wpa_config_blob *blob; 39 40 if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0) 41 return 0; 42 43 blob = eap_get_config_blob(sm, *name + 7); 44 if (blob == NULL) { 45 wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not " 46 "found", __func__, *name + 7); 47 return -1; 48 } 49 50 *name = NULL; 51 *data = blob->data; 52 *data_len = blob->len; 53 54 return 0; 55 } 56 57 58 static void eap_tls_params_flags(struct tls_connection_params *params, 59 const char *txt) 60 { 61 if (txt == NULL) 62 return; 63 if (os_strstr(txt, "tls_allow_md5=1")) 64 params->flags |= TLS_CONN_ALLOW_SIGN_RSA_MD5; 65 if (os_strstr(txt, "tls_disable_time_checks=1")) 66 params->flags |= TLS_CONN_DISABLE_TIME_CHECKS; 67 if (os_strstr(txt, "tls_disable_session_ticket=1")) 68 params->flags |= TLS_CONN_DISABLE_SESSION_TICKET; 69 if (os_strstr(txt, "tls_disable_session_ticket=0")) 70 params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET; 71 if (os_strstr(txt, "tls_disable_tlsv1_1=1")) 72 params->flags |= TLS_CONN_DISABLE_TLSv1_1; 73 if (os_strstr(txt, "tls_disable_tlsv1_1=0")) 74 params->flags &= ~TLS_CONN_DISABLE_TLSv1_1; 75 if (os_strstr(txt, "tls_disable_tlsv1_2=1")) 76 params->flags |= TLS_CONN_DISABLE_TLSv1_2; 77 if (os_strstr(txt, "tls_disable_tlsv1_2=0")) 78 params->flags &= ~TLS_CONN_DISABLE_TLSv1_2; 79 } 80 81 82 static void eap_tls_params_from_conf1(struct tls_connection_params *params, 83 struct eap_peer_config *config) 84 { 85 params->ca_cert = (char *) config->ca_cert; 86 params->ca_path = (char *) config->ca_path; 87 params->client_cert = (char *) config->client_cert; 88 params->private_key = (char *) config->private_key; 89 params->private_key_passwd = (char *) config->private_key_passwd; 90 params->dh_file = (char *) config->dh_file; 91 params->subject_match = (char *) config->subject_match; 92 params->altsubject_match = (char *) config->altsubject_match; 93 params->suffix_match = config->domain_suffix_match; 94 params->domain_match = config->domain_match; 95 params->engine = config->engine; 96 params->engine_id = config->engine_id; 97 params->pin = config->pin; 98 params->key_id = config->key_id; 99 params->cert_id = config->cert_id; 100 params->ca_cert_id = config->ca_cert_id; 101 eap_tls_params_flags(params, config->phase1); 102 } 103 104 105 static void eap_tls_params_from_conf2(struct tls_connection_params *params, 106 struct eap_peer_config *config) 107 { 108 params->ca_cert = (char *) config->ca_cert2; 109 params->ca_path = (char *) config->ca_path2; 110 params->client_cert = (char *) config->client_cert2; 111 params->private_key = (char *) config->private_key2; 112 params->private_key_passwd = (char *) config->private_key2_passwd; 113 params->dh_file = (char *) config->dh_file2; 114 params->subject_match = (char *) config->subject_match2; 115 params->altsubject_match = (char *) config->altsubject_match2; 116 params->suffix_match = config->domain_suffix_match2; 117 params->domain_match = config->domain_match2; 118 params->engine = config->engine2; 119 params->engine_id = config->engine2_id; 120 params->pin = config->pin2; 121 params->key_id = config->key2_id; 122 params->cert_id = config->cert2_id; 123 params->ca_cert_id = config->ca_cert2_id; 124 eap_tls_params_flags(params, config->phase2); 125 } 126 127 128 static int eap_tls_params_from_conf(struct eap_sm *sm, 129 struct eap_ssl_data *data, 130 struct tls_connection_params *params, 131 struct eap_peer_config *config, int phase2) 132 { 133 os_memset(params, 0, sizeof(*params)); 134 if (sm->workaround && data->eap_type != EAP_TYPE_FAST) { 135 /* 136 * Some deployed authentication servers seem to be unable to 137 * handle the TLS Session Ticket extension (they are supposed 138 * to ignore unrecognized TLS extensions, but end up rejecting 139 * the ClientHello instead). As a workaround, disable use of 140 * TLS Sesson Ticket extension for EAP-TLS, EAP-PEAP, and 141 * EAP-TTLS (EAP-FAST uses session ticket, so any server that 142 * supports EAP-FAST does not need this workaround). 143 */ 144 params->flags |= TLS_CONN_DISABLE_SESSION_TICKET; 145 } 146 if (phase2) { 147 wpa_printf(MSG_DEBUG, "TLS: using phase2 config options"); 148 eap_tls_params_from_conf2(params, config); 149 } else { 150 wpa_printf(MSG_DEBUG, "TLS: using phase1 config options"); 151 eap_tls_params_from_conf1(params, config); 152 if (data->eap_type == EAP_TYPE_FAST) 153 params->flags |= TLS_CONN_EAP_FAST; 154 } 155 156 /* 157 * Use blob data, if available. Otherwise, leave reference to external 158 * file as-is. 159 */ 160 if (eap_tls_check_blob(sm, ¶ms->ca_cert, ¶ms->ca_cert_blob, 161 ¶ms->ca_cert_blob_len) || 162 eap_tls_check_blob(sm, ¶ms->client_cert, 163 ¶ms->client_cert_blob, 164 ¶ms->client_cert_blob_len) || 165 eap_tls_check_blob(sm, ¶ms->private_key, 166 ¶ms->private_key_blob, 167 ¶ms->private_key_blob_len) || 168 eap_tls_check_blob(sm, ¶ms->dh_file, ¶ms->dh_blob, 169 ¶ms->dh_blob_len)) { 170 wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs"); 171 return -1; 172 } 173 174 params->openssl_ciphers = config->openssl_ciphers; 175 176 return 0; 177 } 178 179 180 static int eap_tls_init_connection(struct eap_sm *sm, 181 struct eap_ssl_data *data, 182 struct eap_peer_config *config, 183 struct tls_connection_params *params) 184 { 185 int res; 186 187 if (config->ocsp) 188 params->flags |= TLS_CONN_REQUEST_OCSP; 189 if (config->ocsp == 2) 190 params->flags |= TLS_CONN_REQUIRE_OCSP; 191 data->conn = tls_connection_init(data->ssl_ctx); 192 if (data->conn == NULL) { 193 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 194 "connection"); 195 return -1; 196 } 197 198 res = tls_connection_set_params(data->ssl_ctx, data->conn, params); 199 if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) { 200 /* 201 * At this point with the pkcs11 engine the PIN might be wrong. 202 * We reset the PIN in the configuration to be sure to not use 203 * it again and the calling function must request a new one. 204 */ 205 os_free(config->pin); 206 config->pin = NULL; 207 } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) { 208 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 209 /* 210 * We do not know exactly but maybe the PIN was wrong, 211 * so ask for a new one. 212 */ 213 os_free(config->pin); 214 config->pin = NULL; 215 eap_sm_request_pin(sm); 216 sm->ignore = TRUE; 217 tls_connection_deinit(data->ssl_ctx, data->conn); 218 data->conn = NULL; 219 return -1; 220 } else if (res) { 221 wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection " 222 "parameters"); 223 tls_connection_deinit(data->ssl_ctx, data->conn); 224 data->conn = NULL; 225 return -1; 226 } 227 228 return 0; 229 } 230 231 232 /** 233 * eap_peer_tls_ssl_init - Initialize shared TLS functionality 234 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 235 * @data: Data for TLS processing 236 * @config: Pointer to the network configuration 237 * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 238 * Returns: 0 on success, -1 on failure 239 * 240 * This function is used to initialize shared TLS functionality for EAP-TLS, 241 * EAP-PEAP, EAP-TTLS, and EAP-FAST. 242 */ 243 int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 244 struct eap_peer_config *config, u8 eap_type) 245 { 246 struct tls_connection_params params; 247 248 if (config == NULL) 249 return -1; 250 251 data->eap = sm; 252 data->eap_type = eap_type; 253 data->phase2 = sm->init_phase2; 254 data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 : 255 sm->ssl_ctx; 256 if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) < 257 0) 258 return -1; 259 260 if (eap_tls_init_connection(sm, data, config, ¶ms) < 0) 261 return -1; 262 263 data->tls_out_limit = config->fragment_size; 264 if (data->phase2) { 265 /* Limit the fragment size in the inner TLS authentication 266 * since the outer authentication with EAP-PEAP does not yet 267 * support fragmentation */ 268 if (data->tls_out_limit > 100) 269 data->tls_out_limit -= 100; 270 } 271 272 if (config->phase1 && 273 os_strstr(config->phase1, "include_tls_length=1")) { 274 wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in " 275 "unfragmented packets"); 276 data->include_tls_length = 1; 277 } 278 279 return 0; 280 } 281 282 283 /** 284 * eap_peer_tls_ssl_deinit - Deinitialize shared TLS functionality 285 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 286 * @data: Data for TLS processing 287 * 288 * This function deinitializes shared TLS functionality that was initialized 289 * with eap_peer_tls_ssl_init(). 290 */ 291 void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 292 { 293 tls_connection_deinit(data->ssl_ctx, data->conn); 294 eap_peer_tls_reset_input(data); 295 eap_peer_tls_reset_output(data); 296 } 297 298 299 /** 300 * eap_peer_tls_derive_key - Derive a key based on TLS session data 301 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 302 * @data: Data for TLS processing 303 * @label: Label string for deriving the keys, e.g., "client EAP encryption" 304 * @len: Length of the key material to generate (usually 64 for MSK) 305 * Returns: Pointer to allocated key on success or %NULL on failure 306 * 307 * This function uses TLS-PRF to generate pseudo-random data based on the TLS 308 * session data (client/server random and master key). Each key type may use a 309 * different label to bind the key usage into the generated material. 310 * 311 * The caller is responsible for freeing the returned buffer. 312 */ 313 u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 314 const char *label, size_t len) 315 { 316 #ifndef CONFIG_FIPS 317 struct tls_keys keys; 318 #endif /* CONFIG_FIPS */ 319 u8 *rnd = NULL, *out; 320 321 out = os_malloc(len); 322 if (out == NULL) 323 return NULL; 324 325 /* First, try to use TLS library function for PRF, if available. */ 326 if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len) 327 == 0) 328 return out; 329 330 #ifndef CONFIG_FIPS 331 /* 332 * TLS library did not support key generation, so get the needed TLS 333 * session parameters and use an internal implementation of TLS PRF to 334 * derive the key. 335 */ 336 if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys)) 337 goto fail; 338 339 if (keys.client_random == NULL || keys.server_random == NULL || 340 keys.master_key == NULL) 341 goto fail; 342 343 rnd = os_malloc(keys.client_random_len + keys.server_random_len); 344 if (rnd == NULL) 345 goto fail; 346 os_memcpy(rnd, keys.client_random, keys.client_random_len); 347 os_memcpy(rnd + keys.client_random_len, keys.server_random, 348 keys.server_random_len); 349 350 if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len, 351 label, rnd, keys.client_random_len + 352 keys.server_random_len, out, len)) 353 goto fail; 354 355 os_free(rnd); 356 return out; 357 358 fail: 359 #endif /* CONFIG_FIPS */ 360 os_free(out); 361 os_free(rnd); 362 return NULL; 363 } 364 365 366 /** 367 * eap_peer_tls_derive_session_id - Derive a Session-Id based on TLS data 368 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 369 * @data: Data for TLS processing 370 * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 371 * @len: Pointer to length of the session ID generated 372 * Returns: Pointer to allocated Session-Id on success or %NULL on failure 373 * 374 * This function derive the Session-Id based on the TLS session data 375 * (client/server random and method type). 376 * 377 * The caller is responsible for freeing the returned buffer. 378 */ 379 u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm, 380 struct eap_ssl_data *data, u8 eap_type, 381 size_t *len) 382 { 383 struct tls_keys keys; 384 u8 *out; 385 386 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) 387 return NULL; 388 389 if (keys.client_random == NULL || keys.server_random == NULL) 390 return NULL; 391 392 *len = 1 + keys.client_random_len + keys.server_random_len; 393 out = os_malloc(*len); 394 if (out == NULL) 395 return NULL; 396 397 /* Session-Id = EAP type || client.random || server.random */ 398 out[0] = eap_type; 399 os_memcpy(out + 1, keys.client_random, keys.client_random_len); 400 os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 401 keys.server_random_len); 402 403 return out; 404 } 405 406 407 /** 408 * eap_peer_tls_reassemble_fragment - Reassemble a received fragment 409 * @data: Data for TLS processing 410 * @in_data: Next incoming TLS segment 411 * Returns: 0 on success, 1 if more data is needed for the full message, or 412 * -1 on error 413 */ 414 static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data, 415 const struct wpabuf *in_data) 416 { 417 size_t tls_in_len, in_len; 418 419 tls_in_len = data->tls_in ? wpabuf_len(data->tls_in) : 0; 420 in_len = in_data ? wpabuf_len(in_data) : 0; 421 422 if (tls_in_len + in_len == 0) { 423 /* No message data received?! */ 424 wpa_printf(MSG_WARNING, "SSL: Invalid reassembly state: " 425 "tls_in_left=%lu tls_in_len=%lu in_len=%lu", 426 (unsigned long) data->tls_in_left, 427 (unsigned long) tls_in_len, 428 (unsigned long) in_len); 429 eap_peer_tls_reset_input(data); 430 return -1; 431 } 432 433 if (tls_in_len + in_len > 65536) { 434 /* 435 * Limit length to avoid rogue servers from causing large 436 * memory allocations. 437 */ 438 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size over " 439 "64 kB)"); 440 eap_peer_tls_reset_input(data); 441 return -1; 442 } 443 444 if (in_len > data->tls_in_left) { 445 /* Sender is doing something odd - reject message */ 446 wpa_printf(MSG_INFO, "SSL: more data than TLS message length " 447 "indicated"); 448 eap_peer_tls_reset_input(data); 449 return -1; 450 } 451 452 if (wpabuf_resize(&data->tls_in, in_len) < 0) { 453 wpa_printf(MSG_INFO, "SSL: Could not allocate memory for TLS " 454 "data"); 455 eap_peer_tls_reset_input(data); 456 return -1; 457 } 458 if (in_data) 459 wpabuf_put_buf(data->tls_in, in_data); 460 data->tls_in_left -= in_len; 461 462 if (data->tls_in_left > 0) { 463 wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input " 464 "data", (unsigned long) data->tls_in_left); 465 return 1; 466 } 467 468 return 0; 469 } 470 471 472 /** 473 * eap_peer_tls_data_reassemble - Reassemble TLS data 474 * @data: Data for TLS processing 475 * @in_data: Next incoming TLS segment 476 * @need_more_input: Variable for returning whether more input data is needed 477 * to reassemble this TLS packet 478 * Returns: Pointer to output data, %NULL on error or when more data is needed 479 * for the full message (in which case, *need_more_input is also set to 1). 480 * 481 * This function reassembles TLS fragments. Caller must not free the returned 482 * data buffer since an internal pointer to it is maintained. 483 */ 484 static const struct wpabuf * eap_peer_tls_data_reassemble( 485 struct eap_ssl_data *data, const struct wpabuf *in_data, 486 int *need_more_input) 487 { 488 *need_more_input = 0; 489 490 if (data->tls_in_left > wpabuf_len(in_data) || data->tls_in) { 491 /* Message has fragments */ 492 int res = eap_peer_tls_reassemble_fragment(data, in_data); 493 if (res) { 494 if (res == 1) 495 *need_more_input = 1; 496 return NULL; 497 } 498 499 /* Message is now fully reassembled. */ 500 } else { 501 /* No fragments in this message, so just make a copy of it. */ 502 data->tls_in_left = 0; 503 data->tls_in = wpabuf_dup(in_data); 504 if (data->tls_in == NULL) 505 return NULL; 506 } 507 508 return data->tls_in; 509 } 510 511 512 /** 513 * eap_tls_process_input - Process incoming TLS message 514 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 515 * @data: Data for TLS processing 516 * @in_data: Message received from the server 517 * @in_len: Length of in_data 518 * @out_data: Buffer for returning a pointer to application data (if available) 519 * Returns: 0 on success, 1 if more input data is needed, 2 if application data 520 * is available, -1 on failure 521 */ 522 static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data, 523 const u8 *in_data, size_t in_len, 524 struct wpabuf **out_data) 525 { 526 const struct wpabuf *msg; 527 int need_more_input; 528 struct wpabuf *appl_data; 529 struct wpabuf buf; 530 531 wpabuf_set(&buf, in_data, in_len); 532 msg = eap_peer_tls_data_reassemble(data, &buf, &need_more_input); 533 if (msg == NULL) 534 return need_more_input ? 1 : -1; 535 536 /* Full TLS message reassembled - continue handshake processing */ 537 if (data->tls_out) { 538 /* This should not happen.. */ 539 wpa_printf(MSG_INFO, "SSL: eap_tls_process_input - pending " 540 "tls_out data even though tls_out_len = 0"); 541 wpabuf_free(data->tls_out); 542 WPA_ASSERT(data->tls_out == NULL); 543 } 544 appl_data = NULL; 545 data->tls_out = tls_connection_handshake(data->ssl_ctx, data->conn, 546 msg, &appl_data); 547 548 eap_peer_tls_reset_input(data); 549 550 if (appl_data && 551 tls_connection_established(data->ssl_ctx, data->conn) && 552 !tls_connection_get_failed(data->ssl_ctx, data->conn)) { 553 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data", 554 appl_data); 555 *out_data = appl_data; 556 return 2; 557 } 558 559 wpabuf_free(appl_data); 560 561 return 0; 562 } 563 564 565 /** 566 * eap_tls_process_output - Process outgoing TLS message 567 * @data: Data for TLS processing 568 * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 569 * @peap_version: Version number for EAP-PEAP/TTLS 570 * @id: EAP identifier for the response 571 * @ret: Return value to use on success 572 * @out_data: Buffer for returning the allocated output buffer 573 * Returns: ret (0 or 1) on success, -1 on failure 574 */ 575 static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, 576 int peap_version, u8 id, int ret, 577 struct wpabuf **out_data) 578 { 579 size_t len; 580 u8 *flags; 581 int more_fragments, length_included; 582 583 if (data->tls_out == NULL) 584 return -1; 585 len = wpabuf_len(data->tls_out) - data->tls_out_pos; 586 wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total " 587 "%lu bytes)", 588 (unsigned long) len, 589 (unsigned long) wpabuf_len(data->tls_out)); 590 591 /* 592 * Limit outgoing message to the configured maximum size. Fragment 593 * message if needed. 594 */ 595 if (len > data->tls_out_limit) { 596 more_fragments = 1; 597 len = data->tls_out_limit; 598 wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments " 599 "will follow", (unsigned long) len); 600 } else 601 more_fragments = 0; 602 603 length_included = data->tls_out_pos == 0 && 604 (wpabuf_len(data->tls_out) > data->tls_out_limit || 605 data->include_tls_length); 606 if (!length_included && 607 eap_type == EAP_TYPE_PEAP && peap_version == 0 && 608 !tls_connection_established(data->eap->ssl_ctx, data->conn)) { 609 /* 610 * Windows Server 2008 NPS really wants to have the TLS Message 611 * length included in phase 0 even for unfragmented frames or 612 * it will get very confused with Compound MAC calculation and 613 * Outer TLVs. 614 */ 615 length_included = 1; 616 } 617 618 *out_data = eap_tls_msg_alloc(eap_type, 1 + length_included * 4 + len, 619 EAP_CODE_RESPONSE, id); 620 if (*out_data == NULL) 621 return -1; 622 623 flags = wpabuf_put(*out_data, 1); 624 *flags = peap_version; 625 if (more_fragments) 626 *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 627 if (length_included) { 628 *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 629 wpabuf_put_be32(*out_data, wpabuf_len(data->tls_out)); 630 } 631 632 wpabuf_put_data(*out_data, 633 wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 634 len); 635 data->tls_out_pos += len; 636 637 if (!more_fragments) 638 eap_peer_tls_reset_output(data); 639 640 return ret; 641 } 642 643 644 /** 645 * eap_peer_tls_process_helper - Process TLS handshake message 646 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 647 * @data: Data for TLS processing 648 * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 649 * @peap_version: Version number for EAP-PEAP/TTLS 650 * @id: EAP identifier for the response 651 * @in_data: Message received from the server 652 * @in_len: Length of in_data 653 * @out_data: Buffer for returning a pointer to the response message 654 * Returns: 0 on success, 1 if more input data is needed, 2 if application data 655 * is available, or -1 on failure 656 * 657 * This function can be used to process TLS handshake messages. It reassembles 658 * the received fragments and uses a TLS library to process the messages. The 659 * response data from the TLS library is fragmented to suitable output messages 660 * that the caller can send out. 661 * 662 * out_data is used to return the response message if the return value of this 663 * function is 0, 2, or -1. In case of failure, the message is likely a TLS 664 * alarm message. The caller is responsible for freeing the allocated buffer if 665 * *out_data is not %NULL. 666 * 667 * This function is called for each received TLS message during the TLS 668 * handshake after eap_peer_tls_process_init() call and possible processing of 669 * TLS Flags field. Once the handshake has been completed, i.e., when 670 * tls_connection_established() returns 1, EAP method specific decrypting of 671 * the tunneled data is used. 672 */ 673 int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, 674 EapType eap_type, int peap_version, 675 u8 id, const u8 *in_data, size_t in_len, 676 struct wpabuf **out_data) 677 { 678 int ret = 0; 679 680 *out_data = NULL; 681 682 if (data->tls_out && wpabuf_len(data->tls_out) > 0 && in_len > 0) { 683 wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output " 684 "fragments are waiting to be sent out"); 685 return -1; 686 } 687 688 if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) { 689 /* 690 * No more data to send out - expect to receive more data from 691 * the AS. 692 */ 693 int res = eap_tls_process_input(sm, data, in_data, in_len, 694 out_data); 695 if (res) { 696 /* 697 * Input processing failed (res = -1) or more data is 698 * needed (res = 1). 699 */ 700 return res; 701 } 702 703 /* 704 * The incoming message has been reassembled and processed. The 705 * response was allocated into data->tls_out buffer. 706 */ 707 } 708 709 if (data->tls_out == NULL) { 710 /* 711 * No outgoing fragments remaining from the previous message 712 * and no new message generated. This indicates an error in TLS 713 * processing. 714 */ 715 eap_peer_tls_reset_output(data); 716 return -1; 717 } 718 719 if (tls_connection_get_failed(data->ssl_ctx, data->conn)) { 720 /* TLS processing has failed - return error */ 721 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 722 "report error"); 723 ret = -1; 724 /* TODO: clean pin if engine used? */ 725 } 726 727 if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) { 728 /* 729 * TLS negotiation should now be complete since all other cases 730 * needing more data should have been caught above based on 731 * the TLS Message Length field. 732 */ 733 wpa_printf(MSG_DEBUG, "SSL: No data to be sent out"); 734 wpabuf_free(data->tls_out); 735 data->tls_out = NULL; 736 return 1; 737 } 738 739 /* Send the pending message (in fragments, if needed). */ 740 return eap_tls_process_output(data, eap_type, peap_version, id, ret, 741 out_data); 742 } 743 744 745 /** 746 * eap_peer_tls_build_ack - Build a TLS ACK frame 747 * @id: EAP identifier for the response 748 * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 749 * @peap_version: Version number for EAP-PEAP/TTLS 750 * Returns: Pointer to the allocated ACK frame or %NULL on failure 751 */ 752 struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type, 753 int peap_version) 754 { 755 struct wpabuf *resp; 756 757 resp = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_RESPONSE, id); 758 if (resp == NULL) 759 return NULL; 760 wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)", 761 (int) eap_type, id, peap_version); 762 wpabuf_put_u8(resp, peap_version); /* Flags */ 763 return resp; 764 } 765 766 767 /** 768 * eap_peer_tls_reauth_init - Re-initialize shared TLS for session resumption 769 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 770 * @data: Data for TLS processing 771 * Returns: 0 on success, -1 on failure 772 */ 773 int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data) 774 { 775 eap_peer_tls_reset_input(data); 776 eap_peer_tls_reset_output(data); 777 return tls_connection_shutdown(data->ssl_ctx, data->conn); 778 } 779 780 781 /** 782 * eap_peer_tls_status - Get TLS status 783 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 784 * @data: Data for TLS processing 785 * @buf: Buffer for status information 786 * @buflen: Maximum buffer length 787 * @verbose: Whether to include verbose status information 788 * Returns: Number of bytes written to buf. 789 */ 790 int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data, 791 char *buf, size_t buflen, int verbose) 792 { 793 char name[128]; 794 int len = 0, ret; 795 796 if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) == 0) 797 { 798 ret = os_snprintf(buf + len, buflen - len, 799 "EAP TLS cipher=%s\n" 800 "tls_session_reused=%d\n", 801 name, tls_connection_resumed(data->ssl_ctx, 802 data->conn)); 803 if (os_snprintf_error(buflen - len, ret)) 804 return len; 805 len += ret; 806 } 807 808 return len; 809 } 810 811 812 /** 813 * eap_peer_tls_process_init - Initial validation/processing of EAP requests 814 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 815 * @data: Data for TLS processing 816 * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 817 * @ret: Return values from EAP request validation and processing 818 * @reqData: EAP request to be processed (eapReqData) 819 * @len: Buffer for returning length of the remaining payload 820 * @flags: Buffer for returning TLS flags 821 * Returns: Pointer to payload after TLS flags and length or %NULL on failure 822 * 823 * This function validates the EAP header and processes the optional TLS 824 * Message Length field. If this is the first fragment of a TLS message, the 825 * TLS reassembly code is initialized to receive the indicated number of bytes. 826 * 827 * EAP-TLS, EAP-PEAP, EAP-TTLS, and EAP-FAST methods are expected to use this 828 * function as the first step in processing received messages. They will need 829 * to process the flags (apart from Message Length Included) that are returned 830 * through the flags pointer and the message payload that will be returned (and 831 * the length is returned through the len pointer). Return values (ret) are set 832 * for continuation of EAP method processing. The caller is responsible for 833 * setting these to indicate completion (either success or failure) based on 834 * the authentication result. 835 */ 836 const u8 * eap_peer_tls_process_init(struct eap_sm *sm, 837 struct eap_ssl_data *data, 838 EapType eap_type, 839 struct eap_method_ret *ret, 840 const struct wpabuf *reqData, 841 size_t *len, u8 *flags) 842 { 843 const u8 *pos; 844 size_t left; 845 unsigned int tls_msg_len; 846 847 if (tls_get_errors(data->ssl_ctx)) { 848 wpa_printf(MSG_INFO, "SSL: TLS errors detected"); 849 ret->ignore = TRUE; 850 return NULL; 851 } 852 853 if (eap_type == EAP_UNAUTH_TLS_TYPE) 854 pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 855 EAP_VENDOR_TYPE_UNAUTH_TLS, reqData, 856 &left); 857 else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 858 pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 859 EAP_VENDOR_WFA_UNAUTH_TLS, reqData, 860 &left); 861 else 862 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, 863 &left); 864 if (pos == NULL) { 865 ret->ignore = TRUE; 866 return NULL; 867 } 868 if (left == 0) { 869 wpa_printf(MSG_DEBUG, "SSL: Invalid TLS message: no Flags " 870 "octet included"); 871 if (!sm->workaround) { 872 ret->ignore = TRUE; 873 return NULL; 874 } 875 876 wpa_printf(MSG_DEBUG, "SSL: Workaround - assume no Flags " 877 "indicates ACK frame"); 878 *flags = 0; 879 } else { 880 *flags = *pos++; 881 left--; 882 } 883 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - " 884 "Flags 0x%02x", (unsigned long) wpabuf_len(reqData), 885 *flags); 886 if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 887 if (left < 4) { 888 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 889 "length"); 890 ret->ignore = TRUE; 891 return NULL; 892 } 893 tls_msg_len = WPA_GET_BE32(pos); 894 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 895 tls_msg_len); 896 if (data->tls_in_left == 0) { 897 data->tls_in_total = tls_msg_len; 898 data->tls_in_left = tls_msg_len; 899 wpabuf_free(data->tls_in); 900 data->tls_in = NULL; 901 } 902 pos += 4; 903 left -= 4; 904 905 if (left > tls_msg_len) { 906 wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 907 "bytes) smaller than this fragment (%d " 908 "bytes)", (int) tls_msg_len, (int) left); 909 ret->ignore = TRUE; 910 return NULL; 911 } 912 } 913 914 ret->ignore = FALSE; 915 ret->methodState = METHOD_MAY_CONT; 916 ret->decision = DECISION_FAIL; 917 ret->allowNotifications = TRUE; 918 919 *len = left; 920 return pos; 921 } 922 923 924 /** 925 * eap_peer_tls_reset_input - Reset input buffers 926 * @data: Data for TLS processing 927 * 928 * This function frees any allocated memory for input buffers and resets input 929 * state. 930 */ 931 void eap_peer_tls_reset_input(struct eap_ssl_data *data) 932 { 933 data->tls_in_left = data->tls_in_total = 0; 934 wpabuf_free(data->tls_in); 935 data->tls_in = NULL; 936 } 937 938 939 /** 940 * eap_peer_tls_reset_output - Reset output buffers 941 * @data: Data for TLS processing 942 * 943 * This function frees any allocated memory for output buffers and resets 944 * output state. 945 */ 946 void eap_peer_tls_reset_output(struct eap_ssl_data *data) 947 { 948 data->tls_out_pos = 0; 949 wpabuf_free(data->tls_out); 950 data->tls_out = NULL; 951 } 952 953 954 /** 955 * eap_peer_tls_decrypt - Decrypt received phase 2 TLS message 956 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 957 * @data: Data for TLS processing 958 * @in_data: Message received from the server 959 * @in_decrypted: Buffer for returning a pointer to the decrypted message 960 * Returns: 0 on success, 1 if more input data is needed, or -1 on failure 961 */ 962 int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data, 963 const struct wpabuf *in_data, 964 struct wpabuf **in_decrypted) 965 { 966 const struct wpabuf *msg; 967 int need_more_input; 968 969 msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input); 970 if (msg == NULL) 971 return need_more_input ? 1 : -1; 972 973 *in_decrypted = tls_connection_decrypt(data->ssl_ctx, data->conn, msg); 974 eap_peer_tls_reset_input(data); 975 if (*in_decrypted == NULL) { 976 wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data"); 977 return -1; 978 } 979 return 0; 980 } 981 982 983 /** 984 * eap_peer_tls_encrypt - Encrypt phase 2 TLS message 985 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 986 * @data: Data for TLS processing 987 * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 988 * @peap_version: Version number for EAP-PEAP/TTLS 989 * @id: EAP identifier for the response 990 * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments 991 * @out_data: Buffer for returning a pointer to the encrypted response message 992 * Returns: 0 on success, -1 on failure 993 */ 994 int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, 995 EapType eap_type, int peap_version, u8 id, 996 const struct wpabuf *in_data, 997 struct wpabuf **out_data) 998 { 999 if (in_data) { 1000 eap_peer_tls_reset_output(data); 1001 data->tls_out = tls_connection_encrypt(data->ssl_ctx, 1002 data->conn, in_data); 1003 if (data->tls_out == NULL) { 1004 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 " 1005 "data (in_len=%lu)", 1006 (unsigned long) wpabuf_len(in_data)); 1007 eap_peer_tls_reset_output(data); 1008 return -1; 1009 } 1010 } 1011 1012 return eap_tls_process_output(data, eap_type, peap_version, id, 0, 1013 out_data); 1014 } 1015 1016 1017 /** 1018 * eap_peer_select_phase2_methods - Select phase 2 EAP method 1019 * @config: Pointer to the network configuration 1020 * @prefix: 'phase2' configuration prefix, e.g., "auth=" 1021 * @types: Buffer for returning allocated list of allowed EAP methods 1022 * @num_types: Buffer for returning number of allocated EAP methods 1023 * Returns: 0 on success, -1 on failure 1024 * 1025 * This function is used to parse EAP method list and select allowed methods 1026 * for Phase2 authentication. 1027 */ 1028 int eap_peer_select_phase2_methods(struct eap_peer_config *config, 1029 const char *prefix, 1030 struct eap_method_type **types, 1031 size_t *num_types) 1032 { 1033 char *start, *pos, *buf; 1034 struct eap_method_type *methods = NULL, *_methods; 1035 u8 method; 1036 size_t num_methods = 0, prefix_len; 1037 1038 if (config == NULL || config->phase2 == NULL) 1039 goto get_defaults; 1040 1041 start = buf = os_strdup(config->phase2); 1042 if (buf == NULL) 1043 return -1; 1044 1045 prefix_len = os_strlen(prefix); 1046 1047 while (start && *start != '\0') { 1048 int vendor; 1049 pos = os_strstr(start, prefix); 1050 if (pos == NULL) 1051 break; 1052 if (start != pos && *(pos - 1) != ' ') { 1053 start = pos + prefix_len; 1054 continue; 1055 } 1056 1057 start = pos + prefix_len; 1058 pos = os_strchr(start, ' '); 1059 if (pos) 1060 *pos++ = '\0'; 1061 method = eap_get_phase2_type(start, &vendor); 1062 if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { 1063 wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP " 1064 "method '%s'", start); 1065 } else { 1066 num_methods++; 1067 _methods = os_realloc_array(methods, num_methods, 1068 sizeof(*methods)); 1069 if (_methods == NULL) { 1070 os_free(methods); 1071 os_free(buf); 1072 return -1; 1073 } 1074 methods = _methods; 1075 methods[num_methods - 1].vendor = vendor; 1076 methods[num_methods - 1].method = method; 1077 } 1078 1079 start = pos; 1080 } 1081 1082 os_free(buf); 1083 1084 get_defaults: 1085 if (methods == NULL) 1086 methods = eap_get_phase2_types(config, &num_methods); 1087 1088 if (methods == NULL) { 1089 wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available"); 1090 return -1; 1091 } 1092 wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types", 1093 (u8 *) methods, 1094 num_methods * sizeof(struct eap_method_type)); 1095 1096 *types = methods; 1097 *num_types = num_methods; 1098 1099 return 0; 1100 } 1101 1102 1103 /** 1104 * eap_peer_tls_phase2_nak - Generate EAP-Nak for Phase 2 1105 * @types: Buffer for returning allocated list of allowed EAP methods 1106 * @num_types: Buffer for returning number of allocated EAP methods 1107 * @hdr: EAP-Request header (and the following EAP type octet) 1108 * @resp: Buffer for returning the EAP-Nak message 1109 * Returns: 0 on success, -1 on failure 1110 */ 1111 int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types, 1112 struct eap_hdr *hdr, struct wpabuf **resp) 1113 { 1114 u8 *pos = (u8 *) (hdr + 1); 1115 size_t i; 1116 1117 /* TODO: add support for expanded Nak */ 1118 wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos); 1119 wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types", 1120 (u8 *) types, num_types * sizeof(struct eap_method_type)); 1121 *resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types, 1122 EAP_CODE_RESPONSE, hdr->identifier); 1123 if (*resp == NULL) 1124 return -1; 1125 1126 for (i = 0; i < num_types; i++) { 1127 if (types[i].vendor == EAP_VENDOR_IETF && 1128 types[i].method < 256) 1129 wpabuf_put_u8(*resp, types[i].method); 1130 } 1131 1132 eap_update_len(*resp); 1133 1134 return 0; 1135 } 1136