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