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