Home | History | Annotate | Download | only in crypto
      1 /*
      2  * TLS interface functions and an internal TLS implementation
      3  * Copyright (c) 2004-2011, Jouni Malinen <j (at) 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