00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/sha1.h"
00019 #include "crypto/tls.h"
00020 #include "eap_i.h"
00021 #include "eap_tls_common.h"
00022 #include "eap_config.h"
00023
00024
00025 static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
00026 const u8 **data, size_t *data_len)
00027 {
00028 const struct wpa_config_blob *blob;
00029
00030 if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0)
00031 return 0;
00032
00033 blob = eap_get_config_blob(sm, *name + 7);
00034 if (blob == NULL) {
00035 wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not "
00036 "found", __func__, *name + 7);
00037 return -1;
00038 }
00039
00040 *name = NULL;
00041 *data = blob->data;
00042 *data_len = blob->len;
00043
00044 return 0;
00045 }
00046
00047
00048 static void eap_tls_params_flags(struct tls_connection_params *params,
00049 const char *txt)
00050 {
00051 if (txt == NULL)
00052 return;
00053 if (os_strstr(txt, "tls_allow_md5=1"))
00054 params->flags |= TLS_CONN_ALLOW_SIGN_RSA_MD5;
00055 if (os_strstr(txt, "tls_disable_time_checks=1"))
00056 params->flags |= TLS_CONN_DISABLE_TIME_CHECKS;
00057 }
00058
00059
00060 static void eap_tls_params_from_conf1(struct tls_connection_params *params,
00061 struct eap_peer_config *config)
00062 {
00063 params->ca_cert = (char *) config->ca_cert;
00064 params->ca_path = (char *) config->ca_path;
00065 params->client_cert = (char *) config->client_cert;
00066 params->private_key = (char *) config->private_key;
00067 params->private_key_passwd = (char *) config->private_key_passwd;
00068 params->dh_file = (char *) config->dh_file;
00069 params->subject_match = (char *) config->subject_match;
00070 params->altsubject_match = (char *) config->altsubject_match;
00071 params->engine = config->engine;
00072 params->engine_id = config->engine_id;
00073 params->pin = config->pin;
00074 params->key_id = config->key_id;
00075 params->cert_id = config->cert_id;
00076 params->ca_cert_id = config->ca_cert_id;
00077 eap_tls_params_flags(params, config->phase1);
00078 }
00079
00080
00081 static void eap_tls_params_from_conf2(struct tls_connection_params *params,
00082 struct eap_peer_config *config)
00083 {
00084 params->ca_cert = (char *) config->ca_cert2;
00085 params->ca_path = (char *) config->ca_path2;
00086 params->client_cert = (char *) config->client_cert2;
00087 params->private_key = (char *) config->private_key2;
00088 params->private_key_passwd = (char *) config->private_key2_passwd;
00089 params->dh_file = (char *) config->dh_file2;
00090 params->subject_match = (char *) config->subject_match2;
00091 params->altsubject_match = (char *) config->altsubject_match2;
00092 params->engine = config->engine2;
00093 params->engine_id = config->engine2_id;
00094 params->pin = config->pin2;
00095 params->key_id = config->key2_id;
00096 params->cert_id = config->cert2_id;
00097 params->ca_cert_id = config->ca_cert2_id;
00098 eap_tls_params_flags(params, config->phase2);
00099 }
00100
00101
00102 static int eap_tls_params_from_conf(struct eap_sm *sm,
00103 struct eap_ssl_data *data,
00104 struct tls_connection_params *params,
00105 struct eap_peer_config *config, int phase2)
00106 {
00107 os_memset(params, 0, sizeof(*params));
00108 if (phase2) {
00109 wpa_printf(MSG_DEBUG, "TLS: using phase2 config options");
00110 eap_tls_params_from_conf2(params, config);
00111 } else {
00112 wpa_printf(MSG_DEBUG, "TLS: using phase1 config options");
00113 eap_tls_params_from_conf1(params, config);
00114 }
00115 params->tls_ia = data->tls_ia;
00116
00117
00118
00119
00120
00121 if (eap_tls_check_blob(sm, ¶ms->ca_cert, ¶ms->ca_cert_blob,
00122 ¶ms->ca_cert_blob_len) ||
00123 eap_tls_check_blob(sm, ¶ms->client_cert,
00124 ¶ms->client_cert_blob,
00125 ¶ms->client_cert_blob_len) ||
00126 eap_tls_check_blob(sm, ¶ms->private_key,
00127 ¶ms->private_key_blob,
00128 ¶ms->private_key_blob_len) ||
00129 eap_tls_check_blob(sm, ¶ms->dh_file, ¶ms->dh_blob,
00130 ¶ms->dh_blob_len)) {
00131 wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs");
00132 return -1;
00133 }
00134
00135 return 0;
00136 }
00137
00138
00139 static int eap_tls_init_connection(struct eap_sm *sm,
00140 struct eap_ssl_data *data,
00141 struct eap_peer_config *config,
00142 struct tls_connection_params *params)
00143 {
00144 int res;
00145
00146 data->conn = tls_connection_init(sm->ssl_ctx);
00147 if (data->conn == NULL) {
00148 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
00149 "connection");
00150 return -1;
00151 }
00152
00153 res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);
00154 if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
00155
00156
00157
00158
00159
00160 os_free(config->pin);
00161 config->pin = NULL;
00162 } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {
00163 wpa_printf(MSG_INFO, "TLS: Failed to load private key");
00164
00165
00166
00167
00168 os_free(config->pin);
00169 config->pin = NULL;
00170 eap_sm_request_pin(sm);
00171 sm->ignore = TRUE;
00172 tls_connection_deinit(sm->ssl_ctx, data->conn);
00173 data->conn = NULL;
00174 return -1;
00175 } else if (res) {
00176 wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
00177 "parameters");
00178 tls_connection_deinit(sm->ssl_ctx, data->conn);
00179 data->conn = NULL;
00180 return -1;
00181 }
00182
00183 return 0;
00184 }
00185
00186
00197 int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
00198 struct eap_peer_config *config)
00199 {
00200 struct tls_connection_params params;
00201
00202 if (config == NULL)
00203 return -1;
00204
00205 data->eap = sm;
00206 data->phase2 = sm->init_phase2;
00207 if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) <
00208 0)
00209 return -1;
00210
00211 if (eap_tls_init_connection(sm, data, config, ¶ms) < 0)
00212 return -1;
00213
00214 data->tls_out_limit = config->fragment_size;
00215 if (data->phase2) {
00216
00217
00218
00219 if (data->tls_out_limit > 100)
00220 data->tls_out_limit -= 100;
00221 }
00222
00223 if (config->phase1 &&
00224 os_strstr(config->phase1, "include_tls_length=1")) {
00225 wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in "
00226 "unfragmented packets");
00227 data->include_tls_length = 1;
00228 }
00229
00230 return 0;
00231 }
00232
00233
00242 void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
00243 {
00244 tls_connection_deinit(sm->ssl_ctx, data->conn);
00245 eap_peer_tls_reset_input(data);
00246 eap_peer_tls_reset_output(data);
00247 }
00248
00249
00264 u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
00265 const char *label, size_t len)
00266 {
00267 struct tls_keys keys;
00268 u8 *rnd = NULL, *out;
00269
00270 out = os_malloc(len);
00271 if (out == NULL)
00272 return NULL;
00273
00274
00275 if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
00276 0)
00277 return out;
00278
00279
00280
00281
00282
00283
00284 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
00285 goto fail;
00286
00287 if (keys.client_random == NULL || keys.server_random == NULL ||
00288 keys.master_key == NULL)
00289 goto fail;
00290
00291 rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00292 if (rnd == NULL)
00293 goto fail;
00294 os_memcpy(rnd, keys.client_random, keys.client_random_len);
00295 os_memcpy(rnd + keys.client_random_len, keys.server_random,
00296 keys.server_random_len);
00297
00298 if (tls_prf(keys.master_key, keys.master_key_len,
00299 label, rnd, keys.client_random_len +
00300 keys.server_random_len, out, len))
00301 goto fail;
00302
00303 os_free(rnd);
00304 return out;
00305
00306 fail:
00307 os_free(out);
00308 os_free(rnd);
00309 return NULL;
00310 }
00311
00312
00320 static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
00321 const struct wpabuf *in_data)
00322 {
00323 size_t tls_in_len, in_len;
00324
00325 tls_in_len = data->tls_in ? wpabuf_len(data->tls_in) : 0;
00326 in_len = in_data ? wpabuf_len(in_data) : 0;
00327
00328 if (tls_in_len + in_len == 0) {
00329
00330 wpa_printf(MSG_WARNING, "SSL: Invalid reassembly state: "
00331 "tls_in_left=%lu tls_in_len=%lu in_len=%lu",
00332 (unsigned long) data->tls_in_left,
00333 (unsigned long) tls_in_len,
00334 (unsigned long) in_len);
00335 eap_peer_tls_reset_input(data);
00336 return -1;
00337 }
00338
00339 if (tls_in_len + in_len > 65536) {
00340
00341
00342
00343
00344 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size over "
00345 "64 kB)");
00346 eap_peer_tls_reset_input(data);
00347 return -1;
00348 }
00349
00350 if (in_len > data->tls_in_left) {
00351
00352 wpa_printf(MSG_INFO, "SSL: more data than TLS message length "
00353 "indicated");
00354 eap_peer_tls_reset_input(data);
00355 return -1;
00356 }
00357
00358 if (wpabuf_resize(&data->tls_in, in_len) < 0) {
00359 wpa_printf(MSG_INFO, "SSL: Could not allocate memory for TLS "
00360 "data");
00361 eap_peer_tls_reset_input(data);
00362 return -1;
00363 }
00364 wpabuf_put_buf(data->tls_in, in_data);
00365 data->tls_in_left -= in_len;
00366
00367 if (data->tls_in_left > 0) {
00368 wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input "
00369 "data", (unsigned long) data->tls_in_left);
00370 return 1;
00371 }
00372
00373 return 0;
00374 }
00375
00376
00389 static const struct wpabuf * eap_peer_tls_data_reassemble(
00390 struct eap_ssl_data *data, const struct wpabuf *in_data,
00391 int *need_more_input)
00392 {
00393 *need_more_input = 0;
00394
00395 if (data->tls_in_left > wpabuf_len(in_data) || data->tls_in) {
00396
00397 int res = eap_peer_tls_reassemble_fragment(data, in_data);
00398 if (res) {
00399 if (res == 1)
00400 *need_more_input = 1;
00401 return NULL;
00402 }
00403
00404
00405 } else {
00406
00407 data->tls_in_left = 0;
00408 data->tls_in = wpabuf_dup(in_data);
00409 if (data->tls_in == NULL)
00410 return NULL;
00411 }
00412
00413 return data->tls_in;
00414 }
00415
00416
00427 static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
00428 const u8 *in_data, size_t in_len,
00429 struct wpabuf **out_data)
00430 {
00431 const struct wpabuf *msg;
00432 int need_more_input;
00433 struct wpabuf *appl_data;
00434 struct wpabuf buf;
00435
00436 wpabuf_set(&buf, in_data, in_len);
00437 msg = eap_peer_tls_data_reassemble(data, &buf, &need_more_input);
00438 if (msg == NULL)
00439 return need_more_input ? 1 : -1;
00440
00441
00442 if (data->tls_out) {
00443
00444 wpa_printf(MSG_INFO, "SSL: eap_tls_process_input - pending "
00445 "tls_out data even though tls_out_len = 0");
00446 wpabuf_free(data->tls_out);
00447 WPA_ASSERT(data->tls_out == NULL);
00448 }
00449 appl_data = NULL;
00450 data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
00451 msg, &appl_data);
00452
00453 eap_peer_tls_reset_input(data);
00454
00455 if (appl_data &&
00456 tls_connection_established(sm->ssl_ctx, data->conn) &&
00457 !tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
00458 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data",
00459 appl_data);
00460 *out_data = appl_data;
00461 return 2;
00462 }
00463
00464 wpabuf_free(appl_data);
00465
00466 return 0;
00467 }
00468
00469
00480 static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
00481 int peap_version, u8 id, int ret,
00482 struct wpabuf **out_data)
00483 {
00484 size_t len;
00485 u8 *flags;
00486 int more_fragments, length_included;
00487
00488 if (data->tls_out == NULL)
00489 return -1;
00490 len = wpabuf_len(data->tls_out) - data->tls_out_pos;
00491 wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
00492 "%lu bytes)",
00493 (unsigned long) len,
00494 (unsigned long) wpabuf_len(data->tls_out));
00495
00496
00497
00498
00499
00500 if (len > data->tls_out_limit) {
00501 more_fragments = 1;
00502 len = data->tls_out_limit;
00503 wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
00504 "will follow", (unsigned long) len);
00505 } else
00506 more_fragments = 0;
00507
00508 length_included = data->tls_out_pos == 0 &&
00509 (wpabuf_len(data->tls_out) > data->tls_out_limit ||
00510 data->include_tls_length);
00511 if (!length_included &&
00512 eap_type == EAP_TYPE_PEAP && peap_version == 0 &&
00513 !tls_connection_established(data->eap->ssl_ctx, data->conn)) {
00514
00515
00516
00517
00518
00519
00520 length_included = 1;
00521 }
00522
00523 *out_data = eap_msg_alloc(EAP_VENDOR_IETF, eap_type,
00524 1 + length_included * 4 + len,
00525 EAP_CODE_RESPONSE, id);
00526 if (*out_data == NULL)
00527 return -1;
00528
00529 flags = wpabuf_put(*out_data, 1);
00530 *flags = peap_version;
00531 if (more_fragments)
00532 *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
00533 if (length_included) {
00534 *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
00535 wpabuf_put_be32(*out_data, wpabuf_len(data->tls_out));
00536 }
00537
00538 wpabuf_put_data(*out_data,
00539 wpabuf_head_u8(data->tls_out) + data->tls_out_pos,
00540 len);
00541 data->tls_out_pos += len;
00542
00543 if (!more_fragments)
00544 eap_peer_tls_reset_output(data);
00545
00546 return ret;
00547 }
00548
00549
00579 int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
00580 EapType eap_type, int peap_version,
00581 u8 id, const u8 *in_data, size_t in_len,
00582 struct wpabuf **out_data)
00583 {
00584 int ret = 0;
00585
00586 *out_data = NULL;
00587
00588 if (data->tls_out && wpabuf_len(data->tls_out) > 0 && in_len > 0) {
00589 wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output "
00590 "fragments are waiting to be sent out");
00591 return -1;
00592 }
00593
00594 if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) {
00595
00596
00597
00598
00599 int res = eap_tls_process_input(sm, data, in_data, in_len,
00600 out_data);
00601 if (res) {
00602
00603
00604
00605
00606 return res;
00607 }
00608
00609
00610
00611
00612
00613 }
00614
00615 if (data->tls_out == NULL) {
00616
00617
00618
00619
00620
00621 eap_peer_tls_reset_output(data);
00622 return -1;
00623 }
00624
00625 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
00626
00627 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
00628 "report error");
00629 ret = -1;
00630
00631 }
00632
00633 if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) {
00634
00635
00636
00637
00638
00639 wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
00640 wpabuf_free(data->tls_out);
00641 data->tls_out = NULL;
00642 return 1;
00643 }
00644
00645
00646 return eap_tls_process_output(data, eap_type, peap_version, id, ret,
00647 out_data);
00648 }
00649
00650
00658 struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type,
00659 int peap_version)
00660 {
00661 struct wpabuf *resp;
00662
00663 resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_RESPONSE,
00664 id);
00665 if (resp == NULL)
00666 return NULL;
00667 wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)",
00668 (int) eap_type, id, peap_version);
00669 wpabuf_put_u8(resp, peap_version);
00670 return resp;
00671 }
00672
00673
00680 int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data)
00681 {
00682 eap_peer_tls_reset_input(data);
00683 eap_peer_tls_reset_output(data);
00684 return tls_connection_shutdown(sm->ssl_ctx, data->conn);
00685 }
00686
00687
00697 int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
00698 char *buf, size_t buflen, int verbose)
00699 {
00700 char name[128];
00701 int len = 0, ret;
00702
00703 if (tls_get_cipher(sm->ssl_ctx, data->conn, name, sizeof(name)) == 0) {
00704 ret = os_snprintf(buf + len, buflen - len,
00705 "EAP TLS cipher=%s\n", name);
00706 if (ret < 0 || (size_t) ret >= buflen - len)
00707 return len;
00708 len += ret;
00709 }
00710
00711 return len;
00712 }
00713
00714
00739 const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
00740 struct eap_ssl_data *data,
00741 EapType eap_type,
00742 struct eap_method_ret *ret,
00743 const struct wpabuf *reqData,
00744 size_t *len, u8 *flags)
00745 {
00746 const u8 *pos;
00747 size_t left;
00748 unsigned int tls_msg_len;
00749
00750 if (tls_get_errors(sm->ssl_ctx)) {
00751 wpa_printf(MSG_INFO, "SSL: TLS errors detected");
00752 ret->ignore = TRUE;
00753 return NULL;
00754 }
00755
00756 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, &left);
00757 if (pos == NULL) {
00758 ret->ignore = TRUE;
00759 return NULL;
00760 }
00761 if (left == 0) {
00762 wpa_printf(MSG_DEBUG, "SSL: Invalid TLS message: no Flags "
00763 "octet included");
00764 if (!sm->workaround) {
00765 ret->ignore = TRUE;
00766 return NULL;
00767 }
00768
00769 wpa_printf(MSG_DEBUG, "SSL: Workaround - assume no Flags "
00770 "indicates ACK frame");
00771 *flags = 0;
00772 } else {
00773 *flags = *pos++;
00774 left--;
00775 }
00776 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
00777 "Flags 0x%02x", (unsigned long) wpabuf_len(reqData),
00778 *flags);
00779 if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
00780 if (left < 4) {
00781 wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
00782 "length");
00783 ret->ignore = TRUE;
00784 return NULL;
00785 }
00786 tls_msg_len = WPA_GET_BE32(pos);
00787 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
00788 tls_msg_len);
00789 if (data->tls_in_left == 0) {
00790 data->tls_in_total = tls_msg_len;
00791 data->tls_in_left = tls_msg_len;
00792 wpabuf_free(data->tls_in);
00793 data->tls_in = NULL;
00794 }
00795 pos += 4;
00796 left -= 4;
00797 }
00798
00799 ret->ignore = FALSE;
00800 ret->methodState = METHOD_MAY_CONT;
00801 ret->decision = DECISION_FAIL;
00802 ret->allowNotifications = TRUE;
00803
00804 *len = left;
00805 return pos;
00806 }
00807
00808
00816 void eap_peer_tls_reset_input(struct eap_ssl_data *data)
00817 {
00818 data->tls_in_left = data->tls_in_total = 0;
00819 wpabuf_free(data->tls_in);
00820 data->tls_in = NULL;
00821 }
00822
00823
00831 void eap_peer_tls_reset_output(struct eap_ssl_data *data)
00832 {
00833 data->tls_out_pos = 0;
00834 wpabuf_free(data->tls_out);
00835 data->tls_out = NULL;
00836 }
00837
00838
00847 int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
00848 const struct wpabuf *in_data,
00849 struct wpabuf **in_decrypted)
00850 {
00851 const struct wpabuf *msg;
00852 int need_more_input;
00853
00854 msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input);
00855 if (msg == NULL)
00856 return need_more_input ? 1 : -1;
00857
00858 *in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg);
00859 eap_peer_tls_reset_input(data);
00860 if (*in_decrypted == NULL) {
00861 wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
00862 return -1;
00863 }
00864 return 0;
00865 }
00866
00867
00879 int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
00880 EapType eap_type, int peap_version, u8 id,
00881 const struct wpabuf *in_data,
00882 struct wpabuf **out_data)
00883 {
00884 if (in_data) {
00885 eap_peer_tls_reset_output(data);
00886 data->tls_out = tls_connection_encrypt(sm->ssl_ctx, data->conn,
00887 in_data);
00888 if (data->tls_out == NULL) {
00889 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 "
00890 "data (in_len=%lu)",
00891 (unsigned long) wpabuf_len(in_data));
00892 eap_peer_tls_reset_output(data);
00893 return -1;
00894 }
00895 }
00896
00897 return eap_tls_process_output(data, eap_type, peap_version, id, 0,
00898 out_data);
00899 }
00900
00901
00913 int eap_peer_select_phase2_methods(struct eap_peer_config *config,
00914 const char *prefix,
00915 struct eap_method_type **types,
00916 size_t *num_types)
00917 {
00918 char *start, *pos, *buf;
00919 struct eap_method_type *methods = NULL, *_methods;
00920 u8 method;
00921 size_t num_methods = 0, prefix_len;
00922
00923 if (config == NULL || config->phase2 == NULL)
00924 goto get_defaults;
00925
00926 start = buf = os_strdup(config->phase2);
00927 if (buf == NULL)
00928 return -1;
00929
00930 prefix_len = os_strlen(prefix);
00931
00932 while (start && *start != '\0') {
00933 int vendor;
00934 pos = os_strstr(start, prefix);
00935 if (pos == NULL)
00936 break;
00937 if (start != pos && *(pos - 1) != ' ') {
00938 start = pos + prefix_len;
00939 continue;
00940 }
00941
00942 start = pos + prefix_len;
00943 pos = os_strchr(start, ' ');
00944 if (pos)
00945 *pos++ = '\0';
00946 method = eap_get_phase2_type(start, &vendor);
00947 if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) {
00948 wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP "
00949 "method '%s'", start);
00950 } else {
00951 num_methods++;
00952 _methods = os_realloc(methods,
00953 num_methods * sizeof(*methods));
00954 if (_methods == NULL) {
00955 os_free(methods);
00956 os_free(buf);
00957 return -1;
00958 }
00959 methods = _methods;
00960 methods[num_methods - 1].vendor = vendor;
00961 methods[num_methods - 1].method = method;
00962 }
00963
00964 start = pos;
00965 }
00966
00967 os_free(buf);
00968
00969 get_defaults:
00970 if (methods == NULL)
00971 methods = eap_get_phase2_types(config, &num_methods);
00972
00973 if (methods == NULL) {
00974 wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available");
00975 return -1;
00976 }
00977 wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types",
00978 (u8 *) methods,
00979 num_methods * sizeof(struct eap_method_type));
00980
00981 *types = methods;
00982 *num_types = num_methods;
00983
00984 return 0;
00985 }
00986
00987
00996 int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
00997 struct eap_hdr *hdr, struct wpabuf **resp)
00998 {
00999 u8 *pos = (u8 *) (hdr + 1);
01000 size_t i;
01001
01002
01003 wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos);
01004 wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types",
01005 (u8 *) types, num_types * sizeof(struct eap_method_type));
01006 *resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types,
01007 EAP_CODE_RESPONSE, hdr->identifier);
01008 if (*resp == NULL)
01009 return -1;
01010
01011 for (i = 0; i < num_types; i++) {
01012 if (types[i].vendor == EAP_VENDOR_IETF &&
01013 types[i].method < 256)
01014 wpabuf_put_u8(*resp, types[i].method);
01015 }
01016
01017 eap_update_len(*resp);
01018
01019 return 0;
01020 }