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