~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to eap_ttls.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler, Alexander Sack
  • Date: 2007-08-26 16:06:57 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070826160657-2m8pxoweuxe8f93t
Tags: 0.6.0+0.5.8-0ubuntu1
* New upstream release
* remove patch 11_erroneous_manpage_ref, applied upstream
* remove patch 25_wpas_dbus_unregister_iface_fix, applied upstream

[ Alexander Sack ]
* bumping upstream version to replace development version 0.6.0 with
  this package from stable release branch.
* attempt to fix wierd timeout and high latency issues by going
  back to stable upstream version (0.5.9) (LP: #140763,
  LP: #141233).

Show diffs side-by-side

added added

removed removed

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