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