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