xref: /freebsd/contrib/wpa/src/crypto/tls_wolfssl.c (revision 56b17de1e8360fe131d425de20b5e75ff3ea897c)
1 /*
2  * SSL/TLS interface functions for wolfSSL TLS case
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 
11 #include "common.h"
12 #include "crypto.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "tls.h"
16 
17 /* wolfSSL includes */
18 #include <wolfssl/options.h>
19 #include <wolfssl/ssl.h>
20 #include <wolfssl/error-ssl.h>
21 #include <wolfssl/wolfcrypt/asn.h>
22 #include <wolfssl/openssl/x509v3.h>
23 
24 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
25 #define HAVE_AESGCM
26 #include <wolfssl/wolfcrypt/aes.h>
27 #endif
28 
29 #ifdef CONFIG_FIPS
30 #include <wolfssl/wolfcrypt/fips_test.h>
31 #endif /* CONFIG_FIPS */
32 
33 #if !defined(CONFIG_FIPS) &&                             \
34     (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) ||   \
35      defined(EAP_SERVER_FAST))
36 #define WOLFSSL_NEED_EAP_FAST_PRF
37 #endif
38 
39 #define SECRET_LEN          48
40 #define RAN_LEN             32
41 #define SESSION_TICKET_LEN  256
42 
43 static int tls_ref_count = 0;
44 
45 static int tls_ex_idx_session = 0;
46 
47 
48 /* tls input data for wolfSSL Read Callback */
49 struct tls_in_data {
50 	const struct wpabuf *in_data;
51 	size_t consumed; /* how many bytes have we used already */
52 };
53 
54 /* tls output data for wolfSSL Write Callback */
55 struct tls_out_data {
56 	struct wpabuf *out_data;
57 };
58 
59 struct tls_context {
60 	void (*event_cb)(void *ctx, enum tls_event ev,
61 			 union tls_event_data *data);
62 	void *cb_ctx;
63 	int cert_in_cb;
64 	char *ocsp_stapling_response;
65 	unsigned int tls_session_lifetime;
66 };
67 
68 static struct tls_context *tls_global = NULL;
69 
70 /* wolfssl tls_connection */
71 struct tls_connection {
72 	struct tls_context *context;
73 	WOLFSSL *ssl;
74 	int read_alerts;
75 	int write_alerts;
76 	int failed;
77 	struct tls_in_data input;
78 	struct tls_out_data output;
79 	char *subject_match;
80 	char *alt_subject_match;
81 	char *suffix_match;
82 	char *domain_match;
83 
84 	u8 srv_cert_hash[32];
85 
86 	unsigned char client_random[RAN_LEN];
87 	unsigned char server_random[RAN_LEN];
88 	unsigned int flags;
89 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
90 	tls_session_ticket_cb session_ticket_cb;
91 	void *session_ticket_cb_ctx;
92 	byte session_ticket[SESSION_TICKET_LEN];
93 #endif
94 	unsigned int ca_cert_verify:1;
95 	unsigned int cert_probe:1;
96 	unsigned int server_cert_only:1;
97 	unsigned int success_data:1;
98 
99 	WOLFSSL_X509 *peer_cert;
100 	WOLFSSL_X509 *peer_issuer;
101 	WOLFSSL_X509 *peer_issuer_issuer;
102 	char *peer_subject; /* peer subject info for authenticated peer */
103 };
104 
105 
106 static struct tls_context * tls_context_new(const struct tls_config *conf)
107 {
108 	struct tls_context *context = os_zalloc(sizeof(*context));
109 
110 	if (!context)
111 		return NULL;
112 
113 	if (conf) {
114 		context->event_cb = conf->event_cb;
115 		context->cb_ctx = conf->cb_ctx;
116 		context->cert_in_cb = conf->cert_in_cb;
117 	}
118 
119 	return context;
120 }
121 
122 
123 static void wolfssl_reset_in_data(struct tls_in_data *in,
124 				  const struct wpabuf *buf)
125 {
126 	/* old one not owned by us so don't free */
127 	in->in_data = buf;
128 	in->consumed = 0;
129 }
130 
131 
132 static void wolfssl_reset_out_data(struct tls_out_data *out)
133 {
134 	/* old one not owned by us so don't free */
135 	out->out_data = wpabuf_alloc_copy("", 0);
136 }
137 
138 
139 /* wolfSSL I/O Receive CallBack */
140 static int wolfssl_receive_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
141 {
142 	size_t get = sz;
143 	struct tls_in_data *data = ctx;
144 
145 	if (!data)
146 		return -1;
147 
148 	if (get > (wpabuf_len(data->in_data) - data->consumed))
149 		get = wpabuf_len(data->in_data) - data->consumed;
150 
151 	os_memcpy(buf, wpabuf_head_u8(data->in_data) + data->consumed, get);
152 	data->consumed += get;
153 
154 	if (get == 0)
155 		return -2; /* WANT_READ */
156 
157 	return (int) get;
158 }
159 
160 
161 /* wolfSSL I/O Send CallBack */
162 static int wolfssl_send_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
163 {
164 	struct wpabuf *tmp;
165 	struct tls_out_data *data = ctx;
166 
167 	if (!data)
168 		return -1;
169 
170 	wpa_printf(MSG_DEBUG, "SSL: adding %d bytes", sz);
171 
172 	tmp = wpabuf_alloc_copy(buf, sz);
173 	if (!tmp)
174 		return -1;
175 	data->out_data = wpabuf_concat(data->out_data, tmp);
176 	if (!data->out_data)
177 		return -1;
178 
179 	return sz;
180 }
181 
182 
183 static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
184 {
185 	struct wpabuf *buf;
186 
187 	buf = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
188 	if (!buf)
189 		return;
190 	wpa_printf(MSG_DEBUG,
191 		   "wolfSSL: Free application session data %p (sess %p)",
192 		   buf, sess);
193 	wpabuf_free(buf);
194 
195 	wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
196 }
197 
198 
199 #if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
200 static void wcFipsCb(int ok, int err, const char *hash)
201 {
202 	wpa_printf(MSG_INFO,
203 		   "wolfFIPS: wolfCrypt Fips error callback, ok = %d, err = %d",
204 		   ok, err);
205 	wpa_printf(MSG_INFO, "wolfFIPS: message = %s", wc_GetErrorString(err));
206 	wpa_printf(MSG_INFO, "wolfFIPS: hash = %s", hash);
207 	if (err == IN_CORE_FIPS_E) {
208 		wpa_printf(MSG_ERROR,
209 			   "wolfFIPS: In core integrity hash check failure, copy above hash");
210 		wpa_printf(MSG_ERROR, "wolfFIPS: into verifyCore[] in fips_test.c and rebuild");
211 	}
212 }
213 #endif /* CONFIG_FIPS && HAVE_FIPS */
214 
215 
216 #ifdef DEBUG_WOLFSSL
217 static void wolfSSL_logging_cb(const int log_level,
218 			       const char * const log_message)
219 {
220 	(void) log_level;
221 	wpa_printf(MSG_DEBUG, "wolfSSL log:%s", log_message);
222 }
223 #endif /* DEBUG_WOLFSSL */
224 
225 
226 void * tls_init(const struct tls_config *conf)
227 {
228 	WOLFSSL_CTX *ssl_ctx;
229 	struct tls_context *context;
230 	const char *ciphers;
231 
232 #ifdef DEBUG_WOLFSSL
233 	wolfSSL_SetLoggingCb(wolfSSL_logging_cb);
234 	wolfSSL_Debugging_ON();
235 #endif /* DEBUG_WOLFSSL */
236 
237 	context = tls_context_new(conf);
238 	if (!context)
239 		return NULL;
240 
241 	if (tls_ref_count == 0) {
242 		tls_global = context;
243 
244 		if (wolfSSL_Init() < 0)
245 			return NULL;
246 #if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
247 		wolfCrypt_SetCb_fips(wcFipsCb);
248 #endif /* CONFIG_FIPS && HAVE_FIPS */
249 	}
250 
251 	tls_ref_count++;
252 
253 	/* start as client */
254 	ssl_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
255 	if (!ssl_ctx) {
256 		tls_ref_count--;
257 		if (context != tls_global)
258 			os_free(context);
259 		if (tls_ref_count == 0) {
260 			os_free(tls_global);
261 			tls_global = NULL;
262 		}
263 	}
264 	wolfSSL_SetIORecv(ssl_ctx, wolfssl_receive_cb);
265 	wolfSSL_SetIOSend(ssl_ctx, wolfssl_send_cb);
266 	context->tls_session_lifetime = conf->tls_session_lifetime;
267 	wolfSSL_CTX_set_ex_data(ssl_ctx, 0, context);
268 
269 	if (conf->tls_session_lifetime > 0) {
270 		wolfSSL_CTX_set_session_id_context(ssl_ctx,
271 						   (const unsigned char *)
272 						   "hostapd", 7);
273 		wolfSSL_CTX_set_quiet_shutdown(ssl_ctx, 1);
274 		wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
275 						   WOLFSSL_SESS_CACHE_SERVER);
276 		wolfSSL_CTX_set_timeout(ssl_ctx, conf->tls_session_lifetime);
277 		wolfSSL_CTX_sess_set_remove_cb(ssl_ctx, remove_session_cb);
278 	} else {
279 		wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
280 						   WOLFSSL_SESS_CACHE_OFF);
281 	}
282 
283 	if (conf && conf->openssl_ciphers)
284 		ciphers = conf->openssl_ciphers;
285 	else
286 		ciphers = "ALL";
287 	wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", ciphers);
288 	if (wolfSSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
289 		wpa_printf(MSG_ERROR,
290 			   "wolfSSL: Failed to set cipher string '%s'",
291 			   ciphers);
292 		tls_deinit(ssl_ctx);
293 		return NULL;
294 	}
295 
296 	return ssl_ctx;
297 }
298 
299 
300 void tls_deinit(void *ssl_ctx)
301 {
302 	struct tls_context *context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
303 
304 	if (context != tls_global)
305 		os_free(context);
306 
307 	wolfSSL_CTX_free((WOLFSSL_CTX *) ssl_ctx);
308 
309 	tls_ref_count--;
310 	if (tls_ref_count == 0) {
311 		wolfSSL_Cleanup();
312 		os_free(tls_global);
313 		tls_global = NULL;
314 	}
315 }
316 
317 
318 int tls_get_errors(void *tls_ctx)
319 {
320 #ifdef DEBUG_WOLFSSL
321 #if 0
322 	unsigned long err;
323 
324 	err = wolfSSL_ERR_peek_last_error_line(NULL, NULL);
325 	if (err != 0) {
326 		wpa_printf(MSG_INFO, "TLS - SSL error: %s",
327 			   wolfSSL_ERR_error_string(err, NULL));
328 		return 1;
329 	}
330 #endif
331 #endif /* DEBUG_WOLFSSL */
332 	return 0;
333 }
334 
335 
336 struct tls_connection * tls_connection_init(void *tls_ctx)
337 {
338 	WOLFSSL_CTX *ssl_ctx = tls_ctx;
339 	struct tls_connection *conn;
340 
341 	wpa_printf(MSG_DEBUG, "SSL: connection init");
342 
343 	conn = os_zalloc(sizeof(*conn));
344 	if (!conn)
345 		return NULL;
346 	conn->ssl = wolfSSL_new(ssl_ctx);
347 	if (!conn->ssl) {
348 		os_free(conn);
349 		return NULL;
350 	}
351 
352 	wolfSSL_SetIOReadCtx(conn->ssl,  &conn->input);
353 	wolfSSL_SetIOWriteCtx(conn->ssl, &conn->output);
354 	wolfSSL_set_ex_data(conn->ssl, 0, conn);
355 	conn->context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
356 
357 	/* Need randoms post-hanshake for EAP-FAST, export key and deriving
358 	 * session ID in EAP methods. */
359 	wolfSSL_KeepArrays(conn->ssl);
360 	wolfSSL_KeepHandshakeResources(conn->ssl);
361 	wolfSSL_UseClientSuites(conn->ssl);
362 
363 	return conn;
364 }
365 
366 
367 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
368 {
369 	if (!conn)
370 		return;
371 
372 	wpa_printf(MSG_DEBUG, "SSL: connection deinit");
373 
374 	/* parts */
375 	wolfSSL_free(conn->ssl);
376 	os_free(conn->subject_match);
377 	os_free(conn->alt_subject_match);
378 	os_free(conn->suffix_match);
379 	os_free(conn->domain_match);
380 	os_free(conn->peer_subject);
381 
382 	/* self */
383 	os_free(conn);
384 }
385 
386 
387 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
388 {
389 	return conn ? wolfSSL_is_init_finished(conn->ssl) : 0;
390 }
391 
392 
393 char * tls_connection_peer_serial_num(void *tls_ctx,
394 				      struct tls_connection *conn)
395 {
396 	/* TODO */
397 	return NULL;
398 }
399 
400 
401 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
402 {
403 	WOLFSSL_SESSION *session;
404 
405 	if (!conn)
406 		return -1;
407 
408 	wpa_printf(MSG_DEBUG, "SSL: connection shutdown");
409 
410 	/* Set quiet as OpenSSL does */
411 	wolfSSL_set_quiet_shutdown(conn->ssl, 1);
412 	wolfSSL_shutdown(conn->ssl);
413 
414 	session = wolfSSL_get1_session(conn->ssl);
415 	if (wolfSSL_clear(conn->ssl) != 1) {
416 		wolfSSL_SESSION_free(session);
417 		return -1;
418 	}
419 	wolfSSL_set_session(conn->ssl, session);
420 	wolfSSL_SESSION_free(session);
421 
422 	return 0;
423 }
424 
425 
426 static int tls_connection_set_subject_match(struct tls_connection *conn,
427 					    const char *subject_match,
428 					    const char *alt_subject_match,
429 					    const char *suffix_match,
430 					    const char *domain_match)
431 {
432 	os_free(conn->subject_match);
433 	conn->subject_match = NULL;
434 	if (subject_match) {
435 		conn->subject_match = os_strdup(subject_match);
436 		if (!conn->subject_match)
437 			return -1;
438 	}
439 
440 	os_free(conn->alt_subject_match);
441 	conn->alt_subject_match = NULL;
442 	if (alt_subject_match) {
443 		conn->alt_subject_match = os_strdup(alt_subject_match);
444 		if (!conn->alt_subject_match)
445 			return -1;
446 	}
447 
448 	os_free(conn->suffix_match);
449 	conn->suffix_match = NULL;
450 	if (suffix_match) {
451 		conn->suffix_match = os_strdup(suffix_match);
452 		if (!conn->suffix_match)
453 			return -1;
454 	}
455 
456 	os_free(conn->domain_match);
457 	conn->domain_match = NULL;
458 	if (domain_match) {
459 		conn->domain_match = os_strdup(domain_match);
460 		if (!conn->domain_match)
461 			return -1;
462 	}
463 
464 	return 0;
465 }
466 
467 
468 static int tls_connection_client_cert(struct tls_connection *conn,
469 				      const char *client_cert,
470 				      const u8 *client_cert_blob,
471 				      size_t blob_len)
472 {
473 	if (!client_cert && !client_cert_blob)
474 		return 0;
475 
476 	if (client_cert_blob) {
477 		if (wolfSSL_use_certificate_chain_buffer_format(
478 			    conn->ssl, client_cert_blob, blob_len,
479 			    SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
480 			wpa_printf(MSG_INFO,
481 				   "SSL: use client cert DER blob failed");
482 			if (wolfSSL_use_certificate_chain_buffer_format(
483 				    conn->ssl, client_cert_blob, blob_len,
484 				    SSL_FILETYPE_PEM) != SSL_SUCCESS) {
485 				wpa_printf(MSG_INFO,
486 					   "SSL: use client cert PEM blob failed");
487 				return -1;
488 			}
489 		}
490 		wpa_printf(MSG_DEBUG, "SSL: use client cert blob OK");
491 		return 0;
492 	}
493 
494 	if (client_cert) {
495 		if (wolfSSL_use_certificate_chain_file(
496 			    conn->ssl, client_cert) != SSL_SUCCESS) {
497 			wpa_printf(MSG_INFO,
498 				   "SSL: use client cert PEM file failed");
499 			if (wolfSSL_use_certificate_chain_file_format(
500 				    conn->ssl, client_cert,
501 				    SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
502 				wpa_printf(MSG_INFO,
503 					   "SSL: use client cert DER file failed");
504 				return -1;
505 			}
506 		}
507 		wpa_printf(MSG_DEBUG, "SSL: use client cert file OK");
508 		return 0;
509 	}
510 
511 	return 0;
512 }
513 
514 
515 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
516 {
517 	if (!password)
518 		return 0;
519 	os_strlcpy(buf, (char *) password, size);
520 	return os_strlen(buf);
521 }
522 
523 
524 static int tls_connection_private_key(void *tls_ctx,
525 				      struct tls_connection *conn,
526 				      const char *private_key,
527 				      const char *private_key_passwd,
528 				      const u8 *private_key_blob,
529 				      size_t blob_len)
530 {
531 	WOLFSSL_CTX *ctx = tls_ctx;
532 	char *passwd = NULL;
533 	int ok = 0;
534 
535 	if (!private_key && !private_key_blob)
536 		return 0;
537 
538 	if (private_key_passwd) {
539 		passwd = os_strdup(private_key_passwd);
540 		if (!passwd)
541 			return -1;
542 	}
543 
544 	wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
545 	wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
546 
547 	if (private_key_blob) {
548 		if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
549 						  private_key_blob, blob_len,
550 						  SSL_FILETYPE_ASN1) !=
551 		    SSL_SUCCESS) {
552 			wpa_printf(MSG_INFO,
553 				   "SSL: use private DER blob failed");
554 			if (wolfSSL_use_PrivateKey_buffer(
555 				    conn->ssl,
556 				    private_key_blob, blob_len,
557 				    SSL_FILETYPE_PEM) != SSL_SUCCESS) {
558 				wpa_printf(MSG_INFO,
559 					   "SSL: use private PEM blob failed");
560 			} else {
561 				ok = 1;
562 			}
563 		} else {
564 			ok = 1;
565 		}
566 		if (ok)
567 			wpa_printf(MSG_DEBUG, "SSL: use private key blob OK");
568 	}
569 
570 	if (!ok && private_key) {
571 		if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
572 						SSL_FILETYPE_PEM) !=
573 		    SSL_SUCCESS) {
574 			wpa_printf(MSG_INFO,
575 				   "SSL: use private key PEM file failed");
576 			if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
577 							SSL_FILETYPE_ASN1) !=
578 			    SSL_SUCCESS) {
579 				wpa_printf(MSG_INFO,
580 					   "SSL: use private key DER file failed");
581 			} else {
582 				ok = 1;
583 			}
584 		} else {
585 			ok = 1;
586 		}
587 
588 		if (ok)
589 			wpa_printf(MSG_DEBUG, "SSL: use private key file OK");
590 	}
591 
592 	wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
593 	os_free(passwd);
594 
595 	if (!ok)
596 		return -1;
597 
598 	return 0;
599 }
600 
601 
602 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
603 					   const char *value, size_t len)
604 {
605 	WOLFSSL_GENERAL_NAME *gen;
606 	void *ext;
607 	int found = 0;
608 	int i;
609 
610 	ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
611 
612 	for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
613 		gen = wolfSSL_sk_value(ext, i);
614 		if (!gen || gen->type != type)
615 			continue;
616 		if ((size_t) wolfSSL_ASN1_STRING_length(gen->d.ia5) == len &&
617 		    os_memcmp(value, wolfSSL_ASN1_STRING_data(gen->d.ia5),
618 			      len) == 0)
619 			found++;
620 	}
621 
622 	wolfSSL_sk_GENERAL_NAME_free(ext);
623 
624 	return found;
625 }
626 
627 
628 static int tls_match_alt_subject(WOLFSSL_X509 *cert, const char *match)
629 {
630 	int type;
631 	const char *pos, *end;
632 	size_t len;
633 
634 	pos = match;
635 	do {
636 		if (os_strncmp(pos, "EMAIL:", 6) == 0) {
637 			type = GEN_EMAIL;
638 			pos += 6;
639 		} else if (os_strncmp(pos, "DNS:", 4) == 0) {
640 			type = GEN_DNS;
641 			pos += 4;
642 		} else if (os_strncmp(pos, "URI:", 4) == 0) {
643 			type = GEN_URI;
644 			pos += 4;
645 		} else {
646 			wpa_printf(MSG_INFO,
647 				   "TLS: Invalid altSubjectName match '%s'",
648 				   pos);
649 			return 0;
650 		}
651 		end = os_strchr(pos, ';');
652 		while (end) {
653 			if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
654 			    os_strncmp(end + 1, "DNS:", 4) == 0 ||
655 			    os_strncmp(end + 1, "URI:", 4) == 0)
656 				break;
657 			end = os_strchr(end + 1, ';');
658 		}
659 		if (end)
660 			len = end - pos;
661 		else
662 			len = os_strlen(pos);
663 		if (tls_match_alt_subject_component(cert, type, pos, len) > 0)
664 			return 1;
665 		pos = end + 1;
666 	} while (end);
667 
668 	return 0;
669 }
670 
671 
672 static int domain_suffix_match(const char *val, size_t len, const char *match,
673 			       size_t match_len, int full)
674 {
675 	size_t i;
676 
677 	/* Check for embedded nuls that could mess up suffix matching */
678 	for (i = 0; i < len; i++) {
679 		if (val[i] == '\0') {
680 			wpa_printf(MSG_DEBUG,
681 				   "TLS: Embedded null in a string - reject");
682 			return 0;
683 		}
684 	}
685 
686 	if (match_len > len || (full && match_len != len))
687 		return 0;
688 
689 	if (os_strncasecmp(val + len - match_len, match, match_len) != 0)
690 		return 0; /* no match */
691 
692 	if (match_len == len)
693 		return 1; /* exact match */
694 
695 	if (val[len - match_len - 1] == '.')
696 		return 1; /* full label match completes suffix match */
697 
698 	wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
699 	return 0;
700 }
701 
702 
703 static int tls_match_suffix_helper(WOLFSSL_X509 *cert, const char *match,
704 				   size_t match_len, int full)
705 {
706 	WOLFSSL_GENERAL_NAME *gen;
707 	void *ext;
708 	int i;
709 	int j;
710 	int dns_name = 0;
711 	WOLFSSL_X509_NAME *name;
712 
713 	wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
714 		   full ? "" : "suffix ", match);
715 
716 	ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
717 
718 	for (j = 0; ext && j < wolfSSL_sk_num(ext); j++) {
719 		gen = wolfSSL_sk_value(ext, j);
720 		if (!gen || gen->type != ASN_DNS_TYPE)
721 			continue;
722 		dns_name++;
723 		wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
724 				  wolfSSL_ASN1_STRING_data(gen->d.ia5),
725 				  wolfSSL_ASN1_STRING_length(gen->d.ia5));
726 		if (domain_suffix_match(
727 			    (const char *) wolfSSL_ASN1_STRING_data(gen->d.ia5),
728 			    wolfSSL_ASN1_STRING_length(gen->d.ia5), match,
729 			    match_len, full) == 1) {
730 			wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
731 				   full ? "Match" : "Suffix match");
732 			wolfSSL_sk_ASN1_OBJECT_free(ext);
733 			return 1;
734 		}
735 	}
736 	wolfSSL_sk_GENERAL_NAME_free(ext);
737 
738 	if (dns_name) {
739 		wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
740 		return 0;
741 	}
742 
743 	name = wolfSSL_X509_get_subject_name(cert);
744 	i = -1;
745 	for (;;) {
746 		WOLFSSL_X509_NAME_ENTRY *e;
747 		WOLFSSL_ASN1_STRING *cn;
748 
749 		i = wolfSSL_X509_NAME_get_index_by_NID(name, NID_commonName, i);
750 		if (i == -1)
751 			break;
752 		e = wolfSSL_X509_NAME_get_entry(name, i);
753 		if (!e)
754 			continue;
755 		cn = wolfSSL_X509_NAME_ENTRY_get_data(e);
756 		if (!cn)
757 			continue;
758 		wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
759 				  cn->data, cn->length);
760 		if (domain_suffix_match(cn->data, cn->length,
761 					match, match_len, full) == 1) {
762 			wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
763 				   full ? "Match" : "Suffix match");
764 			return 1;
765 		}
766 	}
767 
768 	wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
769 		   full ? "" : "suffix ");
770 	return 0;
771 }
772 
773 
774 static int tls_match_suffix(WOLFSSL_X509 *cert, const char *match, int full)
775 {
776 	const char *token, *last = NULL;
777 
778 	/* Process each match alternative separately until a match is found */
779 	while ((token = cstr_token(match, ";", &last))) {
780 		if (tls_match_suffix_helper(cert, token, last - token, full))
781 			return 1;
782 	}
783 
784 	return 0;
785 }
786 
787 
788 static enum tls_fail_reason wolfssl_tls_fail_reason(int err)
789 {
790 	switch (err) {
791 	case X509_V_ERR_CERT_REVOKED:
792 		return TLS_FAIL_REVOKED;
793 	case ASN_BEFORE_DATE_E:
794 	case X509_V_ERR_CERT_NOT_YET_VALID:
795 	case X509_V_ERR_CRL_NOT_YET_VALID:
796 		return TLS_FAIL_NOT_YET_VALID;
797 	case ASN_AFTER_DATE_E:
798 	case X509_V_ERR_CERT_HAS_EXPIRED:
799 	case X509_V_ERR_CRL_HAS_EXPIRED:
800 		return TLS_FAIL_EXPIRED;
801 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
802 	case X509_V_ERR_UNABLE_TO_GET_CRL:
803 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
804 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
805 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
806 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
807 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
808 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
809 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
810 	case X509_V_ERR_INVALID_CA:
811 		return TLS_FAIL_UNTRUSTED;
812 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
813 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
814 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
815 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
816 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
817 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
818 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
819 	case X509_V_ERR_CERT_UNTRUSTED:
820 	case X509_V_ERR_CERT_REJECTED:
821 		return TLS_FAIL_BAD_CERTIFICATE;
822 	default:
823 		return TLS_FAIL_UNSPECIFIED;
824 	}
825 }
826 
827 
828 static const char * wolfssl_tls_err_string(int err, const char *err_str)
829 {
830 	switch (err) {
831 	case ASN_BEFORE_DATE_E:
832 		return "certificate is not yet valid";
833 	case ASN_AFTER_DATE_E:
834 		return "certificate has expired";
835 	default:
836 		return err_str;
837 	}
838 }
839 
840 
841 static struct wpabuf * get_x509_cert(WOLFSSL_X509 *cert)
842 {
843 	struct wpabuf *buf = NULL;
844 	const u8 *data;
845 	int cert_len;
846 
847 	data = wolfSSL_X509_get_der(cert, &cert_len);
848 	if (!data)
849 		buf = wpabuf_alloc_copy(data, cert_len);
850 
851 	return buf;
852 }
853 
854 
855 static void wolfssl_tls_fail_event(struct tls_connection *conn,
856 				   WOLFSSL_X509 *err_cert, int err, int depth,
857 				   const char *subject, const char *err_str,
858 				   enum tls_fail_reason reason)
859 {
860 	union tls_event_data ev;
861 	struct wpabuf *cert = NULL;
862 	struct tls_context *context = conn->context;
863 
864 	if (!context->event_cb)
865 		return;
866 
867 	cert = get_x509_cert(err_cert);
868 	os_memset(&ev, 0, sizeof(ev));
869 	ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
870 		reason : wolfssl_tls_fail_reason(err);
871 	ev.cert_fail.depth = depth;
872 	ev.cert_fail.subject = subject;
873 	ev.cert_fail.reason_txt = wolfssl_tls_err_string(err, err_str);
874 	ev.cert_fail.cert = cert;
875 	context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
876 	wpabuf_free(cert);
877 }
878 
879 
880 static void wolfssl_tls_cert_event(struct tls_connection *conn,
881 				   WOLFSSL_X509 *err_cert, int depth,
882 				   const char *subject)
883 {
884 	struct wpabuf *cert = NULL;
885 	union tls_event_data ev;
886 	struct tls_context *context = conn->context;
887 	char *alt_subject[TLS_MAX_ALT_SUBJECT];
888 	int alt, num_alt_subject = 0;
889 	WOLFSSL_GENERAL_NAME *gen;
890 	void *ext;
891 	int i;
892 #ifdef CONFIG_SHA256
893 	u8 hash[32];
894 #endif /* CONFIG_SHA256 */
895 
896 	if (!context->event_cb)
897 		return;
898 
899 	os_memset(&ev, 0, sizeof(ev));
900 	if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
901 	    context->cert_in_cb) {
902 		cert = get_x509_cert(err_cert);
903 		ev.peer_cert.cert = cert;
904 	}
905 
906 #ifdef CONFIG_SHA256
907 	if (cert) {
908 		const u8 *addr[1];
909 		size_t len[1];
910 
911 		addr[0] = wpabuf_head(cert);
912 		len[0] = wpabuf_len(cert);
913 		if (sha256_vector(1, addr, len, hash) == 0) {
914 			ev.peer_cert.hash = hash;
915 			ev.peer_cert.hash_len = sizeof(hash);
916 		}
917 	}
918 #endif /* CONFIG_SHA256 */
919 
920 	ev.peer_cert.depth = depth;
921 	ev.peer_cert.subject = subject;
922 
923 	ext = wolfSSL_X509_get_ext_d2i(err_cert, ALT_NAMES_OID, NULL, NULL);
924 	for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
925 		char *pos;
926 
927 		if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
928 			break;
929 		gen = wolfSSL_sk_value((void *) ext, i);
930 		if (!gen ||
931 		    (gen->type != GEN_EMAIL &&
932 		     gen->type != GEN_DNS &&
933 		     gen->type != GEN_URI))
934 			continue;
935 
936 		pos = os_malloc(10 + wolfSSL_ASN1_STRING_length(gen->d.ia5) +
937 				1);
938 		if (!pos)
939 			break;
940 		alt_subject[num_alt_subject++] = pos;
941 
942 		switch (gen->type) {
943 		case GEN_EMAIL:
944 			os_memcpy(pos, "EMAIL:", 6);
945 			pos += 6;
946 			break;
947 		case GEN_DNS:
948 			os_memcpy(pos, "DNS:", 4);
949 			pos += 4;
950 			break;
951 		case GEN_URI:
952 			os_memcpy(pos, "URI:", 4);
953 			pos += 4;
954 			break;
955 		}
956 
957 		os_memcpy(pos, wolfSSL_ASN1_STRING_data(gen->d.ia5),
958 			  wolfSSL_ASN1_STRING_length(gen->d.ia5));
959 		pos += wolfSSL_ASN1_STRING_length(gen->d.ia5);
960 		*pos = '\0';
961 	}
962 	wolfSSL_sk_GENERAL_NAME_free(ext);
963 
964 	for (alt = 0; alt < num_alt_subject; alt++)
965 		ev.peer_cert.altsubject[alt] = alt_subject[alt];
966 	ev.peer_cert.num_altsubject = num_alt_subject;
967 
968 	context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
969 	wpabuf_free(cert);
970 	for (alt = 0; alt < num_alt_subject; alt++)
971 		os_free(alt_subject[alt]);
972 }
973 
974 
975 static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
976 {
977 	char buf[256];
978 	WOLFSSL_X509 *err_cert;
979 	int err, depth;
980 	WOLFSSL *ssl;
981 	struct tls_connection *conn;
982 	struct tls_context *context;
983 	char *match, *altmatch, *suffix_match, *domain_match;
984 	const char *err_str;
985 
986 	err_cert = wolfSSL_X509_STORE_CTX_get_current_cert(x509_ctx);
987 	if (!err_cert) {
988 		wpa_printf(MSG_DEBUG, "wolfSSL: No Cert");
989 		return 0;
990 	}
991 
992 	err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx);
993 	depth = wolfSSL_X509_STORE_CTX_get_error_depth(x509_ctx);
994 	ssl = wolfSSL_X509_STORE_CTX_get_ex_data(
995 		x509_ctx, wolfSSL_get_ex_data_X509_STORE_CTX_idx());
996 	wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(err_cert), buf,
997 				  sizeof(buf));
998 
999 	conn = wolfSSL_get_ex_data(ssl, 0);
1000 	if (!conn) {
1001 		wpa_printf(MSG_DEBUG, "wolfSSL: No ex_data");
1002 		return 0;
1003 	}
1004 
1005 	if (depth == 0)
1006 		conn->peer_cert = err_cert;
1007 	else if (depth == 1)
1008 		conn->peer_issuer = err_cert;
1009 	else if (depth == 2)
1010 		conn->peer_issuer_issuer = err_cert;
1011 
1012 	context = conn->context;
1013 	match = conn->subject_match;
1014 	altmatch = conn->alt_subject_match;
1015 	suffix_match = conn->suffix_match;
1016 	domain_match = conn->domain_match;
1017 
1018 	if (!preverify_ok && !conn->ca_cert_verify)
1019 		preverify_ok = 1;
1020 	if (!preverify_ok && depth > 0 && conn->server_cert_only)
1021 		preverify_ok = 1;
1022 	if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
1023 	    (err == X509_V_ERR_CERT_HAS_EXPIRED ||
1024 	     err == ASN_AFTER_DATE_E || err == ASN_BEFORE_DATE_E ||
1025 	     err == X509_V_ERR_CERT_NOT_YET_VALID)) {
1026 		wpa_printf(MSG_DEBUG,
1027 			   "wolfSSL: Ignore certificate validity time mismatch");
1028 		preverify_ok = 1;
1029 	}
1030 
1031 	err_str = wolfSSL_X509_verify_cert_error_string(err);
1032 
1033 #ifdef CONFIG_SHA256
1034 	/*
1035 	 * Do not require preverify_ok so we can explicity allow otherwise
1036 	 * invalid pinned server certificates.
1037 	 */
1038 	if (depth == 0 && conn->server_cert_only) {
1039 		struct wpabuf *cert;
1040 
1041 		cert = get_x509_cert(err_cert);
1042 		if (!cert) {
1043 			wpa_printf(MSG_DEBUG,
1044 				   "wolfSSL: Could not fetch server certificate data");
1045 			preverify_ok = 0;
1046 		} else {
1047 			u8 hash[32];
1048 			const u8 *addr[1];
1049 			size_t len[1];
1050 
1051 			addr[0] = wpabuf_head(cert);
1052 			len[0] = wpabuf_len(cert);
1053 			if (sha256_vector(1, addr, len, hash) < 0 ||
1054 			    os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1055 				err_str = "Server certificate mismatch";
1056 				err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1057 				preverify_ok = 0;
1058 			} else if (!preverify_ok) {
1059 				/*
1060 				 * Certificate matches pinned certificate, allow
1061 				 * regardless of other problems.
1062 				 */
1063 				wpa_printf(MSG_DEBUG,
1064 					   "wolfSSL: Ignore validation issues for a pinned server certificate");
1065 				preverify_ok = 1;
1066 			}
1067 			wpabuf_free(cert);
1068 		}
1069 	}
1070 #endif /* CONFIG_SHA256 */
1071 
1072 	if (!preverify_ok) {
1073 		wpa_printf(MSG_WARNING,
1074 			   "TLS: Certificate verification failed, error %d (%s) depth %d for '%s'",
1075 			   err, err_str, depth, buf);
1076 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1077 				       err_str, TLS_FAIL_UNSPECIFIED);
1078 		return preverify_ok;
1079 	}
1080 
1081 	wpa_printf(MSG_DEBUG,
1082 		   "TLS: %s - preverify_ok=%d err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1083 		   __func__, preverify_ok, err, err_str,
1084 		   conn->ca_cert_verify, depth, buf);
1085 	if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1086 		wpa_printf(MSG_WARNING,
1087 			   "TLS: Subject '%s' did not match with '%s'",
1088 			   buf, match);
1089 		preverify_ok = 0;
1090 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1091 				       "Subject mismatch",
1092 				       TLS_FAIL_SUBJECT_MISMATCH);
1093 	} else if (depth == 0 && altmatch &&
1094 		   !tls_match_alt_subject(err_cert, altmatch)) {
1095 		wpa_printf(MSG_WARNING,
1096 			   "TLS: altSubjectName match '%s' not found",
1097 			   altmatch);
1098 		preverify_ok = 0;
1099 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1100 				       "AltSubject mismatch",
1101 				       TLS_FAIL_ALTSUBJECT_MISMATCH);
1102 	} else if (depth == 0 && suffix_match &&
1103 		   !tls_match_suffix(err_cert, suffix_match, 0)) {
1104 		wpa_printf(MSG_WARNING,
1105 			   "TLS: Domain suffix match '%s' not found",
1106 			   suffix_match);
1107 		preverify_ok = 0;
1108 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1109 				       "Domain suffix mismatch",
1110 				       TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1111 	} else if (depth == 0 && domain_match &&
1112 		   !tls_match_suffix(err_cert, domain_match, 1)) {
1113 		wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
1114 			   domain_match);
1115 		preverify_ok = 0;
1116 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1117 				       "Domain mismatch",
1118 				       TLS_FAIL_DOMAIN_MISMATCH);
1119 	} else {
1120 		wolfssl_tls_cert_event(conn, err_cert, depth, buf);
1121 	}
1122 
1123 	if (conn->cert_probe && preverify_ok && depth == 0) {
1124 		wpa_printf(MSG_DEBUG,
1125 			   "wolfSSL: Reject server certificate on probe-only run");
1126 		preverify_ok = 0;
1127 		wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1128 				       "Server certificate chain probe",
1129 				       TLS_FAIL_SERVER_CHAIN_PROBE);
1130 	}
1131 
1132 #ifdef HAVE_OCSP_WOLFSSL
1133 	if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
1134 	    preverify_ok) {
1135 		enum ocsp_result res;
1136 
1137 		res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
1138 				      conn->peer_issuer,
1139 				      conn->peer_issuer_issuer);
1140 		if (res == OCSP_REVOKED) {
1141 			preverify_ok = 0;
1142 			wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1143 					       "certificate revoked",
1144 					       TLS_FAIL_REVOKED);
1145 			if (err == X509_V_OK)
1146 				X509_STORE_CTX_set_error(
1147 					x509_ctx, X509_V_ERR_CERT_REVOKED);
1148 		} else if (res != OCSP_GOOD &&
1149 			   (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
1150 			preverify_ok = 0;
1151 			wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1152 					       "bad certificate status response",
1153 					       TLS_FAIL_UNSPECIFIED);
1154 		}
1155 	}
1156 #endif /* HAVE_OCSP_WOLFSSL */
1157 	if (depth == 0 && preverify_ok && context->event_cb != NULL)
1158 		context->event_cb(context->cb_ctx,
1159 				  TLS_CERT_CHAIN_SUCCESS, NULL);
1160 
1161 	if (depth == 0 && preverify_ok) {
1162 		os_free(conn->peer_subject);
1163 		conn->peer_subject = os_strdup(buf);
1164 	}
1165 
1166 	return preverify_ok;
1167 }
1168 
1169 
1170 static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
1171 				  const char *ca_cert,
1172 				  const u8 *ca_cert_blob, size_t blob_len,
1173 				  const char *ca_path)
1174 {
1175 	WOLFSSL_CTX *ctx = tls_ctx;
1176 
1177 	wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1178 	conn->ca_cert_verify = 1;
1179 
1180 	if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1181 		wpa_printf(MSG_DEBUG,
1182 			   "wolfSSL: Probe for server certificate chain");
1183 		conn->cert_probe = 1;
1184 		conn->ca_cert_verify = 0;
1185 		return 0;
1186 	}
1187 
1188 	if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1189 #ifdef CONFIG_SHA256
1190 		const char *pos = ca_cert + 7;
1191 
1192 		if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1193 			wpa_printf(MSG_DEBUG,
1194 				   "wolfSSL: Unsupported ca_cert hash value '%s'",
1195 				   ca_cert);
1196 			return -1;
1197 		}
1198 		pos += 14;
1199 		if (os_strlen(pos) != 32 * 2) {
1200 			wpa_printf(MSG_DEBUG,
1201 				   "wolfSSL: Unexpected SHA256 hash length in ca_cert '%s'",
1202 				   ca_cert);
1203 			return -1;
1204 		}
1205 		if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1206 			wpa_printf(MSG_DEBUG,
1207 				   "wolfSSL: Invalid SHA256 hash value in ca_cert '%s'",
1208 				   ca_cert);
1209 			return -1;
1210 		}
1211 		conn->server_cert_only = 1;
1212 		wpa_printf(MSG_DEBUG,
1213 			   "wolfSSL: Checking only server certificate match");
1214 		return 0;
1215 #else /* CONFIG_SHA256 */
1216 		wpa_printf(MSG_INFO,
1217 			   "No SHA256 included in the build - cannot validate server certificate hash");
1218 		return -1;
1219 #endif /* CONFIG_SHA256 */
1220 	}
1221 
1222 	if (ca_cert_blob) {
1223 		if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_blob, blob_len,
1224 						   SSL_FILETYPE_ASN1) !=
1225 		    SSL_SUCCESS) {
1226 			wpa_printf(MSG_INFO, "SSL: failed to load DER CA blob");
1227 			if (wolfSSL_CTX_load_verify_buffer(
1228 				    ctx, ca_cert_blob, blob_len,
1229 				    SSL_FILETYPE_PEM) != SSL_SUCCESS) {
1230 				wpa_printf(MSG_INFO,
1231 					   "SSL: failed to load PEM CA blob");
1232 				return -1;
1233 			}
1234 		}
1235 		wpa_printf(MSG_DEBUG, "SSL: use CA cert blob OK");
1236 		return 0;
1237 	}
1238 
1239 	if (ca_cert || ca_path) {
1240 		WOLFSSL_X509_STORE *cm = wolfSSL_X509_STORE_new();
1241 
1242 		if (!cm) {
1243 			wpa_printf(MSG_INFO,
1244 				   "SSL: failed to create certificate store");
1245 			return -1;
1246 		}
1247 		wolfSSL_CTX_set_cert_store(ctx, cm);
1248 
1249 		if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
1250 		    SSL_SUCCESS) {
1251 			wpa_printf(MSG_INFO,
1252 				   "SSL: failed to load ca_cert as PEM");
1253 
1254 			if (!ca_cert)
1255 				return -1;
1256 
1257 			if (wolfSSL_CTX_der_load_verify_locations(
1258 				    ctx, ca_cert, SSL_FILETYPE_ASN1) !=
1259 			    SSL_SUCCESS) {
1260 				wpa_printf(MSG_INFO,
1261 					   "SSL: failed to load ca_cert as DER");
1262 				return -1;
1263 			}
1264 		}
1265 		return 0;
1266 	}
1267 
1268 	conn->ca_cert_verify = 0;
1269 	return 0;
1270 }
1271 
1272 
1273 static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags)
1274 {
1275 #ifdef HAVE_SESSION_TICKET
1276 	if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET))
1277 		wolfSSL_UseSessionTicket(ssl);
1278 #endif /* HAVE_SESSION_TICKET */
1279 
1280 	if (flags & TLS_CONN_DISABLE_TLSv1_0)
1281 		wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1);
1282 	if (flags & TLS_CONN_DISABLE_TLSv1_1)
1283 		wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
1284 	if (flags & TLS_CONN_DISABLE_TLSv1_2)
1285 		wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
1286 	if (flags & TLS_CONN_DISABLE_TLSv1_3)
1287 		wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_3);
1288 }
1289 
1290 
1291 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
1292 			      const struct tls_connection_params *params)
1293 {
1294 	wpa_printf(MSG_DEBUG, "SSL: set params");
1295 
1296 	if (tls_connection_set_subject_match(conn, params->subject_match,
1297 					     params->altsubject_match,
1298 					     params->suffix_match,
1299 					     params->domain_match) < 0) {
1300 		wpa_printf(MSG_INFO, "Error setting subject match");
1301 		return -1;
1302 	}
1303 
1304 	if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
1305 				   params->ca_cert_blob,
1306 				   params->ca_cert_blob_len,
1307 				   params->ca_path) < 0) {
1308 		wpa_printf(MSG_INFO, "Error setting CA cert");
1309 		return -1;
1310 	}
1311 
1312 	if (tls_connection_client_cert(conn, params->client_cert,
1313 				       params->client_cert_blob,
1314 				       params->client_cert_blob_len) < 0) {
1315 		wpa_printf(MSG_INFO, "Error setting client cert");
1316 		return -1;
1317 	}
1318 
1319 	if (tls_connection_private_key(tls_ctx, conn, params->private_key,
1320 				       params->private_key_passwd,
1321 				       params->private_key_blob,
1322 				       params->private_key_blob_len) < 0) {
1323 		wpa_printf(MSG_INFO, "Error setting private key");
1324 		return -1;
1325 	}
1326 
1327 	wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s",
1328 		   params->openssl_ciphers ? params->openssl_ciphers : "N/A");
1329 	if (params->openssl_ciphers &&
1330 	    wolfSSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) {
1331 		wpa_printf(MSG_INFO,
1332 			   "wolfSSL: Failed to set cipher string '%s'",
1333 			   params->openssl_ciphers);
1334 		return -1;
1335 	}
1336 
1337 	tls_set_conn_flags(conn->ssl, params->flags);
1338 
1339 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
1340 	if (params->flags & TLS_CONN_REQUEST_OCSP) {
1341 		if (wolfSSL_UseOCSPStapling(conn->ssl, WOLFSSL_CSR_OCSP,
1342 					    WOLFSSL_CSR_OCSP_USE_NONCE) !=
1343 		    SSL_SUCCESS)
1344 			return -1;
1345 		if (wolfSSL_EnableOCSPStapling(conn->ssl) != SSL_SUCCESS)
1346 			return -1;
1347 	}
1348 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
1349 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
1350 	if (params->flags & TLS_CONN_REQUEST_OCSP) {
1351 		if (wolfSSL_UseOCSPStaplingV2(conn->ssl,
1352 					      WOLFSSL_CSR2_OCSP_MULTI, 0) !=
1353 		    SSL_SUCCESS)
1354 			return -1;
1355 		if (wolfSSL_EnableOCSPStapling(conn->ssl) != SSL_SUCCESS)
1356 			return -1;
1357 	}
1358 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1359 #if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
1360     !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1361 #ifdef HAVE_OCSP
1362 	if (params->flags & TLS_CONN_REQUEST_OCSP)
1363 		wolfSSL_CTX_EnableOCSP(ctx, 0);
1364 #else /* HAVE_OCSP */
1365 	if (params->flags & TLS_CONN_REQUIRE_OCSP) {
1366 		wpa_printf(MSG_INFO,
1367 			   "wolfSSL: No OCSP support included - reject configuration");
1368 		return -1;
1369 	}
1370 	if (params->flags & TLS_CONN_REQUEST_OCSP) {
1371 		wpa_printf(MSG_DEBUG,
1372 			   "wolfSSL: No OCSP support included - allow optional OCSP case to continue");
1373 	}
1374 #endif /* HAVE_OCSP */
1375 #endif /* !HAVE_CERTIFICATE_STATUS_REQUEST &&
1376 	* !HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1377 
1378 	conn->flags = params->flags;
1379 
1380 	return 0;
1381 }
1382 
1383 
1384 static int tls_global_ca_cert(void *ssl_ctx, const char *ca_cert)
1385 {
1386 	WOLFSSL_CTX *ctx = ssl_ctx;
1387 
1388 	if (ca_cert) {
1389 		if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1)
1390 		{
1391 			wpa_printf(MSG_WARNING,
1392 				   "Failed to load root certificates");
1393 			return -1;
1394 		}
1395 
1396 		wpa_printf(MSG_DEBUG,
1397 			   "TLS: Trusted root certificate(s) loaded");
1398 	}
1399 
1400 	return 0;
1401 }
1402 
1403 
1404 static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
1405 {
1406 	WOLFSSL_CTX *ctx = ssl_ctx;
1407 
1408 	if (!client_cert)
1409 		return 0;
1410 
1411 	if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1412 							  SSL_FILETYPE_ASN1) !=
1413 	    SSL_SUCCESS &&
1414 	    wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1415 	    SSL_SUCCESS) {
1416 		wpa_printf(MSG_INFO, "Failed to load client certificate");
1417 		return -1;
1418 	}
1419 
1420 	wpa_printf(MSG_DEBUG, "SSL: Loaded global client certificate: %s",
1421 		   client_cert);
1422 
1423 	return 0;
1424 }
1425 
1426 
1427 static int tls_global_private_key(void *ssl_ctx, const char *private_key,
1428 				  const char *private_key_passwd)
1429 {
1430 	WOLFSSL_CTX *ctx = ssl_ctx;
1431 	char *passwd = NULL;
1432 	int ret = 0;
1433 
1434 	if (!private_key)
1435 		return 0;
1436 
1437 	if (private_key_passwd) {
1438 		passwd = os_strdup(private_key_passwd);
1439 		if (!passwd)
1440 			return -1;
1441 	}
1442 
1443 	wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
1444 	wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
1445 
1446 	if (wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1447 					    SSL_FILETYPE_ASN1) != 1 &&
1448 	    wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1449 					    SSL_FILETYPE_PEM) != 1) {
1450 		wpa_printf(MSG_INFO, "Failed to load private key");
1451 		ret = -1;
1452 	}
1453 
1454 	wpa_printf(MSG_DEBUG, "SSL: Loaded global private key");
1455 
1456 	os_free(passwd);
1457 	wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
1458 
1459 	return ret;
1460 }
1461 
1462 
1463 static int tls_global_dh(void *ssl_ctx, const char *dh_file)
1464 {
1465 	WOLFSSL_CTX *ctx = ssl_ctx;
1466 
1467 	if (dh_file) {
1468 		if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file, SSL_FILETYPE_PEM) <
1469 		    0) {
1470 			wpa_printf(MSG_INFO,
1471 				   "SSL: global use DH PEM file failed");
1472 			if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file,
1473 						      SSL_FILETYPE_ASN1) < 0) {
1474 				wpa_printf(MSG_INFO,
1475 					   "SSL: global use DH DER file failed");
1476 				return -1;
1477 			}
1478 		}
1479 		wpa_printf(MSG_DEBUG, "SSL: global use DH file OK");
1480 		return 0;
1481 	}
1482 
1483 	return 0;
1484 }
1485 
1486 
1487 #ifdef HAVE_OCSP
1488 
1489 int ocsp_status_cb(void *unused, const char *url, int url_sz,
1490 		   unsigned char *request, int request_sz,
1491 		   unsigned char **response)
1492 {
1493 	size_t len;
1494 
1495 	(void) unused;
1496 
1497 	if (!url) {
1498 		wpa_printf(MSG_DEBUG,
1499 			   "wolfSSL: OCSP status callback - no response configured");
1500 		*response = NULL;
1501 		return 0;
1502 	}
1503 
1504 	*response = (unsigned char *) os_readfile(url, &len);
1505 	if (!*response) {
1506 		wpa_printf(MSG_DEBUG,
1507 			   "wolfSSL: OCSP status callback - could not read response file");
1508 		return -1;
1509 	}
1510 	wpa_printf(MSG_DEBUG,
1511 		   "wolfSSL: OCSP status callback - send cached response");
1512 	return len;
1513 }
1514 
1515 
1516 void ocsp_resp_free_cb(void *ocsp_stapling_response, unsigned char *response)
1517 {
1518 	os_free(response);
1519 }
1520 
1521 #endif /* HAVE_OCSP */
1522 
1523 
1524 int tls_global_set_params(void *tls_ctx,
1525 			  const struct tls_connection_params *params)
1526 {
1527 	wpa_printf(MSG_DEBUG, "SSL: global set params");
1528 
1529 	if (params->check_cert_subject)
1530 		return -1; /* not yet supported */
1531 
1532 	if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1533 		wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1534 			   params->ca_cert);
1535 		return -1;
1536 	}
1537 
1538 	if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1539 		wpa_printf(MSG_INFO,
1540 			   "SSL: Failed to load client cert file '%s'",
1541 			   params->client_cert);
1542 		return -1;
1543 	}
1544 
1545 	if (tls_global_private_key(tls_ctx, params->private_key,
1546 				   params->private_key_passwd) < 0) {
1547 		wpa_printf(MSG_INFO,
1548 			   "SSL: Failed to load private key file '%s'",
1549 			   params->private_key);
1550 		return -1;
1551 	}
1552 
1553 	if (tls_global_dh(tls_ctx, params->dh_file) < 0) {
1554 		wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1555 			   params->dh_file);
1556 		return -1;
1557 	}
1558 
1559 	wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s",
1560 		   params->openssl_ciphers ? params->openssl_ciphers : "N/A");
1561 	if (params->openssl_ciphers &&
1562 	    wolfSSL_CTX_set_cipher_list(tls_ctx,
1563 					params->openssl_ciphers) != 1) {
1564 		wpa_printf(MSG_INFO,
1565 			   "wolfSSL: Failed to set cipher string '%s'",
1566 			   params->openssl_ciphers);
1567 		return -1;
1568 	}
1569 
1570 	if (params->openssl_ecdh_curves) {
1571 		wpa_printf(MSG_INFO,
1572 			   "wolfSSL: openssl_ecdh_curves not supported");
1573 		return -1;
1574 	}
1575 
1576 #ifdef HAVE_SESSION_TICKET
1577 	/* Session ticket is off by default - can't disable once on. */
1578 	if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1579 		wolfSSL_CTX_UseSessionTicket(tls_ctx);
1580 #endif /* HAVE_SESSION_TICKET */
1581 
1582 #ifdef HAVE_OCSP
1583 	if (params->ocsp_stapling_response) {
1584 		wolfSSL_CTX_SetOCSP_OverrideURL(tls_ctx,
1585 						params->ocsp_stapling_response);
1586 		wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1587 				       ocsp_resp_free_cb, NULL);
1588 	}
1589 #endif /* HAVE_OCSP */
1590 
1591 	return 0;
1592 }
1593 
1594 
1595 int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
1596 {
1597 	wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1598 
1599 	if (check_crl) {
1600 		/* Hack to Enable CRLs. */
1601 		wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
1602 	}
1603 
1604 	return 0;
1605 }
1606 
1607 
1608 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1609 			      int verify_peer, unsigned int flags,
1610 			      const u8 *session_ctx, size_t session_ctx_len)
1611 {
1612 	static int counter = 0;
1613 	struct tls_context *context;
1614 
1615 	if (!conn)
1616 		return -1;
1617 
1618 	wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
1619 
1620 	if (verify_peer) {
1621 		conn->ca_cert_verify = 1;
1622 		wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1623 				   SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1624 				   tls_verify_cb);
1625 	} else {
1626 		conn->ca_cert_verify = 0;
1627 		wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1628 	}
1629 
1630 	wolfSSL_set_accept_state(conn->ssl);
1631 
1632 	context = wolfSSL_CTX_get_ex_data((WOLFSSL_CTX *) ssl_ctx, 0);
1633 	if (context && context->tls_session_lifetime == 0) {
1634 		/*
1635 		 * Set session id context to a unique value to make sure
1636 		 * session resumption cannot be used either through session
1637 		 * caching or TLS ticket extension.
1638 		 */
1639 		counter++;
1640 		wolfSSL_set_session_id_context(conn->ssl,
1641 					       (const unsigned char *) &counter,
1642 					       sizeof(counter));
1643 	} else {
1644 		wolfSSL_set_session_id_context(conn->ssl, session_ctx,
1645 					       session_ctx_len);
1646 	}
1647 
1648 	/* TODO: do we need to fake a session like OpenSSL does here? */
1649 
1650 	return 0;
1651 }
1652 
1653 
1654 static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
1655 					 const struct wpabuf *in_data,
1656 					 int server)
1657 {
1658 	int res;
1659 
1660 	wolfssl_reset_out_data(&conn->output);
1661 
1662 	/* Initiate TLS handshake or continue the existing handshake */
1663 	if (server) {
1664 		wolfSSL_set_accept_state(conn->ssl);
1665 		res = wolfSSL_accept(conn->ssl);
1666 		wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
1667 	} else {
1668 		wolfSSL_set_connect_state(conn->ssl);
1669 		res = wolfSSL_connect(conn->ssl);
1670 		wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
1671 	}
1672 
1673 	if (res != WOLFSSL_SUCCESS) {
1674 		int err = wolfSSL_get_error(conn->ssl, res);
1675 
1676 		if (err == WOLFSSL_ERROR_NONE) {
1677 			wpa_printf(MSG_DEBUG,
1678 				   "SSL: %s - WOLFSSL_ERROR_NONE (%d)",
1679 				   server ? "wolfSSL_accept" :
1680 				   "wolfSSL_connect", res);
1681 		} else if (err == WOLFSSL_ERROR_WANT_READ) {
1682 			wpa_printf(MSG_DEBUG,
1683 				   "SSL: %s - want more data",
1684 				   server ? "wolfSSL_accept" :
1685 				   "wolfSSL_connect");
1686 		} else if (err == WOLFSSL_ERROR_WANT_WRITE) {
1687 			wpa_printf(MSG_DEBUG,
1688 				   "SSL: %s - want to write",
1689 				   server ? "wolfSSL_accept" :
1690 				   "wolfSSL_connect");
1691 		} else {
1692 			char msg[80];
1693 
1694 			wpa_printf(MSG_DEBUG,
1695 				   "SSL: %s - failed %s",
1696 				   server ? "wolfSSL_accept" :
1697 				   "wolfSSL_connect",
1698 				   wolfSSL_ERR_error_string(err, msg));
1699 			conn->failed++;
1700 		}
1701 	}
1702 
1703 	return conn->output.out_data;
1704 }
1705 
1706 
1707 static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
1708 					     size_t max_len)
1709 {
1710 	int res;
1711 	struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
1712 
1713 	if (!appl_data)
1714 		return NULL;
1715 
1716 	res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
1717 			   wpabuf_size(appl_data));
1718 	if (res < 0) {
1719 		int err = wolfSSL_get_error(conn->ssl, res);
1720 
1721 		if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1722 			wpa_printf(MSG_DEBUG,
1723 				   "SSL: No Application Data included");
1724 		} else {
1725 			char msg[80];
1726 
1727 			wpa_printf(MSG_DEBUG,
1728 				   "Failed to read possible Application Data %s",
1729 				   wolfSSL_ERR_error_string(err, msg));
1730 		}
1731 
1732 		wpabuf_free(appl_data);
1733 		return NULL;
1734 	}
1735 
1736 	wpabuf_put(appl_data, res);
1737 	wpa_hexdump_buf_key(MSG_MSGDUMP,
1738 			    "SSL: Application Data in Finished message",
1739 			    appl_data);
1740 	return appl_data;
1741 }
1742 
1743 
1744 static struct wpabuf *
1745 wolfssl_connection_handshake(struct tls_connection *conn,
1746 			     const struct wpabuf *in_data,
1747 			     struct wpabuf **appl_data, int server)
1748 {
1749 	struct wpabuf *out_data;
1750 
1751 	wolfssl_reset_in_data(&conn->input, in_data);
1752 
1753 	if (appl_data)
1754 		*appl_data = NULL;
1755 
1756 	out_data = wolfssl_handshake(conn, in_data, server);
1757 	if (!out_data)
1758 		return NULL;
1759 
1760 	if (wolfSSL_is_init_finished(conn->ssl)) {
1761 		wpa_printf(MSG_DEBUG,
1762 			   "wolfSSL: Handshake finished - resumed=%d",
1763 			   tls_connection_resumed(NULL, conn));
1764 		if (appl_data && in_data)
1765 			*appl_data = wolfssl_get_appl_data(conn,
1766 							   wpabuf_len(in_data));
1767 	}
1768 
1769 	return out_data;
1770 }
1771 
1772 
1773 struct wpabuf * tls_connection_handshake(void *tls_ctx,
1774 					 struct tls_connection *conn,
1775 					 const struct wpabuf *in_data,
1776 					 struct wpabuf **appl_data)
1777 {
1778 	return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
1779 }
1780 
1781 
1782 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1783 						struct tls_connection *conn,
1784 						const struct wpabuf *in_data,
1785 						struct wpabuf **appl_data)
1786 {
1787 	return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
1788 }
1789 
1790 
1791 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1792 				       struct tls_connection *conn,
1793 				       const struct wpabuf *in_data)
1794 {
1795 	int res;
1796 
1797 	if (!conn)
1798 		return NULL;
1799 
1800 	wpa_printf(MSG_DEBUG, "SSL: encrypt: %zu bytes", wpabuf_len(in_data));
1801 
1802 	wolfssl_reset_out_data(&conn->output);
1803 
1804 	res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
1805 			    wpabuf_len(in_data));
1806 	if (res < 0) {
1807 		int  err = wolfSSL_get_error(conn->ssl, res);
1808 		char msg[80];
1809 
1810 		wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
1811 			   wolfSSL_ERR_error_string(err, msg));
1812 		return NULL;
1813 	}
1814 
1815 	return conn->output.out_data;
1816 }
1817 
1818 
1819 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1820 				       struct tls_connection *conn,
1821 				       const struct wpabuf *in_data)
1822 {
1823 	int res;
1824 	struct wpabuf *buf;
1825 
1826 	if (!conn)
1827 		return NULL;
1828 
1829 	wpa_printf(MSG_DEBUG, "SSL: decrypt");
1830 
1831 	wolfssl_reset_in_data(&conn->input, in_data);
1832 
1833 	/* Read decrypted data for further processing */
1834 	/*
1835 	 * Even though we try to disable TLS compression, it is possible that
1836 	 * this cannot be done with all TLS libraries. Add extra buffer space
1837 	 * to handle the possibility of the decrypted data being longer than
1838 	 * input data.
1839 	 */
1840 	buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1841 	if (!buf)
1842 		return NULL;
1843 	res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
1844 	if (res < 0) {
1845 		wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
1846 		wpabuf_free(buf);
1847 		return NULL;
1848 	}
1849 	wpabuf_put(buf, res);
1850 
1851 	wpa_printf(MSG_DEBUG, "SSL: decrypt: %zu bytes", wpabuf_len(buf));
1852 
1853 	return buf;
1854 }
1855 
1856 
1857 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
1858 {
1859 	return conn ? wolfSSL_session_reused(conn->ssl) : 0;
1860 }
1861 
1862 
1863 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1864 				   u8 *ciphers)
1865 {
1866 	char buf[128], *pos, *end;
1867 	u8 *c;
1868 	int ret;
1869 
1870 	if (!conn || !conn->ssl || !ciphers)
1871 		return -1;
1872 
1873 	buf[0] = '\0';
1874 	pos = buf;
1875 	end = pos + sizeof(buf);
1876 
1877 	c = ciphers;
1878 	while (*c != TLS_CIPHER_NONE) {
1879 		const char *suite;
1880 
1881 		switch (*c) {
1882 		case TLS_CIPHER_RC4_SHA:
1883 			suite = "RC4-SHA";
1884 			break;
1885 		case TLS_CIPHER_AES128_SHA:
1886 			suite = "AES128-SHA";
1887 			break;
1888 		case TLS_CIPHER_RSA_DHE_AES128_SHA:
1889 			suite = "DHE-RSA-AES128-SHA";
1890 			break;
1891 		case TLS_CIPHER_ANON_DH_AES128_SHA:
1892 			suite = "ADH-AES128-SHA";
1893 			break;
1894 		case TLS_CIPHER_RSA_DHE_AES256_SHA:
1895 			suite = "DHE-RSA-AES256-SHA";
1896 			break;
1897 		case TLS_CIPHER_AES256_SHA:
1898 			suite = "AES256-SHA";
1899 			break;
1900 		default:
1901 			wpa_printf(MSG_DEBUG,
1902 				   "TLS: Unsupported cipher selection: %d", *c);
1903 			return -1;
1904 		}
1905 		ret = os_snprintf(pos, end - pos, ":%s", suite);
1906 		if (os_snprintf_error(end - pos, ret))
1907 			break;
1908 		pos += ret;
1909 
1910 		c++;
1911 	}
1912 
1913 	wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", buf + 1);
1914 
1915 	if (wolfSSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
1916 		wpa_printf(MSG_DEBUG, "Cipher suite configuration failed");
1917 		return -1;
1918 	}
1919 
1920 	return 0;
1921 }
1922 
1923 
1924 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
1925 		   char *buf, size_t buflen)
1926 {
1927 	WOLFSSL_CIPHER *cipher;
1928 	const char *name;
1929 
1930 	if (!conn || !conn->ssl)
1931 		return -1;
1932 
1933 	cipher = wolfSSL_get_current_cipher(conn->ssl);
1934 	if (!cipher)
1935 		return -1;
1936 
1937 	name = wolfSSL_CIPHER_get_name(cipher);
1938 	if (!name)
1939 		return -1;
1940 
1941 	if (os_strcmp(name, "SSL_RSA_WITH_RC4_128_SHA") == 0)
1942 		os_strlcpy(buf, "RC4-SHA", buflen);
1943 	else if (os_strcmp(name, "TLS_RSA_WITH_AES_128_CBC_SHA") == 0)
1944 		os_strlcpy(buf, "AES128-SHA", buflen);
1945 	else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") == 0)
1946 		os_strlcpy(buf, "DHE-RSA-AES128-SHA", buflen);
1947 	else if (os_strcmp(name, "TLS_DH_anon_WITH_AES_128_CBC_SHA") == 0)
1948 		os_strlcpy(buf, "ADH-AES128-SHA", buflen);
1949 	else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA") == 0)
1950 		os_strlcpy(buf, "DHE-RSA-AES256-SHA", buflen);
1951 	else if (os_strcmp(name, "TLS_RSA_WITH_AES_256_CBC_SHA") == 0)
1952 		os_strlcpy(buf, "AES256-SHA", buflen);
1953 	else
1954 		os_strlcpy(buf, name, buflen);
1955 
1956 	return 0;
1957 }
1958 
1959 
1960 int tls_connection_enable_workaround(void *tls_ctx,
1961 				     struct tls_connection *conn)
1962 {
1963 	/* no empty fragments in wolfSSL for now */
1964 	return 0;
1965 }
1966 
1967 
1968 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
1969 {
1970 	if (!conn)
1971 		return -1;
1972 
1973 	return conn->failed;
1974 }
1975 
1976 
1977 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
1978 {
1979 	if (!conn)
1980 		return -1;
1981 
1982 	/* TODO: this is not incremented anywhere */
1983 	return conn->read_alerts;
1984 }
1985 
1986 
1987 int tls_connection_get_write_alerts(void *tls_ctx,
1988 				    struct tls_connection *conn)
1989 {
1990 	if (!conn)
1991 		return -1;
1992 
1993 	/* TODO: this is not incremented anywhere */
1994 	return conn->write_alerts;
1995 }
1996 
1997 
1998 
1999 int tls_get_library_version(char *buf, size_t buf_len)
2000 {
2001 	return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
2002 			   WOLFSSL_VERSION, wolfSSL_lib_version());
2003 }
2004 
2005 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
2006 		    char *buf, size_t buflen)
2007 {
2008 	const char *name;
2009 
2010 	if (!conn || !conn->ssl)
2011 		return -1;
2012 
2013 	name = wolfSSL_get_version(conn->ssl);
2014 	if (!name)
2015 		return -1;
2016 
2017 	os_strlcpy(buf, name, buflen);
2018 	return 0;
2019 }
2020 
2021 
2022 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
2023 			      struct tls_random *keys)
2024 {
2025 	WOLFSSL *ssl;
2026 
2027 	if (!conn || !keys)
2028 		return -1;
2029 	ssl = conn->ssl;
2030 	if (!ssl)
2031 		return -1;
2032 
2033 	os_memset(keys, 0, sizeof(*keys));
2034 	keys->client_random = conn->client_random;
2035 	keys->client_random_len = wolfSSL_get_client_random(
2036 		ssl, conn->client_random, sizeof(conn->client_random));
2037 	keys->server_random = conn->server_random;
2038 	keys->server_random_len = wolfSSL_get_server_random(
2039 		ssl, conn->server_random, sizeof(conn->server_random));
2040 
2041 	return 0;
2042 }
2043 
2044 
2045 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
2046 			      const char *label, const u8 *context,
2047 			      size_t context_len, u8 *out, size_t out_len)
2048 {
2049 	if (!conn)
2050 		return -1;
2051 #if LIBWOLFSSL_VERSION_HEX >= 0x04007000
2052 	if (wolfSSL_export_keying_material(conn->ssl, out, out_len,
2053 					   label, os_strlen(label),
2054 					   context, context_len,
2055 					   context != NULL) != WOLFSSL_SUCCESS)
2056 		return -1;
2057 	return 0;
2058 #else
2059 	if (context ||
2060 	    wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
2061 		return -1;
2062 #endif
2063 	return 0;
2064 }
2065 
2066 
2067 #define SEED_LEN	(RAN_LEN + RAN_LEN)
2068 
2069 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
2070 				    u8 *out, size_t out_len)
2071 {
2072 	byte seed[SEED_LEN];
2073 	int ret = -1;
2074 	WOLFSSL *ssl;
2075 	byte *tmp_out;
2076 	byte *_out;
2077 	int skip = 0;
2078 	byte *master_key;
2079 	unsigned int master_key_len;
2080 	byte *server_random;
2081 	unsigned int server_len;
2082 	byte *client_random;
2083 	unsigned int client_len;
2084 
2085 	if (!conn || !conn->ssl)
2086 		return -1;
2087 	ssl = conn->ssl;
2088 
2089 	skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
2090 		    wolfSSL_GetIVSize(ssl));
2091 
2092 	tmp_out = os_malloc(skip + out_len);
2093 	if (!tmp_out)
2094 		return -1;
2095 	_out = tmp_out;
2096 
2097 	wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2098 			 &server_len, &client_random, &client_len);
2099 	os_memcpy(seed, server_random, RAN_LEN);
2100 	os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2101 
2102 	if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2103 		tls_prf_sha256(master_key, master_key_len,
2104 			       "key expansion", seed, sizeof(seed),
2105 			       _out, skip + out_len);
2106 		ret = 0;
2107 	} else {
2108 #ifdef CONFIG_FIPS
2109 		wpa_printf(MSG_ERROR,
2110 			   "wolfSSL: Can't use sha1_md5 in FIPS build");
2111 		ret = -1;
2112 #else /* CONFIG_FIPS */
2113 		ret = tls_prf_sha1_md5(master_key, master_key_len,
2114 				       "key expansion", seed, sizeof(seed),
2115 				       _out, skip + out_len);
2116 #endif /* CONFIG_FIPS */
2117 	}
2118 
2119 	forced_memzero(master_key, master_key_len);
2120 	if (ret == 0)
2121 		os_memcpy(out, _out + skip, out_len);
2122 	bin_clear_free(tmp_out, skip + out_len);
2123 
2124 	return ret;
2125 }
2126 
2127 
2128 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2129 
2130 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2131 				    int ext_type, const u8 *data,
2132 				    size_t data_len)
2133 {
2134 	(void) ssl_ctx;
2135 
2136 	if (!conn || !conn->ssl || ext_type != 35)
2137 		return -1;
2138 
2139 	if (wolfSSL_set_SessionTicket(conn->ssl, data,
2140 				      (unsigned int) data_len) != 1)
2141 		return -1;
2142 
2143 	return 0;
2144 }
2145 
2146 
2147 static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2148 {
2149 	struct tls_connection *conn = arg;
2150 	int ret;
2151 	unsigned char client_random[RAN_LEN];
2152 	unsigned char server_random[RAN_LEN];
2153 	word32 ticket_len = sizeof(conn->session_ticket);
2154 
2155 	if (!conn || !conn->session_ticket_cb)
2156 		return 1;
2157 
2158 	if (wolfSSL_get_client_random(s, client_random,
2159 				      sizeof(client_random)) == 0 ||
2160 	    wolfSSL_get_server_random(s, server_random,
2161 				      sizeof(server_random)) == 0 ||
2162 	    wolfSSL_get_SessionTicket(s, conn->session_ticket,
2163 				      &ticket_len) != 1)
2164 		return 1;
2165 
2166 	if (ticket_len == 0)
2167 		return 0;
2168 
2169 	ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2170 				      conn->session_ticket, ticket_len,
2171 				      client_random, server_random, secret);
2172 	if (ret <= 0)
2173 		return 1;
2174 
2175 	*secret_len = SECRET_LEN;
2176 	return 0;
2177 }
2178 
2179 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2180 
2181 
2182 int tls_connection_set_session_ticket_cb(void *tls_ctx,
2183 					 struct tls_connection *conn,
2184 					 tls_session_ticket_cb cb,
2185 					 void *ctx)
2186 {
2187 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2188 	conn->session_ticket_cb = cb;
2189 	conn->session_ticket_cb_ctx = ctx;
2190 
2191 	if (cb) {
2192 		if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2193 						  conn) != 1)
2194 			return -1;
2195 	} else {
2196 		if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2197 			return -1;
2198 	}
2199 
2200 	return 0;
2201 #else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2202 	return -1;
2203 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2204 }
2205 
2206 
2207 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2208 {
2209 	wpa_printf(MSG_DEBUG,
2210 		   "wolfSSL: Success data accepted for resumed session");
2211 }
2212 
2213 
2214 void tls_connection_remove_session(struct tls_connection *conn)
2215 {
2216 	WOLFSSL_SESSION *sess;
2217 
2218 	sess = wolfSSL_get_session(conn->ssl);
2219 	if (!sess)
2220 		return;
2221 
2222 	wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2223 	wpa_printf(MSG_DEBUG,
2224 		   "wolfSSL: Removed cached session to disable session resumption");
2225 }
2226 
2227 
2228 int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len)
2229 {
2230 	size_t len;
2231 	int reused;
2232 
2233 	reused = wolfSSL_session_reused(conn->ssl);
2234 	if ((wolfSSL_is_server(conn->ssl) && !reused) ||
2235 	    (!wolfSSL_is_server(conn->ssl) && reused))
2236 		len = wolfSSL_get_peer_finished(conn->ssl, buf, max_len);
2237 	else
2238 		len = wolfSSL_get_finished(conn->ssl, buf, max_len);
2239 
2240 	if (len == 0 || len > max_len)
2241 		return -1;
2242 
2243 	return len;
2244 }
2245 
2246 
2247 u16 tls_connection_get_cipher_suite(struct tls_connection *conn)
2248 {
2249 	return (u16) wolfSSL_get_current_cipher_suite(conn->ssl);
2250 }
2251 
2252 
2253 const char * tls_connection_get_peer_subject(struct tls_connection *conn)
2254 {
2255 	if (conn)
2256 		return conn->peer_subject;
2257 	return NULL;
2258 }
2259 
2260 
2261 void tls_connection_set_success_data(struct tls_connection *conn,
2262 				     struct wpabuf *data)
2263 {
2264 	WOLFSSL_SESSION *sess;
2265 	struct wpabuf *old;
2266 
2267 	wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2268 
2269 	sess = wolfSSL_get_session(conn->ssl);
2270 	if (!sess) {
2271 		wpa_printf(MSG_DEBUG,
2272 			   "wolfSSL: No session found for success data");
2273 		goto fail;
2274 	}
2275 
2276 	old = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2277 	if (old) {
2278 		wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2279 			   old);
2280 		wpabuf_free(old);
2281 	}
2282 	if (wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
2283 		goto fail;
2284 
2285 	wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2286 	conn->success_data = 1;
2287 	return;
2288 
2289 fail:
2290 	wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2291 	wpabuf_free(data);
2292 }
2293 
2294 
2295 const struct wpabuf *
2296 tls_connection_get_success_data(struct tls_connection *conn)
2297 {
2298 	WOLFSSL_SESSION *sess;
2299 
2300 	wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2301 
2302 	sess = wolfSSL_get_session(conn->ssl);
2303 	if (!sess)
2304 		return NULL;
2305 	return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2306 }
2307 
2308 
2309 bool tls_connection_get_own_cert_used(struct tls_connection *conn)
2310 {
2311 	if (conn)
2312 		return wolfSSL_get_certificate(conn->ssl) != NULL;
2313 	return false;
2314 }
2315