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 2668 : static const char * eap_ttls_state_txt(int state)
46 : {
47 2668 : switch (state) {
48 : case START:
49 615 : return "START";
50 : case PHASE1:
51 916 : return "PHASE1";
52 : case PHASE2_START:
53 530 : return "PHASE2_START";
54 : case PHASE2_METHOD:
55 91 : return "PHASE2_METHOD";
56 : case PHASE2_MSCHAPV2_RESP:
57 221 : return "PHASE2_MSCHAPV2_RESP";
58 : case SUCCESS:
59 250 : return "SUCCESS";
60 : case FAILURE:
61 45 : return "FAILURE";
62 : default:
63 0 : return "Unknown?!";
64 : }
65 : }
66 :
67 :
68 1334 : static void eap_ttls_state(struct eap_ttls_data *data, int state)
69 : {
70 2668 : wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
71 1334 : eap_ttls_state_txt(data->state),
72 : eap_ttls_state_txt(state));
73 1334 : data->state = state;
74 1334 : if (state == FAILURE)
75 45 : tls_connection_remove_session(data->ssl.conn);
76 1334 : }
77 :
78 :
79 221 : static void eap_ttls_valid_session(struct eap_sm *sm,
80 : struct eap_ttls_data *data)
81 : {
82 : struct wpabuf *buf;
83 :
84 221 : if (!sm->tls_session_lifetime)
85 216 : 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 290 : 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 290 : avp = (struct ttls_avp_vendor *) avphdr;
115 290 : flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
116 290 : if (vendor_id) {
117 112 : flags |= AVP_FLAGS_VENDOR;
118 112 : hdrlen = sizeof(*avp);
119 112 : avp->vendor_id = host_to_be32(vendor_id);
120 : } else {
121 178 : hdrlen = sizeof(struct ttls_avp);
122 : }
123 :
124 290 : avp->avp_code = host_to_be32(avp_code);
125 290 : avp->avp_length = host_to_be32(((u32) flags << 24) |
126 : ((u32) (hdrlen + len)));
127 :
128 290 : return avphdr + hdrlen;
129 : }
130 :
131 :
132 178 : 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 178 : avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
139 178 : if (avp == NULL) {
140 0 : wpabuf_free(resp);
141 0 : return NULL;
142 : }
143 :
144 178 : pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
145 : wpabuf_len(resp));
146 178 : os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
147 178 : pos += wpabuf_len(resp);
148 178 : AVP_PAD((const u8 *) wpabuf_head(avp), pos);
149 178 : wpabuf_free(resp);
150 178 : wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
151 178 : 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 405 : 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 405 : pos = wpabuf_mhead(buf);
185 405 : left = wpabuf_len(buf);
186 405 : os_memset(parse, 0, sizeof(*parse));
187 :
188 1571 : while (left > 0) {
189 761 : u32 avp_code, avp_length, vendor_id = 0;
190 : u8 avp_flags, *dpos;
191 : size_t pad, dlen;
192 761 : avp = (struct ttls_avp *) pos;
193 761 : avp_code = be_to_host32(avp->avp_code);
194 761 : avp_length = be_to_host32(avp->avp_length);
195 761 : avp_flags = (avp_length >> 24) & 0xff;
196 761 : avp_length &= 0xffffff;
197 761 : 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 761 : 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 761 : 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 761 : dpos = (u8 *) (avp + 1);
212 761 : dlen = avp_length - sizeof(*avp);
213 761 : if (avp_flags & AVP_FLAGS_VENDOR) {
214 258 : if (dlen < 4) {
215 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
216 : "underflow");
217 0 : goto fail;
218 : }
219 258 : vendor_id = be_to_host32(* (be32 *) dpos);
220 258 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
221 : (int) vendor_id);
222 258 : dpos += 4;
223 258 : dlen -= 4;
224 : }
225 :
226 761 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
227 :
228 761 : if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
229 188 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
230 376 : if (parse->eap == NULL) {
231 188 : parse->eap = os_malloc(dlen);
232 188 : 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 188 : os_memcpy(parse->eap, dpos, dlen);
239 188 : 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 573 : } else if (vendor_id == 0 &&
254 : avp_code == RADIUS_ATTR_USER_NAME) {
255 217 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
256 : dpos, dlen);
257 217 : parse->user_name = dpos;
258 217 : parse->user_name_len = dlen;
259 356 : } else if (vendor_id == 0 &&
260 78 : avp_code == RADIUS_ATTR_USER_PASSWORD) {
261 78 : u8 *password = dpos;
262 78 : size_t password_len = dlen;
263 1468 : while (password_len > 0 &&
264 695 : password[password_len - 1] == '\0') {
265 617 : password_len--;
266 : }
267 78 : wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
268 : "User-Password (PAP)",
269 : password, password_len);
270 78 : parse->user_password = password;
271 78 : parse->user_password_len = password_len;
272 278 : } else if (vendor_id == 0 &&
273 : avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
274 10 : wpa_hexdump(MSG_DEBUG,
275 : "EAP-TTLS: CHAP-Challenge (CHAP)",
276 : dpos, dlen);
277 10 : parse->chap_challenge = dpos;
278 10 : parse->chap_challenge_len = dlen;
279 268 : } else if (vendor_id == 0 &&
280 : avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
281 10 : wpa_hexdump(MSG_DEBUG,
282 : "EAP-TTLS: CHAP-Password (CHAP)",
283 : dpos, dlen);
284 10 : parse->chap_password = dpos;
285 10 : parse->chap_password_len = dlen;
286 258 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
287 : avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
288 129 : wpa_hexdump(MSG_DEBUG,
289 : "EAP-TTLS: MS-CHAP-Challenge",
290 : dpos, dlen);
291 129 : parse->mschap_challenge = dpos;
292 129 : parse->mschap_challenge_len = dlen;
293 129 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
294 : avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
295 16 : wpa_hexdump(MSG_DEBUG,
296 : "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
297 : dpos, dlen);
298 16 : parse->mschap_response = dpos;
299 16 : parse->mschap_response_len = dlen;
300 113 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
301 : avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
302 113 : wpa_hexdump(MSG_DEBUG,
303 : "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
304 : dpos, dlen);
305 113 : parse->mschap2_response = dpos;
306 113 : 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 761 : pad = (4 - (avp_length & 3)) & 3;
319 761 : pos += avp_length + pad;
320 761 : left -= avp_length + pad;
321 : }
322 :
323 405 : return 0;
324 :
325 : fail:
326 0 : os_free(parse->eap);
327 0 : parse->eap = NULL;
328 0 : return -1;
329 : }
330 :
331 :
332 135 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
333 : struct eap_ttls_data *data, size_t len)
334 : {
335 135 : return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
336 : len);
337 : }
338 :
339 :
340 615 : static void * eap_ttls_init(struct eap_sm *sm)
341 : {
342 : struct eap_ttls_data *data;
343 :
344 615 : data = os_zalloc(sizeof(*data));
345 615 : if (data == NULL)
346 0 : return NULL;
347 615 : data->ttls_version = EAP_TTLS_VERSION;
348 615 : data->state = START;
349 :
350 615 : 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 615 : return data;
357 : }
358 :
359 :
360 615 : static void eap_ttls_reset(struct eap_sm *sm, void *priv)
361 : {
362 615 : struct eap_ttls_data *data = priv;
363 615 : if (data == NULL)
364 615 : return;
365 615 : if (data->phase2_priv && data->phase2_method)
366 60 : data->phase2_method->reset(sm, data->phase2_priv);
367 615 : eap_server_tls_ssl_deinit(sm, &data->ssl);
368 615 : wpabuf_free(data->pending_phase2_eap_resp);
369 615 : bin_clear_free(data, sizeof(*data));
370 : }
371 :
372 :
373 615 : 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 615 : req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
379 : EAP_CODE_REQUEST, id);
380 615 : 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 615 : wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
388 :
389 615 : eap_ttls_state(data, PHASE1);
390 :
391 615 : return req;
392 : }
393 :
394 :
395 183 : 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 183 : buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
402 183 : if (buf == NULL)
403 5 : return NULL;
404 :
405 178 : wpa_hexdump_buf_key(MSG_DEBUG,
406 : "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
407 :
408 178 : buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
409 178 : if (buf == NULL) {
410 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
411 : "packet");
412 0 : return NULL;
413 : }
414 :
415 178 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated "
416 : "Phase 2 data", buf);
417 :
418 178 : encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
419 178 : wpabuf_free(buf);
420 :
421 178 : return encr_req;
422 : }
423 :
424 :
425 112 : 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 112 : pos = req = os_malloc(100);
433 112 : if (req == NULL)
434 0 : return NULL;
435 112 : end = req + 100;
436 :
437 112 : if (data->mschapv2_resp_ok) {
438 111 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
439 : RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
440 111 : *pos++ = data->mschapv2_ident;
441 111 : ret = os_snprintf((char *) pos, end - pos, "S=");
442 111 : if (!os_snprintf_error(end - pos, ret))
443 111 : pos += ret;
444 111 : pos += wpa_snprintf_hex_uppercase(
445 111 : (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 112 : wpabuf_set(&msgbuf, req, pos - req);
456 112 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
457 : "data", &msgbuf);
458 :
459 112 : encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
460 112 : os_free(req);
461 :
462 112 : return encr_req;
463 : }
464 :
465 :
466 2169 : static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
467 : {
468 2169 : struct eap_ttls_data *data = priv;
469 :
470 2169 : if (data->ssl.state == FRAG_ACK) {
471 152 : return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
472 : data->ttls_version);
473 : }
474 :
475 2017 : if (data->ssl.state == WAIT_FRAG_ACK) {
476 526 : return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
477 : data->ttls_version, id);
478 : }
479 :
480 1491 : switch (data->state) {
481 : case START:
482 615 : return eap_ttls_build_start(sm, data, id);
483 : case PHASE1:
484 581 : if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
485 274 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "
486 : "starting Phase2");
487 274 : eap_ttls_state(data, PHASE2_START);
488 : }
489 581 : break;
490 : case PHASE2_METHOD:
491 183 : wpabuf_free(data->ssl.tls_out);
492 183 : data->ssl.tls_out_pos = 0;
493 183 : data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data,
494 : id);
495 183 : break;
496 : case PHASE2_MSCHAPV2_RESP:
497 112 : wpabuf_free(data->ssl.tls_out);
498 112 : data->ssl.tls_out_pos = 0;
499 112 : data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data);
500 112 : 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 876 : return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
508 : data->ttls_version, id);
509 : }
510 :
511 :
512 1801 : 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 1801 : pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
519 1801 : if (pos == NULL || len < 1) {
520 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
521 0 : return TRUE;
522 : }
523 :
524 1801 : return FALSE;
525 : }
526 :
527 :
528 75 : 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 150 : if (!sm->user || !sm->user->password || sm->user->password_hash ||
534 75 : !(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 147 : if (sm->user->password_len != user_password_len ||
542 73 : 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 73 : wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
550 73 : eap_ttls_state(data, SUCCESS);
551 73 : eap_ttls_valid_session(sm, data);
552 : }
553 :
554 :
555 10 : 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 10 : if (challenge == NULL || password == NULL ||
565 10 : 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 20 : if (!sm->user || !sm->user->password || sm->user->password_hash ||
576 10 : !(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 9 : chal = eap_ttls_implicit_challenge(sm, data,
584 : EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
585 9 : 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 9 : if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN)
593 9 : != 0 ||
594 9 : 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 9 : os_free(chal);
601 :
602 : /* MD5(Ident + Password + Challenge) */
603 9 : chap_md5(password[0], sm->user->password, sm->user->password_len,
604 : challenge, challenge_len, hash);
605 :
606 9 : if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
607 : 0) {
608 8 : wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
609 8 : eap_ttls_state(data, SUCCESS);
610 8 : 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 15 : 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 15 : if (challenge == NULL || response == NULL ||
626 15 : 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 30 : if (!sm->user || !sm->user->password ||
637 15 : !(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 14 : chal = eap_ttls_implicit_challenge(sm, data,
645 : EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
646 14 : 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 28 : eap_server_mschap_rx_callback(sm, "TTLS-MSCHAP",
655 14 : sm->identity, sm->identity_len,
656 : challenge, response + 2 + 24);
657 : #endif /* CONFIG_TESTING_OPTIONS */
658 :
659 14 : if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
660 14 : != 0 ||
661 14 : 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 14 : os_free(chal);
668 :
669 14 : if (sm->user->password_hash)
670 0 : challenge_response(challenge, sm->user->password, nt_response);
671 : else
672 14 : nt_challenge_response(challenge, sm->user->password,
673 14 : sm->user->password_len, nt_response);
674 :
675 14 : if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
676 13 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
677 13 : eap_ttls_state(data, SUCCESS);
678 13 : 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 113 : 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 113 : if (challenge == NULL || response == NULL ||
701 113 : 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 226 : if (!sm->user || !sm->user->password ||
712 113 : !(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 112 : 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 112 : username = sm->identity;
730 112 : username_len = sm->identity_len;
731 1109 : for (i = 0; i < username_len; i++) {
732 1022 : if (username[i] == '\\') {
733 25 : username_len -= i + 1;
734 25 : username += i + 1;
735 25 : break;
736 : }
737 : }
738 :
739 112 : chal = eap_ttls_implicit_challenge(
740 : sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
741 112 : 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 112 : if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN)
749 112 : != 0 ||
750 112 : 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 112 : os_free(chal);
757 :
758 112 : auth_challenge = challenge;
759 112 : peer_challenge = response + 2;
760 :
761 112 : wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
762 : username, username_len);
763 112 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
764 : auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
765 112 : wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
766 : peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
767 :
768 112 : if (sm->user->password_hash) {
769 26 : generate_nt_response_pwhash(auth_challenge, peer_challenge,
770 : username, username_len,
771 26 : sm->user->password,
772 : nt_response);
773 : } else {
774 172 : generate_nt_response(auth_challenge, peer_challenge,
775 : username, username_len,
776 86 : sm->user->password,
777 86 : sm->user->password_len,
778 : nt_response);
779 : }
780 :
781 112 : rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
782 : #ifdef CONFIG_TESTING_OPTIONS
783 : {
784 : u8 challenge2[8];
785 :
786 112 : if (challenge_hash(peer_challenge, auth_challenge,
787 : username, username_len, challenge2) == 0) {
788 112 : eap_server_mschap_rx_callback(sm, "TTLS-MSCHAPV2",
789 : username, username_len,
790 : challenge2, rx_resp);
791 : }
792 : }
793 : #endif /* CONFIG_TESTING_OPTIONS */
794 112 : if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
795 111 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
796 : "NT-Response");
797 111 : data->mschapv2_resp_ok = 1;
798 :
799 111 : if (sm->user->password_hash) {
800 25 : generate_authenticator_response_pwhash(
801 25 : sm->user->password,
802 : peer_challenge, auth_challenge,
803 : username, username_len, nt_response,
804 25 : data->mschapv2_auth_response);
805 : } else {
806 172 : generate_authenticator_response(
807 172 : sm->user->password, sm->user->password_len,
808 : peer_challenge, auth_challenge,
809 : username, username_len, nt_response,
810 86 : 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 112 : eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
822 112 : data->mschapv2_ident = response[0];
823 : }
824 :
825 :
826 118 : static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
827 : struct eap_ttls_data *data,
828 : EapType eap_type)
829 : {
830 118 : if (data->phase2_priv && data->phase2_method) {
831 55 : data->phase2_method->reset(sm, data->phase2_priv);
832 55 : data->phase2_method = NULL;
833 55 : data->phase2_priv = NULL;
834 : }
835 118 : data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
836 : eap_type);
837 118 : if (!data->phase2_method)
838 0 : return -1;
839 :
840 118 : sm->init_phase2 = 1;
841 118 : data->phase2_priv = data->phase2_method->init(sm);
842 118 : sm->init_phase2 = 0;
843 118 : return data->phase2_priv == NULL ? -1 : 0;
844 : }
845 :
846 :
847 189 : 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 189 : u8 next_type = EAP_TYPE_NONE;
852 : struct eap_hdr *hdr;
853 : u8 *pos;
854 : size_t left;
855 : struct wpabuf buf;
856 189 : const struct eap_method *m = data->phase2_method;
857 189 : void *priv = data->phase2_priv;
858 :
859 189 : if (priv == NULL) {
860 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
861 : "initialized?!", __func__);
862 0 : return;
863 : }
864 :
865 189 : hdr = (struct eap_hdr *) in_data;
866 189 : pos = (u8 *) (hdr + 1);
867 :
868 189 : if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
869 17 : left = in_len - sizeof(*hdr);
870 17 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
871 : "allowed types", pos + 1, left - 1);
872 17 : eap_sm_process_nak(sm, pos + 1, left - 1);
873 34 : if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
874 17 : sm->user->methods[sm->user_eap_method_index].method !=
875 : EAP_TYPE_NONE) {
876 34 : next_type = sm->user->methods[
877 17 : sm->user_eap_method_index++].method;
878 17 : wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
879 : next_type);
880 32 : 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 15 : return;
891 : }
892 :
893 172 : wpabuf_set(&buf, in_data, in_len);
894 :
895 172 : 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 172 : m->process(sm, priv, &buf);
902 :
903 172 : 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 172 : if (!m->isDone(sm, priv))
911 108 : return;
912 :
913 64 : 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 58 : switch (data->state) {
920 : case PHASE2_START:
921 39 : 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 38 : eap_ttls_state(data, PHASE2_METHOD);
931 38 : next_type = sm->user->methods[0].method;
932 38 : sm->user_eap_method_index = 1;
933 38 : wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
934 38 : 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 38 : break;
940 : case PHASE2_METHOD:
941 19 : eap_ttls_state(data, SUCCESS);
942 19 : eap_ttls_valid_session(sm, data);
943 19 : 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 189 : 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 189 : if (data->state == PHASE2_START) {
962 39 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
963 39 : 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 189 : 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 189 : hdr = (struct eap_hdr *) eap;
978 189 : len = be_to_host16(hdr->length);
979 378 : wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
980 378 : "identifier=%d length=%lu", hdr->code, hdr->identifier,
981 : (unsigned long) len);
982 189 : 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 189 : switch (hdr->code) {
990 : case EAP_CODE_RESPONSE:
991 189 : eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
992 : len);
993 189 : 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 407 : 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 407 : wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
1010 : " Phase 2", (unsigned long) wpabuf_len(in_buf));
1011 :
1012 407 : 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 3 : return;
1021 : }
1022 :
1023 406 : in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1024 : in_buf);
1025 406 : if (in_decrypted == NULL) {
1026 1 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
1027 : "data");
1028 1 : eap_ttls_state(data, FAILURE);
1029 1 : return;
1030 : }
1031 :
1032 405 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
1033 : in_decrypted);
1034 :
1035 405 : 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 405 : if (parse.user_name) {
1043 : char *nbuf;
1044 217 : nbuf = os_malloc(parse.user_name_len * 4 + 1);
1045 217 : if (nbuf) {
1046 434 : printf_encode(nbuf, parse.user_name_len * 4 + 1,
1047 217 : parse.user_name,
1048 : parse.user_name_len);
1049 217 : eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf);
1050 217 : os_free(nbuf);
1051 : }
1052 :
1053 217 : os_free(sm->identity);
1054 217 : sm->identity = os_malloc(parse.user_name_len);
1055 217 : if (sm->identity == NULL) {
1056 0 : eap_ttls_state(data, FAILURE);
1057 0 : goto done;
1058 : }
1059 217 : os_memcpy(sm->identity, parse.user_name, parse.user_name_len);
1060 217 : sm->identity_len = parse.user_name_len;
1061 217 : if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1062 : != 0) {
1063 4 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1064 : "found in the user database");
1065 4 : eap_ttls_state(data, FAILURE);
1066 4 : goto done;
1067 : }
1068 : }
1069 :
1070 : #ifdef EAP_SERVER_TNC
1071 401 : 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 401 : if (parse.eap) {
1080 188 : eap_ttls_process_phase2_eap(sm, data, parse.eap,
1081 : parse.eap_len);
1082 213 : } else if (parse.user_password) {
1083 75 : eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1084 : parse.user_password_len);
1085 138 : } else if (parse.chap_password) {
1086 30 : eap_ttls_process_phase2_chap(sm, data,
1087 10 : parse.chap_challenge,
1088 : parse.chap_challenge_len,
1089 10 : parse.chap_password,
1090 : parse.chap_password_len);
1091 128 : } else if (parse.mschap_response) {
1092 15 : 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 113 : } else if (parse.mschap2_response) {
1098 113 : 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 405 : wpabuf_free(in_decrypted);
1107 405 : os_free(parse.eap);
1108 : }
1109 :
1110 :
1111 516 : static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data)
1112 : {
1113 : #ifdef EAP_SERVER_TNC
1114 516 : if (!sm->tnc || data->state != SUCCESS || data->tnc_started)
1115 492 : return;
1116 :
1117 24 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC");
1118 24 : 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 24 : data->tnc_started = 1;
1125 24 : eap_ttls_state(data, PHASE2_METHOD);
1126 : #endif /* EAP_SERVER_TNC */
1127 : }
1128 :
1129 :
1130 1802 : static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
1131 : int peer_version)
1132 : {
1133 1802 : struct eap_ttls_data *data = priv;
1134 1802 : 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 1802 : return 0;
1142 : }
1143 :
1144 :
1145 1124 : static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
1146 : const struct wpabuf *respData)
1147 : {
1148 1124 : struct eap_ttls_data *data = priv;
1149 :
1150 1124 : switch (data->state) {
1151 : case PHASE1:
1152 608 : if (eap_server_tls_phase1(sm, &data->ssl) < 0)
1153 22 : eap_ttls_state(data, FAILURE);
1154 608 : break;
1155 : case PHASE2_START:
1156 : case PHASE2_METHOD:
1157 407 : eap_ttls_process_phase2(sm, data, data->ssl.tls_in);
1158 407 : eap_ttls_start_tnc(sm, data);
1159 407 : break;
1160 : case PHASE2_MSCHAPV2_RESP:
1161 109 : if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) ==
1162 : 0) {
1163 108 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1164 : "acknowledged response");
1165 108 : eap_ttls_state(data, SUCCESS);
1166 108 : 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 109 : eap_ttls_start_tnc(sm, data);
1180 109 : 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 1124 : }
1187 :
1188 :
1189 1802 : static void eap_ttls_process(struct eap_sm *sm, void *priv,
1190 : struct wpabuf *respData)
1191 : {
1192 1802 : struct eap_ttls_data *data = priv;
1193 : const struct wpabuf *buf;
1194 : const u8 *pos;
1195 : u8 id_len;
1196 :
1197 1802 : 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 2632 : if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
1205 830 : !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn))
1206 1797 : 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 1847 : static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1255 : {
1256 1847 : struct eap_ttls_data *data = priv;
1257 1847 : return data->state == SUCCESS || data->state == FAILURE;
1258 : }
1259 :
1260 :
1261 247 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1262 : {
1263 247 : struct eap_ttls_data *data = priv;
1264 : u8 *eapKeyData;
1265 :
1266 247 : if (data->state != SUCCESS)
1267 45 : return NULL;
1268 :
1269 202 : eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
1270 : "ttls keying material",
1271 : EAP_TLS_KEY_LEN);
1272 202 : if (eapKeyData) {
1273 202 : *len = EAP_TLS_KEY_LEN;
1274 202 : 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 202 : return eapKeyData;
1281 : }
1282 :
1283 :
1284 292 : static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1285 : {
1286 292 : struct eap_ttls_data *data = priv;
1287 292 : return data->state == SUCCESS;
1288 : }
1289 :
1290 :
1291 247 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1292 : {
1293 247 : struct eap_ttls_data *data = priv;
1294 :
1295 247 : if (data->state != SUCCESS)
1296 45 : return NULL;
1297 :
1298 202 : return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS,
1299 : len);
1300 : }
1301 :
1302 :
1303 21 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1304 : {
1305 21 : struct eap_ttls_data *data = priv;
1306 : u8 *eapKeyData, *emsk;
1307 :
1308 21 : if (data->state != SUCCESS)
1309 0 : return NULL;
1310 :
1311 21 : eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
1312 : "ttls keying material",
1313 : EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
1314 21 : if (eapKeyData) {
1315 21 : emsk = os_malloc(EAP_EMSK_LEN);
1316 21 : if (emsk)
1317 21 : os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
1318 : EAP_EMSK_LEN);
1319 21 : bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
1320 : } else
1321 0 : emsk = NULL;
1322 :
1323 21 : if (emsk) {
1324 21 : *len = EAP_EMSK_LEN;
1325 21 : 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 21 : return emsk;
1332 : }
1333 :
1334 :
1335 25 : int eap_server_ttls_register(void)
1336 : {
1337 : struct eap_method *eap;
1338 :
1339 25 : eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1340 : EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
1341 25 : if (eap == NULL)
1342 0 : return -1;
1343 :
1344 25 : eap->init = eap_ttls_init;
1345 25 : eap->reset = eap_ttls_reset;
1346 25 : eap->buildReq = eap_ttls_buildReq;
1347 25 : eap->check = eap_ttls_check;
1348 25 : eap->process = eap_ttls_process;
1349 25 : eap->isDone = eap_ttls_isDone;
1350 25 : eap->getKey = eap_ttls_getKey;
1351 25 : eap->isSuccess = eap_ttls_isSuccess;
1352 25 : eap->getSessionId = eap_ttls_get_session_id;
1353 25 : eap->get_emsk = eap_ttls_get_emsk;
1354 :
1355 25 : return eap_server_method_register(eap);
1356 : }
|