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 }
1065