udp: Merge udp_send and udp_output
[dragonfly.git] / contrib / hostapd / src / eap_peer / eap_tls_common.c
1 /*
2  * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
3  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "eap_i.h"
19 #include "eap_tls_common.h"
20 #include "eap_config.h"
21 #include "sha1.h"
22 #include "tls.h"
23
24
25 static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
26                               const u8 **data, size_t *data_len)
27 {
28         const struct wpa_config_blob *blob;
29
30         if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0)
31                 return 0;
32
33         blob = eap_get_config_blob(sm, *name + 7);
34         if (blob == NULL) {
35                 wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not "
36                            "found", __func__, *name + 7);
37                 return -1;
38         }
39
40         *name = NULL;
41         *data = blob->data;
42         *data_len = blob->len;
43
44         return 0;
45 }
46
47
48 static void eap_tls_params_flags(struct tls_connection_params *params,
49                                  const char *txt)
50 {
51         if (txt == NULL)
52                 return;
53         if (os_strstr(txt, "tls_allow_md5=1"))
54                 params->flags |= TLS_CONN_ALLOW_SIGN_RSA_MD5;
55         if (os_strstr(txt, "tls_disable_time_checks=1"))
56                 params->flags |= TLS_CONN_DISABLE_TIME_CHECKS;
57 }
58
59
60 static void eap_tls_params_from_conf1(struct tls_connection_params *params,
61                                       struct eap_peer_config *config)
62 {
63         params->ca_cert = (char *) config->ca_cert;
64         params->ca_path = (char *) config->ca_path;
65         params->client_cert = (char *) config->client_cert;
66         params->private_key = (char *) config->private_key;
67         params->private_key_passwd = (char *) config->private_key_passwd;
68         params->dh_file = (char *) config->dh_file;
69         params->subject_match = (char *) config->subject_match;
70         params->altsubject_match = (char *) config->altsubject_match;
71         params->engine = config->engine;
72         params->engine_id = config->engine_id;
73         params->pin = config->pin;
74         params->key_id = config->key_id;
75         params->cert_id = config->cert_id;
76         params->ca_cert_id = config->ca_cert_id;
77         eap_tls_params_flags(params, config->phase1);
78 }
79
80
81 static void eap_tls_params_from_conf2(struct tls_connection_params *params,
82                                       struct eap_peer_config *config)
83 {
84         params->ca_cert = (char *) config->ca_cert2;
85         params->ca_path = (char *) config->ca_path2;
86         params->client_cert = (char *) config->client_cert2;
87         params->private_key = (char *) config->private_key2;
88         params->private_key_passwd = (char *) config->private_key2_passwd;
89         params->dh_file = (char *) config->dh_file2;
90         params->subject_match = (char *) config->subject_match2;
91         params->altsubject_match = (char *) config->altsubject_match2;
92         params->engine = config->engine2;
93         params->engine_id = config->engine2_id;
94         params->pin = config->pin2;
95         params->key_id = config->key2_id;
96         params->cert_id = config->cert2_id;
97         params->ca_cert_id = config->ca_cert2_id;
98         eap_tls_params_flags(params, config->phase2);
99 }
100
101
102 static int eap_tls_params_from_conf(struct eap_sm *sm,
103                                     struct eap_ssl_data *data,
104                                     struct tls_connection_params *params,
105                                     struct eap_peer_config *config, int phase2)
106 {
107         os_memset(params, 0, sizeof(*params));
108         if (phase2) {
109                 wpa_printf(MSG_DEBUG, "TLS: using phase2 config options");
110                 eap_tls_params_from_conf2(params, config);
111         } else {
112                 wpa_printf(MSG_DEBUG, "TLS: using phase1 config options");
113                 eap_tls_params_from_conf1(params, config);
114         }
115         params->tls_ia = data->tls_ia;
116
117         /*
118          * Use blob data, if available. Otherwise, leave reference to external
119          * file as-is.
120          */
121         if (eap_tls_check_blob(sm, &params->ca_cert, &params->ca_cert_blob,
122                                &params->ca_cert_blob_len) ||
123             eap_tls_check_blob(sm, &params->client_cert,
124                                &params->client_cert_blob,
125                                &params->client_cert_blob_len) ||
126             eap_tls_check_blob(sm, &params->private_key,
127                                &params->private_key_blob,
128                                &params->private_key_blob_len) ||
129             eap_tls_check_blob(sm, &params->dh_file, &params->dh_blob,
130                                &params->dh_blob_len)) {
131                 wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs");
132                 return -1;
133         }
134
135         return 0;
136 }
137
138
139 static int eap_tls_init_connection(struct eap_sm *sm,
140                                    struct eap_ssl_data *data,
141                                    struct eap_peer_config *config,
142                                    struct tls_connection_params *params)
143 {
144         int res;
145
146         data->conn = tls_connection_init(sm->ssl_ctx);
147         if (data->conn == NULL) {
148                 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
149                            "connection");
150                 return -1;
151         }
152
153         res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);
154         if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
155                 /*
156                  * At this point with the pkcs11 engine the PIN might be wrong.
157                  * We reset the PIN in the configuration to be sure to not use
158                  * it again and the calling function must request a new one.
159                  */
160                 os_free(config->pin);
161                 config->pin = NULL;
162         } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {
163                 wpa_printf(MSG_INFO, "TLS: Failed to load private key");
164                 /*
165                  * We do not know exactly but maybe the PIN was wrong,
166                  * so ask for a new one.
167                  */
168                 os_free(config->pin);
169                 config->pin = NULL;
170                 eap_sm_request_pin(sm);
171                 sm->ignore = TRUE;
172                 return -1;
173         } else if (res) {
174                 wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
175                            "parameters");
176                 return -1;
177         }
178
179         return 0;
180 }
181
182
183 /**
184  * eap_peer_tls_ssl_init - Initialize shared TLS functionality
185  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
186  * @data: Data for TLS processing
187  * @config: Pointer to the network configuration
188  * Returns: 0 on success, -1 on failure
189  *
190  * This function is used to initialize shared TLS functionality for EAP-TLS,
191  * EAP-PEAP, EAP-TTLS, and EAP-FAST.
192  */
193 int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
194                           struct eap_peer_config *config)
195 {
196         struct tls_connection_params params;
197
198         if (config == NULL)
199                 return -1;
200
201         data->eap = sm;
202         data->phase2 = sm->init_phase2;
203         if (eap_tls_params_from_conf(sm, data, &params, config, data->phase2) <
204             0)
205                 return -1;
206
207         if (eap_tls_init_connection(sm, data, config, &params) < 0)
208                 return -1;
209
210         data->tls_out_limit = config->fragment_size;
211         if (data->phase2) {
212                 /* Limit the fragment size in the inner TLS authentication
213                  * since the outer authentication with EAP-PEAP does not yet
214                  * support fragmentation */
215                 if (data->tls_out_limit > 100)
216                         data->tls_out_limit -= 100;
217         }
218
219         if (config->phase1 &&
220             os_strstr(config->phase1, "include_tls_length=1")) {
221                 wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in "
222                            "unfragmented packets");
223                 data->include_tls_length = 1;
224         }
225
226         return 0;
227 }
228
229
230 /**
231  * eap_peer_tls_ssl_deinit - Deinitialize shared TLS functionality
232  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
233  * @data: Data for TLS processing
234  *
235  * This function deinitializes shared TLS functionality that was initialized
236  * with eap_peer_tls_ssl_init().
237  */
238 void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
239 {
240         tls_connection_deinit(sm->ssl_ctx, data->conn);
241         eap_peer_tls_reset_input(data);
242         eap_peer_tls_reset_output(data);
243 }
244
245
246 /**
247  * eap_peer_tls_derive_key - Derive a key based on TLS session data
248  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
249  * @data: Data for TLS processing
250  * @label: Label string for deriving the keys, e.g., "client EAP encryption"
251  * @len: Length of the key material to generate (usually 64 for MSK)
252  * Returns: Pointer to allocated key on success or %NULL on failure
253  *
254  * This function uses TLS-PRF to generate pseudo-random data based on the TLS
255  * session data (client/server random and master key). Each key type may use a
256  * different label to bind the key usage into the generated material.
257  *
258  * The caller is responsible for freeing the returned buffer.
259  */
260 u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
261                              const char *label, size_t len)
262 {
263         struct tls_keys keys;
264         u8 *rnd = NULL, *out;
265
266         out = os_malloc(len);
267         if (out == NULL)
268                 return NULL;
269
270         /* First, try to use TLS library function for PRF, if available. */
271         if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
272             0)
273                 return out;
274
275         /*
276          * TLS library did not support key generation, so get the needed TLS
277          * session parameters and use an internal implementation of TLS PRF to
278          * derive the key.
279          */
280         if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
281                 goto fail;
282
283         if (keys.client_random == NULL || keys.server_random == NULL ||
284             keys.master_key == NULL)
285                 goto fail;
286
287         rnd = os_malloc(keys.client_random_len + keys.server_random_len);
288         if (rnd == NULL)
289                 goto fail;
290         os_memcpy(rnd, keys.client_random, keys.client_random_len);
291         os_memcpy(rnd + keys.client_random_len, keys.server_random,
292                   keys.server_random_len);
293
294         if (tls_prf(keys.master_key, keys.master_key_len,
295                     label, rnd, keys.client_random_len +
296                     keys.server_random_len, out, len))
297                 goto fail;
298
299         os_free(rnd);
300         return out;
301
302 fail:
303         os_free(out);
304         os_free(rnd);
305         return NULL;
306 }
307
308
309 /**
310  * eap_peer_tls_reassemble_fragment - Reassemble a received fragment
311  * @data: Data for TLS processing
312  * @in_data: Next incoming TLS segment
313  * @in_len: Length of in_data
314  * Returns: 0 on success, 1 if more data is needed for the full message, or
315  * -1 on error
316  */
317 static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
318                                             const u8 *in_data, size_t in_len)
319 {
320         u8 *buf;
321
322         if (data->tls_in_len + in_len == 0) {
323                 /* No message data received?! */
324                 wpa_printf(MSG_WARNING, "SSL: Invalid reassembly state: "
325                            "tls_in_left=%lu tls_in_len=%lu in_len=%lu",
326                            (unsigned long) data->tls_in_left,
327                            (unsigned long) data->tls_in_len,
328                            (unsigned long) in_len);
329                 eap_peer_tls_reset_input(data);
330                 return -1;
331         }
332
333         if (data->tls_in_len + in_len > 65536) {
334                 /*
335                  * Limit length to avoid rogue servers from causing large
336                  * memory allocations.
337                  */
338                 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size over "
339                            "64 kB)");
340                 eap_peer_tls_reset_input(data);
341                 return -1;
342         }
343
344         if (in_len > data->tls_in_left) {
345                 /* Sender is doing something odd - reject message */
346                 wpa_printf(MSG_INFO, "SSL: more data than TLS message length "
347                            "indicated");
348                 eap_peer_tls_reset_input(data);
349                 return -1;
350         }
351
352         buf = os_realloc(data->tls_in, data->tls_in_len + in_len);
353         if (buf == NULL) {
354                 wpa_printf(MSG_INFO, "SSL: Could not allocate memory for TLS "
355                            "data");
356                 eap_peer_tls_reset_input(data);
357                 return -1;
358         }
359         os_memcpy(buf + data->tls_in_len, in_data, in_len);
360         data->tls_in = buf;
361         data->tls_in_len += in_len;
362         data->tls_in_left -= in_len;
363
364         if (data->tls_in_left > 0) {
365                 wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input "
366                            "data", (unsigned long) data->tls_in_left);
367                 return 1;
368         }
369
370         return 0;
371 }
372
373
374 /**
375  * eap_peer_tls_data_reassemble - Reassemble TLS data
376  * @data: Data for TLS processing
377  * @in_data: Next incoming TLS segment
378  * @in_len: Length of in_data
379  * @out_len: Variable for returning length of the reassembled message
380  * @need_more_input: Variable for returning whether more input data is needed
381  * to reassemble this TLS packet
382  * Returns: Pointer to output data, %NULL on error or when more data is needed
383  * for the full message (in which case, *need_more_input is also set to 1).
384  *
385  * This function reassembles TLS fragments. Caller must not free the returned
386  * data buffer since an internal pointer to it is maintained.
387  */
388 const u8 * eap_peer_tls_data_reassemble(
389         struct eap_ssl_data *data, const u8 *in_data, size_t in_len,
390         size_t *out_len, int *need_more_input)
391 {
392         *need_more_input = 0;
393
394         if (data->tls_in_left > in_len || data->tls_in) {
395                 /* Message has fragments */
396                 int res = eap_peer_tls_reassemble_fragment(data, in_data,
397                                                            in_len);
398                 if (res) {
399                         if (res == 1)
400                                 *need_more_input = 1;
401                         return NULL;
402                 }
403
404                 /* Message is now fully reassembled. */
405         } else {
406                 /* No fragments in this message, so just make a copy of it. */
407                 data->tls_in_left = 0;
408                 data->tls_in = os_malloc(in_len ? in_len : 1);
409                 if (data->tls_in == NULL)
410                         return NULL;
411                 os_memcpy(data->tls_in, in_data, in_len);
412                 data->tls_in_len = in_len;
413         }
414
415         *out_len = data->tls_in_len;
416         return data->tls_in;
417 }
418
419
420 /**
421  * eap_tls_process_input - Process incoming TLS message
422  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
423  * @data: Data for TLS processing
424  * @in_data: Message received from the server
425  * @in_len: Length of in_data
426  * @out_data: Buffer for returning a pointer to application data (if available)
427  * Returns: 0 on success, 1 if more input data is needed, 2 if application data
428  * is available, -1 on failure
429  */
430 static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
431                                  const u8 *in_data, size_t in_len,
432                                  struct wpabuf **out_data)
433 {
434         const u8 *msg;
435         size_t msg_len;
436         int need_more_input;
437         u8 *appl_data;
438         size_t appl_data_len;
439
440         msg = eap_peer_tls_data_reassemble(data, in_data, in_len,
441                                            &msg_len, &need_more_input);
442         if (msg == NULL)
443                 return need_more_input ? 1 : -1;
444
445         /* Full TLS message reassembled - continue handshake processing */
446         if (data->tls_out) {
447                 /* This should not happen.. */
448                 wpa_printf(MSG_INFO, "SSL: eap_tls_process_input - pending "
449                            "tls_out data even though tls_out_len = 0");
450                 os_free(data->tls_out);
451                 WPA_ASSERT(data->tls_out == NULL);
452         }
453         appl_data = NULL;
454         data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
455                                                  msg, msg_len,
456                                                  &data->tls_out_len,
457                                                  &appl_data, &appl_data_len);
458
459         eap_peer_tls_reset_input(data);
460
461         if (appl_data &&
462             tls_connection_established(sm->ssl_ctx, data->conn) &&
463             !tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
464                 wpa_hexdump_key(MSG_MSGDUMP, "SSL: Application data",
465                                 appl_data, appl_data_len);
466                 *out_data = wpabuf_alloc_ext_data(appl_data, appl_data_len);
467                 if (*out_data == NULL) {
468                         os_free(appl_data);
469                         return -1;
470                 }
471                 return 2;
472         }
473
474         os_free(appl_data);
475
476         return 0;
477 }
478
479
480 /**
481  * eap_tls_process_output - Process outgoing TLS message
482  * @data: Data for TLS processing
483  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
484  * @peap_version: Version number for EAP-PEAP/TTLS
485  * @id: EAP identifier for the response
486  * @ret: Return value to use on success
487  * @out_data: Buffer for returning the allocated output buffer
488  * Returns: ret (0 or 1) on success, -1 on failure
489  */
490 static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
491                                   int peap_version, u8 id, int ret,
492                                   struct wpabuf **out_data)
493 {
494         size_t len;
495         u8 *flags;
496         int more_fragments, length_included;
497         
498         len = data->tls_out_len - data->tls_out_pos;
499         wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
500                    "%lu bytes)",
501                    (unsigned long) len, (unsigned long) data->tls_out_len);
502
503         /*
504          * Limit outgoing message to the configured maximum size. Fragment
505          * message if needed.
506          */
507         if (len > data->tls_out_limit) {
508                 more_fragments = 1;
509                 len = data->tls_out_limit;
510                 wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
511                            "will follow", (unsigned long) len);
512         } else
513                 more_fragments = 0;
514
515         length_included = data->tls_out_pos == 0 &&
516                 (data->tls_out_len > data->tls_out_limit ||
517                  data->include_tls_length);
518         if (!length_included &&
519             eap_type == EAP_TYPE_PEAP && peap_version == 0 &&
520             !tls_connection_established(data->eap->ssl_ctx, data->conn)) {
521                 /*
522                  * Windows Server 2008 NPS really wants to have the TLS Message
523                  * length included in phase 0 even for unfragmented frames or
524                  * it will get very confused with Compound MAC calculation and
525                  * Outer TLVs.
526                  */
527                 length_included = 1;
528         }
529
530         *out_data = eap_msg_alloc(EAP_VENDOR_IETF, eap_type,
531                                   1 + length_included * 4 + len,
532                                   EAP_CODE_RESPONSE, id);
533         if (*out_data == NULL)
534                 return -1;
535
536         flags = wpabuf_put(*out_data, 1);
537         *flags = peap_version;
538         if (more_fragments)
539                 *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
540         if (length_included) {
541                 *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
542                 wpabuf_put_be32(*out_data, data->tls_out_len);
543         }
544
545         wpabuf_put_data(*out_data, &data->tls_out[data->tls_out_pos], len);
546         data->tls_out_pos += len;
547
548         if (!more_fragments)
549                 eap_peer_tls_reset_output(data);
550
551         return ret;
552 }
553
554
555 /**
556  * eap_peer_tls_process_helper - Process TLS handshake message
557  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
558  * @data: Data for TLS processing
559  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
560  * @peap_version: Version number for EAP-PEAP/TTLS
561  * @id: EAP identifier for the response
562  * @in_data: Message received from the server
563  * @in_len: Length of in_data
564  * @out_data: Buffer for returning a pointer to the response message
565  * Returns: 0 on success, 1 if more input data is needed, 2 if application data
566  * is available, or -1 on failure
567  *
568  * This function can be used to process TLS handshake messages. It reassembles
569  * the received fragments and uses a TLS library to process the messages. The
570  * response data from the TLS library is fragmented to suitable output messages
571  * that the caller can send out.
572  *
573  * out_data is used to return the response message if the return value of this
574  * function is 0, 2, or -1. In case of failure, the message is likely a TLS
575  * alarm message. The caller is responsible for freeing the allocated buffer if
576  * *out_data is not %NULL.
577  *
578  * This function is called for each received TLS message during the TLS
579  * handshake after eap_peer_tls_process_init() call and possible processing of
580  * TLS Flags field. Once the handshake has been completed, i.e., when
581  * tls_connection_established() returns 1, EAP method specific decrypting of
582  * the tunneled data is used.
583  */
584 int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
585                                 EapType eap_type, int peap_version,
586                                 u8 id, const u8 *in_data, size_t in_len,
587                                 struct wpabuf **out_data)
588 {
589         int ret = 0;
590
591         *out_data = NULL;
592
593         if (data->tls_out_len > 0 && in_len > 0) {
594                 wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output "
595                            "fragments are waiting to be sent out");
596                 return -1;
597         }
598
599         if (data->tls_out_len == 0) {
600                 /*
601                  * No more data to send out - expect to receive more data from
602                  * the AS.
603                  */
604                 int res = eap_tls_process_input(sm, data, in_data, in_len,
605                                                 out_data);
606                 if (res) {
607                         /*
608                          * Input processing failed (res = -1) or more data is
609                          * needed (res = 1).
610                          */
611                         return res;
612                 }
613
614                 /*
615                  * The incoming message has been reassembled and processed. The
616                  * response was allocated into data->tls_out buffer.
617                  */
618         }
619
620         if (data->tls_out == NULL) {
621                 /*
622                  * No outgoing fragments remaining from the previous message
623                  * and no new message generated. This indicates an error in TLS
624                  * processing.
625                  */
626                 eap_peer_tls_reset_output(data);
627                 return -1;
628         }
629
630         if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
631                 /* TLS processing has failed - return error */
632                 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
633                            "report error");
634                 ret = -1;
635                 /* TODO: clean pin if engine used? */
636         }
637
638         if (data->tls_out_len == 0) {
639                 /*
640                  * TLS negotiation should now be complete since all other cases
641                  * needing more data should have been caught above based on
642                  * the TLS Message Length field.
643                  */
644                 wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
645                 os_free(data->tls_out);
646                 data->tls_out = NULL;
647                 return 1;
648         }
649
650         /* Send the pending message (in fragments, if needed). */
651         return eap_tls_process_output(data, eap_type, peap_version, id, ret,
652                                       out_data);
653 }
654
655
656 /**
657  * eap_peer_tls_build_ack - Build a TLS ACK frame
658  * @id: EAP identifier for the response
659  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
660  * @peap_version: Version number for EAP-PEAP/TTLS
661  * Returns: Pointer to the allocated ACK frame or %NULL on failure
662  */
663 struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type,
664                                        int peap_version)
665 {
666         struct wpabuf *resp;
667
668         resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_RESPONSE,
669                              id);
670         if (resp == NULL)
671                 return NULL;
672         wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)",
673                    (int) eap_type, id, peap_version);
674         wpabuf_put_u8(resp, peap_version); /* Flags */
675         return resp;
676 }
677
678
679 /**
680  * eap_peer_tls_reauth_init - Re-initialize shared TLS for session resumption
681  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
682  * @data: Data for TLS processing
683  * Returns: 0 on success, -1 on failure
684  */
685 int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data)
686 {
687         eap_peer_tls_reset_input(data);
688         eap_peer_tls_reset_output(data);
689         return tls_connection_shutdown(sm->ssl_ctx, data->conn);
690 }
691
692
693 /**
694  * eap_peer_tls_status - Get TLS status
695  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
696  * @data: Data for TLS processing
697  * @buf: Buffer for status information
698  * @buflen: Maximum buffer length
699  * @verbose: Whether to include verbose status information
700  * Returns: Number of bytes written to buf.
701  */
702 int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
703                         char *buf, size_t buflen, int verbose)
704 {
705         char name[128];
706         int len = 0, ret;
707
708         if (tls_get_cipher(sm->ssl_ctx, data->conn, name, sizeof(name)) == 0) {
709                 ret = os_snprintf(buf + len, buflen - len,
710                                   "EAP TLS cipher=%s\n", name);
711                 if (ret < 0 || (size_t) ret >= buflen - len)
712                         return len;
713                 len += ret;
714         }
715
716         return len;
717 }
718
719
720 /**
721  * eap_peer_tls_process_init - Initial validation/processing of EAP requests
722  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
723  * @data: Data for TLS processing
724  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
725  * @ret: Return values from EAP request validation and processing
726  * @reqData: EAP request to be processed (eapReqData)
727  * @len: Buffer for returning length of the remaining payload
728  * @flags: Buffer for returning TLS flags
729  * Returns: Pointer to payload after TLS flags and length or %NULL on failure
730  *
731  * This function validates the EAP header and processes the optional TLS
732  * Message Length field. If this is the first fragment of a TLS message, the
733  * TLS reassembly code is initialized to receive the indicated number of bytes.
734  *
735  * EAP-TLS, EAP-PEAP, EAP-TTLS, and EAP-FAST methods are expected to use this
736  * function as the first step in processing received messages. They will need
737  * to process the flags (apart from Message Length Included) that are returned
738  * through the flags pointer and the message payload that will be returned (and
739  * the length is returned through the len pointer). Return values (ret) are set
740  * for continuation of EAP method processing. The caller is responsible for
741  * setting these to indicate completion (either success or failure) based on
742  * the authentication result.
743  */
744 const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
745                                      struct eap_ssl_data *data,
746                                      EapType eap_type,
747                                      struct eap_method_ret *ret,
748                                      const struct wpabuf *reqData,
749                                      size_t *len, u8 *flags)
750 {
751         const u8 *pos;
752         size_t left;
753         unsigned int tls_msg_len;
754
755         if (tls_get_errors(sm->ssl_ctx)) {
756                 wpa_printf(MSG_INFO, "SSL: TLS errors detected");
757                 ret->ignore = TRUE;
758                 return NULL;
759         }
760
761         pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, &left);
762         if (pos == NULL) {
763                 ret->ignore = TRUE;
764                 return NULL;
765         }
766         if (left == 0) {
767                 wpa_printf(MSG_DEBUG, "SSL: Invalid TLS message: no Flags "
768                            "octet included");
769                 if (!sm->workaround) {
770                         ret->ignore = TRUE;
771                         return NULL;
772                 }
773
774                 wpa_printf(MSG_DEBUG, "SSL: Workaround - assume no Flags "
775                            "indicates ACK frame");
776                 *flags = 0;
777         } else {
778                 *flags = *pos++;
779                 left--;
780         }
781         wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
782                    "Flags 0x%02x", (unsigned long) wpabuf_len(reqData),
783                    *flags);
784         if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
785                 if (left < 4) {
786                         wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
787                                    "length");
788                         ret->ignore = TRUE;
789                         return NULL;
790                 }
791                 tls_msg_len = WPA_GET_BE32(pos);
792                 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
793                            tls_msg_len);
794                 if (data->tls_in_left == 0) {
795                         data->tls_in_total = tls_msg_len;
796                         data->tls_in_left = tls_msg_len;
797                         os_free(data->tls_in);
798                         data->tls_in = NULL;
799                         data->tls_in_len = 0;
800                 }
801                 pos += 4;
802                 left -= 4;
803         }
804
805         ret->ignore = FALSE;
806         ret->methodState = METHOD_MAY_CONT;
807         ret->decision = DECISION_FAIL;
808         ret->allowNotifications = TRUE;
809
810         *len = left;
811         return pos;
812 }
813
814
815 /**
816  * eap_peer_tls_reset_input - Reset input buffers
817  * @data: Data for TLS processing
818  *
819  * This function frees any allocated memory for input buffers and resets input
820  * state.
821  */
822 void eap_peer_tls_reset_input(struct eap_ssl_data *data)
823 {
824         data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
825         os_free(data->tls_in);
826         data->tls_in = NULL;
827 }
828
829
830 /**
831  * eap_peer_tls_reset_output - Reset output buffers
832  * @data: Data for TLS processing
833  *
834  * This function frees any allocated memory for output buffers and resets
835  * output state.
836  */
837 void eap_peer_tls_reset_output(struct eap_ssl_data *data)
838 {
839         data->tls_out_len = 0;
840         data->tls_out_pos = 0;
841         os_free(data->tls_out);
842         data->tls_out = NULL;
843 }
844
845
846 /**
847  * eap_peer_tls_decrypt - Decrypt received phase 2 TLS message
848  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
849  * @data: Data for TLS processing
850  * @in_data: Message received from the server
851  * @in_decrypted: Buffer for returning a pointer to the decrypted message
852  * Returns: 0 on success, 1 if more input data is needed, or -1 on failure
853  */
854 int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
855                          const struct wpabuf *in_data,
856                          struct wpabuf **in_decrypted)
857 {
858         int res;
859         const u8 *msg;
860         size_t msg_len, buf_len;
861         int need_more_input;
862
863         msg = eap_peer_tls_data_reassemble(data, wpabuf_head(in_data),
864                                            wpabuf_len(in_data), &msg_len,
865                                            &need_more_input);
866         if (msg == NULL)
867                 return need_more_input ? 1 : -1;
868
869         buf_len = wpabuf_len(in_data);
870         if (data->tls_in_total > buf_len)
871                 buf_len = data->tls_in_total;
872         /*
873          * Even though we try to disable TLS compression, it is possible that
874          * this cannot be done with all TLS libraries. Add extra buffer space
875          * to handle the possibility of the decrypted data being longer than
876          * input data.
877          */
878         buf_len += 500;
879         buf_len *= 3;
880         *in_decrypted = wpabuf_alloc(buf_len ? buf_len : 1);
881         if (*in_decrypted == NULL) {
882                 eap_peer_tls_reset_input(data);
883                 wpa_printf(MSG_WARNING, "SSL: Failed to allocate memory for "
884                            "decryption");
885                 return -1;
886         }
887
888         res = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg, msg_len,
889                                      wpabuf_mhead(*in_decrypted), buf_len);
890         eap_peer_tls_reset_input(data);
891         if (res < 0) {
892                 wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
893                 return -1;
894         }
895         wpabuf_put(*in_decrypted, res);
896         return 0;
897 }
898
899
900 /**
901  * eap_peer_tls_encrypt - Encrypt phase 2 TLS message
902  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
903  * @data: Data for TLS processing
904  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
905  * @peap_version: Version number for EAP-PEAP/TTLS
906  * @id: EAP identifier for the response
907  * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments
908  * @out_data: Buffer for returning a pointer to the encrypted response message
909  * Returns: 0 on success, -1 on failure
910  */
911 int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
912                          EapType eap_type, int peap_version, u8 id,
913                          const struct wpabuf *in_data,
914                          struct wpabuf **out_data)
915 {
916         int res;
917         size_t len;
918
919         if (in_data) {
920                 eap_peer_tls_reset_output(data);
921                 len = wpabuf_len(in_data) + 300;
922                 data->tls_out = os_malloc(len);
923                 if (data->tls_out == NULL)
924                         return -1;
925
926                 res = tls_connection_encrypt(sm->ssl_ctx, data->conn,
927                                              wpabuf_head(in_data),
928                                              wpabuf_len(in_data),
929                                              data->tls_out, len);
930                 if (res < 0) {
931                         wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 "
932                                    "data (in_len=%lu)",
933                                    (unsigned long) wpabuf_len(in_data));
934                         eap_peer_tls_reset_output(data);
935                         return -1;
936                 }
937
938                 data->tls_out_len = res;
939         }
940
941         return eap_tls_process_output(data, eap_type, peap_version, id, 0,
942                                       out_data);
943 }
944
945
946 /**
947  * eap_peer_select_phase2_methods - Select phase 2 EAP method
948  * @config: Pointer to the network configuration
949  * @prefix: 'phase2' configuration prefix, e.g., "auth="
950  * @types: Buffer for returning allocated list of allowed EAP methods
951  * @num_types: Buffer for returning number of allocated EAP methods
952  * Returns: 0 on success, -1 on failure
953  *
954  * This function is used to parse EAP method list and select allowed methods
955  * for Phase2 authentication.
956  */
957 int eap_peer_select_phase2_methods(struct eap_peer_config *config,
958                                    const char *prefix,
959                                    struct eap_method_type **types,
960                                    size_t *num_types)
961 {
962         char *start, *pos, *buf;
963         struct eap_method_type *methods = NULL, *_methods;
964         u8 method;
965         size_t num_methods = 0, prefix_len;
966
967         if (config == NULL || config->phase2 == NULL)
968                 goto get_defaults;
969
970         start = buf = os_strdup(config->phase2);
971         if (buf == NULL)
972                 return -1;
973
974         prefix_len = os_strlen(prefix);
975
976         while (start && *start != '\0') {
977                 int vendor;
978                 pos = os_strstr(start, prefix);
979                 if (pos == NULL)
980                         break;
981                 if (start != pos && *(pos - 1) != ' ') {
982                         start = pos + prefix_len;
983                         continue;
984                 }
985
986                 start = pos + prefix_len;
987                 pos = os_strchr(start, ' ');
988                 if (pos)
989                         *pos++ = '\0';
990                 method = eap_get_phase2_type(start, &vendor);
991                 if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) {
992                         wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP "
993                                    "method '%s'", start);
994                 } else {
995                         num_methods++;
996                         _methods = os_realloc(methods,
997                                               num_methods * sizeof(*methods));
998                         if (_methods == NULL) {
999                                 os_free(methods);
1000                                 os_free(buf);
1001                                 return -1;
1002                         }
1003                         methods = _methods;
1004                         methods[num_methods - 1].vendor = vendor;
1005                         methods[num_methods - 1].method = method;
1006                 }
1007
1008                 start = pos;
1009         }
1010
1011         os_free(buf);
1012
1013 get_defaults:
1014         if (methods == NULL)
1015                 methods = eap_get_phase2_types(config, &num_methods);
1016
1017         if (methods == NULL) {
1018                 wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available");
1019                 return -1;
1020         }
1021         wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types",
1022                     (u8 *) methods,
1023                     num_methods * sizeof(struct eap_method_type));
1024
1025         *types = methods;
1026         *num_types = num_methods;
1027
1028         return 0;
1029 }
1030
1031
1032 /**
1033  * eap_peer_tls_phase2_nak - Generate EAP-Nak for Phase 2
1034  * @types: Buffer for returning allocated list of allowed EAP methods
1035  * @num_types: Buffer for returning number of allocated EAP methods
1036  * @hdr: EAP-Request header (and the following EAP type octet)
1037  * @resp: Buffer for returning the EAP-Nak message
1038  * Returns: 0 on success, -1 on failure
1039  */
1040 int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
1041                             struct eap_hdr *hdr, struct wpabuf **resp)
1042 {
1043         u8 *pos = (u8 *) (hdr + 1);
1044         size_t i;
1045
1046         /* TODO: add support for expanded Nak */
1047         wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos);
1048         wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types",
1049                     (u8 *) types, num_types * sizeof(struct eap_method_type));
1050         *resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types,
1051                               EAP_CODE_RESPONSE, hdr->identifier);
1052         if (*resp == NULL)
1053                 return -1;
1054
1055         for (i = 0; i < num_types; i++) {
1056                 if (types[i].vendor == EAP_VENDOR_IETF &&
1057                     types[i].method < 256)
1058                         wpabuf_put_u8(*resp, types[i].method);
1059         }
1060
1061         eap_update_len(*resp);
1062
1063         return 0;
1064 }