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