1 /* 2 * TLS interface functions and an internal TLS implementation 3 * Copyright (c) 2004-2011, 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 tlsv1_client_set_time_checks( 215 conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS)); 216 217 return 0; 218 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 219 return -1; 220 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 221 } 222 223 224 int tls_global_set_params(void *tls_ctx, 225 const struct tls_connection_params *params) 226 { 227 #ifdef CONFIG_TLS_INTERNAL_SERVER 228 struct tls_global *global = tls_ctx; 229 struct tlsv1_credentials *cred; 230 231 /* Currently, global parameters are only set when running in server 232 * mode. */ 233 global->server = 1; 234 tlsv1_cred_free(global->server_cred); 235 global->server_cred = cred = tlsv1_cred_alloc(); 236 if (cred == NULL) 237 return -1; 238 239 if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, 240 params->ca_cert_blob_len, params->ca_path)) { 241 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 242 "certificates"); 243 return -1; 244 } 245 246 if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob, 247 params->client_cert_blob_len)) { 248 wpa_printf(MSG_INFO, "TLS: Failed to configure server " 249 "certificate"); 250 return -1; 251 } 252 253 if (tlsv1_set_private_key(cred, params->private_key, 254 params->private_key_passwd, 255 params->private_key_blob, 256 params->private_key_blob_len)) { 257 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 258 return -1; 259 } 260 261 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 262 params->dh_blob_len)) { 263 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 264 return -1; 265 } 266 267 return 0; 268 #else /* CONFIG_TLS_INTERNAL_SERVER */ 269 return -1; 270 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 271 } 272 273 274 int tls_global_set_verify(void *tls_ctx, int check_crl) 275 { 276 struct tls_global *global = tls_ctx; 277 global->check_crl = check_crl; 278 return 0; 279 } 280 281 282 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, 283 int verify_peer) 284 { 285 #ifdef CONFIG_TLS_INTERNAL_SERVER 286 if (conn->server) 287 return tlsv1_server_set_verify(conn->server, verify_peer); 288 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 289 return -1; 290 } 291 292 293 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 294 int tls_ia) 295 { 296 return -1; 297 } 298 299 300 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn, 301 struct tls_keys *keys) 302 { 303 #ifdef CONFIG_TLS_INTERNAL_CLIENT 304 if (conn->client) 305 return tlsv1_client_get_keys(conn->client, keys); 306 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 307 #ifdef CONFIG_TLS_INTERNAL_SERVER 308 if (conn->server) 309 return tlsv1_server_get_keys(conn->server, keys); 310 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 311 return -1; 312 } 313 314 315 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 316 const char *label, int server_random_first, 317 u8 *out, size_t out_len) 318 { 319 #ifdef CONFIG_TLS_INTERNAL_CLIENT 320 if (conn->client) { 321 return tlsv1_client_prf(conn->client, label, 322 server_random_first, 323 out, out_len); 324 } 325 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 326 #ifdef CONFIG_TLS_INTERNAL_SERVER 327 if (conn->server) { 328 return tlsv1_server_prf(conn->server, label, 329 server_random_first, 330 out, out_len); 331 } 332 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 333 return -1; 334 } 335 336 337 struct wpabuf * tls_connection_handshake(void *tls_ctx, 338 struct tls_connection *conn, 339 const struct wpabuf *in_data, 340 struct wpabuf **appl_data) 341 { 342 #ifdef CONFIG_TLS_INTERNAL_CLIENT 343 u8 *res, *ad; 344 size_t res_len, ad_len; 345 struct wpabuf *out; 346 347 if (conn->client == NULL) 348 return NULL; 349 350 ad = NULL; 351 res = tlsv1_client_handshake(conn->client, 352 in_data ? wpabuf_head(in_data) : NULL, 353 in_data ? wpabuf_len(in_data) : 0, 354 &res_len, &ad, &ad_len); 355 if (res == NULL) 356 return NULL; 357 out = wpabuf_alloc_ext_data(res, res_len); 358 if (out == NULL) { 359 os_free(res); 360 os_free(ad); 361 return NULL; 362 } 363 if (appl_data) { 364 if (ad) { 365 *appl_data = wpabuf_alloc_ext_data(ad, ad_len); 366 if (*appl_data == NULL) 367 os_free(ad); 368 } else 369 *appl_data = NULL; 370 } else 371 os_free(ad); 372 373 return out; 374 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 375 return NULL; 376 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 377 } 378 379 380 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 381 struct tls_connection *conn, 382 const struct wpabuf *in_data, 383 struct wpabuf **appl_data) 384 { 385 #ifdef CONFIG_TLS_INTERNAL_SERVER 386 u8 *res; 387 size_t res_len; 388 struct wpabuf *out; 389 390 if (conn->server == NULL) 391 return NULL; 392 393 if (appl_data) 394 *appl_data = NULL; 395 396 res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), 397 wpabuf_len(in_data), &res_len); 398 if (res == NULL && tlsv1_server_established(conn->server)) 399 return wpabuf_alloc(0); 400 if (res == NULL) 401 return NULL; 402 out = wpabuf_alloc_ext_data(res, res_len); 403 if (out == NULL) { 404 os_free(res); 405 return NULL; 406 } 407 408 return out; 409 #else /* CONFIG_TLS_INTERNAL_SERVER */ 410 return NULL; 411 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 412 } 413 414 415 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 416 struct tls_connection *conn, 417 const struct wpabuf *in_data) 418 { 419 #ifdef CONFIG_TLS_INTERNAL_CLIENT 420 if (conn->client) { 421 struct wpabuf *buf; 422 int res; 423 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 424 if (buf == NULL) 425 return NULL; 426 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), 427 wpabuf_len(in_data), 428 wpabuf_mhead(buf), 429 wpabuf_size(buf)); 430 if (res < 0) { 431 wpabuf_free(buf); 432 return NULL; 433 } 434 wpabuf_put(buf, res); 435 return buf; 436 } 437 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 438 #ifdef CONFIG_TLS_INTERNAL_SERVER 439 if (conn->server) { 440 struct wpabuf *buf; 441 int res; 442 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 443 if (buf == NULL) 444 return NULL; 445 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), 446 wpabuf_len(in_data), 447 wpabuf_mhead(buf), 448 wpabuf_size(buf)); 449 if (res < 0) { 450 wpabuf_free(buf); 451 return NULL; 452 } 453 wpabuf_put(buf, res); 454 return buf; 455 } 456 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 457 return NULL; 458 } 459 460 461 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 462 struct tls_connection *conn, 463 const struct wpabuf *in_data) 464 { 465 #ifdef CONFIG_TLS_INTERNAL_CLIENT 466 if (conn->client) { 467 struct wpabuf *buf; 468 int res; 469 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 470 if (buf == NULL) 471 return NULL; 472 res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), 473 wpabuf_len(in_data), 474 wpabuf_mhead(buf), 475 wpabuf_size(buf)); 476 if (res < 0) { 477 wpabuf_free(buf); 478 return NULL; 479 } 480 wpabuf_put(buf, res); 481 return buf; 482 } 483 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 484 #ifdef CONFIG_TLS_INTERNAL_SERVER 485 if (conn->server) { 486 struct wpabuf *buf; 487 int res; 488 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 489 if (buf == NULL) 490 return NULL; 491 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), 492 wpabuf_len(in_data), 493 wpabuf_mhead(buf), 494 wpabuf_size(buf)); 495 if (res < 0) { 496 wpabuf_free(buf); 497 return NULL; 498 } 499 wpabuf_put(buf, res); 500 return buf; 501 } 502 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 503 return NULL; 504 } 505 506 507 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) 508 { 509 #ifdef CONFIG_TLS_INTERNAL_CLIENT 510 if (conn->client) 511 return tlsv1_client_resumed(conn->client); 512 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 513 #ifdef CONFIG_TLS_INTERNAL_SERVER 514 if (conn->server) 515 return tlsv1_server_resumed(conn->server); 516 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 517 return -1; 518 } 519 520 521 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 522 u8 *ciphers) 523 { 524 #ifdef CONFIG_TLS_INTERNAL_CLIENT 525 if (conn->client) 526 return tlsv1_client_set_cipher_list(conn->client, ciphers); 527 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 528 #ifdef CONFIG_TLS_INTERNAL_SERVER 529 if (conn->server) 530 return tlsv1_server_set_cipher_list(conn->server, ciphers); 531 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 532 return -1; 533 } 534 535 536 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, 537 char *buf, size_t buflen) 538 { 539 if (conn == NULL) 540 return -1; 541 #ifdef CONFIG_TLS_INTERNAL_CLIENT 542 if (conn->client) 543 return tlsv1_client_get_cipher(conn->client, buf, buflen); 544 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 545 #ifdef CONFIG_TLS_INTERNAL_SERVER 546 if (conn->server) 547 return tlsv1_server_get_cipher(conn->server, buf, buflen); 548 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 549 return -1; 550 } 551 552 553 int tls_connection_enable_workaround(void *tls_ctx, 554 struct tls_connection *conn) 555 { 556 return -1; 557 } 558 559 560 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, 561 int ext_type, const u8 *data, 562 size_t data_len) 563 { 564 #ifdef CONFIG_TLS_INTERNAL_CLIENT 565 if (conn->client) { 566 return tlsv1_client_hello_ext(conn->client, ext_type, 567 data, data_len); 568 } 569 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 570 return -1; 571 } 572 573 574 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 575 { 576 return 0; 577 } 578 579 580 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 581 { 582 return 0; 583 } 584 585 586 int tls_connection_get_write_alerts(void *tls_ctx, 587 struct tls_connection *conn) 588 { 589 return 0; 590 } 591 592 593 int tls_connection_get_keyblock_size(void *tls_ctx, 594 struct tls_connection *conn) 595 { 596 #ifdef CONFIG_TLS_INTERNAL_CLIENT 597 if (conn->client) 598 return tlsv1_client_get_keyblock_size(conn->client); 599 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 600 #ifdef CONFIG_TLS_INTERNAL_SERVER 601 if (conn->server) 602 return tlsv1_server_get_keyblock_size(conn->server); 603 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 604 return -1; 605 } 606 607 608 unsigned int tls_capabilities(void *tls_ctx) 609 { 610 return 0; 611 } 612 613 614 struct wpabuf * tls_connection_ia_send_phase_finished( 615 void *tls_ctx, struct tls_connection *conn, int final) 616 { 617 return NULL; 618 } 619 620 621 int tls_connection_ia_final_phase_finished(void *tls_ctx, 622 struct tls_connection *conn) 623 { 624 return -1; 625 } 626 627 628 int tls_connection_ia_permute_inner_secret(void *tls_ctx, 629 struct tls_connection *conn, 630 const u8 *key, size_t key_len) 631 { 632 return -1; 633 } 634 635 636 int tls_connection_set_session_ticket_cb(void *tls_ctx, 637 struct tls_connection *conn, 638 tls_session_ticket_cb cb, 639 void *ctx) 640 { 641 #ifdef CONFIG_TLS_INTERNAL_CLIENT 642 if (conn->client) { 643 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); 644 return 0; 645 } 646 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 647 #ifdef CONFIG_TLS_INTERNAL_SERVER 648 if (conn->server) { 649 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); 650 return 0; 651 } 652 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 653 return -1; 654 } 655