xref: /freebsd/contrib/wpa/src/crypto/tls_internal.c (revision b1f9167f94059fd55c630891d359bcff987bd7eb)
1 /*
2  * TLS interface functions and an internal TLS implementation
3  * Copyright (c) 2004-2011, 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  * This file interface functions for hostapd/wpa_supplicant to use the
9  * integrated TLSv1 implementation.
10  */
11 
12 #include "includes.h"
13 
14 #include "common.h"
15 #include "tls.h"
16 #include "tls/tlsv1_client.h"
17 #include "tls/tlsv1_server.h"
18 
19 
20 static int tls_ref_count = 0;
21 
22 struct tls_global {
23 	int server;
24 	struct tlsv1_credentials *server_cred;
25 	int check_crl;
26 };
27 
28 struct tls_connection {
29 	struct tlsv1_client *client;
30 	struct tlsv1_server *server;
31 };
32 
33 
34 void * tls_init(const struct tls_config *conf)
35 {
36 	struct tls_global *global;
37 
38 	if (tls_ref_count == 0) {
39 #ifdef CONFIG_TLS_INTERNAL_CLIENT
40 		if (tlsv1_client_global_init())
41 			return NULL;
42 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
43 #ifdef CONFIG_TLS_INTERNAL_SERVER
44 		if (tlsv1_server_global_init())
45 			return NULL;
46 #endif /* CONFIG_TLS_INTERNAL_SERVER */
47 	}
48 	tls_ref_count++;
49 
50 	global = os_zalloc(sizeof(*global));
51 	if (global == NULL)
52 		return NULL;
53 
54 	return global;
55 }
56 
57 void tls_deinit(void *ssl_ctx)
58 {
59 	struct tls_global *global = ssl_ctx;
60 	tls_ref_count--;
61 	if (tls_ref_count == 0) {
62 #ifdef CONFIG_TLS_INTERNAL_CLIENT
63 		tlsv1_client_global_deinit();
64 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
65 #ifdef CONFIG_TLS_INTERNAL_SERVER
66 		tlsv1_cred_free(global->server_cred);
67 		tlsv1_server_global_deinit();
68 #endif /* CONFIG_TLS_INTERNAL_SERVER */
69 	}
70 	os_free(global);
71 }
72 
73 
74 int tls_get_errors(void *tls_ctx)
75 {
76 	return 0;
77 }
78 
79 
80 struct tls_connection * tls_connection_init(void *tls_ctx)
81 {
82 	struct tls_connection *conn;
83 	struct tls_global *global = tls_ctx;
84 
85 	conn = os_zalloc(sizeof(*conn));
86 	if (conn == NULL)
87 		return NULL;
88 
89 #ifdef CONFIG_TLS_INTERNAL_CLIENT
90 	if (!global->server) {
91 		conn->client = tlsv1_client_init();
92 		if (conn->client == NULL) {
93 			os_free(conn);
94 			return NULL;
95 		}
96 	}
97 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
98 #ifdef CONFIG_TLS_INTERNAL_SERVER
99 	if (global->server) {
100 		conn->server = tlsv1_server_init(global->server_cred);
101 		if (conn->server == NULL) {
102 			os_free(conn);
103 			return NULL;
104 		}
105 	}
106 #endif /* CONFIG_TLS_INTERNAL_SERVER */
107 
108 	return conn;
109 }
110 
111 
112 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
113 {
114 	if (conn == NULL)
115 		return;
116 #ifdef CONFIG_TLS_INTERNAL_CLIENT
117 	if (conn->client)
118 		tlsv1_client_deinit(conn->client);
119 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
120 #ifdef CONFIG_TLS_INTERNAL_SERVER
121 	if (conn->server)
122 		tlsv1_server_deinit(conn->server);
123 #endif /* CONFIG_TLS_INTERNAL_SERVER */
124 	os_free(conn);
125 }
126 
127 
128 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
129 {
130 #ifdef CONFIG_TLS_INTERNAL_CLIENT
131 	if (conn->client)
132 		return tlsv1_client_established(conn->client);
133 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
134 #ifdef CONFIG_TLS_INTERNAL_SERVER
135 	if (conn->server)
136 		return tlsv1_server_established(conn->server);
137 #endif /* CONFIG_TLS_INTERNAL_SERVER */
138 	return 0;
139 }
140 
141 
142 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
143 {
144 #ifdef CONFIG_TLS_INTERNAL_CLIENT
145 	if (conn->client)
146 		return tlsv1_client_shutdown(conn->client);
147 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
148 #ifdef CONFIG_TLS_INTERNAL_SERVER
149 	if (conn->server)
150 		return tlsv1_server_shutdown(conn->server);
151 #endif /* CONFIG_TLS_INTERNAL_SERVER */
152 	return -1;
153 }
154 
155 
156 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
157 			      const struct tls_connection_params *params)
158 {
159 #ifdef CONFIG_TLS_INTERNAL_CLIENT
160 	struct tlsv1_credentials *cred;
161 
162 	if (conn->client == NULL)
163 		return -1;
164 
165 	cred = tlsv1_cred_alloc();
166 	if (cred == NULL)
167 		return -1;
168 
169 	if (tlsv1_set_ca_cert(cred, params->ca_cert,
170 			      params->ca_cert_blob, params->ca_cert_blob_len,
171 			      params->ca_path)) {
172 		wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
173 			   "certificates");
174 		tlsv1_cred_free(cred);
175 		return -1;
176 	}
177 
178 	if (tlsv1_set_cert(cred, params->client_cert,
179 			   params->client_cert_blob,
180 			   params->client_cert_blob_len)) {
181 		wpa_printf(MSG_INFO, "TLS: Failed to configure client "
182 			   "certificate");
183 		tlsv1_cred_free(cred);
184 		return -1;
185 	}
186 
187 	if (tlsv1_set_private_key(cred, params->private_key,
188 				  params->private_key_passwd,
189 				  params->private_key_blob,
190 				  params->private_key_blob_len)) {
191 		wpa_printf(MSG_INFO, "TLS: Failed to load private key");
192 		tlsv1_cred_free(cred);
193 		return -1;
194 	}
195 
196 	if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
197 			       params->dh_blob_len)) {
198 		wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
199 		tlsv1_cred_free(cred);
200 		return -1;
201 	}
202 
203 	if (tlsv1_client_set_cred(conn->client, cred) < 0) {
204 		tlsv1_cred_free(cred);
205 		return -1;
206 	}
207 
208 	tlsv1_client_set_time_checks(
209 		conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS));
210 
211 	return 0;
212 #else /* CONFIG_TLS_INTERNAL_CLIENT */
213 	return -1;
214 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
215 }
216 
217 
218 int tls_global_set_params(void *tls_ctx,
219 			  const struct tls_connection_params *params)
220 {
221 #ifdef CONFIG_TLS_INTERNAL_SERVER
222 	struct tls_global *global = tls_ctx;
223 	struct tlsv1_credentials *cred;
224 
225 	/* Currently, global parameters are only set when running in server
226 	 * mode. */
227 	global->server = 1;
228 	tlsv1_cred_free(global->server_cred);
229 	global->server_cred = cred = tlsv1_cred_alloc();
230 	if (cred == NULL)
231 		return -1;
232 
233 	if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
234 			      params->ca_cert_blob_len, params->ca_path)) {
235 		wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
236 			   "certificates");
237 		return -1;
238 	}
239 
240 	if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
241 			   params->client_cert_blob_len)) {
242 		wpa_printf(MSG_INFO, "TLS: Failed to configure server "
243 			   "certificate");
244 		return -1;
245 	}
246 
247 	if (tlsv1_set_private_key(cred, params->private_key,
248 				  params->private_key_passwd,
249 				  params->private_key_blob,
250 				  params->private_key_blob_len)) {
251 		wpa_printf(MSG_INFO, "TLS: Failed to load private key");
252 		return -1;
253 	}
254 
255 	if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
256 			       params->dh_blob_len)) {
257 		wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
258 		return -1;
259 	}
260 
261 	return 0;
262 #else /* CONFIG_TLS_INTERNAL_SERVER */
263 	return -1;
264 #endif /* CONFIG_TLS_INTERNAL_SERVER */
265 }
266 
267 
268 int tls_global_set_verify(void *tls_ctx, int check_crl)
269 {
270 	struct tls_global *global = tls_ctx;
271 	global->check_crl = check_crl;
272 	return 0;
273 }
274 
275 
276 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
277 			      int verify_peer)
278 {
279 #ifdef CONFIG_TLS_INTERNAL_SERVER
280 	if (conn->server)
281 		return tlsv1_server_set_verify(conn->server, verify_peer);
282 #endif /* CONFIG_TLS_INTERNAL_SERVER */
283 	return -1;
284 }
285 
286 
287 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
288 			    struct tls_keys *keys)
289 {
290 #ifdef CONFIG_TLS_INTERNAL_CLIENT
291 	if (conn->client)
292 		return tlsv1_client_get_keys(conn->client, keys);
293 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
294 #ifdef CONFIG_TLS_INTERNAL_SERVER
295 	if (conn->server)
296 		return tlsv1_server_get_keys(conn->server, keys);
297 #endif /* CONFIG_TLS_INTERNAL_SERVER */
298 	return -1;
299 }
300 
301 
302 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
303 		       const char *label, int server_random_first,
304 		       u8 *out, size_t out_len)
305 {
306 #ifdef CONFIG_TLS_INTERNAL_CLIENT
307 	if (conn->client) {
308 		return tlsv1_client_prf(conn->client, label,
309 					server_random_first,
310 					out, out_len);
311 	}
312 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
313 #ifdef CONFIG_TLS_INTERNAL_SERVER
314 	if (conn->server) {
315 		return tlsv1_server_prf(conn->server, label,
316 					server_random_first,
317 					out, out_len);
318 	}
319 #endif /* CONFIG_TLS_INTERNAL_SERVER */
320 	return -1;
321 }
322 
323 
324 struct wpabuf * tls_connection_handshake(void *tls_ctx,
325 					 struct tls_connection *conn,
326 					 const struct wpabuf *in_data,
327 					 struct wpabuf **appl_data)
328 {
329 	return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data,
330 					 NULL);
331 }
332 
333 
334 struct wpabuf * tls_connection_handshake2(void *tls_ctx,
335 					  struct tls_connection *conn,
336 					  const struct wpabuf *in_data,
337 					  struct wpabuf **appl_data,
338 					  int *need_more_data)
339 {
340 #ifdef CONFIG_TLS_INTERNAL_CLIENT
341 	u8 *res, *ad;
342 	size_t res_len, ad_len;
343 	struct wpabuf *out;
344 
345 	if (conn->client == NULL)
346 		return NULL;
347 
348 	ad = NULL;
349 	res = tlsv1_client_handshake(conn->client,
350 				     in_data ? wpabuf_head(in_data) : NULL,
351 				     in_data ? wpabuf_len(in_data) : 0,
352 				     &res_len, &ad, &ad_len, need_more_data);
353 	if (res == NULL)
354 		return NULL;
355 	out = wpabuf_alloc_ext_data(res, res_len);
356 	if (out == NULL) {
357 		os_free(res);
358 		os_free(ad);
359 		return NULL;
360 	}
361 	if (appl_data) {
362 		if (ad) {
363 			*appl_data = wpabuf_alloc_ext_data(ad, ad_len);
364 			if (*appl_data == NULL)
365 				os_free(ad);
366 		} else
367 			*appl_data = NULL;
368 	} else
369 		os_free(ad);
370 
371 	return out;
372 #else /* CONFIG_TLS_INTERNAL_CLIENT */
373 	return NULL;
374 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
375 }
376 
377 
378 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
379 						struct tls_connection *conn,
380 						const struct wpabuf *in_data,
381 						struct wpabuf **appl_data)
382 {
383 #ifdef CONFIG_TLS_INTERNAL_SERVER
384 	u8 *res;
385 	size_t res_len;
386 	struct wpabuf *out;
387 
388 	if (conn->server == NULL)
389 		return NULL;
390 
391 	if (appl_data)
392 		*appl_data = NULL;
393 
394 	res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data),
395 				     wpabuf_len(in_data), &res_len);
396 	if (res == NULL && tlsv1_server_established(conn->server))
397 		return wpabuf_alloc(0);
398 	if (res == NULL)
399 		return NULL;
400 	out = wpabuf_alloc_ext_data(res, res_len);
401 	if (out == NULL) {
402 		os_free(res);
403 		return NULL;
404 	}
405 
406 	return out;
407 #else /* CONFIG_TLS_INTERNAL_SERVER */
408 	return NULL;
409 #endif /* CONFIG_TLS_INTERNAL_SERVER */
410 }
411 
412 
413 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
414 				       struct tls_connection *conn,
415 				       const struct wpabuf *in_data)
416 {
417 #ifdef CONFIG_TLS_INTERNAL_CLIENT
418 	if (conn->client) {
419 		struct wpabuf *buf;
420 		int res;
421 		buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
422 		if (buf == NULL)
423 			return NULL;
424 		res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data),
425 					   wpabuf_len(in_data),
426 					   wpabuf_mhead(buf),
427 					   wpabuf_size(buf));
428 		if (res < 0) {
429 			wpabuf_free(buf);
430 			return NULL;
431 		}
432 		wpabuf_put(buf, res);
433 		return buf;
434 	}
435 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
436 #ifdef CONFIG_TLS_INTERNAL_SERVER
437 	if (conn->server) {
438 		struct wpabuf *buf;
439 		int res;
440 		buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
441 		if (buf == NULL)
442 			return NULL;
443 		res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data),
444 					   wpabuf_len(in_data),
445 					   wpabuf_mhead(buf),
446 					   wpabuf_size(buf));
447 		if (res < 0) {
448 			wpabuf_free(buf);
449 			return NULL;
450 		}
451 		wpabuf_put(buf, res);
452 		return buf;
453 	}
454 #endif /* CONFIG_TLS_INTERNAL_SERVER */
455 	return NULL;
456 }
457 
458 
459 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
460 				       struct tls_connection *conn,
461 				       const struct wpabuf *in_data)
462 {
463 	return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL);
464 }
465 
466 
467 struct wpabuf * tls_connection_decrypt2(void *tls_ctx,
468 					struct tls_connection *conn,
469 					const struct wpabuf *in_data,
470 					int *need_more_data)
471 {
472 	if (need_more_data)
473 		*need_more_data = 0;
474 
475 #ifdef CONFIG_TLS_INTERNAL_CLIENT
476 	if (conn->client) {
477 		return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data),
478 					    wpabuf_len(in_data),
479 					    need_more_data);
480 	}
481 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
482 #ifdef CONFIG_TLS_INTERNAL_SERVER
483 	if (conn->server) {
484 		struct wpabuf *buf;
485 		int res;
486 		buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
487 		if (buf == NULL)
488 			return NULL;
489 		res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data),
490 					   wpabuf_len(in_data),
491 					   wpabuf_mhead(buf),
492 					   wpabuf_size(buf));
493 		if (res < 0) {
494 			wpabuf_free(buf);
495 			return NULL;
496 		}
497 		wpabuf_put(buf, res);
498 		return buf;
499 	}
500 #endif /* CONFIG_TLS_INTERNAL_SERVER */
501 	return NULL;
502 }
503 
504 
505 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
506 {
507 #ifdef CONFIG_TLS_INTERNAL_CLIENT
508 	if (conn->client)
509 		return tlsv1_client_resumed(conn->client);
510 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
511 #ifdef CONFIG_TLS_INTERNAL_SERVER
512 	if (conn->server)
513 		return tlsv1_server_resumed(conn->server);
514 #endif /* CONFIG_TLS_INTERNAL_SERVER */
515 	return -1;
516 }
517 
518 
519 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
520 				   u8 *ciphers)
521 {
522 #ifdef CONFIG_TLS_INTERNAL_CLIENT
523 	if (conn->client)
524 		return tlsv1_client_set_cipher_list(conn->client, ciphers);
525 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
526 #ifdef CONFIG_TLS_INTERNAL_SERVER
527 	if (conn->server)
528 		return tlsv1_server_set_cipher_list(conn->server, ciphers);
529 #endif /* CONFIG_TLS_INTERNAL_SERVER */
530 	return -1;
531 }
532 
533 
534 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
535 		   char *buf, size_t buflen)
536 {
537 	if (conn == NULL)
538 		return -1;
539 #ifdef CONFIG_TLS_INTERNAL_CLIENT
540 	if (conn->client)
541 		return tlsv1_client_get_cipher(conn->client, buf, buflen);
542 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
543 #ifdef CONFIG_TLS_INTERNAL_SERVER
544 	if (conn->server)
545 		return tlsv1_server_get_cipher(conn->server, buf, buflen);
546 #endif /* CONFIG_TLS_INTERNAL_SERVER */
547 	return -1;
548 }
549 
550 
551 int tls_connection_enable_workaround(void *tls_ctx,
552 				     struct tls_connection *conn)
553 {
554 	return -1;
555 }
556 
557 
558 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
559 				    int ext_type, const u8 *data,
560 				    size_t data_len)
561 {
562 #ifdef CONFIG_TLS_INTERNAL_CLIENT
563 	if (conn->client) {
564 		return tlsv1_client_hello_ext(conn->client, ext_type,
565 					      data, data_len);
566 	}
567 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
568 	return -1;
569 }
570 
571 
572 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
573 {
574 	return 0;
575 }
576 
577 
578 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
579 {
580 	return 0;
581 }
582 
583 
584 int tls_connection_get_write_alerts(void *tls_ctx,
585 				    struct tls_connection *conn)
586 {
587 	return 0;
588 }
589 
590 
591 int tls_connection_get_keyblock_size(void *tls_ctx,
592 				     struct tls_connection *conn)
593 {
594 #ifdef CONFIG_TLS_INTERNAL_CLIENT
595 	if (conn->client)
596 		return tlsv1_client_get_keyblock_size(conn->client);
597 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
598 #ifdef CONFIG_TLS_INTERNAL_SERVER
599 	if (conn->server)
600 		return tlsv1_server_get_keyblock_size(conn->server);
601 #endif /* CONFIG_TLS_INTERNAL_SERVER */
602 	return -1;
603 }
604 
605 
606 unsigned int tls_capabilities(void *tls_ctx)
607 {
608 	return 0;
609 }
610 
611 
612 int tls_connection_set_session_ticket_cb(void *tls_ctx,
613 					 struct tls_connection *conn,
614 					 tls_session_ticket_cb cb,
615 					 void *ctx)
616 {
617 #ifdef CONFIG_TLS_INTERNAL_CLIENT
618 	if (conn->client) {
619 		tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
620 		return 0;
621 	}
622 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
623 #ifdef CONFIG_TLS_INTERNAL_SERVER
624 	if (conn->server) {
625 		tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
626 		return 0;
627 	}
628 #endif /* CONFIG_TLS_INTERNAL_SERVER */
629 	return -1;
630 }
631