$search
00001 /* 00002 * TLS interface functions and an internal TLS implementation 00003 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 * 00014 * This file interface functions for hostapd/wpa_supplicant to use the 00015 * integrated TLSv1 implementation. 00016 */ 00017 00018 #include "includes.h" 00019 00020 #include "common.h" 00021 #include "tls.h" 00022 #include "tls/tlsv1_client.h" 00023 #include "tls/tlsv1_server.h" 00024 00025 00026 static int tls_ref_count = 0; 00027 00028 struct tls_global { 00029 int server; 00030 struct tlsv1_credentials *server_cred; 00031 int check_crl; 00032 }; 00033 00034 struct tls_connection { 00035 struct tlsv1_client *client; 00036 struct tlsv1_server *server; 00037 }; 00038 00039 00040 void * tls_init(const struct tls_config *conf) 00041 { 00042 struct tls_global *global; 00043 00044 if (tls_ref_count == 0) { 00045 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00046 if (tlsv1_client_global_init()) 00047 return NULL; 00048 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00049 #ifdef CONFIG_TLS_INTERNAL_SERVER 00050 if (tlsv1_server_global_init()) 00051 return NULL; 00052 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00053 } 00054 tls_ref_count++; 00055 00056 global = os_zalloc(sizeof(*global)); 00057 if (global == NULL) 00058 return NULL; 00059 00060 return global; 00061 } 00062 00063 void tls_deinit(void *ssl_ctx) 00064 { 00065 struct tls_global *global = ssl_ctx; 00066 tls_ref_count--; 00067 if (tls_ref_count == 0) { 00068 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00069 tlsv1_client_global_deinit(); 00070 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00071 #ifdef CONFIG_TLS_INTERNAL_SERVER 00072 tlsv1_cred_free(global->server_cred); 00073 tlsv1_server_global_deinit(); 00074 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00075 } 00076 os_free(global); 00077 } 00078 00079 00080 int tls_get_errors(void *tls_ctx) 00081 { 00082 return 0; 00083 } 00084 00085 00086 struct tls_connection * tls_connection_init(void *tls_ctx) 00087 { 00088 struct tls_connection *conn; 00089 struct tls_global *global = tls_ctx; 00090 00091 conn = os_zalloc(sizeof(*conn)); 00092 if (conn == NULL) 00093 return NULL; 00094 00095 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00096 if (!global->server) { 00097 conn->client = tlsv1_client_init(); 00098 if (conn->client == NULL) { 00099 os_free(conn); 00100 return NULL; 00101 } 00102 } 00103 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00104 #ifdef CONFIG_TLS_INTERNAL_SERVER 00105 if (global->server) { 00106 conn->server = tlsv1_server_init(global->server_cred); 00107 if (conn->server == NULL) { 00108 os_free(conn); 00109 return NULL; 00110 } 00111 } 00112 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00113 00114 return conn; 00115 } 00116 00117 00118 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) 00119 { 00120 if (conn == NULL) 00121 return; 00122 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00123 if (conn->client) 00124 tlsv1_client_deinit(conn->client); 00125 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00126 #ifdef CONFIG_TLS_INTERNAL_SERVER 00127 if (conn->server) 00128 tlsv1_server_deinit(conn->server); 00129 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00130 os_free(conn); 00131 } 00132 00133 00134 int tls_connection_established(void *tls_ctx, struct tls_connection *conn) 00135 { 00136 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00137 if (conn->client) 00138 return tlsv1_client_established(conn->client); 00139 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00140 #ifdef CONFIG_TLS_INTERNAL_SERVER 00141 if (conn->server) 00142 return tlsv1_server_established(conn->server); 00143 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00144 return 0; 00145 } 00146 00147 00148 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) 00149 { 00150 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00151 if (conn->client) 00152 return tlsv1_client_shutdown(conn->client); 00153 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00154 #ifdef CONFIG_TLS_INTERNAL_SERVER 00155 if (conn->server) 00156 return tlsv1_server_shutdown(conn->server); 00157 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00158 return -1; 00159 } 00160 00161 00162 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 00163 const struct tls_connection_params *params) 00164 { 00165 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00166 struct tlsv1_credentials *cred; 00167 00168 if (conn->client == NULL) 00169 return -1; 00170 00171 cred = tlsv1_cred_alloc(); 00172 if (cred == NULL) 00173 return -1; 00174 00175 if (tlsv1_set_ca_cert(cred, params->ca_cert, 00176 params->ca_cert_blob, params->ca_cert_blob_len, 00177 params->ca_path)) { 00178 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 00179 "certificates"); 00180 tlsv1_cred_free(cred); 00181 return -1; 00182 } 00183 00184 if (tlsv1_set_cert(cred, params->client_cert, 00185 params->client_cert_blob, 00186 params->client_cert_blob_len)) { 00187 wpa_printf(MSG_INFO, "TLS: Failed to configure client " 00188 "certificate"); 00189 tlsv1_cred_free(cred); 00190 return -1; 00191 } 00192 00193 if (tlsv1_set_private_key(cred, params->private_key, 00194 params->private_key_passwd, 00195 params->private_key_blob, 00196 params->private_key_blob_len)) { 00197 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 00198 tlsv1_cred_free(cred); 00199 return -1; 00200 } 00201 00202 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 00203 params->dh_blob_len)) { 00204 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 00205 tlsv1_cred_free(cred); 00206 return -1; 00207 } 00208 00209 if (tlsv1_client_set_cred(conn->client, cred) < 0) { 00210 tlsv1_cred_free(cred); 00211 return -1; 00212 } 00213 00214 return 0; 00215 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 00216 return -1; 00217 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00218 } 00219 00220 00221 int tls_global_set_params(void *tls_ctx, 00222 const struct tls_connection_params *params) 00223 { 00224 #ifdef CONFIG_TLS_INTERNAL_SERVER 00225 struct tls_global *global = tls_ctx; 00226 struct tlsv1_credentials *cred; 00227 00228 /* Currently, global parameters are only set when running in server 00229 * mode. */ 00230 global->server = 1; 00231 tlsv1_cred_free(global->server_cred); 00232 global->server_cred = cred = tlsv1_cred_alloc(); 00233 if (cred == NULL) 00234 return -1; 00235 00236 if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, 00237 params->ca_cert_blob_len, params->ca_path)) { 00238 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 00239 "certificates"); 00240 return -1; 00241 } 00242 00243 if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob, 00244 params->client_cert_blob_len)) { 00245 wpa_printf(MSG_INFO, "TLS: Failed to configure server " 00246 "certificate"); 00247 return -1; 00248 } 00249 00250 if (tlsv1_set_private_key(cred, params->private_key, 00251 params->private_key_passwd, 00252 params->private_key_blob, 00253 params->private_key_blob_len)) { 00254 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 00255 return -1; 00256 } 00257 00258 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 00259 params->dh_blob_len)) { 00260 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 00261 return -1; 00262 } 00263 00264 return 0; 00265 #else /* CONFIG_TLS_INTERNAL_SERVER */ 00266 return -1; 00267 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00268 } 00269 00270 00271 int tls_global_set_verify(void *tls_ctx, int check_crl) 00272 { 00273 struct tls_global *global = tls_ctx; 00274 global->check_crl = check_crl; 00275 return 0; 00276 } 00277 00278 00279 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, 00280 int verify_peer) 00281 { 00282 #ifdef CONFIG_TLS_INTERNAL_SERVER 00283 if (conn->server) 00284 return tlsv1_server_set_verify(conn->server, verify_peer); 00285 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00286 return -1; 00287 } 00288 00289 00290 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 00291 int tls_ia) 00292 { 00293 return -1; 00294 } 00295 00296 00297 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn, 00298 struct tls_keys *keys) 00299 { 00300 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00301 if (conn->client) 00302 return tlsv1_client_get_keys(conn->client, keys); 00303 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00304 #ifdef CONFIG_TLS_INTERNAL_SERVER 00305 if (conn->server) 00306 return tlsv1_server_get_keys(conn->server, keys); 00307 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00308 return -1; 00309 } 00310 00311 00312 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 00313 const char *label, int server_random_first, 00314 u8 *out, size_t out_len) 00315 { 00316 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00317 if (conn->client) { 00318 return tlsv1_client_prf(conn->client, label, 00319 server_random_first, 00320 out, out_len); 00321 } 00322 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00323 #ifdef CONFIG_TLS_INTERNAL_SERVER 00324 if (conn->server) { 00325 return tlsv1_server_prf(conn->server, label, 00326 server_random_first, 00327 out, out_len); 00328 } 00329 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00330 return -1; 00331 } 00332 00333 00334 struct wpabuf * tls_connection_handshake(void *tls_ctx, 00335 struct tls_connection *conn, 00336 const struct wpabuf *in_data, 00337 struct wpabuf **appl_data) 00338 { 00339 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00340 u8 *res, *ad; 00341 size_t res_len, ad_len; 00342 struct wpabuf *out; 00343 00344 if (conn->client == NULL) 00345 return NULL; 00346 00347 ad = NULL; 00348 res = tlsv1_client_handshake(conn->client, 00349 in_data ? wpabuf_head(in_data) : NULL, 00350 in_data ? wpabuf_len(in_data) : 0, 00351 &res_len, &ad, &ad_len); 00352 if (res == NULL) 00353 return NULL; 00354 out = wpabuf_alloc_ext_data(res, res_len); 00355 if (out == NULL) { 00356 os_free(res); 00357 os_free(ad); 00358 return NULL; 00359 } 00360 if (appl_data) { 00361 if (ad) { 00362 *appl_data = wpabuf_alloc_ext_data(ad, ad_len); 00363 if (*appl_data == NULL) 00364 os_free(ad); 00365 } else 00366 *appl_data = NULL; 00367 } else 00368 os_free(ad); 00369 00370 return out; 00371 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 00372 return NULL; 00373 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00374 } 00375 00376 00377 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 00378 struct tls_connection *conn, 00379 const struct wpabuf *in_data, 00380 struct wpabuf **appl_data) 00381 { 00382 #ifdef CONFIG_TLS_INTERNAL_SERVER 00383 u8 *res; 00384 size_t res_len; 00385 struct wpabuf *out; 00386 00387 if (conn->server == NULL) 00388 return NULL; 00389 00390 if (appl_data) 00391 *appl_data = NULL; 00392 00393 res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), 00394 wpabuf_len(in_data), &res_len); 00395 if (res == NULL && tlsv1_server_established(conn->server)) 00396 return wpabuf_alloc(0); 00397 if (res == NULL) 00398 return NULL; 00399 out = wpabuf_alloc_ext_data(res, res_len); 00400 if (out == NULL) { 00401 os_free(res); 00402 return NULL; 00403 } 00404 00405 return out; 00406 #else /* CONFIG_TLS_INTERNAL_SERVER */ 00407 return NULL; 00408 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00409 } 00410 00411 00412 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 00413 struct tls_connection *conn, 00414 const struct wpabuf *in_data) 00415 { 00416 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00417 if (conn->client) { 00418 struct wpabuf *buf; 00419 int res; 00420 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 00421 if (buf == NULL) 00422 return NULL; 00423 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), 00424 wpabuf_len(in_data), 00425 wpabuf_mhead(buf), 00426 wpabuf_size(buf)); 00427 if (res < 0) { 00428 wpabuf_free(buf); 00429 return NULL; 00430 } 00431 wpabuf_put(buf, res); 00432 return buf; 00433 } 00434 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00435 #ifdef CONFIG_TLS_INTERNAL_SERVER 00436 if (conn->server) { 00437 struct wpabuf *buf; 00438 int res; 00439 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 00440 if (buf == NULL) 00441 return NULL; 00442 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), 00443 wpabuf_len(in_data), 00444 wpabuf_mhead(buf), 00445 wpabuf_size(buf)); 00446 if (res < 0) { 00447 wpabuf_free(buf); 00448 return NULL; 00449 } 00450 wpabuf_put(buf, res); 00451 return buf; 00452 } 00453 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00454 return NULL; 00455 } 00456 00457 00458 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 00459 struct tls_connection *conn, 00460 const struct wpabuf *in_data) 00461 { 00462 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00463 if (conn->client) { 00464 struct wpabuf *buf; 00465 int res; 00466 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 00467 if (buf == NULL) 00468 return NULL; 00469 res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), 00470 wpabuf_len(in_data), 00471 wpabuf_mhead(buf), 00472 wpabuf_size(buf)); 00473 if (res < 0) { 00474 wpabuf_free(buf); 00475 return NULL; 00476 } 00477 wpabuf_put(buf, res); 00478 return buf; 00479 } 00480 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00481 #ifdef CONFIG_TLS_INTERNAL_SERVER 00482 if (conn->server) { 00483 struct wpabuf *buf; 00484 int res; 00485 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 00486 if (buf == NULL) 00487 return NULL; 00488 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), 00489 wpabuf_len(in_data), 00490 wpabuf_mhead(buf), 00491 wpabuf_size(buf)); 00492 if (res < 0) { 00493 wpabuf_free(buf); 00494 return NULL; 00495 } 00496 wpabuf_put(buf, res); 00497 return buf; 00498 } 00499 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00500 return NULL; 00501 } 00502 00503 00504 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) 00505 { 00506 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00507 if (conn->client) 00508 return tlsv1_client_resumed(conn->client); 00509 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00510 #ifdef CONFIG_TLS_INTERNAL_SERVER 00511 if (conn->server) 00512 return tlsv1_server_resumed(conn->server); 00513 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00514 return -1; 00515 } 00516 00517 00518 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 00519 u8 *ciphers) 00520 { 00521 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00522 if (conn->client) 00523 return tlsv1_client_set_cipher_list(conn->client, ciphers); 00524 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00525 #ifdef CONFIG_TLS_INTERNAL_SERVER 00526 if (conn->server) 00527 return tlsv1_server_set_cipher_list(conn->server, ciphers); 00528 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00529 return -1; 00530 } 00531 00532 00533 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, 00534 char *buf, size_t buflen) 00535 { 00536 if (conn == NULL) 00537 return -1; 00538 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00539 if (conn->client) 00540 return tlsv1_client_get_cipher(conn->client, buf, buflen); 00541 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00542 #ifdef CONFIG_TLS_INTERNAL_SERVER 00543 if (conn->server) 00544 return tlsv1_server_get_cipher(conn->server, buf, buflen); 00545 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00546 return -1; 00547 } 00548 00549 00550 int tls_connection_enable_workaround(void *tls_ctx, 00551 struct tls_connection *conn) 00552 { 00553 return -1; 00554 } 00555 00556 00557 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, 00558 int ext_type, const u8 *data, 00559 size_t data_len) 00560 { 00561 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00562 if (conn->client) { 00563 return tlsv1_client_hello_ext(conn->client, ext_type, 00564 data, data_len); 00565 } 00566 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00567 return -1; 00568 } 00569 00570 00571 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 00572 { 00573 return 0; 00574 } 00575 00576 00577 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 00578 { 00579 return 0; 00580 } 00581 00582 00583 int tls_connection_get_write_alerts(void *tls_ctx, 00584 struct tls_connection *conn) 00585 { 00586 return 0; 00587 } 00588 00589 00590 int tls_connection_get_keyblock_size(void *tls_ctx, 00591 struct tls_connection *conn) 00592 { 00593 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00594 if (conn->client) 00595 return tlsv1_client_get_keyblock_size(conn->client); 00596 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00597 #ifdef CONFIG_TLS_INTERNAL_SERVER 00598 if (conn->server) 00599 return tlsv1_server_get_keyblock_size(conn->server); 00600 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00601 return -1; 00602 } 00603 00604 00605 unsigned int tls_capabilities(void *tls_ctx) 00606 { 00607 return 0; 00608 } 00609 00610 00611 struct wpabuf * tls_connection_ia_send_phase_finished( 00612 void *tls_ctx, struct tls_connection *conn, int final) 00613 { 00614 return NULL; 00615 } 00616 00617 00618 int tls_connection_ia_final_phase_finished(void *tls_ctx, 00619 struct tls_connection *conn) 00620 { 00621 return -1; 00622 } 00623 00624 00625 int tls_connection_ia_permute_inner_secret(void *tls_ctx, 00626 struct tls_connection *conn, 00627 const u8 *key, size_t key_len) 00628 { 00629 return -1; 00630 } 00631 00632 00633 int tls_connection_set_session_ticket_cb(void *tls_ctx, 00634 struct tls_connection *conn, 00635 tls_session_ticket_cb cb, 00636 void *ctx) 00637 { 00638 #ifdef CONFIG_TLS_INTERNAL_CLIENT 00639 if (conn->client) { 00640 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); 00641 return 0; 00642 } 00643 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 00644 #ifdef CONFIG_TLS_INTERNAL_SERVER 00645 if (conn->server) { 00646 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); 00647 return 0; 00648 } 00649 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 00650 return -1; 00651 }