xref: /freebsd/contrib/wpa/src/crypto/tls_gnutls.c (revision 6829dae12bb055451fa467da4589c43bd03b1e64)
1 /*
2  * SSL/TLS interface functions for GnuTLS
3  * Copyright (c) 2004-2017, 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 #include <gnutls/gnutls.h>
11 #include <gnutls/x509.h>
12 #ifdef PKCS12_FUNCS
13 #include <gnutls/pkcs12.h>
14 #endif /* PKCS12_FUNCS */
15 #if GNUTLS_VERSION_NUMBER >= 0x030103
16 #include <gnutls/ocsp.h>
17 #endif /* 3.1.3 */
18 
19 #include "common.h"
20 #include "crypto/crypto.h"
21 #include "tls.h"
22 
23 
24 static int tls_gnutls_ref_count = 0;
25 
26 struct tls_global {
27 	/* Data for session resumption */
28 	void *session_data;
29 	size_t session_data_size;
30 
31 	int server;
32 
33 	int params_set;
34 	gnutls_certificate_credentials_t xcred;
35 
36 	void (*event_cb)(void *ctx, enum tls_event ev,
37 			 union tls_event_data *data);
38 	void *cb_ctx;
39 	int cert_in_cb;
40 
41 	char *ocsp_stapling_response;
42 };
43 
44 struct tls_connection {
45 	struct tls_global *global;
46 	gnutls_session_t session;
47 	int read_alerts, write_alerts, failed;
48 
49 	u8 *pre_shared_secret;
50 	size_t pre_shared_secret_len;
51 	int established;
52 	int verify_peer;
53 	unsigned int disable_time_checks:1;
54 
55 	struct wpabuf *push_buf;
56 	struct wpabuf *pull_buf;
57 	const u8 *pull_buf_offset;
58 
59 	int params_set;
60 	gnutls_certificate_credentials_t xcred;
61 
62 	char *suffix_match;
63 	char *domain_match;
64 	unsigned int flags;
65 };
66 
67 
68 static int tls_connection_verify_peer(gnutls_session_t session);
69 
70 
71 static void tls_log_func(int level, const char *msg)
72 {
73 	char *s, *pos;
74 	if (level == 6 || level == 7) {
75 		/* These levels seem to be mostly I/O debug and msg dumps */
76 		return;
77 	}
78 
79 	s = os_strdup(msg);
80 	if (s == NULL)
81 		return;
82 
83 	pos = s;
84 	while (*pos != '\0') {
85 		if (*pos == '\n') {
86 			*pos = '\0';
87 			break;
88 		}
89 		pos++;
90 	}
91 	wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG,
92 		   "gnutls<%d> %s", level, s);
93 	os_free(s);
94 }
95 
96 
97 void * tls_init(const struct tls_config *conf)
98 {
99 	struct tls_global *global;
100 
101 	if (tls_gnutls_ref_count == 0) {
102 		wpa_printf(MSG_DEBUG,
103 			   "GnuTLS: Library version %s (runtime) - %s (build)",
104 			   gnutls_check_version(NULL), GNUTLS_VERSION);
105 	}
106 
107 	global = os_zalloc(sizeof(*global));
108 	if (global == NULL)
109 		return NULL;
110 
111 	if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) {
112 		os_free(global);
113 		return NULL;
114 	}
115 	tls_gnutls_ref_count++;
116 
117 	gnutls_global_set_log_function(tls_log_func);
118 	if (wpa_debug_show_keys)
119 		gnutls_global_set_log_level(11);
120 
121 	if (conf) {
122 		global->event_cb = conf->event_cb;
123 		global->cb_ctx = conf->cb_ctx;
124 		global->cert_in_cb = conf->cert_in_cb;
125 	}
126 
127 	return global;
128 }
129 
130 
131 void tls_deinit(void *ssl_ctx)
132 {
133 	struct tls_global *global = ssl_ctx;
134 	if (global) {
135 		if (global->params_set)
136 			gnutls_certificate_free_credentials(global->xcred);
137 		os_free(global->session_data);
138 		os_free(global->ocsp_stapling_response);
139 		os_free(global);
140 	}
141 
142 	tls_gnutls_ref_count--;
143 	if (tls_gnutls_ref_count == 0)
144 		gnutls_global_deinit();
145 }
146 
147 
148 int tls_get_errors(void *ssl_ctx)
149 {
150 	return 0;
151 }
152 
153 
154 static ssize_t tls_pull_func(gnutls_transport_ptr_t ptr, void *buf,
155 			     size_t len)
156 {
157 	struct tls_connection *conn = (struct tls_connection *) ptr;
158 	const u8 *end;
159 	if (conn->pull_buf == NULL) {
160 		errno = EWOULDBLOCK;
161 		return -1;
162 	}
163 
164 	end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf);
165 	if ((size_t) (end - conn->pull_buf_offset) < len)
166 		len = end - conn->pull_buf_offset;
167 	os_memcpy(buf, conn->pull_buf_offset, len);
168 	conn->pull_buf_offset += len;
169 	if (conn->pull_buf_offset == end) {
170 		wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
171 		wpabuf_free(conn->pull_buf);
172 		conn->pull_buf = NULL;
173 		conn->pull_buf_offset = NULL;
174 	} else {
175 		wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
176 			   __func__,
177 			   (unsigned long) (end - conn->pull_buf_offset));
178 	}
179 	return len;
180 }
181 
182 
183 static ssize_t tls_push_func(gnutls_transport_ptr_t ptr, const void *buf,
184 			     size_t len)
185 {
186 	struct tls_connection *conn = (struct tls_connection *) ptr;
187 
188 	if (wpabuf_resize(&conn->push_buf, len) < 0) {
189 		errno = ENOMEM;
190 		return -1;
191 	}
192 	wpabuf_put_data(conn->push_buf, buf, len);
193 
194 	return len;
195 }
196 
197 
198 static int tls_gnutls_init_session(struct tls_global *global,
199 				   struct tls_connection *conn)
200 {
201 	const char *err;
202 	int ret;
203 
204 	ret = gnutls_init(&conn->session,
205 			  global->server ? GNUTLS_SERVER : GNUTLS_CLIENT);
206 	if (ret < 0) {
207 		wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS "
208 			   "connection: %s", gnutls_strerror(ret));
209 		return -1;
210 	}
211 
212 	ret = gnutls_set_default_priority(conn->session);
213 	if (ret < 0)
214 		goto fail;
215 
216 	ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0",
217 					 &err);
218 	if (ret < 0) {
219 		wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at "
220 			   "'%s'", err);
221 		goto fail;
222 	}
223 
224 	gnutls_transport_set_pull_function(conn->session, tls_pull_func);
225 	gnutls_transport_set_push_function(conn->session, tls_push_func);
226 	gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn);
227 	gnutls_session_set_ptr(conn->session, conn);
228 
229 	return 0;
230 
231 fail:
232 	wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s",
233 		   gnutls_strerror(ret));
234 	gnutls_deinit(conn->session);
235 	return -1;
236 }
237 
238 
239 struct tls_connection * tls_connection_init(void *ssl_ctx)
240 {
241 	struct tls_global *global = ssl_ctx;
242 	struct tls_connection *conn;
243 	int ret;
244 
245 	conn = os_zalloc(sizeof(*conn));
246 	if (conn == NULL)
247 		return NULL;
248 	conn->global = global;
249 
250 	if (tls_gnutls_init_session(global, conn)) {
251 		os_free(conn);
252 		return NULL;
253 	}
254 
255 	if (global->params_set) {
256 		ret = gnutls_credentials_set(conn->session,
257 					     GNUTLS_CRD_CERTIFICATE,
258 					     global->xcred);
259 		if (ret < 0) {
260 			wpa_printf(MSG_INFO, "Failed to configure "
261 				   "credentials: %s", gnutls_strerror(ret));
262 			os_free(conn);
263 			return NULL;
264 		}
265 	}
266 
267 	if (gnutls_certificate_allocate_credentials(&conn->xcred)) {
268 		os_free(conn);
269 		return NULL;
270 	}
271 
272 	return conn;
273 }
274 
275 
276 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
277 {
278 	if (conn == NULL)
279 		return;
280 
281 	gnutls_certificate_free_credentials(conn->xcred);
282 	gnutls_deinit(conn->session);
283 	os_free(conn->pre_shared_secret);
284 	wpabuf_free(conn->push_buf);
285 	wpabuf_free(conn->pull_buf);
286 	os_free(conn->suffix_match);
287 	os_free(conn->domain_match);
288 	os_free(conn);
289 }
290 
291 
292 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
293 {
294 	return conn ? conn->established : 0;
295 }
296 
297 
298 char * tls_connection_peer_serial_num(void *tls_ctx,
299 				      struct tls_connection *conn)
300 {
301 	/* TODO */
302 	return NULL;
303 }
304 
305 
306 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
307 {
308 	struct tls_global *global = ssl_ctx;
309 	int ret;
310 
311 	if (conn == NULL)
312 		return -1;
313 
314 	/* Shutdown previous TLS connection without notifying the peer
315 	 * because the connection was already terminated in practice
316 	 * and "close notify" shutdown alert would confuse AS. */
317 	gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
318 	wpabuf_free(conn->push_buf);
319 	conn->push_buf = NULL;
320 	conn->established = 0;
321 
322 	gnutls_deinit(conn->session);
323 	if (tls_gnutls_init_session(global, conn)) {
324 		wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session "
325 			   "for session resumption use");
326 		return -1;
327 	}
328 
329 	ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
330 				     conn->params_set ? conn->xcred :
331 				     global->xcred);
332 	if (ret < 0) {
333 		wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials "
334 			   "for session resumption: %s", gnutls_strerror(ret));
335 		return -1;
336 	}
337 
338 	if (global->session_data) {
339 		ret = gnutls_session_set_data(conn->session,
340 					      global->session_data,
341 					      global->session_data_size);
342 		if (ret < 0) {
343 			wpa_printf(MSG_INFO, "GnuTLS: Failed to set session "
344 				   "data: %s", gnutls_strerror(ret));
345 			return -1;
346 		}
347 	}
348 
349 	return 0;
350 }
351 
352 
353 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
354 			      const struct tls_connection_params *params)
355 {
356 	int ret;
357 	const char *err;
358 	char prio_buf[100];
359 	const char *prio = NULL;
360 
361 	if (conn == NULL || params == NULL)
362 		return -1;
363 
364 	if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
365 		wpa_printf(MSG_INFO,
366 			   "GnuTLS: ocsp=3 not supported");
367 		return -1;
368 	}
369 
370 	if (params->flags & TLS_CONN_EXT_CERT_CHECK) {
371 		wpa_printf(MSG_INFO,
372 			   "GnuTLS: tls_ext_cert_check=1 not supported");
373 		return -1;
374 	}
375 
376 	if (params->subject_match) {
377 		wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported");
378 		return -1;
379 	}
380 
381 	if (params->altsubject_match) {
382 		wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported");
383 		return -1;
384 	}
385 
386 	os_free(conn->suffix_match);
387 	conn->suffix_match = NULL;
388 	if (params->suffix_match) {
389 		conn->suffix_match = os_strdup(params->suffix_match);
390 		if (conn->suffix_match == NULL)
391 			return -1;
392 	}
393 
394 #if GNUTLS_VERSION_NUMBER >= 0x030300
395 	os_free(conn->domain_match);
396 	conn->domain_match = NULL;
397 	if (params->domain_match) {
398 		conn->domain_match = os_strdup(params->domain_match);
399 		if (conn->domain_match == NULL)
400 			return -1;
401 	}
402 #else /* < 3.3.0 */
403 	if (params->domain_match) {
404 		wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported");
405 		return -1;
406 	}
407 #endif /* >= 3.3.0 */
408 
409 	conn->flags = params->flags;
410 
411 	if (params->flags & (TLS_CONN_DISABLE_TLSv1_0 |
412 			     TLS_CONN_DISABLE_TLSv1_1 |
413 			     TLS_CONN_DISABLE_TLSv1_2)) {
414 		os_snprintf(prio_buf, sizeof(prio_buf),
415 			    "NORMAL:-VERS-SSL3.0%s%s%s",
416 			    params->flags & TLS_CONN_DISABLE_TLSv1_0 ?
417 			    ":-VERS-TLS1.0" : "",
418 			    params->flags & TLS_CONN_DISABLE_TLSv1_1 ?
419 			    ":-VERS-TLS1.1" : "",
420 			    params->flags & TLS_CONN_DISABLE_TLSv1_2 ?
421 			    ":-VERS-TLS1.2" : "");
422 		prio = prio_buf;
423 	}
424 
425 	if (params->openssl_ciphers) {
426 		if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) {
427 			prio = "SUITEB128";
428 		} else if (os_strcmp(params->openssl_ciphers,
429 				     "SUITEB192") == 0) {
430 			prio = "SUITEB192";
431 		} else if ((params->flags & TLS_CONN_SUITEB) &&
432 			   os_strcmp(params->openssl_ciphers,
433 				     "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
434 			prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
435 		} else if (os_strcmp(params->openssl_ciphers,
436 				     "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
437 			prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
438 		} else if (os_strcmp(params->openssl_ciphers,
439 				     "DHE-RSA-AES256-GCM-SHA384") == 0) {
440 			prio = "NONE:+VERS-TLS1.2:+AEAD:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
441 		} else if (os_strcmp(params->openssl_ciphers,
442 				     "ECDHE-ECDSA-AES256-GCM-SHA384") == 0) {
443 			prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
444 		} else {
445 			wpa_printf(MSG_INFO,
446 				   "GnuTLS: openssl_ciphers not supported");
447 			return -1;
448 		}
449 	} else if (params->flags & TLS_CONN_SUITEB) {
450 		prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
451 	}
452 
453 	if (prio) {
454 		wpa_printf(MSG_DEBUG, "GnuTLS: Set priority string: %s", prio);
455 		ret = gnutls_priority_set_direct(conn->session, prio, &err);
456 		if (ret < 0) {
457 			wpa_printf(MSG_ERROR,
458 				   "GnuTLS: Priority string failure at '%s'",
459 				   err);
460 			return -1;
461 		}
462 	}
463 
464 	/* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
465 	 * to force peer validation(?) */
466 
467 	if (params->ca_cert) {
468 		wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format",
469 			   params->ca_cert);
470 		ret = gnutls_certificate_set_x509_trust_file(
471 			conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
472 		if (ret < 0) {
473 			wpa_printf(MSG_DEBUG,
474 				   "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format",
475 				   params->ca_cert,
476 				   gnutls_strerror(ret));
477 			ret = gnutls_certificate_set_x509_trust_file(
478 				conn->xcred, params->ca_cert,
479 				GNUTLS_X509_FMT_PEM);
480 			if (ret < 0) {
481 				wpa_printf(MSG_DEBUG,
482 					   "Failed to read CA cert '%s' in PEM format: %s",
483 					   params->ca_cert,
484 					   gnutls_strerror(ret));
485 				return -1;
486 			}
487 			wpa_printf(MSG_DEBUG,
488 				   "GnuTLS: Successfully read CA cert '%s' in PEM format",
489 				   params->ca_cert);
490 		} else {
491 			wpa_printf(MSG_DEBUG,
492 				   "GnuTLS: Successfully read CA cert '%s' in DER format",
493 				   params->ca_cert);
494 		}
495 	} else if (params->ca_cert_blob) {
496 		gnutls_datum_t ca;
497 
498 		ca.data = (unsigned char *) params->ca_cert_blob;
499 		ca.size = params->ca_cert_blob_len;
500 
501 		ret = gnutls_certificate_set_x509_trust_mem(
502 			conn->xcred, &ca, GNUTLS_X509_FMT_DER);
503 		if (ret < 0) {
504 			wpa_printf(MSG_DEBUG,
505 				   "Failed to parse CA cert in DER format: %s",
506 				   gnutls_strerror(ret));
507 			ret = gnutls_certificate_set_x509_trust_mem(
508 				conn->xcred, &ca, GNUTLS_X509_FMT_PEM);
509 			if (ret < 0) {
510 				wpa_printf(MSG_DEBUG,
511 					   "Failed to parse CA cert in PEM format: %s",
512 					   gnutls_strerror(ret));
513 				return -1;
514 			}
515 		}
516 	} else if (params->ca_path) {
517 		wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported");
518 		return -1;
519 	}
520 
521 	conn->disable_time_checks = 0;
522 	if (params->ca_cert || params->ca_cert_blob) {
523 		conn->verify_peer = 1;
524 		gnutls_certificate_set_verify_function(
525 			conn->xcred, tls_connection_verify_peer);
526 
527 		if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
528 			gnutls_certificate_set_verify_flags(
529 				conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
530 		}
531 
532 		if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
533 			conn->disable_time_checks = 1;
534 			gnutls_certificate_set_verify_flags(
535 				conn->xcred,
536 				GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
537 		}
538 	}
539 
540 	if (params->client_cert && params->private_key) {
541 		wpa_printf(MSG_DEBUG,
542 			   "GnuTLS: Try to parse client cert '%s' and key '%s' in DER format",
543 			   params->client_cert, params->private_key);
544 #if GNUTLS_VERSION_NUMBER >= 0x03010b
545 		ret = gnutls_certificate_set_x509_key_file2(
546 			conn->xcred, params->client_cert, params->private_key,
547 			GNUTLS_X509_FMT_DER, params->private_key_passwd, 0);
548 #else
549 		/* private_key_passwd not (easily) supported here */
550 		ret = gnutls_certificate_set_x509_key_file(
551 			conn->xcred, params->client_cert, params->private_key,
552 			GNUTLS_X509_FMT_DER);
553 #endif
554 		if (ret < 0) {
555 			wpa_printf(MSG_DEBUG,
556 				   "GnuTLS: Failed to read client cert/key in DER format (%s) - try in PEM format",
557 				   gnutls_strerror(ret));
558 #if GNUTLS_VERSION_NUMBER >= 0x03010b
559 			ret = gnutls_certificate_set_x509_key_file2(
560 				conn->xcred, params->client_cert,
561 				params->private_key, GNUTLS_X509_FMT_PEM,
562 				params->private_key_passwd, 0);
563 #else
564 			ret = gnutls_certificate_set_x509_key_file(
565 				conn->xcred, params->client_cert,
566 				params->private_key, GNUTLS_X509_FMT_PEM);
567 #endif
568 			if (ret < 0) {
569 				wpa_printf(MSG_DEBUG, "Failed to read client "
570 					   "cert/key in PEM format: %s",
571 					   gnutls_strerror(ret));
572 				return ret;
573 			}
574 			wpa_printf(MSG_DEBUG,
575 				   "GnuTLS: Successfully read client cert/key in PEM format");
576 		} else {
577 			wpa_printf(MSG_DEBUG,
578 				   "GnuTLS: Successfully read client cert/key in DER format");
579 		}
580 	} else if (params->private_key) {
581 		int pkcs12_ok = 0;
582 #ifdef PKCS12_FUNCS
583 		/* Try to load in PKCS#12 format */
584 		wpa_printf(MSG_DEBUG,
585 			   "GnuTLS: Try to parse client cert/key '%s'in PKCS#12 DER format",
586 			   params->private_key);
587 		ret = gnutls_certificate_set_x509_simple_pkcs12_file(
588 			conn->xcred, params->private_key, GNUTLS_X509_FMT_DER,
589 			params->private_key_passwd);
590 		if (ret != 0) {
591 			wpa_printf(MSG_DEBUG, "Failed to load private_key in "
592 				   "PKCS#12 format: %s", gnutls_strerror(ret));
593 			return -1;
594 		} else
595 			pkcs12_ok = 1;
596 #endif /* PKCS12_FUNCS */
597 
598 		if (!pkcs12_ok) {
599 			wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
600 				   "included");
601 			return -1;
602 		}
603 	} else if (params->client_cert_blob && params->private_key_blob) {
604 		gnutls_datum_t cert, key;
605 
606 		cert.data = (unsigned char *) params->client_cert_blob;
607 		cert.size = params->client_cert_blob_len;
608 		key.data = (unsigned char *) params->private_key_blob;
609 		key.size = params->private_key_blob_len;
610 
611 #if GNUTLS_VERSION_NUMBER >= 0x03010b
612 		ret = gnutls_certificate_set_x509_key_mem2(
613 			conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER,
614 			params->private_key_passwd, 0);
615 #else
616 		/* private_key_passwd not (easily) supported here */
617 		ret = gnutls_certificate_set_x509_key_mem(
618 			conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER);
619 #endif
620 		if (ret < 0) {
621 			wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
622 				   "in DER format: %s", gnutls_strerror(ret));
623 #if GNUTLS_VERSION_NUMBER >= 0x03010b
624 			ret = gnutls_certificate_set_x509_key_mem2(
625 				conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM,
626 				params->private_key_passwd, 0);
627 #else
628 			/* private_key_passwd not (easily) supported here */
629 			ret = gnutls_certificate_set_x509_key_mem(
630 				conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM);
631 #endif
632 			if (ret < 0) {
633 				wpa_printf(MSG_DEBUG, "Failed to read client "
634 					   "cert/key in PEM format: %s",
635 					   gnutls_strerror(ret));
636 				return ret;
637 			}
638 		}
639 	} else if (params->private_key_blob) {
640 #ifdef PKCS12_FUNCS
641 		gnutls_datum_t key;
642 
643 		key.data = (unsigned char *) params->private_key_blob;
644 		key.size = params->private_key_blob_len;
645 
646 		/* Try to load in PKCS#12 format */
647 		ret = gnutls_certificate_set_x509_simple_pkcs12_mem(
648 			conn->xcred, &key, GNUTLS_X509_FMT_DER,
649 			params->private_key_passwd);
650 		if (ret != 0) {
651 			wpa_printf(MSG_DEBUG, "Failed to load private_key in "
652 				   "PKCS#12 format: %s", gnutls_strerror(ret));
653 			return -1;
654 		}
655 #else /* PKCS12_FUNCS */
656 		wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included");
657 		return -1;
658 #endif /* PKCS12_FUNCS */
659 	}
660 
661 #if GNUTLS_VERSION_NUMBER >= 0x030103
662 	if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) {
663 		ret = gnutls_ocsp_status_request_enable_client(conn->session,
664 							       NULL, 0, NULL);
665 		if (ret != GNUTLS_E_SUCCESS) {
666 			wpa_printf(MSG_INFO,
667 				   "GnuTLS: Failed to enable OCSP client");
668 			return -1;
669 		}
670 	}
671 #else /* 3.1.3 */
672 	if (params->flags & TLS_CONN_REQUIRE_OCSP) {
673 		wpa_printf(MSG_INFO,
674 			   "GnuTLS: OCSP not supported by this version of GnuTLS");
675 		return -1;
676 	}
677 #endif /* 3.1.3 */
678 
679 	conn->params_set = 1;
680 
681 	ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
682 				     conn->xcred);
683 	if (ret < 0) {
684 		wpa_printf(MSG_INFO, "Failed to configure credentials: %s",
685 			   gnutls_strerror(ret));
686 	}
687 
688 	return ret;
689 }
690 
691 
692 #if GNUTLS_VERSION_NUMBER >= 0x030103
693 static int server_ocsp_status_req(gnutls_session_t session, void *ptr,
694 				  gnutls_datum_t *resp)
695 {
696 	struct tls_global *global = ptr;
697 	char *cached;
698 	size_t len;
699 
700 	if (!global->ocsp_stapling_response) {
701 		wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured");
702 		return GNUTLS_E_NO_CERTIFICATE_STATUS;
703 	}
704 
705 	cached = os_readfile(global->ocsp_stapling_response, &len);
706 	if (!cached) {
707 		wpa_printf(MSG_DEBUG,
708 			   "GnuTLS: OCSP status callback - could not read response file (%s)",
709 			   global->ocsp_stapling_response);
710 		return GNUTLS_E_NO_CERTIFICATE_STATUS;
711 	}
712 
713 	wpa_printf(MSG_DEBUG,
714 		   "GnuTLS: OCSP status callback - send cached response");
715 	resp->data = gnutls_malloc(len);
716 	if (!resp->data) {
717 		os_free(resp);
718 		return GNUTLS_E_MEMORY_ERROR;
719 	}
720 
721 	os_memcpy(resp->data, cached, len);
722 	resp->size = len;
723 	os_free(cached);
724 
725 	return GNUTLS_E_SUCCESS;
726 }
727 #endif /* 3.1.3 */
728 
729 
730 int tls_global_set_params(void *tls_ctx,
731 			  const struct tls_connection_params *params)
732 {
733 	struct tls_global *global = tls_ctx;
734 	int ret;
735 
736 	/* Currently, global parameters are only set when running in server
737 	 * mode. */
738 	global->server = 1;
739 
740 	if (global->params_set) {
741 		gnutls_certificate_free_credentials(global->xcred);
742 		global->params_set = 0;
743 	}
744 
745 	ret = gnutls_certificate_allocate_credentials(&global->xcred);
746 	if (ret) {
747 		wpa_printf(MSG_DEBUG, "Failed to allocate global credentials "
748 			   "%s", gnutls_strerror(ret));
749 		return -1;
750 	}
751 
752 	if (params->ca_cert) {
753 		ret = gnutls_certificate_set_x509_trust_file(
754 			global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
755 		if (ret < 0) {
756 			wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' "
757 				   "in DER format: %s", params->ca_cert,
758 				   gnutls_strerror(ret));
759 			ret = gnutls_certificate_set_x509_trust_file(
760 				global->xcred, params->ca_cert,
761 				GNUTLS_X509_FMT_PEM);
762 			if (ret < 0) {
763 				wpa_printf(MSG_DEBUG, "Failed to read CA cert "
764 					   "'%s' in PEM format: %s",
765 					   params->ca_cert,
766 					   gnutls_strerror(ret));
767 				goto fail;
768 			}
769 		}
770 
771 		if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
772 			gnutls_certificate_set_verify_flags(
773 				global->xcred,
774 				GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
775 		}
776 
777 		if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
778 			gnutls_certificate_set_verify_flags(
779 				global->xcred,
780 				GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
781 		}
782 	}
783 
784 	if (params->client_cert && params->private_key) {
785 		/* TODO: private_key_passwd? */
786 		ret = gnutls_certificate_set_x509_key_file(
787 			global->xcred, params->client_cert,
788 			params->private_key, GNUTLS_X509_FMT_DER);
789 		if (ret < 0) {
790 			wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
791 				   "in DER format: %s", gnutls_strerror(ret));
792 			ret = gnutls_certificate_set_x509_key_file(
793 				global->xcred, params->client_cert,
794 				params->private_key, GNUTLS_X509_FMT_PEM);
795 			if (ret < 0) {
796 				wpa_printf(MSG_DEBUG, "Failed to read client "
797 					   "cert/key in PEM format: %s",
798 					   gnutls_strerror(ret));
799 				goto fail;
800 			}
801 		}
802 	} else if (params->private_key) {
803 		int pkcs12_ok = 0;
804 #ifdef PKCS12_FUNCS
805 		/* Try to load in PKCS#12 format */
806 		ret = gnutls_certificate_set_x509_simple_pkcs12_file(
807 			global->xcred, params->private_key,
808 			GNUTLS_X509_FMT_DER, params->private_key_passwd);
809 		if (ret != 0) {
810 			wpa_printf(MSG_DEBUG, "Failed to load private_key in "
811 				   "PKCS#12 format: %s", gnutls_strerror(ret));
812 			goto fail;
813 		} else
814 			pkcs12_ok = 1;
815 #endif /* PKCS12_FUNCS */
816 
817 		if (!pkcs12_ok) {
818 			wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
819 				   "included");
820 			goto fail;
821 		}
822 	}
823 
824 #if GNUTLS_VERSION_NUMBER >= 0x030103
825 	os_free(global->ocsp_stapling_response);
826 	if (params->ocsp_stapling_response)
827 		global->ocsp_stapling_response =
828 			os_strdup(params->ocsp_stapling_response);
829 	else
830 		global->ocsp_stapling_response = NULL;
831 	gnutls_certificate_set_ocsp_status_request_function(
832 		global->xcred, server_ocsp_status_req, global);
833 #endif /* 3.1.3 */
834 
835 	global->params_set = 1;
836 
837 	return 0;
838 
839 fail:
840 	gnutls_certificate_free_credentials(global->xcred);
841 	return -1;
842 }
843 
844 
845 int tls_global_set_verify(void *ssl_ctx, int check_crl)
846 {
847 	/* TODO */
848 	return 0;
849 }
850 
851 
852 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
853 			      int verify_peer, unsigned int flags,
854 			      const u8 *session_ctx, size_t session_ctx_len)
855 {
856 	if (conn == NULL || conn->session == NULL)
857 		return -1;
858 
859 	conn->verify_peer = verify_peer;
860 	gnutls_certificate_server_set_request(conn->session,
861 					      verify_peer ? GNUTLS_CERT_REQUIRE
862 					      : GNUTLS_CERT_REQUEST);
863 
864 	return 0;
865 }
866 
867 
868 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
869 			    struct tls_random *keys)
870 {
871 #if GNUTLS_VERSION_NUMBER >= 0x030012
872 	gnutls_datum_t client, server;
873 
874 	if (conn == NULL || conn->session == NULL || keys == NULL)
875 		return -1;
876 
877 	os_memset(keys, 0, sizeof(*keys));
878 	gnutls_session_get_random(conn->session, &client, &server);
879 	keys->client_random = client.data;
880 	keys->server_random = server.data;
881 	keys->client_random_len = client.size;
882 	keys->server_random_len = client.size;
883 
884 	return 0;
885 #else /* 3.0.18 */
886 	return -1;
887 #endif /* 3.0.18 */
888 }
889 
890 
891 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
892 			      const char *label, u8 *out, size_t out_len)
893 {
894 	if (conn == NULL || conn->session == NULL)
895 		return -1;
896 
897 	return gnutls_prf(conn->session, os_strlen(label), label,
898 			  0 /* client_random first */, 0, NULL, out_len,
899 			  (char *) out);
900 }
901 
902 
903 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
904 				    u8 *out, size_t out_len)
905 {
906 	return -1;
907 }
908 
909 
910 static void gnutls_tls_fail_event(struct tls_connection *conn,
911 				  const gnutls_datum_t *cert, int depth,
912 				  const char *subject, const char *err_str,
913 				  enum tls_fail_reason reason)
914 {
915 	union tls_event_data ev;
916 	struct tls_global *global = conn->global;
917 	struct wpabuf *cert_buf = NULL;
918 
919 	if (global->event_cb == NULL)
920 		return;
921 
922 	os_memset(&ev, 0, sizeof(ev));
923 	ev.cert_fail.depth = depth;
924 	ev.cert_fail.subject = subject ? subject : "";
925 	ev.cert_fail.reason = reason;
926 	ev.cert_fail.reason_txt = err_str;
927 	if (cert) {
928 		cert_buf = wpabuf_alloc_copy(cert->data, cert->size);
929 		ev.cert_fail.cert = cert_buf;
930 	}
931 	global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
932 	wpabuf_free(cert_buf);
933 }
934 
935 
936 #if GNUTLS_VERSION_NUMBER < 0x030300
937 static int server_eku_purpose(gnutls_x509_crt_t cert)
938 {
939 	unsigned int i;
940 
941 	for (i = 0; ; i++) {
942 		char oid[128];
943 		size_t oid_size = sizeof(oid);
944 		int res;
945 
946 		res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid,
947 							  &oid_size, NULL);
948 		if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
949 			if (i == 0) {
950 				/* No EKU - assume any use allowed */
951 				return 1;
952 			}
953 			break;
954 		}
955 
956 		if (res < 0) {
957 			wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU");
958 			return 0;
959 		}
960 
961 		wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid);
962 		if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 ||
963 		    os_strcmp(oid, GNUTLS_KP_ANY) == 0)
964 			return 1;
965 	}
966 
967 	return 0;
968 }
969 #endif /* < 3.3.0 */
970 
971 
972 static int check_ocsp(struct tls_connection *conn, gnutls_session_t session,
973 		      gnutls_alert_description_t *err)
974 {
975 #if GNUTLS_VERSION_NUMBER >= 0x030103
976 	gnutls_datum_t response, buf;
977 	gnutls_ocsp_resp_t resp;
978 	unsigned int cert_status;
979 	int res;
980 
981 	if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)))
982 		return 0;
983 
984 	if (!gnutls_ocsp_status_request_is_checked(session, 0)) {
985 		if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
986 			wpa_printf(MSG_INFO,
987 				   "GnuTLS: No valid OCSP response received");
988 			goto ocsp_error;
989 		}
990 
991 		wpa_printf(MSG_DEBUG,
992 			   "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required");
993 		return 0;
994 	}
995 
996 	/*
997 	 * GnuTLS has already verified the OCSP response in
998 	 * check_ocsp_response() and rejected handshake if the certificate was
999 	 * found to be revoked. However, if the response indicates that the
1000 	 * status is unknown, handshake continues and reaches here. We need to
1001 	 * re-import the OCSP response to check for unknown certificate status,
1002 	 * but we do not need to repeat gnutls_ocsp_resp_check_crt() and
1003 	 * gnutls_ocsp_resp_verify_direct() calls.
1004 	 */
1005 
1006 	res = gnutls_ocsp_status_request_get(session, &response);
1007 	if (res != GNUTLS_E_SUCCESS) {
1008 		wpa_printf(MSG_INFO,
1009 			   "GnuTLS: OCSP response was received, but it was not valid");
1010 		goto ocsp_error;
1011 	}
1012 
1013 	if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS)
1014 		goto ocsp_error;
1015 
1016 	res = gnutls_ocsp_resp_import(resp, &response);
1017 	if (res != GNUTLS_E_SUCCESS) {
1018 		wpa_printf(MSG_INFO,
1019 			   "GnuTLS: Could not parse received OCSP response: %s",
1020 			   gnutls_strerror(res));
1021 		gnutls_ocsp_resp_deinit(resp);
1022 		goto ocsp_error;
1023 	}
1024 
1025 	res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf);
1026 	if (res == GNUTLS_E_SUCCESS) {
1027 		wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data);
1028 		gnutls_free(buf.data);
1029 	}
1030 
1031 	res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL,
1032 					  NULL, &cert_status, NULL,
1033 					  NULL, NULL, NULL);
1034 	gnutls_ocsp_resp_deinit(resp);
1035 	if (res != GNUTLS_E_SUCCESS) {
1036 		wpa_printf(MSG_INFO,
1037 			   "GnuTLS: Failed to extract OCSP information: %s",
1038 			   gnutls_strerror(res));
1039 		goto ocsp_error;
1040 	}
1041 
1042 	if (cert_status == GNUTLS_OCSP_CERT_GOOD) {
1043 		wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good");
1044 	} else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
1045 		wpa_printf(MSG_DEBUG,
1046 			   "GnuTLS: OCSP cert status: revoked");
1047 		goto ocsp_error;
1048 	} else {
1049 		wpa_printf(MSG_DEBUG,
1050 			   "GnuTLS: OCSP cert status: unknown");
1051 		if (conn->flags & TLS_CONN_REQUIRE_OCSP)
1052 			goto ocsp_error;
1053 		wpa_printf(MSG_DEBUG,
1054 			   "GnuTLS: OCSP was not required, so allow connection to continue");
1055 	}
1056 
1057 	return 0;
1058 
1059 ocsp_error:
1060 	gnutls_tls_fail_event(conn, NULL, 0, NULL,
1061 			      "bad certificate status response",
1062 			      TLS_FAIL_REVOKED);
1063 	*err = GNUTLS_A_CERTIFICATE_REVOKED;
1064 	return -1;
1065 #else /* GnuTLS 3.1.3 or newer */
1066 	return 0;
1067 #endif /* GnuTLS 3.1.3 or newer */
1068 }
1069 
1070 
1071 static int tls_connection_verify_peer(gnutls_session_t session)
1072 {
1073 	struct tls_connection *conn;
1074 	unsigned int status, num_certs, i;
1075 	struct os_time now;
1076 	const gnutls_datum_t *certs;
1077 	gnutls_x509_crt_t cert;
1078 	gnutls_alert_description_t err;
1079 	int res;
1080 
1081 	conn = gnutls_session_get_ptr(session);
1082 	if (!conn->verify_peer) {
1083 		wpa_printf(MSG_DEBUG,
1084 			   "GnuTLS: No peer certificate verification enabled");
1085 		return 0;
1086 	}
1087 
1088 	wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate");
1089 
1090 #if GNUTLS_VERSION_NUMBER >= 0x030300
1091 	{
1092 		gnutls_typed_vdata_st data[1];
1093 		unsigned int elements = 0;
1094 
1095 		os_memset(data, 0, sizeof(data));
1096 		if (!conn->global->server) {
1097 			data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID;
1098 			data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER;
1099 			elements++;
1100 		}
1101 		res = gnutls_certificate_verify_peers(session, data, 1,
1102 						      &status);
1103 	}
1104 #else /* < 3.3.0 */
1105 	res = gnutls_certificate_verify_peers2(session, &status);
1106 #endif
1107 	if (res < 0) {
1108 		wpa_printf(MSG_INFO, "TLS: Failed to verify peer "
1109 			   "certificate chain");
1110 		err = GNUTLS_A_INTERNAL_ERROR;
1111 		goto out;
1112 	}
1113 
1114 #if GNUTLS_VERSION_NUMBER >= 0x030104
1115 	{
1116 		gnutls_datum_t info;
1117 		int ret, type;
1118 
1119 		type = gnutls_certificate_type_get(session);
1120 		ret = gnutls_certificate_verification_status_print(status, type,
1121 								   &info, 0);
1122 		if (ret < 0) {
1123 			wpa_printf(MSG_DEBUG,
1124 				   "GnuTLS: Failed to print verification status");
1125 			err = GNUTLS_A_INTERNAL_ERROR;
1126 			goto out;
1127 		}
1128 		wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data);
1129 		gnutls_free(info.data);
1130 	}
1131 #endif /* GnuTLS 3.1.4 or newer */
1132 
1133 	certs = gnutls_certificate_get_peers(session, &num_certs);
1134 	if (certs == NULL || num_certs == 0) {
1135 		wpa_printf(MSG_INFO, "TLS: No peer certificate chain received");
1136 		err = GNUTLS_A_UNKNOWN_CA;
1137 		goto out;
1138 	}
1139 
1140 	if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) {
1141 		wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted");
1142 		if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
1143 			wpa_printf(MSG_INFO, "TLS: Certificate uses insecure "
1144 				   "algorithm");
1145 			gnutls_tls_fail_event(conn, NULL, 0, NULL,
1146 					      "certificate uses insecure algorithm",
1147 					      TLS_FAIL_BAD_CERTIFICATE);
1148 			err = GNUTLS_A_INSUFFICIENT_SECURITY;
1149 			goto out;
1150 		}
1151 		if (status & GNUTLS_CERT_NOT_ACTIVATED) {
1152 			wpa_printf(MSG_INFO, "TLS: Certificate not yet "
1153 				   "activated");
1154 			gnutls_tls_fail_event(conn, NULL, 0, NULL,
1155 					      "certificate not yet valid",
1156 					      TLS_FAIL_NOT_YET_VALID);
1157 			err = GNUTLS_A_CERTIFICATE_EXPIRED;
1158 			goto out;
1159 		}
1160 		if (status & GNUTLS_CERT_EXPIRED) {
1161 			wpa_printf(MSG_INFO, "TLS: Certificate expired");
1162 			gnutls_tls_fail_event(conn, NULL, 0, NULL,
1163 					      "certificate has expired",
1164 					      TLS_FAIL_EXPIRED);
1165 			err = GNUTLS_A_CERTIFICATE_EXPIRED;
1166 			goto out;
1167 		}
1168 		gnutls_tls_fail_event(conn, NULL, 0, NULL,
1169 				      "untrusted certificate",
1170 				      TLS_FAIL_UNTRUSTED);
1171 		err = GNUTLS_A_INTERNAL_ERROR;
1172 		goto out;
1173 	}
1174 
1175 	if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
1176 		wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a "
1177 			   "known issuer");
1178 		gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found",
1179 				      TLS_FAIL_UNTRUSTED);
1180 		err = GNUTLS_A_UNKNOWN_CA;
1181 		goto out;
1182 	}
1183 
1184 	if (status & GNUTLS_CERT_REVOKED) {
1185 		wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked");
1186 		gnutls_tls_fail_event(conn, NULL, 0, NULL,
1187 				      "certificate revoked",
1188 				      TLS_FAIL_REVOKED);
1189 		err = GNUTLS_A_CERTIFICATE_REVOKED;
1190 		goto out;
1191 	}
1192 
1193 	if (status != 0) {
1194 		wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d",
1195 			   status);
1196 		err = GNUTLS_A_INTERNAL_ERROR;
1197 		goto out;
1198 	}
1199 
1200 	if (check_ocsp(conn, session, &err))
1201 		goto out;
1202 
1203 	os_get_time(&now);
1204 
1205 	for (i = 0; i < num_certs; i++) {
1206 		char *buf;
1207 		size_t len;
1208 		if (gnutls_x509_crt_init(&cert) < 0) {
1209 			wpa_printf(MSG_INFO, "TLS: Certificate initialization "
1210 				   "failed");
1211 			err = GNUTLS_A_BAD_CERTIFICATE;
1212 			goto out;
1213 		}
1214 
1215 		if (gnutls_x509_crt_import(cert, &certs[i],
1216 					   GNUTLS_X509_FMT_DER) < 0) {
1217 			wpa_printf(MSG_INFO, "TLS: Could not parse peer "
1218 				   "certificate %d/%d", i + 1, num_certs);
1219 			gnutls_x509_crt_deinit(cert);
1220 			err = GNUTLS_A_BAD_CERTIFICATE;
1221 			goto out;
1222 		}
1223 
1224 		gnutls_x509_crt_get_dn(cert, NULL, &len);
1225 		len++;
1226 		buf = os_malloc(len + 1);
1227 		if (buf) {
1228 			buf[0] = buf[len] = '\0';
1229 			gnutls_x509_crt_get_dn(cert, buf, &len);
1230 		}
1231 		wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s",
1232 			   i + 1, num_certs, buf);
1233 
1234 		if (conn->global->event_cb) {
1235 			struct wpabuf *cert_buf = NULL;
1236 			union tls_event_data ev;
1237 #ifdef CONFIG_SHA256
1238 			u8 hash[32];
1239 			const u8 *_addr[1];
1240 			size_t _len[1];
1241 #endif /* CONFIG_SHA256 */
1242 
1243 			os_memset(&ev, 0, sizeof(ev));
1244 			if (conn->global->cert_in_cb) {
1245 				cert_buf = wpabuf_alloc_copy(certs[i].data,
1246 							     certs[i].size);
1247 				ev.peer_cert.cert = cert_buf;
1248 			}
1249 #ifdef CONFIG_SHA256
1250 			_addr[0] = certs[i].data;
1251 			_len[0] = certs[i].size;
1252 			if (sha256_vector(1, _addr, _len, hash) == 0) {
1253 				ev.peer_cert.hash = hash;
1254 				ev.peer_cert.hash_len = sizeof(hash);
1255 			}
1256 #endif /* CONFIG_SHA256 */
1257 			ev.peer_cert.depth = i;
1258 			ev.peer_cert.subject = buf;
1259 			conn->global->event_cb(conn->global->cb_ctx,
1260 					       TLS_PEER_CERTIFICATE, &ev);
1261 			wpabuf_free(cert_buf);
1262 		}
1263 
1264 		if (i == 0) {
1265 			if (conn->suffix_match &&
1266 			    !gnutls_x509_crt_check_hostname(
1267 				    cert, conn->suffix_match)) {
1268 				wpa_printf(MSG_WARNING,
1269 					   "TLS: Domain suffix match '%s' not found",
1270 					   conn->suffix_match);
1271 				gnutls_tls_fail_event(
1272 					conn, &certs[i], i, buf,
1273 					"Domain suffix mismatch",
1274 					TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1275 				err = GNUTLS_A_BAD_CERTIFICATE;
1276 				gnutls_x509_crt_deinit(cert);
1277 				os_free(buf);
1278 				goto out;
1279 			}
1280 
1281 #if GNUTLS_VERSION_NUMBER >= 0x030300
1282 			if (conn->domain_match &&
1283 			    !gnutls_x509_crt_check_hostname2(
1284 				    cert, conn->domain_match,
1285 				    GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) {
1286 				wpa_printf(MSG_WARNING,
1287 					   "TLS: Domain match '%s' not found",
1288 					   conn->domain_match);
1289 				gnutls_tls_fail_event(
1290 					conn, &certs[i], i, buf,
1291 					"Domain mismatch",
1292 					TLS_FAIL_DOMAIN_MISMATCH);
1293 				err = GNUTLS_A_BAD_CERTIFICATE;
1294 				gnutls_x509_crt_deinit(cert);
1295 				os_free(buf);
1296 				goto out;
1297 			}
1298 #endif /* >= 3.3.0 */
1299 
1300 			/* TODO: validate altsubject_match.
1301 			 * For now, any such configuration is rejected in
1302 			 * tls_connection_set_params() */
1303 
1304 #if GNUTLS_VERSION_NUMBER < 0x030300
1305 			/*
1306 			 * gnutls_certificate_verify_peers() not available, so
1307 			 * need to check EKU separately.
1308 			 */
1309 			if (!conn->global->server &&
1310 			    !server_eku_purpose(cert)) {
1311 				wpa_printf(MSG_WARNING,
1312 					   "GnuTLS: No server EKU");
1313 				gnutls_tls_fail_event(
1314 					conn, &certs[i], i, buf,
1315 					"No server EKU",
1316 					TLS_FAIL_BAD_CERTIFICATE);
1317 				err = GNUTLS_A_BAD_CERTIFICATE;
1318 				gnutls_x509_crt_deinit(cert);
1319 				os_free(buf);
1320 				goto out;
1321 			}
1322 #endif /* < 3.3.0 */
1323 		}
1324 
1325 		if (!conn->disable_time_checks &&
1326 		    (gnutls_x509_crt_get_expiration_time(cert) < now.sec ||
1327 		     gnutls_x509_crt_get_activation_time(cert) > now.sec)) {
1328 			wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is "
1329 				   "not valid at this time",
1330 				   i + 1, num_certs);
1331 			gnutls_tls_fail_event(
1332 				conn, &certs[i], i, buf,
1333 				"Certificate is not valid at this time",
1334 				TLS_FAIL_EXPIRED);
1335 			gnutls_x509_crt_deinit(cert);
1336 			os_free(buf);
1337 			err = GNUTLS_A_CERTIFICATE_EXPIRED;
1338 			goto out;
1339 		}
1340 
1341 		os_free(buf);
1342 
1343 		gnutls_x509_crt_deinit(cert);
1344 	}
1345 
1346 	if (conn->global->event_cb != NULL)
1347 		conn->global->event_cb(conn->global->cb_ctx,
1348 				       TLS_CERT_CHAIN_SUCCESS, NULL);
1349 
1350 	return 0;
1351 
1352 out:
1353 	conn->failed++;
1354 	gnutls_alert_send(session, GNUTLS_AL_FATAL, err);
1355 	return GNUTLS_E_CERTIFICATE_ERROR;
1356 }
1357 
1358 
1359 static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn)
1360 {
1361 	int res;
1362 	struct wpabuf *ad;
1363 	wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data");
1364 	ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3);
1365 	if (ad == NULL)
1366 		return NULL;
1367 
1368 	res = gnutls_record_recv(conn->session, wpabuf_mhead(ad),
1369 				 wpabuf_size(ad));
1370 	wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res);
1371 	if (res < 0) {
1372 		wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
1373 			   "(%s)", __func__, (int) res,
1374 			   gnutls_strerror(res));
1375 		wpabuf_free(ad);
1376 		return NULL;
1377 	}
1378 
1379 	wpabuf_put(ad, res);
1380 	wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data",
1381 		   res);
1382 	return ad;
1383 }
1384 
1385 
1386 struct wpabuf * tls_connection_handshake(void *tls_ctx,
1387 					 struct tls_connection *conn,
1388 					 const struct wpabuf *in_data,
1389 					 struct wpabuf **appl_data)
1390 {
1391 	struct tls_global *global = tls_ctx;
1392 	struct wpabuf *out_data;
1393 	int ret;
1394 
1395 	if (appl_data)
1396 		*appl_data = NULL;
1397 
1398 	if (in_data && wpabuf_len(in_data) > 0) {
1399 		if (conn->pull_buf) {
1400 			wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
1401 				   "pull_buf", __func__,
1402 				   (unsigned long) wpabuf_len(conn->pull_buf));
1403 			wpabuf_free(conn->pull_buf);
1404 		}
1405 		conn->pull_buf = wpabuf_dup(in_data);
1406 		if (conn->pull_buf == NULL)
1407 			return NULL;
1408 		conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1409 	}
1410 
1411 	ret = gnutls_handshake(conn->session);
1412 	if (ret < 0) {
1413 		gnutls_alert_description_t alert;
1414 		union tls_event_data ev;
1415 
1416 		switch (ret) {
1417 		case GNUTLS_E_AGAIN:
1418 			if (global->server && conn->established &&
1419 			    conn->push_buf == NULL) {
1420 				/* Need to return something to trigger
1421 				 * completion of EAP-TLS. */
1422 				conn->push_buf = wpabuf_alloc(0);
1423 			}
1424 			break;
1425 		case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
1426 			wpa_printf(MSG_DEBUG, "GnuTLS: Unacceptable DH prime");
1427 			if (conn->global->event_cb) {
1428 				os_memset(&ev, 0, sizeof(ev));
1429 				ev.alert.is_local = 1;
1430 				ev.alert.type = "fatal";
1431 				ev.alert.description = "insufficient security";
1432 				conn->global->event_cb(conn->global->cb_ctx,
1433 						       TLS_ALERT, &ev);
1434 			}
1435 			/*
1436 			 * Could send a TLS Alert to the server, but for now,
1437 			 * simply terminate handshake.
1438 			 */
1439 			conn->failed++;
1440 			conn->write_alerts++;
1441 			break;
1442 		case GNUTLS_E_FATAL_ALERT_RECEIVED:
1443 			alert = gnutls_alert_get(conn->session);
1444 			wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
1445 				   __func__, gnutls_alert_get_name(alert));
1446 			conn->read_alerts++;
1447 			if (conn->global->event_cb != NULL) {
1448 				os_memset(&ev, 0, sizeof(ev));
1449 				ev.alert.is_local = 0;
1450 				ev.alert.type = gnutls_alert_get_name(alert);
1451 				ev.alert.description = ev.alert.type;
1452 				conn->global->event_cb(conn->global->cb_ctx,
1453 						       TLS_ALERT, &ev);
1454 			}
1455 			/* continue */
1456 		default:
1457 			wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
1458 				   "-> %s", __func__, gnutls_strerror(ret));
1459 			conn->failed++;
1460 		}
1461 	} else {
1462 		size_t size;
1463 
1464 		wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");
1465 
1466 #if GNUTLS_VERSION_NUMBER >= 0x03010a
1467 		{
1468 			char *desc;
1469 
1470 			desc = gnutls_session_get_desc(conn->session);
1471 			if (desc) {
1472 				wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc);
1473 				gnutls_free(desc);
1474 			}
1475 		}
1476 #endif /* GnuTLS 3.1.10 or newer */
1477 
1478 		conn->established = 1;
1479 		if (conn->push_buf == NULL) {
1480 			/* Need to return something to get final TLS ACK. */
1481 			conn->push_buf = wpabuf_alloc(0);
1482 		}
1483 
1484 		gnutls_session_get_data(conn->session, NULL, &size);
1485 		if (global->session_data == NULL ||
1486 		    global->session_data_size < size) {
1487 			os_free(global->session_data);
1488 			global->session_data = os_malloc(size);
1489 		}
1490 		if (global->session_data) {
1491 			global->session_data_size = size;
1492 			gnutls_session_get_data(conn->session,
1493 						global->session_data,
1494 						&global->session_data_size);
1495 		}
1496 
1497 		if (conn->pull_buf && appl_data)
1498 			*appl_data = gnutls_get_appl_data(conn);
1499 	}
1500 
1501 	out_data = conn->push_buf;
1502 	conn->push_buf = NULL;
1503 	return out_data;
1504 }
1505 
1506 
1507 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1508 						struct tls_connection *conn,
1509 						const struct wpabuf *in_data,
1510 						struct wpabuf **appl_data)
1511 {
1512 	return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
1513 }
1514 
1515 
1516 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1517 				       struct tls_connection *conn,
1518 				       const struct wpabuf *in_data)
1519 {
1520 	ssize_t res;
1521 	struct wpabuf *buf;
1522 
1523 	res = gnutls_record_send(conn->session, wpabuf_head(in_data),
1524 				 wpabuf_len(in_data));
1525 	if (res < 0) {
1526 		wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
1527 			   __func__, gnutls_strerror(res));
1528 		return NULL;
1529 	}
1530 
1531 	buf = conn->push_buf;
1532 	conn->push_buf = NULL;
1533 	return buf;
1534 }
1535 
1536 
1537 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1538 				       struct tls_connection *conn,
1539 				       const struct wpabuf *in_data)
1540 {
1541 	ssize_t res;
1542 	struct wpabuf *out;
1543 
1544 	if (conn->pull_buf) {
1545 		wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
1546 			   "pull_buf", __func__,
1547 			   (unsigned long) wpabuf_len(conn->pull_buf));
1548 		wpabuf_free(conn->pull_buf);
1549 	}
1550 	conn->pull_buf = wpabuf_dup(in_data);
1551 	if (conn->pull_buf == NULL)
1552 		return NULL;
1553 	conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1554 
1555 	/*
1556 	 * Even though we try to disable TLS compression, it is possible that
1557 	 * this cannot be done with all TLS libraries. Add extra buffer space
1558 	 * to handle the possibility of the decrypted data being longer than
1559 	 * input data.
1560 	 */
1561 	out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1562 	if (out == NULL)
1563 		return NULL;
1564 
1565 	res = gnutls_record_recv(conn->session, wpabuf_mhead(out),
1566 				 wpabuf_size(out));
1567 	if (res < 0) {
1568 		wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
1569 			   "(%s)", __func__, (int) res, gnutls_strerror(res));
1570 		wpabuf_free(out);
1571 		return NULL;
1572 	}
1573 	wpabuf_put(out, res);
1574 
1575 	return out;
1576 }
1577 
1578 
1579 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
1580 {
1581 	if (conn == NULL)
1582 		return 0;
1583 	return gnutls_session_is_resumed(conn->session);
1584 }
1585 
1586 
1587 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1588 				   u8 *ciphers)
1589 {
1590 	/* TODO */
1591 	return -1;
1592 }
1593 
1594 
1595 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1596 		    char *buf, size_t buflen)
1597 {
1598 	gnutls_protocol_t ver;
1599 
1600 	ver = gnutls_protocol_get_version(conn->session);
1601 	if (ver == GNUTLS_TLS1_0)
1602 		os_strlcpy(buf, "TLSv1", buflen);
1603 	else if (ver == GNUTLS_TLS1_1)
1604 		os_strlcpy(buf, "TLSv1.1", buflen);
1605 	else if (ver == GNUTLS_TLS1_2)
1606 		os_strlcpy(buf, "TLSv1.2", buflen);
1607 	else
1608 		return -1;
1609 	return 0;
1610 }
1611 
1612 
1613 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
1614 		   char *buf, size_t buflen)
1615 {
1616 	gnutls_cipher_algorithm_t cipher;
1617 	gnutls_kx_algorithm_t kx;
1618 	gnutls_mac_algorithm_t mac;
1619 	const char *kx_str, *cipher_str, *mac_str;
1620 	int res;
1621 
1622 	cipher = gnutls_cipher_get(conn->session);
1623 	cipher_str = gnutls_cipher_get_name(cipher);
1624 	if (!cipher_str)
1625 		cipher_str = "";
1626 
1627 	kx = gnutls_kx_get(conn->session);
1628 	kx_str = gnutls_kx_get_name(kx);
1629 	if (!kx_str)
1630 		kx_str = "";
1631 
1632 	mac = gnutls_mac_get(conn->session);
1633 	mac_str = gnutls_mac_get_name(mac);
1634 	if (!mac_str)
1635 		mac_str = "";
1636 
1637 	if (kx == GNUTLS_KX_RSA)
1638 		res = os_snprintf(buf, buflen, "%s-%s", cipher_str, mac_str);
1639 	else
1640 		res = os_snprintf(buf, buflen, "%s-%s-%s",
1641 				  kx_str, cipher_str, mac_str);
1642 	if (os_snprintf_error(buflen, res))
1643 		return -1;
1644 
1645 	return 0;
1646 }
1647 
1648 
1649 int tls_connection_enable_workaround(void *ssl_ctx,
1650 				     struct tls_connection *conn)
1651 {
1652 	gnutls_record_disable_padding(conn->session);
1653 	return 0;
1654 }
1655 
1656 
1657 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
1658 				    int ext_type, const u8 *data,
1659 				    size_t data_len)
1660 {
1661 	/* TODO */
1662 	return -1;
1663 }
1664 
1665 
1666 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
1667 {
1668 	if (conn == NULL)
1669 		return -1;
1670 	return conn->failed;
1671 }
1672 
1673 
1674 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
1675 {
1676 	if (conn == NULL)
1677 		return -1;
1678 	return conn->read_alerts;
1679 }
1680 
1681 
1682 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
1683 {
1684 	if (conn == NULL)
1685 		return -1;
1686 	return conn->write_alerts;
1687 }
1688 
1689 
1690 int tls_connection_set_session_ticket_cb(void *tls_ctx,
1691 					 struct tls_connection *conn,
1692 					 tls_session_ticket_cb cb, void *ctx)
1693 {
1694 	return -1;
1695 }
1696 
1697 
1698 int tls_get_library_version(char *buf, size_t buf_len)
1699 {
1700 	return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s",
1701 			   GNUTLS_VERSION, gnutls_check_version(NULL));
1702 }
1703 
1704 
1705 void tls_connection_set_success_data(struct tls_connection *conn,
1706 				     struct wpabuf *data)
1707 {
1708 }
1709 
1710 
1711 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
1712 {
1713 }
1714 
1715 
1716 const struct wpabuf *
1717 tls_connection_get_success_data(struct tls_connection *conn)
1718 {
1719 	return NULL;
1720 }
1721 
1722 
1723 void tls_connection_remove_session(struct tls_connection *conn)
1724 {
1725 }
1726