1/* 2 * WPA Supplicant / TLS interface functions and an internal TLS implementation 3 * Copyright (c) 2004-2007, Jouni Malinen <j@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 26static int tls_ref_count = 0; 27 28struct tls_global { 29 int server; 30 struct tlsv1_credentials *server_cred; 31 int check_crl; 32}; 33 34struct tls_connection { 35 struct tlsv1_client *client; 36 struct tlsv1_server *server; 37}; 38 39 40void * 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 63void 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 80int tls_get_errors(void *tls_ctx) 81{ 82 return 0; 83} 84 85 86struct 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 118void 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 134int 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 148int 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 162int 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 221int 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 271int 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 279int 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 290int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 291 int tls_ia) 292{ 293 return -1; 294} 295 296 297int 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 312int 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 334u8 * 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 356u8 * 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 380int 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 400int 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 420int 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 434int 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 449int 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 466int tls_connection_enable_workaround(void *tls_ctx, 467 struct tls_connection *conn) 468{ 469 return -1; 470} 471 472 473int 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 487int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 488{ 489 return 0; 490} 491 492 493int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 494{ 495 return 0; 496} 497 498 499int tls_connection_get_write_alerts(void *tls_ctx, 500 struct tls_connection *conn) 501{ 502 return 0; 503} 504 505 506int 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 521unsigned int tls_capabilities(void *tls_ctx) 522{ 523 return 0; 524} 525 526 527int 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 536int tls_connection_ia_final_phase_finished(void *tls_ctx, 537 struct tls_connection *conn) 538{ 539 return -1; 540} 541 542 543int 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 551int 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