Line data Source code
1 : /*
2 : * hostapd / EAP-TTLS (RFC 5281)
3 : * Copyright (c) 2004-2011, 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/ms_funcs.h"
13 : #include "crypto/sha1.h"
14 : #include "crypto/tls.h"
15 : #include "eap_server/eap_i.h"
16 : #include "eap_server/eap_tls_common.h"
17 : #include "eap_common/chap.h"
18 : #include "eap_common/eap_ttls.h"
19 :
20 :
21 : #define EAP_TTLS_VERSION 0
22 :
23 :
24 : static void eap_ttls_reset(struct eap_sm *sm, void *priv);
25 :
26 :
27 : struct eap_ttls_data {
28 : struct eap_ssl_data ssl;
29 : enum {
30 : START, PHASE1, PHASE2_START, PHASE2_METHOD,
31 : PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
32 : } state;
33 :
34 : int ttls_version;
35 : const struct eap_method *phase2_method;
36 : void *phase2_priv;
37 : int mschapv2_resp_ok;
38 : u8 mschapv2_auth_response[20];
39 : u8 mschapv2_ident;
40 : struct wpabuf *pending_phase2_eap_resp;
41 : int tnc_started;
42 : };
43 :
44 :
45 1632 : static const char * eap_ttls_state_txt(int state)
46 : {
47 1632 : switch (state) {
48 : case START:
49 327 : return "START";
50 : case PHASE1:
51 529 : return "PHASE1";
52 : case PHASE2_START:
53 349 : return "PHASE2_START";
54 : case PHASE2_METHOD:
55 55 : return "PHASE2_METHOD";
56 : case PHASE2_MSCHAPV2_RESP:
57 172 : return "PHASE2_MSCHAPV2_RESP";
58 : case SUCCESS:
59 159 : return "SUCCESS";
60 : case FAILURE:
61 41 : return "FAILURE";
62 : default:
63 0 : return "Unknown?!";
64 : }
65 : }
66 :
67 :
68 816 : static void eap_ttls_state(struct eap_ttls_data *data, int state)
69 : {
70 1632 : wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
71 816 : eap_ttls_state_txt(data->state),
72 : eap_ttls_state_txt(state));
73 816 : data->state = state;
74 816 : if (state == FAILURE)
75 41 : tls_connection_remove_session(data->ssl.conn);
76 816 : }
77 :
78 :
79 152 : static void eap_ttls_valid_session(struct eap_sm *sm,
80 : struct eap_ttls_data *data)
81 : {
82 : struct wpabuf *buf;
83 :
84 152 : if (!sm->tls_session_lifetime)
85 147 : return;
86 :
87 5 : buf = wpabuf_alloc(1 + 1 + sm->identity_len);
88 5 : if (!buf)
89 0 : return;
90 5 : wpabuf_put_u8(buf, EAP_TYPE_TTLS);
91 5 : if (sm->identity) {
92 : u8 id_len;
93 :
94 5 : if (sm->identity_len <= 255)
95 5 : id_len = sm->identity_len;
96 : else
97 0 : id_len = 255;
98 5 : wpabuf_put_u8(buf, id_len);
99 5 : wpabuf_put_data(buf, sm->identity, id_len);
100 : } else {
101 0 : wpabuf_put_u8(buf, 0);
102 : }
103 5 : tls_connection_set_success_data(data->ssl.conn, buf);
104 : }
105 :
106 :
107 154 : static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
108 : int mandatory, size_t len)
109 : {
110 : struct ttls_avp_vendor *avp;
111 : u8 flags;
112 : size_t hdrlen;
113 :
114 154 : avp = (struct ttls_avp_vendor *) avphdr;
115 154 : flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
116 154 : if (vendor_id) {
117 86 : flags |= AVP_FLAGS_VENDOR;
118 86 : hdrlen = sizeof(*avp);
119 86 : avp->vendor_id = host_to_be32(vendor_id);
120 : } else {
121 68 : hdrlen = sizeof(struct ttls_avp);
122 : }
123 :
124 154 : avp->avp_code = host_to_be32(avp_code);
125 154 : avp->avp_length = host_to_be32(((u32) flags << 24) |
126 : ((u32) (hdrlen + len)));
127 :
128 154 : return avphdr + hdrlen;
129 : }
130 :
131 :
132 68 : static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp,
133 : u32 avp_code, int mandatory)
134 : {
135 : struct wpabuf *avp;
136 : u8 *pos;
137 :
138 68 : avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
139 68 : if (avp == NULL) {
140 0 : wpabuf_free(resp);
141 0 : return NULL;
142 : }
143 :
144 68 : pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
145 : wpabuf_len(resp));
146 68 : os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
147 68 : pos += wpabuf_len(resp);
148 68 : AVP_PAD((const u8 *) wpabuf_head(avp), pos);
149 68 : wpabuf_free(resp);
150 68 : wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
151 68 : return avp;
152 : }
153 :
154 :
155 : struct eap_ttls_avp {
156 : /* Note: eap is allocated memory; caller is responsible for freeing
157 : * it. All the other pointers are pointing to the packet data, i.e.,
158 : * they must not be freed separately. */
159 : u8 *eap;
160 : size_t eap_len;
161 : u8 *user_name;
162 : size_t user_name_len;
163 : u8 *user_password;
164 : size_t user_password_len;
165 : u8 *chap_challenge;
166 : size_t chap_challenge_len;
167 : u8 *chap_password;
168 : size_t chap_password_len;
169 : u8 *mschap_challenge;
170 : size_t mschap_challenge_len;
171 : u8 *mschap_response;
172 : size_t mschap_response_len;
173 : u8 *mschap2_response;
174 : size_t mschap2_response_len;
175 : };
176 :
177 :
178 242 : static int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse)
179 : {
180 : struct ttls_avp *avp;
181 : u8 *pos;
182 : int left;
183 :
184 242 : pos = wpabuf_mhead(buf);
185 242 : left = wpabuf_len(buf);
186 242 : os_memset(parse, 0, sizeof(*parse));
187 :
188 980 : while (left > 0) {
189 496 : u32 avp_code, avp_length, vendor_id = 0;
190 : u8 avp_flags, *dpos;
191 : size_t pad, dlen;
192 496 : avp = (struct ttls_avp *) pos;
193 496 : avp_code = be_to_host32(avp->avp_code);
194 496 : avp_length = be_to_host32(avp->avp_length);
195 496 : avp_flags = (avp_length >> 24) & 0xff;
196 496 : avp_length &= 0xffffff;
197 496 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
198 : "length=%d", (int) avp_code, avp_flags,
199 : (int) avp_length);
200 496 : if ((int) avp_length > left) {
201 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
202 : "(len=%d, left=%d) - dropped",
203 : (int) avp_length, left);
204 0 : goto fail;
205 : }
206 496 : if (avp_length < sizeof(*avp)) {
207 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
208 : "%d", avp_length);
209 0 : goto fail;
210 : }
211 496 : dpos = (u8 *) (avp + 1);
212 496 : dlen = avp_length - sizeof(*avp);
213 496 : if (avp_flags & AVP_FLAGS_VENDOR) {
214 200 : if (dlen < 4) {
215 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
216 : "underflow");
217 0 : goto fail;
218 : }
219 200 : vendor_id = be_to_host32(* (be32 *) dpos);
220 200 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
221 : (int) vendor_id);
222 200 : dpos += 4;
223 200 : dlen -= 4;
224 : }
225 :
226 496 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
227 :
228 496 : if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
229 97 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
230 194 : if (parse->eap == NULL) {
231 97 : parse->eap = os_malloc(dlen);
232 97 : if (parse->eap == NULL) {
233 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: "
234 : "failed to allocate memory "
235 : "for Phase 2 EAP data");
236 0 : goto fail;
237 : }
238 97 : os_memcpy(parse->eap, dpos, dlen);
239 97 : parse->eap_len = dlen;
240 : } else {
241 0 : u8 *neweap = os_realloc(parse->eap,
242 0 : parse->eap_len + dlen);
243 0 : if (neweap == NULL) {
244 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: "
245 : "failed to allocate memory "
246 : "for Phase 2 EAP data");
247 0 : goto fail;
248 : }
249 0 : os_memcpy(neweap + parse->eap_len, dpos, dlen);
250 0 : parse->eap = neweap;
251 0 : parse->eap_len += dlen;
252 : }
253 399 : } else if (vendor_id == 0 &&
254 : avp_code == RADIUS_ATTR_USER_NAME) {
255 145 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
256 : dpos, dlen);
257 145 : parse->user_name = dpos;
258 145 : parse->user_name_len = dlen;
259 254 : } else if (vendor_id == 0 &&
260 36 : avp_code == RADIUS_ATTR_USER_PASSWORD) {
261 36 : u8 *password = dpos;
262 36 : size_t password_len = dlen;
263 658 : while (password_len > 0 &&
264 311 : password[password_len - 1] == '\0') {
265 275 : password_len--;
266 : }
267 36 : wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
268 : "User-Password (PAP)",
269 : password, password_len);
270 36 : parse->user_password = password;
271 36 : parse->user_password_len = password_len;
272 218 : } else if (vendor_id == 0 &&
273 : avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
274 9 : wpa_hexdump(MSG_DEBUG,
275 : "EAP-TTLS: CHAP-Challenge (CHAP)",
276 : dpos, dlen);
277 9 : parse->chap_challenge = dpos;
278 9 : parse->chap_challenge_len = dlen;
279 209 : } else if (vendor_id == 0 &&
280 : avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
281 9 : wpa_hexdump(MSG_DEBUG,
282 : "EAP-TTLS: CHAP-Password (CHAP)",
283 : dpos, dlen);
284 9 : parse->chap_password = dpos;
285 9 : parse->chap_password_len = dlen;
286 200 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
287 : avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
288 100 : wpa_hexdump(MSG_DEBUG,
289 : "EAP-TTLS: MS-CHAP-Challenge",
290 : dpos, dlen);
291 100 : parse->mschap_challenge = dpos;
292 100 : parse->mschap_challenge_len = dlen;
293 100 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
294 : avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
295 13 : wpa_hexdump(MSG_DEBUG,
296 : "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
297 : dpos, dlen);
298 13 : parse->mschap_response = dpos;
299 13 : parse->mschap_response_len = dlen;
300 87 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
301 : avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
302 87 : wpa_hexdump(MSG_DEBUG,
303 : "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
304 : dpos, dlen);
305 87 : parse->mschap2_response = dpos;
306 87 : parse->mschap2_response_len = dlen;
307 0 : } else if (avp_flags & AVP_FLAGS_MANDATORY) {
308 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
309 : "mandatory AVP code %d vendor_id %d - "
310 : "dropped", (int) avp_code, (int) vendor_id);
311 0 : goto fail;
312 : } else {
313 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
314 : "AVP code %d vendor_id %d",
315 : (int) avp_code, (int) vendor_id);
316 : }
317 :
318 496 : pad = (4 - (avp_length & 3)) & 3;
319 496 : pos += avp_length + pad;
320 496 : left -= avp_length + pad;
321 : }
322 :
323 242 : return 0;
324 :
325 : fail:
326 0 : os_free(parse->eap);
327 0 : parse->eap = NULL;
328 0 : return -1;
329 : }
330 :
331 :
332 105 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
333 : struct eap_ttls_data *data, size_t len)
334 : {
335 105 : return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
336 : len);
337 : }
338 :
339 :
340 327 : static void * eap_ttls_init(struct eap_sm *sm)
341 : {
342 : struct eap_ttls_data *data;
343 :
344 327 : data = os_zalloc(sizeof(*data));
345 327 : if (data == NULL)
346 0 : return NULL;
347 327 : data->ttls_version = EAP_TTLS_VERSION;
348 327 : data->state = START;
349 :
350 327 : if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TTLS)) {
351 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
352 0 : eap_ttls_reset(sm, data);
353 0 : return NULL;
354 : }
355 :
356 327 : return data;
357 : }
358 :
359 :
360 327 : static void eap_ttls_reset(struct eap_sm *sm, void *priv)
361 : {
362 327 : struct eap_ttls_data *data = priv;
363 327 : if (data == NULL)
364 327 : return;
365 327 : if (data->phase2_priv && data->phase2_method)
366 28 : data->phase2_method->reset(sm, data->phase2_priv);
367 327 : eap_server_tls_ssl_deinit(sm, &data->ssl);
368 327 : wpabuf_free(data->pending_phase2_eap_resp);
369 327 : bin_clear_free(data, sizeof(*data));
370 : }
371 :
372 :
373 327 : static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm,
374 : struct eap_ttls_data *data, u8 id)
375 : {
376 : struct wpabuf *req;
377 :
378 327 : req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
379 : EAP_CODE_REQUEST, id);
380 327 : if (req == NULL) {
381 0 : wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
382 : " request");
383 0 : eap_ttls_state(data, FAILURE);
384 0 : return NULL;
385 : }
386 :
387 327 : wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
388 :
389 327 : eap_ttls_state(data, PHASE1);
390 :
391 327 : return req;
392 : }
393 :
394 :
395 73 : static struct wpabuf * eap_ttls_build_phase2_eap_req(
396 : struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
397 : {
398 : struct wpabuf *buf, *encr_req;
399 :
400 :
401 73 : buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
402 73 : if (buf == NULL)
403 5 : return NULL;
404 :
405 68 : wpa_hexdump_buf_key(MSG_DEBUG,
406 : "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
407 :
408 68 : buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
409 68 : if (buf == NULL) {
410 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
411 : "packet");
412 0 : return NULL;
413 : }
414 :
415 68 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated "
416 : "Phase 2 data", buf);
417 :
418 68 : encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
419 68 : wpabuf_free(buf);
420 :
421 68 : return encr_req;
422 : }
423 :
424 :
425 86 : static struct wpabuf * eap_ttls_build_phase2_mschapv2(
426 : struct eap_sm *sm, struct eap_ttls_data *data)
427 : {
428 : struct wpabuf *encr_req, msgbuf;
429 : u8 *req, *pos, *end;
430 : int ret;
431 :
432 86 : pos = req = os_malloc(100);
433 86 : if (req == NULL)
434 0 : return NULL;
435 86 : end = req + 100;
436 :
437 86 : if (data->mschapv2_resp_ok) {
438 85 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
439 : RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
440 85 : *pos++ = data->mschapv2_ident;
441 85 : ret = os_snprintf((char *) pos, end - pos, "S=");
442 85 : if (!os_snprintf_error(end - pos, ret))
443 85 : pos += ret;
444 85 : pos += wpa_snprintf_hex_uppercase(
445 85 : (char *) pos, end - pos, data->mschapv2_auth_response,
446 : sizeof(data->mschapv2_auth_response));
447 : } else {
448 1 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
449 : RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
450 1 : os_memcpy(pos, "Failed", 6);
451 1 : pos += 6;
452 1 : AVP_PAD(req, pos);
453 : }
454 :
455 86 : wpabuf_set(&msgbuf, req, pos - req);
456 86 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
457 : "data", &msgbuf);
458 :
459 86 : encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
460 86 : os_free(req);
461 :
462 86 : return encr_req;
463 : }
464 :
465 :
466 1095 : static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
467 : {
468 1095 : struct eap_ttls_data *data = priv;
469 :
470 1095 : if (data->ssl.state == FRAG_ACK) {
471 57 : return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
472 : data->ttls_version);
473 : }
474 :
475 1038 : if (data->ssl.state == WAIT_FRAG_ACK) {
476 174 : return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
477 : data->ttls_version, id);
478 : }
479 :
480 864 : switch (data->state) {
481 : case START:
482 327 : return eap_ttls_build_start(sm, data, id);
483 : case PHASE1:
484 378 : if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
485 175 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "
486 : "starting Phase2");
487 175 : eap_ttls_state(data, PHASE2_START);
488 : }
489 378 : break;
490 : case PHASE2_METHOD:
491 73 : wpabuf_free(data->ssl.tls_out);
492 73 : data->ssl.tls_out_pos = 0;
493 73 : data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data,
494 : id);
495 73 : break;
496 : case PHASE2_MSCHAPV2_RESP:
497 86 : wpabuf_free(data->ssl.tls_out);
498 86 : data->ssl.tls_out_pos = 0;
499 86 : data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data);
500 86 : break;
501 : default:
502 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
503 0 : __func__, data->state);
504 0 : return NULL;
505 : }
506 :
507 537 : return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
508 : data->ttls_version, id);
509 : }
510 :
511 :
512 964 : static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
513 : struct wpabuf *respData)
514 : {
515 : const u8 *pos;
516 : size_t len;
517 :
518 964 : pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
519 964 : if (pos == NULL || len < 1) {
520 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
521 0 : return TRUE;
522 : }
523 :
524 964 : return FALSE;
525 : }
526 :
527 :
528 36 : static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
529 : struct eap_ttls_data *data,
530 : const u8 *user_password,
531 : size_t user_password_len)
532 : {
533 72 : if (!sm->user || !sm->user->password || sm->user->password_hash ||
534 36 : !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {
535 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
536 : "password configured");
537 1 : eap_ttls_state(data, FAILURE);
538 1 : return;
539 : }
540 :
541 69 : if (sm->user->password_len != user_password_len ||
542 34 : os_memcmp_const(sm->user->password, user_password,
543 : user_password_len) != 0) {
544 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
545 1 : eap_ttls_state(data, FAILURE);
546 1 : return;
547 : }
548 :
549 34 : wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
550 34 : eap_ttls_state(data, SUCCESS);
551 34 : eap_ttls_valid_session(sm, data);
552 : }
553 :
554 :
555 9 : static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
556 : struct eap_ttls_data *data,
557 : const u8 *challenge,
558 : size_t challenge_len,
559 : const u8 *password,
560 : size_t password_len)
561 : {
562 : u8 *chal, hash[CHAP_MD5_LEN];
563 :
564 9 : if (challenge == NULL || password == NULL ||
565 9 : challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
566 : password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
567 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
568 : "(challenge len %lu password len %lu)",
569 : (unsigned long) challenge_len,
570 : (unsigned long) password_len);
571 0 : eap_ttls_state(data, FAILURE);
572 0 : return;
573 : }
574 :
575 18 : if (!sm->user || !sm->user->password || sm->user->password_hash ||
576 9 : !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {
577 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
578 : "password configured");
579 1 : eap_ttls_state(data, FAILURE);
580 1 : return;
581 : }
582 :
583 8 : chal = eap_ttls_implicit_challenge(sm, data,
584 : EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
585 8 : if (chal == NULL) {
586 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
587 : "challenge from TLS data");
588 0 : eap_ttls_state(data, FAILURE);
589 0 : return;
590 : }
591 :
592 8 : if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN)
593 8 : != 0 ||
594 8 : password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
595 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
596 0 : os_free(chal);
597 0 : eap_ttls_state(data, FAILURE);
598 0 : return;
599 : }
600 8 : os_free(chal);
601 :
602 : /* MD5(Ident + Password + Challenge) */
603 8 : chap_md5(password[0], sm->user->password, sm->user->password_len,
604 : challenge, challenge_len, hash);
605 :
606 8 : if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
607 : 0) {
608 7 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
609 7 : eap_ttls_state(data, SUCCESS);
610 7 : eap_ttls_valid_session(sm, data);
611 : } else {
612 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
613 1 : eap_ttls_state(data, FAILURE);
614 : }
615 : }
616 :
617 :
618 12 : static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
619 : struct eap_ttls_data *data,
620 : u8 *challenge, size_t challenge_len,
621 : u8 *response, size_t response_len)
622 : {
623 : u8 *chal, nt_response[24];
624 :
625 12 : if (challenge == NULL || response == NULL ||
626 12 : challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
627 : response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
628 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
629 : "attributes (challenge len %lu response len %lu)",
630 : (unsigned long) challenge_len,
631 : (unsigned long) response_len);
632 0 : eap_ttls_state(data, FAILURE);
633 0 : return;
634 : }
635 :
636 24 : if (!sm->user || !sm->user->password ||
637 12 : !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {
638 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
639 : "configured");
640 1 : eap_ttls_state(data, FAILURE);
641 1 : return;
642 : }
643 :
644 11 : chal = eap_ttls_implicit_challenge(sm, data,
645 : EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
646 11 : if (chal == NULL) {
647 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
648 : "challenge from TLS data");
649 0 : eap_ttls_state(data, FAILURE);
650 0 : return;
651 : }
652 :
653 : #ifdef CONFIG_TESTING_OPTIONS
654 22 : eap_server_mschap_rx_callback(sm, "TTLS-MSCHAP",
655 11 : sm->identity, sm->identity_len,
656 : challenge, response + 2 + 24);
657 : #endif /* CONFIG_TESTING_OPTIONS */
658 :
659 11 : if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
660 11 : != 0 ||
661 11 : response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
662 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
663 0 : os_free(chal);
664 0 : eap_ttls_state(data, FAILURE);
665 0 : return;
666 : }
667 11 : os_free(chal);
668 :
669 11 : if (sm->user->password_hash)
670 0 : challenge_response(challenge, sm->user->password, nt_response);
671 : else
672 11 : nt_challenge_response(challenge, sm->user->password,
673 11 : sm->user->password_len, nt_response);
674 :
675 11 : if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
676 10 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
677 10 : eap_ttls_state(data, SUCCESS);
678 10 : eap_ttls_valid_session(sm, data);
679 : } else {
680 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
681 1 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
682 : response + 2 + 24, 24);
683 1 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
684 : nt_response, 24);
685 1 : eap_ttls_state(data, FAILURE);
686 : }
687 : }
688 :
689 :
690 87 : static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
691 : struct eap_ttls_data *data,
692 : u8 *challenge,
693 : size_t challenge_len,
694 : u8 *response, size_t response_len)
695 : {
696 : u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
697 : *auth_challenge;
698 : size_t username_len, i;
699 :
700 87 : if (challenge == NULL || response == NULL ||
701 87 : challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
702 : response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
703 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
704 : "attributes (challenge len %lu response len %lu)",
705 : (unsigned long) challenge_len,
706 : (unsigned long) response_len);
707 0 : eap_ttls_state(data, FAILURE);
708 0 : return;
709 : }
710 :
711 174 : if (!sm->user || !sm->user->password ||
712 87 : !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {
713 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
714 : "configured");
715 1 : eap_ttls_state(data, FAILURE);
716 1 : return;
717 : }
718 :
719 86 : if (sm->identity == NULL) {
720 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user identity "
721 : "known");
722 0 : eap_ttls_state(data, FAILURE);
723 0 : return;
724 : }
725 :
726 : /* MSCHAPv2 does not include optional domain name in the
727 : * challenge-response calculation, so remove domain prefix
728 : * (if present). */
729 86 : username = sm->identity;
730 86 : username_len = sm->identity_len;
731 852 : for (i = 0; i < username_len; i++) {
732 782 : if (username[i] == '\\') {
733 16 : username_len -= i + 1;
734 16 : username += i + 1;
735 16 : break;
736 : }
737 : }
738 :
739 86 : chal = eap_ttls_implicit_challenge(
740 : sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
741 86 : if (chal == NULL) {
742 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
743 : "challenge from TLS data");
744 0 : eap_ttls_state(data, FAILURE);
745 0 : return;
746 : }
747 :
748 86 : if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN)
749 86 : != 0 ||
750 86 : response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
751 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
752 0 : os_free(chal);
753 0 : eap_ttls_state(data, FAILURE);
754 0 : return;
755 : }
756 86 : os_free(chal);
757 :
758 86 : auth_challenge = challenge;
759 86 : peer_challenge = response + 2;
760 :
761 86 : wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
762 : username, username_len);
763 86 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
764 : auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
765 86 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
766 : peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
767 :
768 86 : if (sm->user->password_hash) {
769 17 : generate_nt_response_pwhash(auth_challenge, peer_challenge,
770 : username, username_len,
771 17 : sm->user->password,
772 : nt_response);
773 : } else {
774 138 : generate_nt_response(auth_challenge, peer_challenge,
775 : username, username_len,
776 69 : sm->user->password,
777 69 : sm->user->password_len,
778 : nt_response);
779 : }
780 :
781 86 : rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
782 : #ifdef CONFIG_TESTING_OPTIONS
783 : {
784 : u8 challenge2[8];
785 :
786 86 : if (challenge_hash(peer_challenge, auth_challenge,
787 : username, username_len, challenge2) == 0) {
788 86 : eap_server_mschap_rx_callback(sm, "TTLS-MSCHAPV2",
789 : username, username_len,
790 : challenge2, rx_resp);
791 : }
792 : }
793 : #endif /* CONFIG_TESTING_OPTIONS */
794 86 : if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
795 85 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
796 : "NT-Response");
797 85 : data->mschapv2_resp_ok = 1;
798 :
799 85 : if (sm->user->password_hash) {
800 16 : generate_authenticator_response_pwhash(
801 16 : sm->user->password,
802 : peer_challenge, auth_challenge,
803 : username, username_len, nt_response,
804 16 : data->mschapv2_auth_response);
805 : } else {
806 138 : generate_authenticator_response(
807 138 : sm->user->password, sm->user->password_len,
808 : peer_challenge, auth_challenge,
809 : username, username_len, nt_response,
810 69 : data->mschapv2_auth_response);
811 : }
812 : } else {
813 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
814 : "NT-Response");
815 1 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
816 : rx_resp, 24);
817 1 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
818 : nt_response, 24);
819 1 : data->mschapv2_resp_ok = 0;
820 : }
821 86 : eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
822 86 : data->mschapv2_ident = response[0];
823 : }
824 :
825 :
826 73 : static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
827 : struct eap_ttls_data *data,
828 : EapType eap_type)
829 : {
830 73 : if (data->phase2_priv && data->phase2_method) {
831 42 : data->phase2_method->reset(sm, data->phase2_priv);
832 42 : data->phase2_method = NULL;
833 42 : data->phase2_priv = NULL;
834 : }
835 73 : data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
836 : eap_type);
837 73 : if (!data->phase2_method)
838 0 : return -1;
839 :
840 73 : sm->init_phase2 = 1;
841 73 : data->phase2_priv = data->phase2_method->init(sm);
842 73 : sm->init_phase2 = 0;
843 73 : return data->phase2_priv == NULL ? -1 : 0;
844 : }
845 :
846 :
847 98 : static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
848 : struct eap_ttls_data *data,
849 : u8 *in_data, size_t in_len)
850 : {
851 98 : u8 next_type = EAP_TYPE_NONE;
852 : struct eap_hdr *hdr;
853 : u8 *pos;
854 : size_t left;
855 : struct wpabuf buf;
856 98 : const struct eap_method *m = data->phase2_method;
857 98 : void *priv = data->phase2_priv;
858 :
859 98 : if (priv == NULL) {
860 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
861 : "initialized?!", __func__);
862 0 : return;
863 : }
864 :
865 98 : hdr = (struct eap_hdr *) in_data;
866 98 : pos = (u8 *) (hdr + 1);
867 :
868 98 : if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
869 14 : left = in_len - sizeof(*hdr);
870 14 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
871 : "allowed types", pos + 1, left - 1);
872 14 : eap_sm_process_nak(sm, pos + 1, left - 1);
873 28 : if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
874 14 : sm->user->methods[sm->user_eap_method_index].method !=
875 : EAP_TYPE_NONE) {
876 28 : next_type = sm->user->methods[
877 14 : sm->user_eap_method_index++].method;
878 14 : wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
879 : next_type);
880 26 : if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
881 2 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "
882 : "initialize EAP type %d",
883 : next_type);
884 2 : eap_ttls_state(data, FAILURE);
885 2 : return;
886 : }
887 : } else {
888 0 : eap_ttls_state(data, FAILURE);
889 : }
890 12 : return;
891 : }
892 :
893 84 : wpabuf_set(&buf, in_data, in_len);
894 :
895 84 : if (m->check(sm, priv, &buf)) {
896 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
897 : "ignore the packet");
898 0 : return;
899 : }
900 :
901 84 : m->process(sm, priv, &buf);
902 :
903 84 : if (sm->method_pending == METHOD_PENDING_WAIT) {
904 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in "
905 : "pending wait state - save decrypted response");
906 1 : wpabuf_free(data->pending_phase2_eap_resp);
907 1 : data->pending_phase2_eap_resp = wpabuf_dup(&buf);
908 : }
909 :
910 84 : if (!m->isDone(sm, priv))
911 33 : return;
912 :
913 51 : if (!m->isSuccess(sm, priv)) {
914 6 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
915 6 : eap_ttls_state(data, FAILURE);
916 6 : return;
917 : }
918 :
919 45 : switch (data->state) {
920 : case PHASE2_START:
921 29 : if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
922 2 : wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
923 : "Identity not found in the user "
924 : "database",
925 1 : sm->identity, sm->identity_len);
926 1 : eap_ttls_state(data, FAILURE);
927 1 : break;
928 : }
929 :
930 28 : eap_ttls_state(data, PHASE2_METHOD);
931 28 : next_type = sm->user->methods[0].method;
932 28 : sm->user_eap_method_index = 1;
933 28 : wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
934 28 : if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
935 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
936 : "EAP type %d", next_type);
937 1 : eap_ttls_state(data, FAILURE);
938 : }
939 28 : break;
940 : case PHASE2_METHOD:
941 16 : eap_ttls_state(data, SUCCESS);
942 16 : eap_ttls_valid_session(sm, data);
943 16 : break;
944 : case FAILURE:
945 0 : break;
946 : default:
947 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
948 0 : __func__, data->state);
949 0 : break;
950 : }
951 : }
952 :
953 :
954 98 : static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
955 : struct eap_ttls_data *data,
956 : const u8 *eap, size_t eap_len)
957 : {
958 : struct eap_hdr *hdr;
959 : size_t len;
960 :
961 98 : if (data->state == PHASE2_START) {
962 29 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
963 29 : if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
964 : {
965 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
966 : "initialize EAP-Identity");
967 0 : return;
968 : }
969 : }
970 :
971 98 : if (eap_len < sizeof(*hdr)) {
972 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
973 : "packet (len=%lu)", (unsigned long) eap_len);
974 0 : return;
975 : }
976 :
977 98 : hdr = (struct eap_hdr *) eap;
978 98 : len = be_to_host16(hdr->length);
979 196 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
980 196 : "identifier=%d length=%lu", hdr->code, hdr->identifier,
981 : (unsigned long) len);
982 98 : if (len > eap_len) {
983 0 : wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
984 : " EAP frame (hdr len=%lu, data len in AVP=%lu)",
985 : (unsigned long) len, (unsigned long) eap_len);
986 0 : return;
987 : }
988 :
989 98 : switch (hdr->code) {
990 : case EAP_CODE_RESPONSE:
991 98 : eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
992 : len);
993 98 : break;
994 : default:
995 0 : wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
996 0 : "Phase 2 EAP header", hdr->code);
997 0 : break;
998 : }
999 : }
1000 :
1001 :
1002 243 : static void eap_ttls_process_phase2(struct eap_sm *sm,
1003 : struct eap_ttls_data *data,
1004 : struct wpabuf *in_buf)
1005 : {
1006 : struct wpabuf *in_decrypted;
1007 : struct eap_ttls_avp parse;
1008 :
1009 243 : wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
1010 : " Phase 2", (unsigned long) wpabuf_len(in_buf));
1011 :
1012 243 : if (data->pending_phase2_eap_resp) {
1013 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response "
1014 : "- skip decryption and use old data");
1015 2 : eap_ttls_process_phase2_eap(
1016 1 : sm, data, wpabuf_head(data->pending_phase2_eap_resp),
1017 1 : wpabuf_len(data->pending_phase2_eap_resp));
1018 1 : wpabuf_free(data->pending_phase2_eap_resp);
1019 1 : data->pending_phase2_eap_resp = NULL;
1020 2 : return;
1021 : }
1022 :
1023 242 : in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1024 : in_buf);
1025 242 : if (in_decrypted == NULL) {
1026 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
1027 : "data");
1028 0 : eap_ttls_state(data, FAILURE);
1029 0 : return;
1030 : }
1031 :
1032 242 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
1033 : in_decrypted);
1034 :
1035 242 : if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) {
1036 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
1037 0 : wpabuf_free(in_decrypted);
1038 0 : eap_ttls_state(data, FAILURE);
1039 0 : return;
1040 : }
1041 :
1042 242 : if (parse.user_name) {
1043 : char *nbuf;
1044 145 : nbuf = os_malloc(parse.user_name_len * 4 + 1);
1045 145 : if (nbuf) {
1046 290 : printf_encode(nbuf, parse.user_name_len * 4 + 1,
1047 145 : parse.user_name,
1048 : parse.user_name_len);
1049 145 : eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf);
1050 145 : os_free(nbuf);
1051 : }
1052 :
1053 145 : os_free(sm->identity);
1054 145 : sm->identity = os_malloc(parse.user_name_len);
1055 145 : if (sm->identity == NULL) {
1056 0 : eap_ttls_state(data, FAILURE);
1057 0 : goto done;
1058 : }
1059 145 : os_memcpy(sm->identity, parse.user_name, parse.user_name_len);
1060 145 : sm->identity_len = parse.user_name_len;
1061 145 : if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1062 : != 0) {
1063 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1064 : "found in the user database");
1065 1 : eap_ttls_state(data, FAILURE);
1066 1 : goto done;
1067 : }
1068 : }
1069 :
1070 : #ifdef EAP_SERVER_TNC
1071 241 : if (data->tnc_started && parse.eap == NULL) {
1072 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP "
1073 : "response from peer");
1074 0 : eap_ttls_state(data, FAILURE);
1075 0 : goto done;
1076 : }
1077 : #endif /* EAP_SERVER_TNC */
1078 :
1079 241 : if (parse.eap) {
1080 97 : eap_ttls_process_phase2_eap(sm, data, parse.eap,
1081 : parse.eap_len);
1082 144 : } else if (parse.user_password) {
1083 36 : eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1084 : parse.user_password_len);
1085 108 : } else if (parse.chap_password) {
1086 27 : eap_ttls_process_phase2_chap(sm, data,
1087 9 : parse.chap_challenge,
1088 : parse.chap_challenge_len,
1089 9 : parse.chap_password,
1090 : parse.chap_password_len);
1091 99 : } else if (parse.mschap_response) {
1092 12 : eap_ttls_process_phase2_mschap(sm, data,
1093 : parse.mschap_challenge,
1094 : parse.mschap_challenge_len,
1095 : parse.mschap_response,
1096 : parse.mschap_response_len);
1097 87 : } else if (parse.mschap2_response) {
1098 87 : eap_ttls_process_phase2_mschapv2(sm, data,
1099 : parse.mschap_challenge,
1100 : parse.mschap_challenge_len,
1101 : parse.mschap2_response,
1102 : parse.mschap2_response_len);
1103 : }
1104 :
1105 : done:
1106 242 : wpabuf_free(in_decrypted);
1107 242 : os_free(parse.eap);
1108 : }
1109 :
1110 :
1111 329 : static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data)
1112 : {
1113 : #ifdef EAP_SERVER_TNC
1114 329 : if (!sm->tnc || data->state != SUCCESS || data->tnc_started)
1115 327 : return;
1116 :
1117 2 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC");
1118 2 : if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) {
1119 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC");
1120 0 : eap_ttls_state(data, FAILURE);
1121 0 : return;
1122 : }
1123 :
1124 2 : data->tnc_started = 1;
1125 2 : eap_ttls_state(data, PHASE2_METHOD);
1126 : #endif /* EAP_SERVER_TNC */
1127 : }
1128 :
1129 :
1130 965 : static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
1131 : int peer_version)
1132 : {
1133 965 : struct eap_ttls_data *data = priv;
1134 965 : if (peer_version < data->ttls_version) {
1135 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
1136 : "use version %d",
1137 : peer_version, data->ttls_version, peer_version);
1138 0 : data->ttls_version = peer_version;
1139 : }
1140 :
1141 965 : return 0;
1142 : }
1143 :
1144 :
1145 734 : static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
1146 : const struct wpabuf *respData)
1147 : {
1148 734 : struct eap_ttls_data *data = priv;
1149 :
1150 734 : switch (data->state) {
1151 : case PHASE1:
1152 405 : if (eap_server_tls_phase1(sm, &data->ssl) < 0)
1153 22 : eap_ttls_state(data, FAILURE);
1154 405 : break;
1155 : case PHASE2_START:
1156 : case PHASE2_METHOD:
1157 243 : eap_ttls_process_phase2(sm, data, data->ssl.tls_in);
1158 243 : eap_ttls_start_tnc(sm, data);
1159 243 : break;
1160 : case PHASE2_MSCHAPV2_RESP:
1161 86 : if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) ==
1162 : 0) {
1163 85 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1164 : "acknowledged response");
1165 85 : eap_ttls_state(data, SUCCESS);
1166 85 : eap_ttls_valid_session(sm, data);
1167 1 : } else if (!data->mschapv2_resp_ok) {
1168 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1169 : "acknowledged error");
1170 1 : eap_ttls_state(data, FAILURE);
1171 : } else {
1172 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
1173 : "frame from peer (payload len %lu, "
1174 : "expected empty frame)",
1175 : (unsigned long)
1176 0 : wpabuf_len(data->ssl.tls_in));
1177 0 : eap_ttls_state(data, FAILURE);
1178 : }
1179 86 : eap_ttls_start_tnc(sm, data);
1180 86 : break;
1181 : default:
1182 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1183 0 : data->state, __func__);
1184 0 : break;
1185 : }
1186 734 : }
1187 :
1188 :
1189 965 : static void eap_ttls_process(struct eap_sm *sm, void *priv,
1190 : struct wpabuf *respData)
1191 : {
1192 965 : struct eap_ttls_data *data = priv;
1193 : const struct wpabuf *buf;
1194 : const u8 *pos;
1195 : u8 id_len;
1196 :
1197 965 : if (eap_server_tls_process(sm, &data->ssl, respData, data,
1198 : EAP_TYPE_TTLS, eap_ttls_process_version,
1199 : eap_ttls_process_msg) < 0) {
1200 0 : eap_ttls_state(data, FAILURE);
1201 0 : return;
1202 : }
1203 :
1204 1480 : if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
1205 515 : !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn))
1206 960 : return;
1207 :
1208 5 : buf = tls_connection_get_success_data(data->ssl.conn);
1209 5 : if (!buf || wpabuf_len(buf) < 1) {
1210 0 : wpa_printf(MSG_DEBUG,
1211 : "EAP-TTLS: No success data in resumed session - reject attempt");
1212 0 : eap_ttls_state(data, FAILURE);
1213 0 : return;
1214 : }
1215 :
1216 5 : pos = wpabuf_head(buf);
1217 5 : if (*pos != EAP_TYPE_TTLS) {
1218 0 : wpa_printf(MSG_DEBUG,
1219 : "EAP-TTLS: Resumed session for another EAP type (%u) - reject attempt",
1220 0 : *pos);
1221 0 : eap_ttls_state(data, FAILURE);
1222 0 : return;
1223 : }
1224 :
1225 5 : pos++;
1226 5 : id_len = *pos++;
1227 5 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: Identity from cached session",
1228 : pos, id_len);
1229 5 : os_free(sm->identity);
1230 5 : sm->identity = os_malloc(id_len ? id_len : 1);
1231 5 : if (!sm->identity) {
1232 0 : sm->identity_len = 0;
1233 0 : eap_ttls_state(data, FAILURE);
1234 0 : return;
1235 : }
1236 :
1237 5 : os_memcpy(sm->identity, pos, id_len);
1238 5 : sm->identity_len = id_len;
1239 :
1240 5 : if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1241 0 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not found in the user database",
1242 0 : sm->identity, sm->identity_len);
1243 0 : eap_ttls_state(data, FAILURE);
1244 0 : return;
1245 : }
1246 :
1247 5 : wpa_printf(MSG_DEBUG,
1248 : "EAP-TTLS: Resuming previous session - skip Phase2");
1249 5 : eap_ttls_state(data, SUCCESS);
1250 5 : tls_connection_set_success_data_resumed(data->ssl.conn);
1251 : }
1252 :
1253 :
1254 1006 : static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1255 : {
1256 1006 : struct eap_ttls_data *data = priv;
1257 1006 : return data->state == SUCCESS || data->state == FAILURE;
1258 : }
1259 :
1260 :
1261 196 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1262 : {
1263 196 : struct eap_ttls_data *data = priv;
1264 : u8 *eapKeyData;
1265 :
1266 196 : if (data->state != SUCCESS)
1267 41 : return NULL;
1268 :
1269 155 : eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
1270 : "ttls keying material",
1271 : EAP_TLS_KEY_LEN);
1272 155 : if (eapKeyData) {
1273 155 : *len = EAP_TLS_KEY_LEN;
1274 155 : wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
1275 : eapKeyData, EAP_TLS_KEY_LEN);
1276 : } else {
1277 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1278 : }
1279 :
1280 155 : return eapKeyData;
1281 : }
1282 :
1283 :
1284 237 : static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1285 : {
1286 237 : struct eap_ttls_data *data = priv;
1287 237 : return data->state == SUCCESS;
1288 : }
1289 :
1290 :
1291 196 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1292 : {
1293 196 : struct eap_ttls_data *data = priv;
1294 :
1295 196 : if (data->state != SUCCESS)
1296 41 : return NULL;
1297 :
1298 155 : return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS,
1299 : len);
1300 : }
1301 :
1302 :
1303 2 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1304 : {
1305 2 : struct eap_ttls_data *data = priv;
1306 : u8 *eapKeyData, *emsk;
1307 :
1308 2 : if (data->state != SUCCESS)
1309 0 : return NULL;
1310 :
1311 2 : eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
1312 : "ttls keying material",
1313 : EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
1314 2 : if (eapKeyData) {
1315 2 : emsk = os_malloc(EAP_EMSK_LEN);
1316 2 : if (emsk)
1317 2 : os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
1318 : EAP_EMSK_LEN);
1319 2 : bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
1320 : } else
1321 0 : emsk = NULL;
1322 :
1323 2 : if (emsk) {
1324 2 : *len = EAP_EMSK_LEN;
1325 2 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
1326 : emsk, EAP_EMSK_LEN);
1327 : } else {
1328 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive EMSK");
1329 : }
1330 :
1331 2 : return emsk;
1332 : }
1333 :
1334 :
1335 25 : int eap_server_ttls_register(void)
1336 : {
1337 : struct eap_method *eap;
1338 : int ret;
1339 :
1340 25 : eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1341 : EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
1342 25 : if (eap == NULL)
1343 0 : return -1;
1344 :
1345 25 : eap->init = eap_ttls_init;
1346 25 : eap->reset = eap_ttls_reset;
1347 25 : eap->buildReq = eap_ttls_buildReq;
1348 25 : eap->check = eap_ttls_check;
1349 25 : eap->process = eap_ttls_process;
1350 25 : eap->isDone = eap_ttls_isDone;
1351 25 : eap->getKey = eap_ttls_getKey;
1352 25 : eap->isSuccess = eap_ttls_isSuccess;
1353 25 : eap->getSessionId = eap_ttls_get_session_id;
1354 25 : eap->get_emsk = eap_ttls_get_emsk;
1355 :
1356 25 : ret = eap_server_method_register(eap);
1357 25 : if (ret)
1358 0 : eap_server_method_free(eap);
1359 25 : return ret;
1360 : }
|