tls_internal.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
1/* 2 * TLS interface functions and an internal TLS implementation 3 * Copyright (c) 2004-2009, 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 334struct wpabuf * tls_connection_handshake(void *tls_ctx, 335 struct tls_connection *conn, 336 const struct wpabuf *in_data, 337 struct wpabuf **appl_data) 338{ 339#ifdef CONFIG_TLS_INTERNAL_CLIENT 340 u8 *res, *ad; 341 size_t res_len, ad_len; 342 struct wpabuf *out; 343 344 if (conn->client == NULL) 345 return NULL; 346 347 ad = NULL; 348 res = tlsv1_client_handshake(conn->client, 349 in_data ? wpabuf_head(in_data) : NULL, 350 in_data ? wpabuf_len(in_data) : 0, 351 &res_len, &ad, &ad_len); 352 if (res == NULL) 353 return NULL; 354 out = wpabuf_alloc_ext_data(res, res_len); 355 if (out == NULL) { 356 os_free(res); 357 os_free(ad); 358 return NULL; 359 } 360 if (appl_data) { 361 if (ad) { 362 *appl_data = wpabuf_alloc_ext_data(ad, ad_len); 363 if (*appl_data == NULL) 364 os_free(ad); 365 } else 366 *appl_data = NULL; 367 } else 368 os_free(ad); 369 370 return out; 371#else /* CONFIG_TLS_INTERNAL_CLIENT */ 372 return NULL; 373#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 374} 375 376 377struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 378 struct tls_connection *conn, 379 const struct wpabuf *in_data, 380 struct wpabuf **appl_data) 381{ 382#ifdef CONFIG_TLS_INTERNAL_SERVER 383 u8 *res; 384 size_t res_len; 385 struct wpabuf *out; 386 387 if (conn->server == NULL) 388 return NULL; 389 390 if (appl_data) 391 *appl_data = NULL; 392 393 res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), 394 wpabuf_len(in_data), &res_len); 395 if (res == NULL && tlsv1_server_established(conn->server)) 396 return wpabuf_alloc(0); 397 if (res == NULL) 398 return NULL; 399 out = wpabuf_alloc_ext_data(res, res_len); 400 if (out == NULL) { 401 os_free(res); 402 return NULL; 403 } 404 405 return out; 406#else /* CONFIG_TLS_INTERNAL_SERVER */ 407 return NULL; 408#endif /* CONFIG_TLS_INTERNAL_SERVER */ 409} 410 411 412struct wpabuf * tls_connection_encrypt(void *tls_ctx, 413 struct tls_connection *conn, 414 const struct wpabuf *in_data) 415{ 416#ifdef CONFIG_TLS_INTERNAL_CLIENT 417 if (conn->client) { 418 struct wpabuf *buf; 419 int res; 420 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 421 if (buf == NULL) 422 return NULL; 423 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), 424 wpabuf_len(in_data), 425 wpabuf_mhead(buf), 426 wpabuf_size(buf)); 427 if (res < 0) { 428 wpabuf_free(buf); 429 return NULL; 430 } 431 wpabuf_put(buf, res); 432 return buf; 433 } 434#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 435#ifdef CONFIG_TLS_INTERNAL_SERVER 436 if (conn->server) { 437 struct wpabuf *buf; 438 int res; 439 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 440 if (buf == NULL) 441 return NULL; 442 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), 443 wpabuf_len(in_data), 444 wpabuf_mhead(buf), 445 wpabuf_size(buf)); 446 if (res < 0) { 447 wpabuf_free(buf); 448 return NULL; 449 } 450 wpabuf_put(buf, res); 451 return buf; 452 } 453#endif /* CONFIG_TLS_INTERNAL_SERVER */ 454 return NULL; 455} 456 457 458struct wpabuf * tls_connection_decrypt(void *tls_ctx, 459 struct tls_connection *conn, 460 const struct wpabuf *in_data) 461{ 462#ifdef CONFIG_TLS_INTERNAL_CLIENT 463 if (conn->client) { 464 struct wpabuf *buf; 465 int res; 466 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 467 if (buf == NULL) 468 return NULL; 469 res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), 470 wpabuf_len(in_data), 471 wpabuf_mhead(buf), 472 wpabuf_size(buf)); 473 if (res < 0) { 474 wpabuf_free(buf); 475 return NULL; 476 } 477 wpabuf_put(buf, res); 478 return buf; 479 } 480#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 481#ifdef CONFIG_TLS_INTERNAL_SERVER 482 if (conn->server) { 483 struct wpabuf *buf; 484 int res; 485 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 486 if (buf == NULL) 487 return NULL; 488 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), 489 wpabuf_len(in_data), 490 wpabuf_mhead(buf), 491 wpabuf_size(buf)); 492 if (res < 0) { 493 wpabuf_free(buf); 494 return NULL; 495 } 496 wpabuf_put(buf, res); 497 return buf; 498 } 499#endif /* CONFIG_TLS_INTERNAL_SERVER */ 500 return NULL; 501} 502 503 504int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) 505{ 506#ifdef CONFIG_TLS_INTERNAL_CLIENT 507 if (conn->client) 508 return tlsv1_client_resumed(conn->client); 509#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 510#ifdef CONFIG_TLS_INTERNAL_SERVER 511 if (conn->server) 512 return tlsv1_server_resumed(conn->server); 513#endif /* CONFIG_TLS_INTERNAL_SERVER */ 514 return -1; 515} 516 517 518int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 519 u8 *ciphers) 520{ 521#ifdef CONFIG_TLS_INTERNAL_CLIENT 522 if (conn->client) 523 return tlsv1_client_set_cipher_list(conn->client, ciphers); 524#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 525#ifdef CONFIG_TLS_INTERNAL_SERVER 526 if (conn->server) 527 return tlsv1_server_set_cipher_list(conn->server, ciphers); 528#endif /* CONFIG_TLS_INTERNAL_SERVER */ 529 return -1; 530} 531 532 533int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, 534 char *buf, size_t buflen) 535{ 536 if (conn == NULL) 537 return -1; 538#ifdef CONFIG_TLS_INTERNAL_CLIENT 539 if (conn->client) 540 return tlsv1_client_get_cipher(conn->client, buf, buflen); 541#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 542#ifdef CONFIG_TLS_INTERNAL_SERVER 543 if (conn->server) 544 return tlsv1_server_get_cipher(conn->server, buf, buflen); 545#endif /* CONFIG_TLS_INTERNAL_SERVER */ 546 return -1; 547} 548 549 550int tls_connection_enable_workaround(void *tls_ctx, 551 struct tls_connection *conn) 552{ 553 return -1; 554} 555 556 557int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, 558 int ext_type, const u8 *data, 559 size_t data_len) 560{ 561#ifdef CONFIG_TLS_INTERNAL_CLIENT 562 if (conn->client) { 563 return tlsv1_client_hello_ext(conn->client, ext_type, 564 data, data_len); 565 } 566#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 567 return -1; 568} 569 570 571int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 572{ 573 return 0; 574} 575 576 577int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 578{ 579 return 0; 580} 581 582 583int tls_connection_get_write_alerts(void *tls_ctx, 584 struct tls_connection *conn) 585{ 586 return 0; 587} 588 589 590int tls_connection_get_keyblock_size(void *tls_ctx, 591 struct tls_connection *conn) 592{ 593#ifdef CONFIG_TLS_INTERNAL_CLIENT 594 if (conn->client) 595 return tlsv1_client_get_keyblock_size(conn->client); 596#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 597#ifdef CONFIG_TLS_INTERNAL_SERVER 598 if (conn->server) 599 return tlsv1_server_get_keyblock_size(conn->server); 600#endif /* CONFIG_TLS_INTERNAL_SERVER */ 601 return -1; 602} 603 604 605unsigned int tls_capabilities(void *tls_ctx) 606{ 607 return 0; 608} 609 610 611struct wpabuf * tls_connection_ia_send_phase_finished( 612 void *tls_ctx, struct tls_connection *conn, int final) 613{ 614 return NULL; 615} 616 617 618int tls_connection_ia_final_phase_finished(void *tls_ctx, 619 struct tls_connection *conn) 620{ 621 return -1; 622} 623 624 625int tls_connection_ia_permute_inner_secret(void *tls_ctx, 626 struct tls_connection *conn, 627 const u8 *key, size_t key_len) 628{ 629 return -1; 630} 631 632 633int tls_connection_set_session_ticket_cb(void *tls_ctx, 634 struct tls_connection *conn, 635 tls_session_ticket_cb cb, 636 void *ctx) 637{ 638#ifdef CONFIG_TLS_INTERNAL_CLIENT 639 if (conn->client) { 640 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); 641 return 0; 642 } 643#endif /* CONFIG_TLS_INTERNAL_CLIENT */ 644#ifdef CONFIG_TLS_INTERNAL_SERVER 645 if (conn->server) { 646 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); 647 return 0; 648 } 649#endif /* CONFIG_TLS_INTERNAL_SERVER */ 650 return -1; 651} 652