]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/hostapd/eap_ttls.c
This commit was generated by cvs2svn to compensate for changes in r154032,
[FreeBSD/FreeBSD.git] / contrib / hostapd / eap_ttls.c
1 /*
2  * hostapd / EAP-TTLS (draft-ietf-pppext-eap-ttls-05.txt)
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.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 <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <netinet/in.h>
19
20 #include "hostapd.h"
21 #include "common.h"
22 #include "eap_i.h"
23 #include "eap_tls_common.h"
24 #include "ms_funcs.h"
25 #include "md5.h"
26 #include "tls.h"
27 #include "eap_ttls.h"
28
29 #define EAP_TTLS_VERSION 0
30
31
32 static void eap_ttls_reset(struct eap_sm *sm, void *priv);
33
34
35 struct eap_ttls_data {
36         struct eap_ssl_data ssl;
37         enum {
38                 START, PHASE1, PHASE2_START, PHASE2_METHOD,
39                 PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
40         } state;
41
42         int ttls_version;
43         const struct eap_method *phase2_method;
44         void *phase2_priv;
45         int mschapv2_resp_ok;
46         u8 mschapv2_auth_response[20];
47         u8 mschapv2_ident;
48 };
49
50
51 static const char * eap_ttls_state_txt(int state)
52 {
53         switch (state) {
54         case START:
55                 return "START";
56         case PHASE1:
57                 return "PHASE1";
58         case PHASE2_START:
59                 return "PHASE2_START";
60         case PHASE2_METHOD:
61                 return "PHASE2_METHOD";
62         case PHASE2_MSCHAPV2_RESP:
63                 return "PHASE2_MSCHAPV2_RESP";
64         case SUCCESS:
65                 return "SUCCESS";
66         case FAILURE:
67                 return "FAILURE";
68         default:
69                 return "Unknown?!";
70         }
71 }
72
73
74 static void eap_ttls_state(struct eap_ttls_data *data, int state)
75 {
76         wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
77                    eap_ttls_state_txt(data->state),
78                    eap_ttls_state_txt(state));
79         data->state = state;
80 }
81
82
83 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
84                              int mandatory, size_t len)
85 {
86         struct ttls_avp_vendor *avp;
87         u8 flags;
88         size_t hdrlen;
89
90         avp = (struct ttls_avp_vendor *) avphdr;
91         flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
92         if (vendor_id) {
93                 flags |= AVP_FLAGS_VENDOR;
94                 hdrlen = sizeof(*avp);
95                 avp->vendor_id = host_to_be32(vendor_id);
96         } else {
97                 hdrlen = sizeof(struct ttls_avp);
98         }
99
100         avp->avp_code = host_to_be32(avp_code);
101         avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
102
103         return avphdr + hdrlen;
104 }
105
106
107 static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
108                                     int mandatory)
109 {
110         u8 *avp, *pos;
111
112         avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
113         if (avp == NULL) {
114                 free(*resp);
115                 *resp_len = 0;
116                 return -1;
117         }
118
119         pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
120         memcpy(pos, *resp, *resp_len);
121         pos += *resp_len;
122         AVP_PAD(avp, pos);
123         free(*resp);
124         *resp = avp;
125         *resp_len = pos - avp;
126         return 0;
127 }
128
129
130 struct eap_ttls_avp {
131          /* Note: eap is allocated memory; caller is responsible for freeing
132           * it. All the other pointers are pointing to the packet data, i.e.,
133           * they must not be freed separately. */
134         u8 *eap;
135         size_t eap_len;
136         u8 *user_name;
137         size_t user_name_len;
138         u8 *user_password;
139         size_t user_password_len;
140         u8 *chap_challenge;
141         size_t chap_challenge_len;
142         u8 *chap_password;
143         size_t chap_password_len;
144         u8 *mschap_challenge;
145         size_t mschap_challenge_len;
146         u8 *mschap_response;
147         size_t mschap_response_len;
148         u8 *mschap2_response;
149         size_t mschap2_response_len;
150 };
151
152
153 static int eap_ttls_avp_parse(u8 *buf, size_t len, struct eap_ttls_avp *parse)
154 {
155         struct ttls_avp *avp;
156         u8 *pos;
157         int left;
158
159         pos = buf;
160         left = len;
161         memset(parse, 0, sizeof(*parse));
162
163         while (left > 0) {
164                 u32 avp_code, avp_length, vendor_id = 0;
165                 u8 avp_flags, *dpos;
166                 size_t pad, dlen;
167                 avp = (struct ttls_avp *) pos;
168                 avp_code = be_to_host32(avp->avp_code);
169                 avp_length = be_to_host32(avp->avp_length);
170                 avp_flags = (avp_length >> 24) & 0xff;
171                 avp_length &= 0xffffff;
172                 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
173                            "length=%d", (int) avp_code, avp_flags,
174                            (int) avp_length);
175                 if (avp_length > left) {
176                         wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
177                                    "(len=%d, left=%d) - dropped",
178                                    (int) avp_length, left);
179                         return -1;
180                 }
181                 dpos = (u8 *) (avp + 1);
182                 dlen = avp_length - sizeof(*avp);
183                 if (avp_flags & AVP_FLAGS_VENDOR) {
184                         if (dlen < 4) {
185                                 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
186                                            "underflow");
187                                 return -1;
188                         }
189                         vendor_id = be_to_host32(* (u32 *) dpos);
190                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
191                                    (int) vendor_id);
192                         dpos += 4;
193                         dlen -= 4;
194                 }
195
196                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
197
198                 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
199                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
200                         if (parse->eap == NULL) {
201                                 parse->eap = malloc(dlen);
202                                 if (parse->eap == NULL) {
203                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
204                                                    "failed to allocate memory "
205                                                    "for Phase 2 EAP data");
206                                         return -1;
207                                 }
208                                 memcpy(parse->eap, dpos, dlen);
209                                 parse->eap_len = dlen;
210                         } else {
211                                 u8 *neweap = realloc(parse->eap,
212                                                      parse->eap_len + dlen);
213                                 if (neweap == NULL) {
214                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
215                                                    "failed to allocate memory "
216                                                    "for Phase 2 EAP data");
217                                         free(parse->eap);
218                                         parse->eap = NULL;
219                                         return -1;
220                                 }
221                                 memcpy(neweap + parse->eap_len, dpos, dlen);
222                                 parse->eap = neweap;
223                                 parse->eap_len += dlen;
224                         }
225                 } else if (vendor_id == 0 &&
226                            avp_code == RADIUS_ATTR_USER_NAME) {
227                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
228                                           dpos, dlen);
229                         parse->user_name = dpos;
230                         parse->user_name_len = dlen;
231                 } else if (vendor_id == 0 &&
232                            avp_code == RADIUS_ATTR_USER_PASSWORD) {
233                         u8 *password = dpos;
234                         size_t password_len = dlen;
235                         while (password_len > 0 &&
236                                password[password_len - 1] == '\0') {
237                                 password_len--;
238                         }
239                         wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
240                                               "User-Password (PAP)",
241                                               password, password_len);
242                         parse->user_password = password;
243                         parse->user_password_len = password_len;
244                 } else if (vendor_id == 0 &&
245                            avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
246                         wpa_hexdump(MSG_DEBUG,
247                                     "EAP-TTLS: CHAP-Challenge (CHAP)",
248                                     dpos, dlen);
249                         parse->chap_challenge = dpos;
250                         parse->chap_challenge_len = dlen;
251                 } else if (vendor_id == 0 &&
252                            avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
253                         wpa_hexdump(MSG_DEBUG,
254                                     "EAP-TTLS: CHAP-Password (CHAP)",
255                                     dpos, dlen);
256                         parse->chap_password = dpos;
257                         parse->chap_password_len = dlen;
258                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
259                            avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
260                         wpa_hexdump(MSG_DEBUG,
261                                     "EAP-TTLS: MS-CHAP-Challenge",
262                                     dpos, dlen);
263                         parse->mschap_challenge = dpos;
264                         parse->mschap_challenge_len = dlen;
265                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
266                            avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
267                         wpa_hexdump(MSG_DEBUG,
268                                     "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
269                                     dpos, dlen);
270                         parse->mschap_response = dpos;
271                         parse->mschap_response_len = dlen;
272                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
273                            avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
274                         wpa_hexdump(MSG_DEBUG,
275                                     "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
276                                     dpos, dlen);
277                         parse->mschap2_response = dpos;
278                         parse->mschap2_response_len = dlen;
279                 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
280                         wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
281                                    "mandatory AVP code %d vendor_id %d - "
282                                    "dropped", (int) avp_code, (int) vendor_id);
283                         return -1;
284                 } else {
285                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
286                                    "AVP code %d vendor_id %d",
287                                    (int) avp_code, (int) vendor_id);
288                 }
289
290                 pad = (4 - (avp_length & 3)) & 3;
291                 pos += avp_length + pad;
292                 left -= avp_length + pad;
293         }
294
295         return 0;
296 }
297
298
299 static void * eap_ttls_init(struct eap_sm *sm)
300 {
301         struct eap_ttls_data *data;
302
303         data = malloc(sizeof(*data));
304         if (data == NULL)
305                 return data;
306         memset(data, 0, sizeof(*data));
307         data->ttls_version = EAP_TTLS_VERSION;
308         data->state = START;
309
310         if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
311                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
312                 eap_ttls_reset(sm, data);
313                 return NULL;
314         }
315
316         return data;
317 }
318
319
320 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
321 {
322         struct eap_ttls_data *data = priv;
323         if (data == NULL)
324                 return;
325         if (data->phase2_priv && data->phase2_method)
326                 data->phase2_method->reset(sm, data->phase2_priv);
327         eap_tls_ssl_deinit(sm, &data->ssl);
328         free(data);
329 }
330
331
332 static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
333                                  int id, size_t *reqDataLen)
334 {
335         struct eap_hdr *req;
336         u8 *pos;
337
338         *reqDataLen = sizeof(*req) + 2;
339         req = malloc(*reqDataLen);
340         if (req == NULL) {
341                 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
342                            " request");
343                 eap_ttls_state(data, FAILURE);
344                 return NULL;
345         }
346
347         req->code = EAP_CODE_REQUEST;
348         req->identifier = id;
349         req->length = htons(*reqDataLen);
350         pos = (u8 *) (req + 1);
351         *pos++ = EAP_TYPE_TTLS;
352         *pos = EAP_TLS_FLAGS_START | data->ttls_version;
353
354         eap_ttls_state(data, PHASE1);
355
356         return (u8 *) req;
357 }
358
359
360 static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
361                                int id, size_t *reqDataLen)
362 {
363         int res;
364         u8 *req;
365
366         res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
367                                       data->ttls_version, id, &req,
368                                       reqDataLen);
369
370         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
371                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
372                            "Phase2");
373                 eap_ttls_state(data, PHASE2_START);
374         }
375
376         if (res == 1)
377                 return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
378                                          data->ttls_version);
379         return req;
380 }
381
382
383 static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
384                              int id, u8 *plain, size_t plain_len,
385                              size_t *out_len)
386 {
387         int res;
388         u8 *pos;
389         struct eap_hdr *req;
390
391         /* TODO: add support for fragmentation, if needed. This will need to
392          * add TLS Message Length field, if the frame is fragmented. */
393         req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
394         if (req == NULL)
395                 return NULL;
396
397         req->code = EAP_CODE_REQUEST;
398         req->identifier = id;
399
400         pos = (u8 *) (req + 1);
401         *pos++ = EAP_TYPE_TTLS;
402         *pos++ = data->ttls_version;
403
404         res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
405                                      plain, plain_len,
406                                      pos, data->ssl.tls_out_limit);
407         if (res < 0) {
408                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
409                            "data");
410                 free(req);
411                 return NULL;
412         }
413
414         *out_len = sizeof(struct eap_hdr) + 2 + res;
415         req->length = host_to_be16(*out_len);
416         return (u8 *) req;
417 }
418
419
420 static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,
421                                           struct eap_ttls_data *data,
422                                           int id, size_t *reqDataLen)
423 {
424         u8 *req, *encr_req;
425         size_t req_len;
426
427
428         req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
429                                             &req_len);
430         if (req == NULL)
431                 return NULL;
432
433         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
434                         req, req_len);
435
436         if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
437                                      1) < 0) {
438                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
439                            "packet");
440                 return NULL;
441         }
442
443         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "
444                         "2 data", req, req_len);
445
446         encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
447         free(req);
448
449         return encr_req;
450 }
451
452
453 static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,
454                                            struct eap_ttls_data *data,
455                                            int id, size_t *reqDataLen)
456 {
457         u8 *req, *encr_req, *pos, *end;
458         size_t req_len;
459         int i;
460
461         pos = req = malloc(100);
462         if (req == NULL)
463                 return NULL;
464         end = req + 200;
465
466         if (data->mschapv2_resp_ok) {
467                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
468                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
469                 *pos++ = data->mschapv2_ident;
470                 pos += snprintf((char *) pos, end - pos, "S=");
471                 for (i = 0; i < sizeof(data->mschapv2_auth_response); i++) {
472                         pos += snprintf((char *) pos, end - pos, "%02X",
473                                         data->mschapv2_auth_response[i]);
474                 }
475         } else {
476                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
477                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
478                 memcpy(pos, "Failed", 6);
479                 pos += 6;
480                 AVP_PAD(req, pos);
481         }
482
483         req_len = pos - req;
484         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
485                         "data", req, req_len);
486
487         encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
488         free(req);
489
490         return encr_req;
491 }
492
493
494 static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
495                               size_t *reqDataLen)
496 {
497         struct eap_ttls_data *data = priv;
498
499         switch (data->state) {
500         case START:
501                 return eap_ttls_build_start(sm, data, id, reqDataLen);
502         case PHASE1:
503                 return eap_ttls_build_req(sm, data, id, reqDataLen);
504         case PHASE2_METHOD:
505                 return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);
506         case PHASE2_MSCHAPV2_RESP:
507                 return eap_ttls_build_phase2_mschapv2(sm, data, id,
508                                                       reqDataLen);
509         default:
510                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
511                            __func__, data->state);
512                 return NULL;
513         }
514 }
515
516
517 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
518                               u8 *respData, size_t respDataLen)
519 {
520         struct eap_hdr *resp;
521         u8 *pos;
522         size_t len;
523
524         resp = (struct eap_hdr *) respData;
525         pos = (u8 *) (resp + 1);
526         if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_TTLS ||
527             (len = ntohs(resp->length)) > respDataLen) {
528                 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
529                 return TRUE;
530         }
531
532         return FALSE;
533 }
534
535
536 static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
537                                         struct eap_ttls_data *data,
538                                         const u8 *user_password,
539                                         size_t user_password_len)
540 {
541         /* TODO: add support for verifying that the user entry accepts
542          * EAP-TTLS/PAP. */
543         if (!sm->user || !sm->user->password) {
544                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No user password "
545                            "configured");
546                 eap_ttls_state(data, FAILURE);
547                 return;
548         }
549
550         if (sm->user->password_len != user_password_len ||
551             memcmp(sm->user->password, user_password, user_password_len) != 0)
552         {
553                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
554                 eap_ttls_state(data, FAILURE);
555                 return;
556         }
557
558         wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
559         eap_ttls_state(data, SUCCESS);
560 }
561
562
563 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
564                                          struct eap_ttls_data *data,
565                                          const u8 *challenge,
566                                          size_t challenge_len,
567                                          const u8 *password,
568                                          size_t password_len)
569 {
570         MD5_CTX context;
571         u8 *chal, hash[MD5_MAC_LEN];
572
573         if (challenge == NULL || password == NULL ||
574             challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
575             password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
576                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
577                            "(challenge len %lu password len %lu)",
578                            (unsigned long) challenge_len,
579                            (unsigned long) password_len);
580                 eap_ttls_state(data, FAILURE);
581                 return;
582         }
583
584         /* TODO: add support for verifying that the user entry accepts
585          * EAP-TTLS/CHAP. */
586         if (!sm->user || !sm->user->password) {
587                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No user password "
588                            "configured");
589                 eap_ttls_state(data, FAILURE);
590                 return;
591         }
592
593         chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
594                                   EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
595         if (chal == NULL) {
596                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
597                            "challenge from TLS data");
598                 eap_ttls_state(data, FAILURE);
599                 return;
600         }
601
602         if (memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
603             password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
604                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
605                 free(chal);
606                 eap_ttls_state(data, FAILURE);
607                 return;
608         }
609         free(chal);
610
611         /* MD5(Ident + Password + Challenge) */
612         MD5Init(&context);
613         MD5Update(&context, password, 1);
614         MD5Update(&context, sm->user->password, sm->user->password_len);
615         MD5Update(&context, challenge, challenge_len);
616         MD5Final(hash, &context);
617
618         if (memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
619                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
620                 eap_ttls_state(data, SUCCESS);
621         } else {
622                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
623                 eap_ttls_state(data, FAILURE);
624         }
625 }
626
627
628 static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
629                                            struct eap_ttls_data *data,
630                                            u8 *challenge, size_t challenge_len,
631                                            u8 *response, size_t response_len)
632 {
633         u8 *chal, nt_response[24];
634
635         if (challenge == NULL || response == NULL ||
636             challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
637             response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
638                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
639                            "attributes (challenge len %lu response len %lu)",
640                            (unsigned long) challenge_len,
641                            (unsigned long) response_len);
642                 eap_ttls_state(data, FAILURE);
643                 return;
644         }
645
646         /* TODO: add support for verifying that the user entry accepts
647          * EAP-TTLS/MSCHAP. */
648         if (!sm->user || !sm->user->password) {
649                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
650                            "configured");
651                 eap_ttls_state(data, FAILURE);
652                 return;
653         }
654
655         chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
656                                   EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
657         if (chal == NULL) {
658                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
659                            "challenge from TLS data");
660                 eap_ttls_state(data, FAILURE);
661                 return;
662         }
663
664         if (memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
665             response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
666                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
667                 free(chal);
668                 eap_ttls_state(data, FAILURE);
669                 return;
670         }
671         free(chal);
672
673         nt_challenge_response(challenge, sm->user->password,
674                               sm->user->password_len, nt_response);
675
676         if (memcmp(nt_response, response + 2 + 24, 24) == 0) {
677                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
678                 eap_ttls_state(data, SUCCESS);
679         } else {
680                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
681                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
682                             response + 2 + 24, 24);
683                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
684                             nt_response, 24);
685                 eap_ttls_state(data, FAILURE);
686         }
687 }
688
689
690 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
691                                              struct eap_ttls_data *data,
692                                              u8 *challenge,
693                                              size_t challenge_len,
694                                              u8 *response, size_t response_len)
695 {
696         u8 *chal, *username, nt_response[24], *pos, *rx_resp, *peer_challenge,
697                 *auth_challenge;
698         size_t username_len;
699         int i;
700
701         if (challenge == NULL || response == NULL ||
702             challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
703             response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
704                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
705                            "attributes (challenge len %lu response len %lu)",
706                            (unsigned long) challenge_len,
707                            (unsigned long) response_len);
708                 eap_ttls_state(data, FAILURE);
709                 return;
710         }
711
712         /* TODO: add support for verifying that the user entry accepts
713          * EAP-TTLS/MSCHAPV2. */
714         if (!sm->user || !sm->user->password) {
715                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
716                            "configured");
717                 eap_ttls_state(data, FAILURE);
718                 return;
719         }
720
721         /* MSCHAPv2 does not include optional domain name in the
722          * challenge-response calculation, so remove domain prefix
723          * (if present). */
724         username = sm->identity;
725         username_len = sm->identity_len;
726         pos = username;
727         for (i = 0; i < username_len; i++) {
728                 if (username[i] == '\\') {
729                         username_len -= i + 1;
730                         username += i + 1;
731                         break;
732                 }
733         }
734
735         chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
736                                   EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
737         if (chal == NULL) {
738                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
739                            "challenge from TLS data");
740                 eap_ttls_state(data, FAILURE);
741                 return;
742         }
743
744         if (memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
745             response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
746                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
747                 free(chal);
748                 eap_ttls_state(data, FAILURE);
749                 return;
750         }
751         free(chal);
752
753         auth_challenge = challenge;
754         peer_challenge = response + 2;
755
756         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
757                           username, username_len);
758         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
759                     auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
760         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
761                     peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
762
763         generate_nt_response(auth_challenge, peer_challenge,
764                              username, username_len,
765                              sm->user->password, sm->user->password_len,
766                              nt_response);
767
768         rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
769         if (memcmp(nt_response, rx_resp, 24) == 0) {
770                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
771                            "NT-Response");
772                 data->mschapv2_resp_ok = 1;
773
774                 generate_authenticator_response(sm->user->password,
775                                                 sm->user->password_len,
776                                                 peer_challenge,
777                                                 auth_challenge,
778                                                 username, username_len,
779                                                 nt_response,
780                                                 data->mschapv2_auth_response);
781
782         } else {
783                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
784                            "NT-Response");
785                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
786                             rx_resp, 24);
787                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
788                             nt_response, 24);
789                 data->mschapv2_resp_ok = 0;
790         }
791         eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
792         data->mschapv2_ident = response[0];
793 }
794
795
796 static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
797                                     struct eap_ttls_data *data, u8 eap_type)
798 {
799         if (data->phase2_priv && data->phase2_method) {
800                 data->phase2_method->reset(sm, data->phase2_priv);
801                 data->phase2_method = NULL;
802                 data->phase2_priv = NULL;
803         }
804         data->phase2_method = eap_sm_get_eap_methods(eap_type);
805         if (!data->phase2_method)
806                 return -1;
807
808         sm->init_phase2 = 1;
809         data->phase2_priv = data->phase2_method->init(sm);
810         sm->init_phase2 = 0;
811         return 0;
812 }
813
814
815 static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
816                                                  struct eap_ttls_data *data,
817                                                  u8 *in_data, size_t in_len)
818 {
819         u8 next_type = EAP_TYPE_NONE;
820         struct eap_hdr *hdr;
821         u8 *pos;
822         size_t left;
823
824         if (data->phase2_priv == NULL) {
825                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
826                            "initialized?!", __func__);
827                 return;
828         }
829
830         hdr = (struct eap_hdr *) in_data;
831         pos = (u8 *) (hdr + 1);
832         left = in_len - sizeof(*hdr);
833
834         if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
835                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
836                             "allowed types", pos + 1, left - 1);
837                 eap_sm_process_nak(sm, pos + 1, left - 1);
838                 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
839                     sm->user->methods[sm->user_eap_method_index] !=
840                     EAP_TYPE_NONE) {
841                         next_type =
842                                 sm->user->methods[sm->user_eap_method_index++];
843                         wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
844                                    next_type);
845                         eap_ttls_phase2_eap_init(sm, data, next_type);
846                 } else {
847                         eap_ttls_state(data, FAILURE);
848                 }
849                 return;
850         }
851
852         if (data->phase2_method->check(sm, data->phase2_priv, in_data,
853                                        in_len)) {
854                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
855                            "ignore the packet");
856                 return;
857         }
858
859         data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
860
861         if (!data->phase2_method->isDone(sm, data->phase2_priv))
862                 return;
863
864         if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
865                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
866                 eap_ttls_state(data, FAILURE);
867                 return;
868         }
869
870         switch (data->state) {
871         case PHASE2_START:
872                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
873                         wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
874                                           "Identity not found in the user "
875                                           "database",
876                                           sm->identity, sm->identity_len);
877                         eap_ttls_state(data, FAILURE);
878                         break;
879                 }
880
881                 eap_ttls_state(data, PHASE2_METHOD);
882                 next_type = sm->user->methods[0];
883                 sm->user_eap_method_index = 1;
884                 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
885                 break;
886         case PHASE2_METHOD:
887                 eap_ttls_state(data, SUCCESS);
888                 break;
889         case FAILURE:
890                 break;
891         default:
892                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
893                            __func__, data->state);
894                 break;
895         }
896
897         eap_ttls_phase2_eap_init(sm, data, next_type);
898 }
899
900
901 static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
902                                         struct eap_ttls_data *data,
903                                         const u8 *eap, size_t eap_len)
904 {
905         struct eap_hdr *hdr;
906         size_t len;
907
908         if (data->state == PHASE2_START) {
909                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
910                 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
911                 {
912                         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
913                                    "initialize EAP-Identity");
914                         return;
915                 }
916         }
917
918         if (eap_len < sizeof(*hdr)) {
919                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
920                            "packet (len=%lu)", (unsigned long) eap_len);
921                 return;
922         }
923
924         hdr = (struct eap_hdr *) eap;
925         len = be_to_host16(hdr->length);
926         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
927                    "identifier=%d length=%lu", hdr->code, hdr->identifier,
928                    (unsigned long) len);
929         if (len > eap_len) {
930                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
931                            " EAP frame (hdr len=%lu, data len in AVP=%lu)",
932                            (unsigned long) len, (unsigned long) eap_len);
933                 return;
934         }
935
936         switch (hdr->code) {
937         case EAP_CODE_RESPONSE:
938                 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
939                                                      len);
940                 break;
941         default:
942                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
943                            "Phase 2 EAP header", hdr->code);
944                 break;
945         }
946 }
947
948
949 static void eap_ttls_process_phase2(struct eap_sm *sm,
950                                     struct eap_ttls_data *data,
951                                     struct eap_hdr *resp,
952                                     u8 *in_data, size_t in_len)
953 {
954         u8 *in_decrypted;
955         int buf_len, len_decrypted, res;
956         struct eap_ttls_avp parse;
957
958         wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
959                    " Phase 2", (unsigned long) in_len);
960
961         res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
962         if (res < 0 || res == 1)
963                 return;
964
965         buf_len = in_len;
966         if (data->ssl.tls_in_total > buf_len)
967                 buf_len = data->ssl.tls_in_total;
968         in_decrypted = malloc(buf_len);
969         if (in_decrypted == NULL) {
970                 free(data->ssl.tls_in);
971                 data->ssl.tls_in = NULL;
972                 data->ssl.tls_in_len = 0;
973                 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
974                            "for decryption");
975                 return;
976         }
977
978         len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
979                                                in_data, in_len,
980                                                in_decrypted, buf_len);
981         free(data->ssl.tls_in);
982         data->ssl.tls_in = NULL;
983         data->ssl.tls_in_len = 0;
984         if (len_decrypted < 0) {
985                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
986                            "data");
987                 free(in_decrypted);
988                 eap_ttls_state(data, FAILURE);
989                 return;
990         }
991
992         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
993                         in_decrypted, len_decrypted);
994
995         if (eap_ttls_avp_parse(in_decrypted, len_decrypted, &parse) < 0) {
996                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
997                 free(in_decrypted);
998                 eap_ttls_state(data, FAILURE);
999                 return;
1000         }
1001
1002         if (parse.user_name) {
1003                 free(sm->identity);
1004                 sm->identity = malloc(parse.user_name_len);
1005                 if (sm->identity) {
1006                         memcpy(sm->identity, parse.user_name,
1007                                parse.user_name_len);
1008                         sm->identity_len = parse.user_name_len;
1009                 }
1010                 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1011                     != 0) {
1012                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1013                                    "found in the user database");
1014                         eap_ttls_state(data, FAILURE);
1015                         goto done;
1016                 }
1017         }
1018
1019         if (parse.eap) {
1020                 eap_ttls_process_phase2_eap(sm, data, parse.eap,
1021                                             parse.eap_len);
1022         } else if (parse.user_password) {
1023                 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1024                                             parse.user_password_len);
1025         } else if (parse.chap_password) {
1026                 eap_ttls_process_phase2_chap(sm, data,
1027                                              parse.chap_challenge,
1028                                              parse.chap_challenge_len,
1029                                              parse.chap_password,
1030                                              parse.chap_password_len);
1031         } else if (parse.mschap_response) {
1032                 eap_ttls_process_phase2_mschap(sm, data,
1033                                                parse.mschap_challenge,
1034                                                parse.mschap_challenge_len,
1035                                                parse.mschap_response,
1036                                                parse.mschap_response_len);
1037         } else if (parse.mschap2_response) {
1038                 eap_ttls_process_phase2_mschapv2(sm, data,
1039                                                  parse.mschap_challenge,
1040                                                  parse.mschap_challenge_len,
1041                                                  parse.mschap2_response,
1042                                                  parse.mschap2_response_len);
1043         }
1044
1045 done:
1046         free(in_decrypted);
1047         free(parse.eap);
1048  }
1049
1050
1051 static void eap_ttls_process(struct eap_sm *sm, void *priv,
1052                              u8 *respData, size_t respDataLen)
1053 {
1054         struct eap_ttls_data *data = priv;
1055         struct eap_hdr *resp;
1056         u8 *pos, flags;
1057         int left;
1058         unsigned int tls_msg_len;
1059         int peer_version;
1060
1061         resp = (struct eap_hdr *) respData;
1062         pos = (u8 *) (resp + 1);
1063         pos++;
1064         flags = *pos++;
1065         left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
1066         wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
1067                    "Flags 0x%02x", (unsigned long) respDataLen, flags);
1068         peer_version = flags & EAP_PEAP_VERSION_MASK;
1069         if (peer_version < data->ttls_version) {
1070                 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
1071                            "use version %d",
1072                            peer_version, data->ttls_version, peer_version);
1073                 data->ttls_version = peer_version;
1074                            
1075         }
1076         if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1077                 if (left < 4) {
1078                         wpa_printf(MSG_INFO, "EAP-TTLS: Short frame with TLS "
1079                                    "length");
1080                         eap_ttls_state(data, FAILURE);
1081                         return;
1082                 }
1083                 tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
1084                         pos[3];
1085                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS Message Length: %d",
1086                            tls_msg_len);
1087                 if (data->ssl.tls_in_left == 0) {
1088                         data->ssl.tls_in_total = tls_msg_len;
1089                         data->ssl.tls_in_left = tls_msg_len;
1090                         free(data->ssl.tls_in);
1091                         data->ssl.tls_in = NULL;
1092                         data->ssl.tls_in_len = 0;
1093                 }
1094                 pos += 4;
1095                 left -= 4;
1096         }
1097
1098         switch (data->state) {
1099         case PHASE1:
1100                 if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
1101                         wpa_printf(MSG_INFO, "EAP-TTLS: TLS processing "
1102                                    "failed");
1103                         eap_ttls_state(data, FAILURE);
1104                 }
1105                 break;
1106         case PHASE2_START:
1107         case PHASE2_METHOD:
1108                 eap_ttls_process_phase2(sm, data, resp, pos, left);
1109                 break;
1110         case PHASE2_MSCHAPV2_RESP:
1111                 if (data->mschapv2_resp_ok && left == 0) {
1112                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1113                                    "acknowledged response");
1114                         eap_ttls_state(data, SUCCESS);
1115                 } else if (!data->mschapv2_resp_ok) {
1116                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1117                                    "acknowledged error");
1118                         eap_ttls_state(data, FAILURE);
1119                 } else {
1120                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
1121                                    "frame from peer (payload len %d, expected "
1122                                    "empty frame)", left);
1123                         eap_ttls_state(data, FAILURE);
1124                 }
1125                 break;
1126         default:
1127                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1128                            data->state, __func__);
1129                 break;
1130         }
1131 }
1132
1133
1134 static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1135 {
1136         struct eap_ttls_data *data = priv;
1137         return data->state == SUCCESS || data->state == FAILURE;
1138 }
1139
1140
1141 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1142 {
1143         struct eap_ttls_data *data = priv;
1144         u8 *eapKeyData;
1145
1146         if (data->state != SUCCESS)
1147                 return NULL;
1148
1149         eapKeyData = eap_tls_derive_key(sm, &data->ssl,
1150                                         "ttls keying material",
1151                                         EAP_TLS_KEY_LEN);
1152         if (eapKeyData) {
1153                 *len = EAP_TLS_KEY_LEN;
1154                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived key",
1155                             eapKeyData, EAP_TLS_KEY_LEN);
1156         } else {
1157                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1158         }
1159
1160         return eapKeyData;
1161 }
1162
1163
1164 static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1165 {
1166         struct eap_ttls_data *data = priv;
1167         return data->state == SUCCESS;
1168 }
1169
1170
1171 const struct eap_method eap_method_ttls =
1172 {
1173         .method = EAP_TYPE_TTLS,
1174         .name = "TTLS",
1175         .init = eap_ttls_init,
1176         .reset = eap_ttls_reset,
1177         .buildReq = eap_ttls_buildReq,
1178         .check = eap_ttls_check,
1179         .process = eap_ttls_process,
1180         .isDone = eap_ttls_isDone,
1181         .getKey = eap_ttls_getKey,
1182         .isSuccess = eap_ttls_isSuccess,
1183 };