Line data Source code
1 : /*
2 : * EAP peer method: EAP-TTLS (RFC 5281)
3 : * Copyright (c) 2004-2015, 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_common/chap.h"
16 : #include "eap_common/eap_ttls.h"
17 : #include "mschapv2.h"
18 : #include "eap_i.h"
19 : #include "eap_tls_common.h"
20 : #include "eap_config.h"
21 :
22 :
23 : #define EAP_TTLS_VERSION 0
24 :
25 :
26 : static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
27 :
28 :
29 : struct eap_ttls_data {
30 : struct eap_ssl_data ssl;
31 :
32 : int ttls_version;
33 :
34 : const struct eap_method *phase2_method;
35 : void *phase2_priv;
36 : int phase2_success;
37 : int phase2_start;
38 : EapDecision decision_succ;
39 :
40 : enum phase2_types {
41 : EAP_TTLS_PHASE2_EAP,
42 : EAP_TTLS_PHASE2_MSCHAPV2,
43 : EAP_TTLS_PHASE2_MSCHAP,
44 : EAP_TTLS_PHASE2_PAP,
45 : EAP_TTLS_PHASE2_CHAP
46 : } phase2_type;
47 : struct eap_method_type phase2_eap_type;
48 : struct eap_method_type *phase2_eap_types;
49 : size_t num_phase2_eap_types;
50 :
51 : u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN];
52 : int auth_response_valid;
53 : u8 master_key[MSCHAPV2_MASTER_KEY_LEN]; /* MSCHAPv2 master key */
54 : u8 ident;
55 : int resuming; /* starting a resumed session */
56 : int reauth; /* reauthentication */
57 : u8 *key_data;
58 : u8 *session_id;
59 : size_t id_len;
60 :
61 : struct wpabuf *pending_phase2_req;
62 : struct wpabuf *pending_resp;
63 :
64 : #ifdef EAP_TNC
65 : int ready_for_tnc;
66 : int tnc_started;
67 : #endif /* EAP_TNC */
68 : };
69 :
70 :
71 300 : static void * eap_ttls_init(struct eap_sm *sm)
72 : {
73 : struct eap_ttls_data *data;
74 300 : struct eap_peer_config *config = eap_get_config(sm);
75 : int selected_non_eap;
76 : char *selected;
77 :
78 300 : data = os_zalloc(sizeof(*data));
79 300 : if (data == NULL)
80 1 : return NULL;
81 299 : data->ttls_version = EAP_TTLS_VERSION;
82 299 : selected = "EAP";
83 299 : selected_non_eap = 0;
84 299 : data->phase2_type = EAP_TTLS_PHASE2_EAP;
85 :
86 : /*
87 : * Either one auth= type or one or more autheap= methods can be
88 : * specified.
89 : */
90 299 : if (config && config->phase2) {
91 293 : const char *token, *last = NULL;
92 :
93 882 : while ((token = cstr_token(config->phase2, " \t", &last))) {
94 298 : if (os_strncmp(token, "auth=", 5) != 0)
95 48 : continue;
96 250 : token += 5;
97 :
98 385 : if (last - token == 8 &&
99 135 : os_strncmp(token, "MSCHAPV2", 8) == 0) {
100 134 : selected = "MSCHAPV2";
101 134 : data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
102 136 : } else if (last - token == 6 &&
103 20 : os_strncmp(token, "MSCHAP", 6) == 0) {
104 20 : selected = "MSCHAP";
105 20 : data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
106 180 : } else if (last - token == 3 &&
107 84 : os_strncmp(token, "PAP", 3) == 0) {
108 84 : selected = "PAP";
109 84 : data->phase2_type = EAP_TTLS_PHASE2_PAP;
110 23 : } else if (last - token == 4 &&
111 11 : os_strncmp(token, "CHAP", 4) == 0) {
112 11 : selected = "CHAP";
113 11 : data->phase2_type = EAP_TTLS_PHASE2_CHAP;
114 : } else {
115 1 : wpa_printf(MSG_ERROR,
116 : "EAP-TTLS: Unsupported Phase2 type '%s'",
117 : token);
118 1 : eap_ttls_deinit(sm, data);
119 5 : return NULL;
120 : }
121 :
122 249 : if (selected_non_eap) {
123 1 : wpa_printf(MSG_ERROR,
124 : "EAP-TTLS: Only one Phase2 type can be specified");
125 1 : eap_ttls_deinit(sm, data);
126 1 : return NULL;
127 : }
128 :
129 248 : selected_non_eap = 1;
130 : }
131 :
132 291 : if (os_strstr(config->phase2, "autheap=")) {
133 46 : if (selected_non_eap) {
134 2 : wpa_printf(MSG_ERROR,
135 : "EAP-TTLS: Both auth= and autheap= params cannot be specified");
136 2 : eap_ttls_deinit(sm, data);
137 2 : return NULL;
138 : }
139 44 : selected = "EAP";
140 44 : data->phase2_type = EAP_TTLS_PHASE2_EAP;
141 : }
142 : }
143 :
144 295 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
145 :
146 295 : if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
147 50 : if (eap_peer_select_phase2_methods(config, "autheap=",
148 : &data->phase2_eap_types,
149 : &data->num_phase2_eap_types)
150 : < 0) {
151 3 : eap_ttls_deinit(sm, data);
152 3 : return NULL;
153 : }
154 :
155 47 : data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
156 47 : data->phase2_eap_type.method = EAP_TYPE_NONE;
157 : }
158 :
159 292 : if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TTLS)) {
160 5 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
161 5 : eap_ttls_deinit(sm, data);
162 5 : return NULL;
163 : }
164 :
165 287 : return data;
166 : }
167 :
168 :
169 299 : static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm,
170 : struct eap_ttls_data *data)
171 : {
172 299 : if (data->phase2_priv && data->phase2_method) {
173 39 : data->phase2_method->deinit(sm, data->phase2_priv);
174 39 : data->phase2_method = NULL;
175 39 : data->phase2_priv = NULL;
176 : }
177 299 : }
178 :
179 :
180 600 : static void eap_ttls_free_key(struct eap_ttls_data *data)
181 : {
182 600 : if (data->key_data) {
183 277 : bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
184 277 : data->key_data = NULL;
185 : }
186 600 : }
187 :
188 :
189 299 : static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
190 : {
191 299 : struct eap_ttls_data *data = priv;
192 299 : if (data == NULL)
193 299 : return;
194 299 : eap_ttls_phase2_eap_deinit(sm, data);
195 299 : os_free(data->phase2_eap_types);
196 299 : eap_peer_tls_ssl_deinit(sm, &data->ssl);
197 299 : eap_ttls_free_key(data);
198 299 : os_free(data->session_id);
199 299 : wpabuf_free(data->pending_phase2_req);
200 299 : wpabuf_free(data->pending_resp);
201 299 : os_free(data);
202 : }
203 :
204 :
205 785 : static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
206 : int mandatory, size_t len)
207 : {
208 : struct ttls_avp_vendor *avp;
209 : u8 flags;
210 : size_t hdrlen;
211 :
212 785 : avp = (struct ttls_avp_vendor *) avphdr;
213 785 : flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
214 785 : if (vendor_id) {
215 270 : flags |= AVP_FLAGS_VENDOR;
216 270 : hdrlen = sizeof(*avp);
217 270 : avp->vendor_id = host_to_be32(vendor_id);
218 : } else {
219 515 : hdrlen = sizeof(struct ttls_avp);
220 : }
221 :
222 785 : avp->avp_code = host_to_be32(avp_code);
223 785 : avp->avp_length = host_to_be32(((u32) flags << 24) |
224 : (u32) (hdrlen + len));
225 :
226 785 : return avphdr + hdrlen;
227 : }
228 :
229 :
230 371 : static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
231 : u32 vendor_id, int mandatory,
232 : const u8 *data, size_t len)
233 : {
234 : u8 *pos;
235 371 : pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
236 371 : os_memcpy(pos, data, len);
237 371 : pos += len;
238 371 : AVP_PAD(start, pos);
239 371 : return pos;
240 : }
241 :
242 :
243 193 : static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
244 : int mandatory)
245 : {
246 : struct wpabuf *msg;
247 : u8 *avp, *pos;
248 :
249 193 : msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
250 193 : if (msg == NULL) {
251 2 : wpabuf_free(*resp);
252 2 : *resp = NULL;
253 2 : return -1;
254 : }
255 :
256 191 : avp = wpabuf_mhead(msg);
257 191 : pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp));
258 191 : os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
259 191 : pos += wpabuf_len(*resp);
260 191 : AVP_PAD(avp, pos);
261 191 : wpabuf_free(*resp);
262 191 : wpabuf_put(msg, pos - avp);
263 191 : *resp = msg;
264 191 : return 0;
265 : }
266 :
267 :
268 278 : static int eap_ttls_v0_derive_key(struct eap_sm *sm,
269 : struct eap_ttls_data *data)
270 : {
271 278 : eap_ttls_free_key(data);
272 278 : data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
273 : "ttls keying material",
274 : EAP_TLS_KEY_LEN +
275 : EAP_EMSK_LEN);
276 278 : if (!data->key_data) {
277 1 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to derive key");
278 1 : return -1;
279 : }
280 :
281 277 : wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
282 277 : data->key_data, EAP_TLS_KEY_LEN);
283 277 : wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
284 277 : data->key_data + EAP_TLS_KEY_LEN,
285 : EAP_EMSK_LEN);
286 :
287 277 : os_free(data->session_id);
288 277 : data->session_id = eap_peer_tls_derive_session_id(sm, &data->ssl,
289 : EAP_TYPE_TTLS,
290 : &data->id_len);
291 277 : if (data->session_id) {
292 552 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived Session-Id",
293 276 : data->session_id, data->id_len);
294 : } else {
295 1 : wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to derive Session-Id");
296 : }
297 :
298 277 : return 0;
299 : }
300 :
301 :
302 : #ifndef CONFIG_FIPS
303 148 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
304 : struct eap_ttls_data *data, size_t len)
305 : {
306 148 : return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
307 : }
308 : #endif /* CONFIG_FIPS */
309 :
310 :
311 42 : static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
312 : u8 method)
313 : {
314 : size_t i;
315 118 : for (i = 0; i < data->num_phase2_eap_types; i++) {
316 86 : if (data->phase2_eap_types[i].vendor != EAP_VENDOR_IETF ||
317 43 : data->phase2_eap_types[i].method != method)
318 17 : continue;
319 :
320 26 : data->phase2_eap_type.vendor =
321 26 : data->phase2_eap_types[i].vendor;
322 26 : data->phase2_eap_type.method =
323 26 : data->phase2_eap_types[i].method;
324 26 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
325 : "Phase 2 EAP vendor %d method %d",
326 : data->phase2_eap_type.vendor,
327 : data->phase2_eap_type.method);
328 26 : break;
329 : }
330 42 : }
331 :
332 :
333 146 : static int eap_ttls_phase2_eap_process(struct eap_sm *sm,
334 : struct eap_ttls_data *data,
335 : struct eap_method_ret *ret,
336 : struct eap_hdr *hdr, size_t len,
337 : struct wpabuf **resp)
338 : {
339 : struct wpabuf msg;
340 : struct eap_method_ret iret;
341 :
342 146 : os_memset(&iret, 0, sizeof(iret));
343 146 : wpabuf_set(&msg, hdr, len);
344 146 : *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
345 : &msg);
346 270 : if ((iret.methodState == METHOD_DONE ||
347 207 : iret.methodState == METHOD_MAY_CONT) &&
348 150 : (iret.decision == DECISION_UNCOND_SUCC ||
349 121 : iret.decision == DECISION_COND_SUCC ||
350 54 : iret.decision == DECISION_FAIL)) {
351 83 : ret->methodState = iret.methodState;
352 83 : ret->decision = iret.decision;
353 : }
354 :
355 146 : return 0;
356 : }
357 :
358 :
359 175 : static int eap_ttls_phase2_request_eap_method(struct eap_sm *sm,
360 : struct eap_ttls_data *data,
361 : struct eap_method_ret *ret,
362 : struct eap_hdr *hdr, size_t len,
363 : u8 method, struct wpabuf **resp)
364 : {
365 : #ifdef EAP_TNC
366 266 : if (data->tnc_started && data->phase2_method &&
367 273 : data->phase2_priv && method == EAP_TYPE_TNC &&
368 91 : data->phase2_eap_type.method == EAP_TYPE_TNC)
369 91 : return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len,
370 : resp);
371 :
372 84 : if (data->ready_for_tnc && !data->tnc_started &&
373 : method == EAP_TYPE_TNC) {
374 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
375 : "EAP method");
376 0 : data->tnc_started = 1;
377 : }
378 :
379 84 : if (data->tnc_started) {
380 48 : if (data->phase2_eap_type.vendor != EAP_VENDOR_IETF ||
381 24 : data->phase2_eap_type.method == EAP_TYPE_TNC) {
382 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected EAP "
383 : "type %d for TNC", method);
384 0 : return -1;
385 : }
386 :
387 24 : data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
388 24 : data->phase2_eap_type.method = method;
389 24 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
390 : "Phase 2 EAP vendor %d method %d (TNC)",
391 : data->phase2_eap_type.vendor,
392 : data->phase2_eap_type.method);
393 :
394 24 : if (data->phase2_type == EAP_TTLS_PHASE2_EAP)
395 0 : eap_ttls_phase2_eap_deinit(sm, data);
396 : }
397 : #endif /* EAP_TNC */
398 :
399 168 : if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF &&
400 84 : data->phase2_eap_type.method == EAP_TYPE_NONE)
401 42 : eap_ttls_phase2_select_eap_method(data, method);
402 :
403 84 : if (method != data->phase2_eap_type.method || method == EAP_TYPE_NONE)
404 : {
405 18 : if (eap_peer_tls_phase2_nak(data->phase2_eap_types,
406 : data->num_phase2_eap_types,
407 : hdr, resp))
408 1 : return -1;
409 17 : return 0;
410 : }
411 :
412 66 : if (data->phase2_priv == NULL) {
413 50 : data->phase2_method = eap_peer_get_eap_method(
414 : EAP_VENDOR_IETF, method);
415 50 : if (data->phase2_method) {
416 50 : sm->init_phase2 = 1;
417 50 : data->phase2_priv = data->phase2_method->init(sm);
418 50 : sm->init_phase2 = 0;
419 : }
420 : }
421 66 : if (data->phase2_priv == NULL || data->phase2_method == NULL) {
422 11 : wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
423 : "Phase 2 EAP method %d", method);
424 11 : return -1;
425 : }
426 :
427 55 : return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, resp);
428 : }
429 :
430 :
431 217 : static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
432 : struct eap_ttls_data *data,
433 : struct eap_method_ret *ret,
434 : struct eap_hdr *hdr,
435 : struct wpabuf **resp)
436 : {
437 217 : size_t len = be_to_host16(hdr->length);
438 : u8 *pos;
439 217 : struct eap_peer_config *config = eap_get_config(sm);
440 :
441 217 : if (len <= sizeof(struct eap_hdr)) {
442 0 : wpa_printf(MSG_INFO, "EAP-TTLS: too short "
443 : "Phase 2 request (len=%lu)", (unsigned long) len);
444 0 : return -1;
445 : }
446 217 : pos = (u8 *) (hdr + 1);
447 217 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
448 217 : switch (*pos) {
449 : case EAP_TYPE_IDENTITY:
450 42 : *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
451 42 : break;
452 : default:
453 175 : if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len,
454 175 : *pos, resp) < 0)
455 12 : return -1;
456 163 : break;
457 : }
458 :
459 217 : if (*resp == NULL &&
460 34 : (config->pending_req_identity || config->pending_req_password ||
461 10 : config->pending_req_otp)) {
462 2 : return 0;
463 : }
464 :
465 203 : if (*resp == NULL)
466 10 : return -1;
467 :
468 193 : wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
469 : *resp);
470 193 : return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1);
471 : }
472 :
473 :
474 121 : static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
475 : struct eap_ttls_data *data,
476 : struct eap_method_ret *ret,
477 : struct wpabuf **resp)
478 : {
479 : #ifdef CONFIG_FIPS
480 : wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPV2 not supported in FIPS build");
481 : return -1;
482 : #else /* CONFIG_FIPS */
483 : #ifdef EAP_MSCHAPv2
484 : struct wpabuf *msg;
485 : u8 *buf, *pos, *challenge, *peer_challenge;
486 : const u8 *identity, *password;
487 : size_t identity_len, password_len;
488 : int pwhash;
489 :
490 121 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
491 :
492 121 : identity = eap_get_config_identity(sm, &identity_len);
493 121 : password = eap_get_config_password2(sm, &password_len, &pwhash);
494 121 : if (identity == NULL || password == NULL)
495 0 : return -1;
496 :
497 121 : msg = wpabuf_alloc(identity_len + 1000);
498 121 : if (msg == NULL) {
499 1 : wpa_printf(MSG_ERROR,
500 : "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
501 1 : return -1;
502 : }
503 120 : pos = buf = wpabuf_mhead(msg);
504 :
505 : /* User-Name */
506 120 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
507 : identity, identity_len);
508 :
509 : /* MS-CHAP-Challenge */
510 120 : challenge = eap_ttls_implicit_challenge(
511 : sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
512 120 : if (challenge == NULL) {
513 1 : wpabuf_free(msg);
514 1 : wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
515 : "implicit challenge");
516 1 : return -1;
517 : }
518 :
519 119 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
520 : RADIUS_VENDOR_ID_MICROSOFT, 1,
521 : challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
522 :
523 : /* MS-CHAP2-Response */
524 119 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,
525 : RADIUS_VENDOR_ID_MICROSOFT, 1,
526 : EAP_TTLS_MSCHAPV2_RESPONSE_LEN);
527 119 : data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
528 119 : *pos++ = data->ident;
529 119 : *pos++ = 0; /* Flags */
530 119 : if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
531 1 : os_free(challenge);
532 1 : wpabuf_free(msg);
533 1 : wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
534 : "random data for peer challenge");
535 1 : return -1;
536 : }
537 118 : peer_challenge = pos;
538 118 : pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
539 118 : os_memset(pos, 0, 8); /* Reserved, must be zero */
540 118 : pos += 8;
541 118 : if (mschapv2_derive_response(identity, identity_len, password,
542 : password_len, pwhash, challenge,
543 118 : peer_challenge, pos, data->auth_response,
544 118 : data->master_key)) {
545 4 : os_free(challenge);
546 4 : wpabuf_free(msg);
547 4 : wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
548 : "response");
549 4 : return -1;
550 : }
551 114 : data->auth_response_valid = 1;
552 :
553 114 : pos += 24;
554 114 : os_free(challenge);
555 114 : AVP_PAD(buf, pos);
556 :
557 114 : wpabuf_put(msg, pos - buf);
558 114 : *resp = msg;
559 :
560 114 : return 0;
561 : #else /* EAP_MSCHAPv2 */
562 : wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
563 : return -1;
564 : #endif /* EAP_MSCHAPv2 */
565 : #endif /* CONFIG_FIPS */
566 : }
567 :
568 :
569 18 : static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
570 : struct eap_ttls_data *data,
571 : struct eap_method_ret *ret,
572 : struct wpabuf **resp)
573 : {
574 : #ifdef CONFIG_FIPS
575 : wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAP not supported in FIPS build");
576 : return -1;
577 : #else /* CONFIG_FIPS */
578 : struct wpabuf *msg;
579 : u8 *buf, *pos, *challenge;
580 : const u8 *identity, *password;
581 : size_t identity_len, password_len;
582 : int pwhash;
583 :
584 18 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
585 :
586 18 : identity = eap_get_config_identity(sm, &identity_len);
587 18 : password = eap_get_config_password2(sm, &password_len, &pwhash);
588 18 : if (identity == NULL || password == NULL)
589 0 : return -1;
590 :
591 18 : msg = wpabuf_alloc(identity_len + 1000);
592 18 : if (msg == NULL) {
593 1 : wpa_printf(MSG_ERROR,
594 : "EAP-TTLS/MSCHAP: Failed to allocate memory");
595 1 : return -1;
596 : }
597 17 : pos = buf = wpabuf_mhead(msg);
598 :
599 : /* User-Name */
600 17 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
601 : identity, identity_len);
602 :
603 : /* MS-CHAP-Challenge */
604 17 : challenge = eap_ttls_implicit_challenge(
605 : sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
606 17 : if (challenge == NULL) {
607 1 : wpabuf_free(msg);
608 1 : wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
609 : "implicit challenge");
610 1 : return -1;
611 : }
612 :
613 16 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
614 : RADIUS_VENDOR_ID_MICROSOFT, 1,
615 : challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
616 :
617 : /* MS-CHAP-Response */
618 16 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,
619 : RADIUS_VENDOR_ID_MICROSOFT, 1,
620 : EAP_TTLS_MSCHAP_RESPONSE_LEN);
621 16 : data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];
622 16 : *pos++ = data->ident;
623 16 : *pos++ = 1; /* Flags: Use NT style passwords */
624 16 : os_memset(pos, 0, 24); /* LM-Response */
625 16 : pos += 24;
626 16 : if (pwhash) {
627 1 : challenge_response(challenge, password, pos); /* NT-Response */
628 1 : wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash",
629 : password, 16);
630 : } else {
631 15 : nt_challenge_response(challenge, password, password_len,
632 : pos); /* NT-Response */
633 15 : wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
634 : password, password_len);
635 : }
636 16 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
637 : challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
638 16 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
639 16 : pos += 24;
640 16 : os_free(challenge);
641 16 : AVP_PAD(buf, pos);
642 :
643 16 : wpabuf_put(msg, pos - buf);
644 16 : *resp = msg;
645 :
646 : /* EAP-TTLS/MSCHAP does not provide tunneled success
647 : * notification, so assume that Phase2 succeeds. */
648 16 : ret->methodState = METHOD_DONE;
649 16 : ret->decision = DECISION_COND_SUCC;
650 :
651 16 : return 0;
652 : #endif /* CONFIG_FIPS */
653 : }
654 :
655 :
656 79 : static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
657 : struct eap_ttls_data *data,
658 : struct eap_method_ret *ret,
659 : struct wpabuf **resp)
660 : {
661 : struct wpabuf *msg;
662 : u8 *buf, *pos;
663 : size_t pad;
664 : const u8 *identity, *password;
665 : size_t identity_len, password_len;
666 :
667 79 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
668 :
669 79 : identity = eap_get_config_identity(sm, &identity_len);
670 79 : password = eap_get_config_password(sm, &password_len);
671 79 : if (identity == NULL || password == NULL)
672 0 : return -1;
673 :
674 79 : msg = wpabuf_alloc(identity_len + password_len + 100);
675 79 : if (msg == NULL) {
676 1 : wpa_printf(MSG_ERROR,
677 : "EAP-TTLS/PAP: Failed to allocate memory");
678 1 : return -1;
679 : }
680 78 : pos = buf = wpabuf_mhead(msg);
681 :
682 : /* User-Name */
683 78 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
684 : identity, identity_len);
685 :
686 : /* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
687 : * the data, so no separate encryption is used in the AVP itself.
688 : * However, the password is padded to obfuscate its length. */
689 78 : pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15;
690 78 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
691 : password_len + pad);
692 78 : os_memcpy(pos, password, password_len);
693 78 : pos += password_len;
694 78 : os_memset(pos, 0, pad);
695 78 : pos += pad;
696 78 : AVP_PAD(buf, pos);
697 :
698 78 : wpabuf_put(msg, pos - buf);
699 78 : *resp = msg;
700 :
701 : /* EAP-TTLS/PAP does not provide tunneled success notification,
702 : * so assume that Phase2 succeeds. */
703 78 : ret->methodState = METHOD_DONE;
704 78 : ret->decision = DECISION_COND_SUCC;
705 :
706 78 : return 0;
707 : }
708 :
709 :
710 12 : static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
711 : struct eap_ttls_data *data,
712 : struct eap_method_ret *ret,
713 : struct wpabuf **resp)
714 : {
715 : #ifdef CONFIG_FIPS
716 : wpa_printf(MSG_ERROR, "EAP-TTLS: CHAP not supported in FIPS build");
717 : return -1;
718 : #else /* CONFIG_FIPS */
719 : struct wpabuf *msg;
720 : u8 *buf, *pos, *challenge;
721 : const u8 *identity, *password;
722 : size_t identity_len, password_len;
723 :
724 12 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
725 :
726 12 : identity = eap_get_config_identity(sm, &identity_len);
727 12 : password = eap_get_config_password(sm, &password_len);
728 12 : if (identity == NULL || password == NULL)
729 0 : return -1;
730 :
731 12 : msg = wpabuf_alloc(identity_len + 1000);
732 12 : if (msg == NULL) {
733 1 : wpa_printf(MSG_ERROR,
734 : "EAP-TTLS/CHAP: Failed to allocate memory");
735 1 : return -1;
736 : }
737 11 : pos = buf = wpabuf_mhead(msg);
738 :
739 : /* User-Name */
740 11 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
741 : identity, identity_len);
742 :
743 : /* CHAP-Challenge */
744 11 : challenge = eap_ttls_implicit_challenge(
745 : sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
746 11 : if (challenge == NULL) {
747 1 : wpabuf_free(msg);
748 1 : wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
749 : "implicit challenge");
750 1 : return -1;
751 : }
752 :
753 10 : pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,
754 : challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
755 :
756 : /* CHAP-Password */
757 10 : pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,
758 : 1 + EAP_TTLS_CHAP_PASSWORD_LEN);
759 10 : data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];
760 10 : *pos++ = data->ident;
761 :
762 : /* MD5(Ident + Password + Challenge) */
763 10 : chap_md5(data->ident, password, password_len, challenge,
764 : EAP_TTLS_CHAP_CHALLENGE_LEN, pos);
765 :
766 10 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
767 : identity, identity_len);
768 10 : wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
769 : password, password_len);
770 10 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
771 : challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
772 10 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
773 : pos, EAP_TTLS_CHAP_PASSWORD_LEN);
774 10 : pos += EAP_TTLS_CHAP_PASSWORD_LEN;
775 10 : os_free(challenge);
776 10 : AVP_PAD(buf, pos);
777 :
778 10 : wpabuf_put(msg, pos - buf);
779 10 : *resp = msg;
780 :
781 : /* EAP-TTLS/CHAP does not provide tunneled success
782 : * notification, so assume that Phase2 succeeds. */
783 10 : ret->methodState = METHOD_DONE;
784 10 : ret->decision = DECISION_COND_SUCC;
785 :
786 10 : return 0;
787 : #endif /* CONFIG_FIPS */
788 : }
789 :
790 :
791 452 : static int eap_ttls_phase2_request(struct eap_sm *sm,
792 : struct eap_ttls_data *data,
793 : struct eap_method_ret *ret,
794 : struct eap_hdr *hdr,
795 : struct wpabuf **resp)
796 : {
797 452 : int res = 0;
798 : size_t len;
799 452 : enum phase2_types phase2_type = data->phase2_type;
800 :
801 : #ifdef EAP_TNC
802 452 : if (data->tnc_started) {
803 115 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC");
804 115 : phase2_type = EAP_TTLS_PHASE2_EAP;
805 : }
806 : #endif /* EAP_TNC */
807 :
808 452 : if (phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||
809 309 : phase2_type == EAP_TTLS_PHASE2_MSCHAP ||
810 229 : phase2_type == EAP_TTLS_PHASE2_PAP ||
811 : phase2_type == EAP_TTLS_PHASE2_CHAP) {
812 235 : if (eap_get_config_identity(sm, &len) == NULL) {
813 2 : wpa_printf(MSG_INFO,
814 : "EAP-TTLS: Identity not configured");
815 2 : eap_sm_request_identity(sm);
816 2 : if (eap_get_config_password(sm, &len) == NULL)
817 1 : eap_sm_request_password(sm);
818 2 : return 0;
819 : }
820 :
821 233 : if (eap_get_config_password(sm, &len) == NULL) {
822 3 : wpa_printf(MSG_INFO,
823 : "EAP-TTLS: Password not configured");
824 3 : eap_sm_request_password(sm);
825 3 : return 0;
826 : }
827 : }
828 :
829 447 : switch (phase2_type) {
830 : case EAP_TTLS_PHASE2_EAP:
831 217 : res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
832 217 : break;
833 : case EAP_TTLS_PHASE2_MSCHAPV2:
834 121 : res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);
835 121 : break;
836 : case EAP_TTLS_PHASE2_MSCHAP:
837 18 : res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);
838 18 : break;
839 : case EAP_TTLS_PHASE2_PAP:
840 79 : res = eap_ttls_phase2_request_pap(sm, data, ret, resp);
841 79 : break;
842 : case EAP_TTLS_PHASE2_CHAP:
843 12 : res = eap_ttls_phase2_request_chap(sm, data, ret, resp);
844 12 : break;
845 : default:
846 0 : wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
847 0 : res = -1;
848 0 : break;
849 : }
850 :
851 447 : if (res < 0) {
852 36 : ret->methodState = METHOD_DONE;
853 36 : ret->decision = DECISION_FAIL;
854 : }
855 :
856 447 : return res;
857 : }
858 :
859 :
860 : struct ttls_parse_avp {
861 : u8 *mschapv2;
862 : u8 *eapdata;
863 : size_t eap_len;
864 : int mschapv2_error;
865 : };
866 :
867 :
868 176 : static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen,
869 : struct ttls_parse_avp *parse)
870 : {
871 176 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
872 176 : if (parse->eapdata == NULL) {
873 176 : parse->eapdata = os_malloc(dlen);
874 176 : if (parse->eapdata == NULL) {
875 1 : wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
876 : "memory for Phase 2 EAP data");
877 1 : return -1;
878 : }
879 175 : os_memcpy(parse->eapdata, dpos, dlen);
880 175 : parse->eap_len = dlen;
881 : } else {
882 0 : u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen);
883 0 : if (neweap == NULL) {
884 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
885 : "memory for Phase 2 EAP data");
886 0 : return -1;
887 : }
888 0 : os_memcpy(neweap + parse->eap_len, dpos, dlen);
889 0 : parse->eapdata = neweap;
890 0 : parse->eap_len += dlen;
891 : }
892 :
893 175 : return 0;
894 : }
895 :
896 :
897 285 : static int eap_ttls_parse_avp(u8 *pos, size_t left,
898 : struct ttls_parse_avp *parse)
899 : {
900 : struct ttls_avp *avp;
901 285 : u32 avp_code, avp_length, vendor_id = 0;
902 : u8 avp_flags, *dpos;
903 : size_t dlen;
904 :
905 285 : avp = (struct ttls_avp *) pos;
906 285 : avp_code = be_to_host32(avp->avp_code);
907 285 : avp_length = be_to_host32(avp->avp_length);
908 285 : avp_flags = (avp_length >> 24) & 0xff;
909 285 : avp_length &= 0xffffff;
910 285 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
911 : "length=%d", (int) avp_code, avp_flags,
912 : (int) avp_length);
913 :
914 285 : if (avp_length > left) {
915 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
916 : "(len=%d, left=%lu) - dropped",
917 : (int) avp_length, (unsigned long) left);
918 0 : return -1;
919 : }
920 :
921 285 : if (avp_length < sizeof(*avp)) {
922 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d",
923 : avp_length);
924 0 : return -1;
925 : }
926 :
927 285 : dpos = (u8 *) (avp + 1);
928 285 : dlen = avp_length - sizeof(*avp);
929 285 : if (avp_flags & AVP_FLAGS_VENDOR) {
930 109 : if (dlen < 4) {
931 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP "
932 : "underflow");
933 0 : return -1;
934 : }
935 109 : vendor_id = WPA_GET_BE32(dpos);
936 109 : wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
937 : (int) vendor_id);
938 109 : dpos += 4;
939 109 : dlen -= 4;
940 : }
941 :
942 285 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
943 :
944 285 : if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
945 351 : if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0)
946 1 : return -1;
947 109 : } else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) {
948 : /* This is an optional message that can be displayed to
949 : * the user. */
950 0 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message",
951 : dpos, dlen);
952 109 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
953 : avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {
954 108 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success",
955 : dpos, dlen);
956 108 : if (dlen != 43) {
957 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "
958 : "MS-CHAP2-Success length "
959 : "(len=%lu, expected 43)",
960 : (unsigned long) dlen);
961 0 : return -1;
962 : }
963 108 : parse->mschapv2 = dpos;
964 1 : } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
965 : avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {
966 1 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error",
967 : dpos, dlen);
968 1 : parse->mschapv2_error = 1;
969 0 : } else if (avp_flags & AVP_FLAGS_MANDATORY) {
970 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP "
971 : "code %d vendor_id %d - dropped",
972 : (int) avp_code, (int) vendor_id);
973 0 : return -1;
974 : } else {
975 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP "
976 : "code %d vendor_id %d",
977 : (int) avp_code, (int) vendor_id);
978 : }
979 :
980 284 : return avp_length;
981 : }
982 :
983 :
984 285 : static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,
985 : struct ttls_parse_avp *parse)
986 : {
987 : u8 *pos;
988 : size_t left, pad;
989 : int avp_length;
990 :
991 285 : pos = wpabuf_mhead(in_decrypted);
992 285 : left = wpabuf_len(in_decrypted);
993 285 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);
994 285 : if (left < sizeof(struct ttls_avp)) {
995 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
996 : " len=%lu expected %lu or more - dropped",
997 : (unsigned long) left,
998 : (unsigned long) sizeof(struct ttls_avp));
999 0 : return -1;
1000 : }
1001 :
1002 : /* Parse AVPs */
1003 285 : os_memset(parse, 0, sizeof(*parse));
1004 :
1005 854 : while (left > 0) {
1006 285 : avp_length = eap_ttls_parse_avp(pos, left, parse);
1007 285 : if (avp_length < 0)
1008 1 : return -1;
1009 :
1010 284 : pad = (4 - (avp_length & 3)) & 3;
1011 284 : pos += avp_length + pad;
1012 284 : if (left < avp_length + pad)
1013 108 : left = 0;
1014 : else
1015 176 : left -= avp_length + pad;
1016 : }
1017 :
1018 284 : return 0;
1019 : }
1020 :
1021 :
1022 278 : static u8 * eap_ttls_fake_identity_request(void)
1023 : {
1024 : struct eap_hdr *hdr;
1025 : u8 *buf;
1026 :
1027 278 : wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "
1028 : "Phase 2 - use fake EAP-Request Identity");
1029 278 : buf = os_malloc(sizeof(*hdr) + 1);
1030 278 : if (buf == NULL) {
1031 1 : wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "
1032 : "memory for fake EAP-Identity Request");
1033 1 : return NULL;
1034 : }
1035 :
1036 277 : hdr = (struct eap_hdr *) buf;
1037 277 : hdr->code = EAP_CODE_REQUEST;
1038 277 : hdr->identifier = 0;
1039 277 : hdr->length = host_to_be16(sizeof(*hdr) + 1);
1040 277 : buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY;
1041 :
1042 277 : return buf;
1043 : }
1044 :
1045 :
1046 414 : static int eap_ttls_encrypt_response(struct eap_sm *sm,
1047 : struct eap_ttls_data *data,
1048 : struct wpabuf *resp, u8 identifier,
1049 : struct wpabuf **out_data)
1050 : {
1051 414 : if (resp == NULL)
1052 5 : return 0;
1053 :
1054 409 : wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
1055 : resp);
1056 409 : if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
1057 : data->ttls_version, identifier,
1058 : resp, out_data)) {
1059 2 : wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
1060 : "frame");
1061 2 : wpabuf_free(resp);
1062 2 : return -1;
1063 : }
1064 407 : wpabuf_free(resp);
1065 :
1066 407 : return 0;
1067 : }
1068 :
1069 :
1070 175 : static int eap_ttls_process_phase2_eap(struct eap_sm *sm,
1071 : struct eap_ttls_data *data,
1072 : struct eap_method_ret *ret,
1073 : struct ttls_parse_avp *parse,
1074 : struct wpabuf **resp)
1075 : {
1076 : struct eap_hdr *hdr;
1077 : size_t len;
1078 :
1079 175 : if (parse->eapdata == NULL) {
1080 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the "
1081 : "packet - dropped");
1082 0 : return -1;
1083 : }
1084 :
1085 350 : wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",
1086 175 : parse->eapdata, parse->eap_len);
1087 175 : hdr = (struct eap_hdr *) parse->eapdata;
1088 :
1089 175 : if (parse->eap_len < sizeof(*hdr)) {
1090 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP "
1091 : "frame (len=%lu, expected %lu or more) - dropped",
1092 : (unsigned long) parse->eap_len,
1093 : (unsigned long) sizeof(*hdr));
1094 0 : return -1;
1095 : }
1096 175 : len = be_to_host16(hdr->length);
1097 175 : if (len > parse->eap_len) {
1098 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 "
1099 : "EAP frame (EAP hdr len=%lu, EAP data len in "
1100 : "AVP=%lu)",
1101 : (unsigned long) len,
1102 : (unsigned long) parse->eap_len);
1103 0 : return -1;
1104 : }
1105 350 : wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "
1106 : "identifier=%d length=%lu",
1107 350 : hdr->code, hdr->identifier, (unsigned long) len);
1108 175 : switch (hdr->code) {
1109 : case EAP_CODE_REQUEST:
1110 175 : if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {
1111 21 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
1112 : "processing failed");
1113 21 : return -1;
1114 : }
1115 154 : break;
1116 : default:
1117 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "
1118 0 : "Phase 2 EAP header", hdr->code);
1119 0 : return -1;
1120 : }
1121 :
1122 154 : return 0;
1123 : }
1124 :
1125 :
1126 112 : static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
1127 : struct eap_ttls_data *data,
1128 : struct eap_method_ret *ret,
1129 : struct ttls_parse_avp *parse)
1130 : {
1131 : #ifdef EAP_MSCHAPv2
1132 112 : if (parse->mschapv2_error) {
1133 1 : wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "
1134 : "MS-CHAP-Error - failed");
1135 1 : ret->methodState = METHOD_DONE;
1136 1 : ret->decision = DECISION_FAIL;
1137 : /* Reply with empty data to ACK error */
1138 1 : return 1;
1139 : }
1140 :
1141 111 : if (parse->mschapv2 == NULL) {
1142 : #ifdef EAP_TNC
1143 3 : if (data->phase2_success && parse->eapdata) {
1144 : /*
1145 : * Allow EAP-TNC to be started after successfully
1146 : * completed MSCHAPV2.
1147 : */
1148 3 : return 1;
1149 : }
1150 : #endif /* EAP_TNC */
1151 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP "
1152 : "received for Phase2 MSCHAPV2");
1153 0 : return -1;
1154 : }
1155 108 : if (parse->mschapv2[0] != data->ident) {
1156 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 "
1157 : "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)",
1158 0 : parse->mschapv2[0], data->ident);
1159 0 : return -1;
1160 : }
1161 216 : if (!data->auth_response_valid ||
1162 108 : mschapv2_verify_auth_response(data->auth_response,
1163 108 : parse->mschapv2 + 1, 42)) {
1164 0 : wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator "
1165 : "response in Phase 2 MSCHAPV2 success request");
1166 0 : return -1;
1167 : }
1168 :
1169 108 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
1170 : "authentication succeeded");
1171 108 : ret->methodState = METHOD_DONE;
1172 108 : ret->decision = DECISION_UNCOND_SUCC;
1173 108 : data->phase2_success = 1;
1174 :
1175 : /*
1176 : * Reply with empty data; authentication server will reply
1177 : * with EAP-Success after this.
1178 : */
1179 108 : return 1;
1180 : #else /* EAP_MSCHAPv2 */
1181 : wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
1182 : return -1;
1183 : #endif /* EAP_MSCHAPv2 */
1184 : }
1185 :
1186 :
1187 : #ifdef EAP_TNC
1188 24 : static int eap_ttls_process_tnc_start(struct eap_sm *sm,
1189 : struct eap_ttls_data *data,
1190 : struct eap_method_ret *ret,
1191 : struct ttls_parse_avp *parse,
1192 : struct wpabuf **resp)
1193 : {
1194 : /* TNC uses inner EAP method after non-EAP TTLS phase 2. */
1195 24 : if (parse->eapdata == NULL) {
1196 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
1197 : "unexpected tunneled data (no EAP)");
1198 0 : return -1;
1199 : }
1200 :
1201 24 : if (!data->ready_for_tnc) {
1202 0 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
1203 : "EAP after non-EAP, but not ready for TNC");
1204 0 : return -1;
1205 : }
1206 :
1207 24 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
1208 : "non-EAP method");
1209 24 : data->tnc_started = 1;
1210 :
1211 24 : if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)
1212 13 : return -1;
1213 :
1214 11 : return 0;
1215 : }
1216 : #endif /* EAP_TNC */
1217 :
1218 :
1219 284 : static int eap_ttls_process_decrypted(struct eap_sm *sm,
1220 : struct eap_ttls_data *data,
1221 : struct eap_method_ret *ret,
1222 : u8 identifier,
1223 : struct ttls_parse_avp *parse,
1224 : struct wpabuf *in_decrypted,
1225 : struct wpabuf **out_data)
1226 : {
1227 284 : struct wpabuf *resp = NULL;
1228 284 : struct eap_peer_config *config = eap_get_config(sm);
1229 : int res;
1230 284 : enum phase2_types phase2_type = data->phase2_type;
1231 :
1232 : #ifdef EAP_TNC
1233 284 : if (data->tnc_started)
1234 91 : phase2_type = EAP_TTLS_PHASE2_EAP;
1235 : #endif /* EAP_TNC */
1236 :
1237 284 : switch (phase2_type) {
1238 : case EAP_TTLS_PHASE2_EAP:
1239 151 : if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <
1240 : 0)
1241 8 : return -1;
1242 143 : break;
1243 : case EAP_TTLS_PHASE2_MSCHAPV2:
1244 112 : res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse);
1245 : #ifdef EAP_TNC
1246 112 : if (res == 1 && parse->eapdata && data->phase2_success) {
1247 : /*
1248 : * TNC may be required as the next
1249 : * authentication method within the tunnel.
1250 : */
1251 3 : ret->methodState = METHOD_MAY_CONT;
1252 3 : data->ready_for_tnc = 1;
1253 3 : if (eap_ttls_process_tnc_start(sm, data, ret, parse,
1254 : &resp) == 0)
1255 2 : break;
1256 : }
1257 : #endif /* EAP_TNC */
1258 110 : return res;
1259 : case EAP_TTLS_PHASE2_MSCHAP:
1260 : case EAP_TTLS_PHASE2_PAP:
1261 : case EAP_TTLS_PHASE2_CHAP:
1262 : #ifdef EAP_TNC
1263 21 : if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <
1264 : 0)
1265 12 : return -1;
1266 9 : break;
1267 : #else /* EAP_TNC */
1268 : /* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled
1269 : * requests to the supplicant */
1270 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "
1271 : "tunneled data");
1272 : return -1;
1273 : #endif /* EAP_TNC */
1274 : }
1275 :
1276 154 : if (resp) {
1277 152 : if (eap_ttls_encrypt_response(sm, data, resp, identifier,
1278 : out_data) < 0)
1279 1 : return -1;
1280 4 : } else if (config->pending_req_identity ||
1281 2 : config->pending_req_password ||
1282 0 : config->pending_req_otp ||
1283 0 : config->pending_req_new_password) {
1284 2 : wpabuf_free(data->pending_phase2_req);
1285 2 : data->pending_phase2_req = wpabuf_dup(in_decrypted);
1286 : }
1287 :
1288 153 : return 0;
1289 : }
1290 :
1291 :
1292 278 : static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
1293 : struct eap_ttls_data *data,
1294 : struct eap_method_ret *ret,
1295 : u8 identifier,
1296 : struct wpabuf **out_data)
1297 : {
1298 278 : int retval = 0;
1299 : struct eap_hdr *hdr;
1300 : struct wpabuf *resp;
1301 :
1302 278 : hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();
1303 278 : if (hdr == NULL) {
1304 1 : ret->methodState = METHOD_DONE;
1305 1 : ret->decision = DECISION_FAIL;
1306 1 : return -1;
1307 : }
1308 :
1309 277 : resp = NULL;
1310 277 : if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {
1311 15 : wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
1312 : "processing failed");
1313 15 : retval = -1;
1314 : } else {
1315 262 : struct eap_peer_config *config = eap_get_config(sm);
1316 267 : if (resp == NULL &&
1317 8 : (config->pending_req_identity ||
1318 3 : config->pending_req_password ||
1319 0 : config->pending_req_otp ||
1320 0 : config->pending_req_new_password)) {
1321 : /*
1322 : * Use empty buffer to force implicit request
1323 : * processing when EAP request is re-processed after
1324 : * user input.
1325 : */
1326 5 : wpabuf_free(data->pending_phase2_req);
1327 5 : data->pending_phase2_req = wpabuf_alloc(0);
1328 : }
1329 :
1330 262 : retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
1331 : out_data);
1332 : }
1333 :
1334 277 : os_free(hdr);
1335 :
1336 277 : if (retval < 0) {
1337 16 : ret->methodState = METHOD_DONE;
1338 16 : ret->decision = DECISION_FAIL;
1339 : }
1340 :
1341 277 : return retval;
1342 : }
1343 :
1344 :
1345 273 : static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,
1346 : struct eap_method_ret *ret, u8 identifier,
1347 : struct wpabuf **out_data)
1348 : {
1349 273 : data->phase2_start = 0;
1350 :
1351 : /*
1352 : * EAP-TTLS does not use Phase2 on fast re-auth; this must be done only
1353 : * if TLS part was indeed resuming a previous session. Most
1354 : * Authentication Servers terminate EAP-TTLS before reaching this
1355 : * point, but some do not. Make wpa_supplicant stop phase 2 here, if
1356 : * needed.
1357 : */
1358 287 : if (data->reauth &&
1359 14 : tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
1360 0 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
1361 : "skip phase 2");
1362 0 : *out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,
1363 : data->ttls_version);
1364 0 : ret->methodState = METHOD_DONE;
1365 0 : ret->decision = DECISION_UNCOND_SUCC;
1366 0 : data->phase2_success = 1;
1367 0 : return 0;
1368 : }
1369 :
1370 273 : return eap_ttls_implicit_identity_request(sm, data, ret, identifier,
1371 : out_data);
1372 : }
1373 :
1374 :
1375 598 : static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
1376 : struct eap_method_ret *ret, u8 identifier,
1377 : const struct wpabuf *in_data,
1378 : struct wpabuf **out_data)
1379 : {
1380 598 : struct wpabuf *in_decrypted = NULL;
1381 598 : int retval = 0;
1382 : struct ttls_parse_avp parse;
1383 :
1384 598 : os_memset(&parse, 0, sizeof(parse));
1385 :
1386 598 : wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
1387 : " Phase 2",
1388 : in_data ? (unsigned long) wpabuf_len(in_data) : 0);
1389 :
1390 598 : if (data->pending_phase2_req) {
1391 7 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
1392 : "skip decryption and use old data");
1393 : /* Clear TLS reassembly state. */
1394 7 : eap_peer_tls_reset_input(&data->ssl);
1395 :
1396 7 : in_decrypted = data->pending_phase2_req;
1397 7 : data->pending_phase2_req = NULL;
1398 7 : if (wpabuf_len(in_decrypted) == 0) {
1399 5 : wpabuf_free(in_decrypted);
1400 5 : return eap_ttls_implicit_identity_request(
1401 : sm, data, ret, identifier, out_data);
1402 : }
1403 2 : goto continue_req;
1404 : }
1405 :
1406 897 : if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
1407 306 : data->phase2_start) {
1408 273 : return eap_ttls_phase2_start(sm, data, ret, identifier,
1409 : out_data);
1410 : }
1411 :
1412 318 : if (in_data == NULL || wpabuf_len(in_data) == 0) {
1413 : /* Received TLS ACK - requesting more fragments */
1414 33 : return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
1415 : data->ttls_version,
1416 : identifier, NULL, out_data);
1417 : }
1418 :
1419 285 : retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
1420 285 : if (retval)
1421 2 : goto done;
1422 :
1423 : continue_req:
1424 285 : data->phase2_start = 0;
1425 :
1426 285 : if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {
1427 1 : retval = -1;
1428 1 : goto done;
1429 : }
1430 :
1431 284 : retval = eap_ttls_process_decrypted(sm, data, ret, identifier,
1432 : &parse, in_decrypted, out_data);
1433 :
1434 : done:
1435 287 : wpabuf_free(in_decrypted);
1436 287 : os_free(parse.eapdata);
1437 :
1438 287 : if (retval < 0) {
1439 24 : ret->methodState = METHOD_DONE;
1440 24 : ret->decision = DECISION_FAIL;
1441 : }
1442 :
1443 287 : return retval;
1444 : }
1445 :
1446 :
1447 1530 : static int eap_ttls_process_handshake(struct eap_sm *sm,
1448 : struct eap_ttls_data *data,
1449 : struct eap_method_ret *ret,
1450 : u8 identifier,
1451 : const struct wpabuf *in_data,
1452 : struct wpabuf **out_data)
1453 : {
1454 : int res;
1455 :
1456 1530 : if (sm->waiting_ext_cert_check && data->pending_resp) {
1457 2 : struct eap_peer_config *config = eap_get_config(sm);
1458 :
1459 2 : if (config->pending_ext_cert_check == EXT_CERT_CHECK_GOOD) {
1460 1 : wpa_printf(MSG_DEBUG,
1461 : "EAP-TTLS: External certificate check succeeded - continue handshake");
1462 1 : *out_data = data->pending_resp;
1463 1 : data->pending_resp = NULL;
1464 1 : sm->waiting_ext_cert_check = 0;
1465 1 : return 0;
1466 : }
1467 :
1468 1 : if (config->pending_ext_cert_check == EXT_CERT_CHECK_BAD) {
1469 1 : wpa_printf(MSG_DEBUG,
1470 : "EAP-TTLS: External certificate check failed - force authentication failure");
1471 1 : ret->methodState = METHOD_DONE;
1472 1 : ret->decision = DECISION_FAIL;
1473 1 : sm->waiting_ext_cert_check = 0;
1474 1 : return 0;
1475 : }
1476 :
1477 0 : wpa_printf(MSG_DEBUG,
1478 : "EAP-TTLS: Continuing to wait external server certificate validation");
1479 0 : return 0;
1480 : }
1481 :
1482 1528 : res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
1483 : data->ttls_version, identifier,
1484 : in_data, out_data);
1485 1528 : if (res < 0) {
1486 21 : wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS processing failed");
1487 21 : ret->methodState = METHOD_DONE;
1488 21 : ret->decision = DECISION_FAIL;
1489 21 : return -1;
1490 : }
1491 :
1492 1507 : if (sm->waiting_ext_cert_check) {
1493 2 : wpa_printf(MSG_DEBUG,
1494 : "EAP-TTLS: Waiting external server certificate validation");
1495 2 : wpabuf_free(data->pending_resp);
1496 2 : data->pending_resp = *out_data;
1497 2 : *out_data = NULL;
1498 2 : return 0;
1499 : }
1500 :
1501 1505 : if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
1502 278 : wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
1503 : "Phase 2");
1504 278 : if (data->resuming) {
1505 19 : wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth - may "
1506 : "skip Phase 2");
1507 19 : ret->decision = DECISION_COND_SUCC;
1508 19 : ret->methodState = METHOD_MAY_CONT;
1509 : }
1510 278 : data->phase2_start = 1;
1511 278 : eap_ttls_v0_derive_key(sm, data);
1512 :
1513 278 : if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
1514 273 : if (eap_ttls_decrypt(sm, data, ret, identifier,
1515 : NULL, out_data)) {
1516 17 : wpa_printf(MSG_WARNING, "EAP-TTLS: "
1517 : "failed to process early "
1518 : "start for Phase 2");
1519 : }
1520 273 : res = 0;
1521 : }
1522 278 : data->resuming = 0;
1523 : }
1524 :
1525 1505 : if (res == 2) {
1526 : /*
1527 : * Application data included in the handshake message.
1528 : */
1529 0 : wpabuf_free(data->pending_phase2_req);
1530 0 : data->pending_phase2_req = *out_data;
1531 0 : *out_data = NULL;
1532 0 : res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
1533 : out_data);
1534 : }
1535 :
1536 1505 : return res;
1537 : }
1538 :
1539 :
1540 1855 : static void eap_ttls_check_auth_status(struct eap_sm *sm,
1541 : struct eap_ttls_data *data,
1542 : struct eap_method_ret *ret)
1543 : {
1544 1855 : if (ret->methodState == METHOD_DONE) {
1545 298 : ret->allowNotifications = FALSE;
1546 479 : if (ret->decision == DECISION_UNCOND_SUCC ||
1547 181 : ret->decision == DECISION_COND_SUCC) {
1548 232 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
1549 : "completed successfully");
1550 232 : data->phase2_success = 1;
1551 232 : data->decision_succ = ret->decision;
1552 : #ifdef EAP_TNC
1553 232 : if (!data->ready_for_tnc && !data->tnc_started) {
1554 : /*
1555 : * TNC may be required as the next
1556 : * authentication method within the tunnel.
1557 : */
1558 232 : ret->methodState = METHOD_MAY_CONT;
1559 232 : data->ready_for_tnc = 1;
1560 : }
1561 : #endif /* EAP_TNC */
1562 : }
1563 3114 : } else if (ret->methodState == METHOD_MAY_CONT &&
1564 3112 : (ret->decision == DECISION_UNCOND_SUCC ||
1565 1555 : ret->decision == DECISION_COND_SUCC)) {
1566 14 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
1567 : "completed successfully (MAY_CONT)");
1568 14 : data->phase2_success = 1;
1569 14 : data->decision_succ = ret->decision;
1570 1675 : } else if (data->decision_succ != DECISION_FAIL &&
1571 264 : data->phase2_success &&
1572 132 : !data->ssl.tls_out) {
1573 : /*
1574 : * This is needed to cover the case where the final Phase 2
1575 : * message gets fragmented since fragmentation clears
1576 : * decision back to FAIL.
1577 : */
1578 97 : wpa_printf(MSG_DEBUG,
1579 : "EAP-TTLS: Restore success decision after fragmented frame sent completely");
1580 97 : ret->decision = data->decision_succ;
1581 : }
1582 1855 : }
1583 :
1584 :
1585 1855 : static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
1586 : struct eap_method_ret *ret,
1587 : const struct wpabuf *reqData)
1588 : {
1589 : size_t left;
1590 : int res;
1591 : u8 flags, id;
1592 : struct wpabuf *resp;
1593 : const u8 *pos;
1594 1855 : struct eap_ttls_data *data = priv;
1595 : struct wpabuf msg;
1596 :
1597 1855 : pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
1598 : reqData, &left, &flags);
1599 1855 : if (pos == NULL)
1600 0 : return NULL;
1601 1855 : id = eap_get_id(reqData);
1602 :
1603 1855 : if (flags & EAP_TLS_FLAGS_START) {
1604 310 : wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own "
1605 : "ver=%d)", flags & EAP_TLS_VERSION_MASK,
1606 : data->ttls_version);
1607 :
1608 : /* RFC 5281, Ch. 9.2:
1609 : * "This packet MAY contain additional information in the form
1610 : * of AVPs, which may provide useful hints to the client"
1611 : * For now, ignore any potential extra data.
1612 : */
1613 310 : left = 0;
1614 : }
1615 :
1616 1855 : wpabuf_set(&msg, pos, left);
1617 :
1618 1855 : resp = NULL;
1619 2180 : if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1620 325 : !data->resuming) {
1621 325 : res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
1622 : } else {
1623 1530 : res = eap_ttls_process_handshake(sm, data, ret, id,
1624 : &msg, &resp);
1625 : }
1626 :
1627 1855 : eap_ttls_check_auth_status(sm, data, ret);
1628 :
1629 : /* FIX: what about res == -1? Could just move all error processing into
1630 : * the other functions and get rid of this res==1 case here. */
1631 1855 : if (res == 1) {
1632 637 : wpabuf_free(resp);
1633 637 : return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
1634 : data->ttls_version);
1635 : }
1636 1218 : return resp;
1637 : }
1638 :
1639 :
1640 76 : static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv)
1641 : {
1642 76 : struct eap_ttls_data *data = priv;
1643 152 : return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1644 76 : data->phase2_success;
1645 : }
1646 :
1647 :
1648 43 : static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
1649 : {
1650 43 : struct eap_ttls_data *data = priv;
1651 43 : wpabuf_free(data->pending_phase2_req);
1652 43 : data->pending_phase2_req = NULL;
1653 43 : wpabuf_free(data->pending_resp);
1654 43 : data->pending_resp = NULL;
1655 43 : data->decision_succ = DECISION_FAIL;
1656 : #ifdef EAP_TNC
1657 43 : data->ready_for_tnc = 0;
1658 43 : data->tnc_started = 0;
1659 : #endif /* EAP_TNC */
1660 43 : }
1661 :
1662 :
1663 23 : static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
1664 : {
1665 23 : struct eap_ttls_data *data = priv;
1666 23 : eap_ttls_free_key(data);
1667 23 : os_free(data->session_id);
1668 23 : data->session_id = NULL;
1669 23 : if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
1670 0 : os_free(data);
1671 0 : return NULL;
1672 : }
1673 27 : if (data->phase2_priv && data->phase2_method &&
1674 4 : data->phase2_method->init_for_reauth)
1675 0 : data->phase2_method->init_for_reauth(sm, data->phase2_priv);
1676 23 : data->phase2_start = 0;
1677 23 : data->phase2_success = 0;
1678 23 : data->resuming = 1;
1679 23 : data->reauth = 1;
1680 23 : return priv;
1681 : }
1682 :
1683 :
1684 116 : static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,
1685 : size_t buflen, int verbose)
1686 : {
1687 116 : struct eap_ttls_data *data = priv;
1688 : int len, ret;
1689 :
1690 116 : len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
1691 116 : ret = os_snprintf(buf + len, buflen - len,
1692 : "EAP-TTLSv%d Phase2 method=",
1693 : data->ttls_version);
1694 116 : if (os_snprintf_error(buflen - len, ret))
1695 0 : return len;
1696 116 : len += ret;
1697 116 : switch (data->phase2_type) {
1698 : case EAP_TTLS_PHASE2_EAP:
1699 32 : ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n",
1700 16 : data->phase2_method ?
1701 16 : data->phase2_method->name : "?");
1702 16 : break;
1703 : case EAP_TTLS_PHASE2_MSCHAPV2:
1704 55 : ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n");
1705 55 : break;
1706 : case EAP_TTLS_PHASE2_MSCHAP:
1707 9 : ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n");
1708 9 : break;
1709 : case EAP_TTLS_PHASE2_PAP:
1710 27 : ret = os_snprintf(buf + len, buflen - len, "PAP\n");
1711 27 : break;
1712 : case EAP_TTLS_PHASE2_CHAP:
1713 9 : ret = os_snprintf(buf + len, buflen - len, "CHAP\n");
1714 9 : break;
1715 : default:
1716 0 : ret = 0;
1717 0 : break;
1718 : }
1719 116 : if (os_snprintf_error(buflen - len, ret))
1720 0 : return len;
1721 116 : len += ret;
1722 :
1723 116 : return len;
1724 : }
1725 :
1726 :
1727 1855 : static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv)
1728 : {
1729 1855 : struct eap_ttls_data *data = priv;
1730 1855 : return data->key_data != NULL && data->phase2_success;
1731 : }
1732 :
1733 :
1734 395 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1735 : {
1736 395 : struct eap_ttls_data *data = priv;
1737 : u8 *key;
1738 :
1739 395 : if (data->key_data == NULL || !data->phase2_success)
1740 0 : return NULL;
1741 :
1742 395 : key = os_malloc(EAP_TLS_KEY_LEN);
1743 395 : if (key == NULL)
1744 1 : return NULL;
1745 :
1746 394 : *len = EAP_TLS_KEY_LEN;
1747 394 : os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
1748 :
1749 394 : return key;
1750 : }
1751 :
1752 :
1753 395 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1754 : {
1755 395 : struct eap_ttls_data *data = priv;
1756 : u8 *id;
1757 :
1758 395 : if (data->session_id == NULL || !data->phase2_success)
1759 0 : return NULL;
1760 :
1761 395 : id = os_malloc(data->id_len);
1762 395 : if (id == NULL)
1763 1 : return NULL;
1764 :
1765 394 : *len = data->id_len;
1766 394 : os_memcpy(id, data->session_id, data->id_len);
1767 :
1768 394 : return id;
1769 : }
1770 :
1771 :
1772 19 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1773 : {
1774 19 : struct eap_ttls_data *data = priv;
1775 : u8 *key;
1776 :
1777 19 : if (data->key_data == NULL)
1778 0 : return NULL;
1779 :
1780 19 : key = os_malloc(EAP_EMSK_LEN);
1781 19 : if (key == NULL)
1782 1 : return NULL;
1783 :
1784 18 : *len = EAP_EMSK_LEN;
1785 18 : os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
1786 :
1787 18 : return key;
1788 : }
1789 :
1790 :
1791 49 : int eap_peer_ttls_register(void)
1792 : {
1793 : struct eap_method *eap;
1794 :
1795 49 : eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1796 : EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
1797 49 : if (eap == NULL)
1798 0 : return -1;
1799 :
1800 49 : eap->init = eap_ttls_init;
1801 49 : eap->deinit = eap_ttls_deinit;
1802 49 : eap->process = eap_ttls_process;
1803 49 : eap->isKeyAvailable = eap_ttls_isKeyAvailable;
1804 49 : eap->getKey = eap_ttls_getKey;
1805 49 : eap->getSessionId = eap_ttls_get_session_id;
1806 49 : eap->get_status = eap_ttls_get_status;
1807 49 : eap->has_reauth_data = eap_ttls_has_reauth_data;
1808 49 : eap->deinit_for_reauth = eap_ttls_deinit_for_reauth;
1809 49 : eap->init_for_reauth = eap_ttls_init_for_reauth;
1810 49 : eap->get_emsk = eap_ttls_get_emsk;
1811 :
1812 49 : return eap_peer_method_register(eap);
1813 : }
|