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