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