1 /* 2 * TLS interface functions and an internal TLS implementation 3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * This file interface functions for hostapd/wpa_supplicant to use the 9 * integrated TLSv1 implementation. 10 */ 11 12 #include "includes.h" 13 14 #include "common.h" 15 #include "tls.h" 16 #include "tls/tlsv1_client.h" 17 #include "tls/tlsv1_server.h" 18 19 20 static int tls_ref_count = 0; 21 22 struct tls_global { 23 int server; 24 struct tlsv1_credentials *server_cred; 25 int check_crl; 26 }; 27 28 struct tls_connection { 29 struct tlsv1_client *client; 30 struct tlsv1_server *server; 31 struct tls_global *global; 32 }; 33 34 35 void * tls_init(const struct tls_config *conf) 36 { 37 struct tls_global *global; 38 39 if (tls_ref_count == 0) { 40 #ifdef CONFIG_TLS_INTERNAL_CLIENT 41 if (tlsv1_client_global_init()) 42 return NULL; 43 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 44 #ifdef CONFIG_TLS_INTERNAL_SERVER 45 if (tlsv1_server_global_init()) 46 return NULL; 47 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 48 } 49 tls_ref_count++; 50 51 global = os_zalloc(sizeof(*global)); 52 if (global == NULL) 53 return NULL; 54 55 return global; 56 } 57 58 void tls_deinit(void *ssl_ctx) 59 { 60 struct tls_global *global = ssl_ctx; 61 tls_ref_count--; 62 if (tls_ref_count == 0) { 63 #ifdef CONFIG_TLS_INTERNAL_CLIENT 64 tlsv1_client_global_deinit(); 65 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 66 #ifdef CONFIG_TLS_INTERNAL_SERVER 67 tlsv1_cred_free(global->server_cred); 68 tlsv1_server_global_deinit(); 69 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 70 } 71 os_free(global); 72 } 73 74 75 int tls_get_errors(void *tls_ctx) 76 { 77 return 0; 78 } 79 80 81 struct tls_connection * tls_connection_init(void *tls_ctx) 82 { 83 struct tls_connection *conn; 84 struct tls_global *global = tls_ctx; 85 86 conn = os_zalloc(sizeof(*conn)); 87 if (conn == NULL) 88 return NULL; 89 conn->global = global; 90 91 #ifdef CONFIG_TLS_INTERNAL_CLIENT 92 if (!global->server) { 93 conn->client = tlsv1_client_init(); 94 if (conn->client == NULL) { 95 os_free(conn); 96 return NULL; 97 } 98 } 99 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 100 #ifdef CONFIG_TLS_INTERNAL_SERVER 101 if (global->server) { 102 conn->server = tlsv1_server_init(global->server_cred); 103 if (conn->server == NULL) { 104 os_free(conn); 105 return NULL; 106 } 107 } 108 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 109 110 return conn; 111 } 112 113 114 #ifdef CONFIG_TESTING_OPTIONS 115 #ifdef CONFIG_TLS_INTERNAL_SERVER 116 void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags) 117 { 118 if (conn->server) 119 tlsv1_server_set_test_flags(conn->server, flags); 120 } 121 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 122 #endif /* CONFIG_TESTING_OPTIONS */ 123 124 125 void tls_connection_set_log_cb(struct tls_connection *conn, 126 void (*log_cb)(void *ctx, const char *msg), 127 void *ctx) 128 { 129 #ifdef CONFIG_TLS_INTERNAL_SERVER 130 if (conn->server) 131 tlsv1_server_set_log_cb(conn->server, log_cb, ctx); 132 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 133 } 134 135 136 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) 137 { 138 if (conn == NULL) 139 return; 140 #ifdef CONFIG_TLS_INTERNAL_CLIENT 141 if (conn->client) 142 tlsv1_client_deinit(conn->client); 143 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 144 #ifdef CONFIG_TLS_INTERNAL_SERVER 145 if (conn->server) 146 tlsv1_server_deinit(conn->server); 147 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 148 os_free(conn); 149 } 150 151 152 int tls_connection_established(void *tls_ctx, struct tls_connection *conn) 153 { 154 #ifdef CONFIG_TLS_INTERNAL_CLIENT 155 if (conn->client) 156 return tlsv1_client_established(conn->client); 157 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 158 #ifdef CONFIG_TLS_INTERNAL_SERVER 159 if (conn->server) 160 return tlsv1_server_established(conn->server); 161 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 162 return 0; 163 } 164 165 166 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) 167 { 168 #ifdef CONFIG_TLS_INTERNAL_CLIENT 169 if (conn->client) 170 return tlsv1_client_shutdown(conn->client); 171 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 172 #ifdef CONFIG_TLS_INTERNAL_SERVER 173 if (conn->server) 174 return tlsv1_server_shutdown(conn->server); 175 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 176 return -1; 177 } 178 179 180 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 181 const struct tls_connection_params *params) 182 { 183 #ifdef CONFIG_TLS_INTERNAL_CLIENT 184 struct tlsv1_credentials *cred; 185 186 if (conn->client == NULL) 187 return -1; 188 189 cred = tlsv1_cred_alloc(); 190 if (cred == NULL) 191 return -1; 192 193 if (params->subject_match) { 194 wpa_printf(MSG_INFO, "TLS: subject_match not supported"); 195 tlsv1_cred_free(cred); 196 return -1; 197 } 198 199 if (params->altsubject_match) { 200 wpa_printf(MSG_INFO, "TLS: altsubject_match not supported"); 201 tlsv1_cred_free(cred); 202 return -1; 203 } 204 205 if (params->suffix_match) { 206 wpa_printf(MSG_INFO, "TLS: suffix_match not supported"); 207 tlsv1_cred_free(cred); 208 return -1; 209 } 210 211 if (params->domain_match) { 212 wpa_printf(MSG_INFO, "TLS: domain_match not supported"); 213 tlsv1_cred_free(cred); 214 return -1; 215 } 216 217 if (params->openssl_ciphers) { 218 wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported"); 219 tlsv1_cred_free(cred); 220 return -1; 221 } 222 223 if (tlsv1_set_ca_cert(cred, params->ca_cert, 224 params->ca_cert_blob, params->ca_cert_blob_len, 225 params->ca_path)) { 226 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 227 "certificates"); 228 tlsv1_cred_free(cred); 229 return -1; 230 } 231 232 if (tlsv1_set_cert(cred, params->client_cert, 233 params->client_cert_blob, 234 params->client_cert_blob_len)) { 235 wpa_printf(MSG_INFO, "TLS: Failed to configure client " 236 "certificate"); 237 tlsv1_cred_free(cred); 238 return -1; 239 } 240 241 if (tlsv1_set_private_key(cred, params->private_key, 242 params->private_key_passwd, 243 params->private_key_blob, 244 params->private_key_blob_len)) { 245 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 246 tlsv1_cred_free(cred); 247 return -1; 248 } 249 250 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 251 params->dh_blob_len)) { 252 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 253 tlsv1_cred_free(cred); 254 return -1; 255 } 256 257 if (tlsv1_client_set_cred(conn->client, cred) < 0) { 258 tlsv1_cred_free(cred); 259 return -1; 260 } 261 262 tlsv1_client_set_time_checks( 263 conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS)); 264 265 return 0; 266 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 267 return -1; 268 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 269 } 270 271 272 int tls_global_set_params(void *tls_ctx, 273 const struct tls_connection_params *params) 274 { 275 #ifdef CONFIG_TLS_INTERNAL_SERVER 276 struct tls_global *global = tls_ctx; 277 struct tlsv1_credentials *cred; 278 279 /* Currently, global parameters are only set when running in server 280 * mode. */ 281 global->server = 1; 282 tlsv1_cred_free(global->server_cred); 283 global->server_cred = cred = tlsv1_cred_alloc(); 284 if (cred == NULL) 285 return -1; 286 287 if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, 288 params->ca_cert_blob_len, params->ca_path)) { 289 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 290 "certificates"); 291 return -1; 292 } 293 294 if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob, 295 params->client_cert_blob_len)) { 296 wpa_printf(MSG_INFO, "TLS: Failed to configure server " 297 "certificate"); 298 return -1; 299 } 300 301 if (tlsv1_set_private_key(cred, params->private_key, 302 params->private_key_passwd, 303 params->private_key_blob, 304 params->private_key_blob_len)) { 305 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 306 return -1; 307 } 308 309 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 310 params->dh_blob_len)) { 311 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 312 return -1; 313 } 314 315 return 0; 316 #else /* CONFIG_TLS_INTERNAL_SERVER */ 317 return -1; 318 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 319 } 320 321 322 int tls_global_set_verify(void *tls_ctx, int check_crl) 323 { 324 struct tls_global *global = tls_ctx; 325 global->check_crl = check_crl; 326 return 0; 327 } 328 329 330 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, 331 int verify_peer, unsigned int flags, 332 const u8 *session_ctx, size_t session_ctx_len) 333 { 334 #ifdef CONFIG_TLS_INTERNAL_SERVER 335 if (conn->server) 336 return tlsv1_server_set_verify(conn->server, verify_peer); 337 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 338 return -1; 339 } 340 341 342 int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, 343 struct tls_random *data) 344 { 345 #ifdef CONFIG_TLS_INTERNAL_CLIENT 346 if (conn->client) 347 return tlsv1_client_get_random(conn->client, data); 348 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 349 #ifdef CONFIG_TLS_INTERNAL_SERVER 350 if (conn->server) 351 return tlsv1_server_get_random(conn->server, data); 352 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 353 return -1; 354 } 355 356 357 static int tls_get_keyblock_size(struct tls_connection *conn) 358 { 359 #ifdef CONFIG_TLS_INTERNAL_CLIENT 360 if (conn->client) 361 return tlsv1_client_get_keyblock_size(conn->client); 362 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 363 #ifdef CONFIG_TLS_INTERNAL_SERVER 364 if (conn->server) 365 return tlsv1_server_get_keyblock_size(conn->server); 366 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 367 return -1; 368 } 369 370 371 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 372 const char *label, int server_random_first, 373 int skip_keyblock, u8 *out, size_t out_len) 374 { 375 int ret = -1, skip = 0; 376 u8 *tmp_out = NULL; 377 u8 *_out = out; 378 379 if (skip_keyblock) { 380 skip = tls_get_keyblock_size(conn); 381 if (skip < 0) 382 return -1; 383 tmp_out = os_malloc(skip + out_len); 384 if (!tmp_out) 385 return -1; 386 _out = tmp_out; 387 } 388 389 #ifdef CONFIG_TLS_INTERNAL_CLIENT 390 if (conn->client) { 391 ret = tlsv1_client_prf(conn->client, label, 392 server_random_first, 393 _out, out_len); 394 } 395 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 396 #ifdef CONFIG_TLS_INTERNAL_SERVER 397 if (conn->server) { 398 ret = tlsv1_server_prf(conn->server, label, 399 server_random_first, 400 _out, out_len); 401 } 402 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 403 if (ret == 0 && skip_keyblock) 404 os_memcpy(out, _out + skip, out_len); 405 bin_clear_free(tmp_out, skip); 406 407 return ret; 408 } 409 410 411 struct wpabuf * tls_connection_handshake(void *tls_ctx, 412 struct tls_connection *conn, 413 const struct wpabuf *in_data, 414 struct wpabuf **appl_data) 415 { 416 return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data, 417 NULL); 418 } 419 420 421 struct wpabuf * tls_connection_handshake2(void *tls_ctx, 422 struct tls_connection *conn, 423 const struct wpabuf *in_data, 424 struct wpabuf **appl_data, 425 int *need_more_data) 426 { 427 #ifdef CONFIG_TLS_INTERNAL_CLIENT 428 u8 *res, *ad; 429 size_t res_len, ad_len; 430 struct wpabuf *out; 431 432 if (conn->client == NULL) 433 return NULL; 434 435 ad = NULL; 436 res = tlsv1_client_handshake(conn->client, 437 in_data ? wpabuf_head(in_data) : NULL, 438 in_data ? wpabuf_len(in_data) : 0, 439 &res_len, &ad, &ad_len, need_more_data); 440 if (res == NULL) 441 return NULL; 442 out = wpabuf_alloc_ext_data(res, res_len); 443 if (out == NULL) { 444 os_free(res); 445 os_free(ad); 446 return NULL; 447 } 448 if (appl_data) { 449 if (ad) { 450 *appl_data = wpabuf_alloc_ext_data(ad, ad_len); 451 if (*appl_data == NULL) 452 os_free(ad); 453 } else 454 *appl_data = NULL; 455 } else 456 os_free(ad); 457 458 return out; 459 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 460 return NULL; 461 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 462 } 463 464 465 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 466 struct tls_connection *conn, 467 const struct wpabuf *in_data, 468 struct wpabuf **appl_data) 469 { 470 #ifdef CONFIG_TLS_INTERNAL_SERVER 471 u8 *res; 472 size_t res_len; 473 struct wpabuf *out; 474 475 if (conn->server == NULL) 476 return NULL; 477 478 if (appl_data) 479 *appl_data = NULL; 480 481 res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), 482 wpabuf_len(in_data), &res_len); 483 if (res == NULL && tlsv1_server_established(conn->server)) 484 return wpabuf_alloc(0); 485 if (res == NULL) 486 return NULL; 487 out = wpabuf_alloc_ext_data(res, res_len); 488 if (out == NULL) { 489 os_free(res); 490 return NULL; 491 } 492 493 return out; 494 #else /* CONFIG_TLS_INTERNAL_SERVER */ 495 return NULL; 496 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 497 } 498 499 500 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 501 struct tls_connection *conn, 502 const struct wpabuf *in_data) 503 { 504 #ifdef CONFIG_TLS_INTERNAL_CLIENT 505 if (conn->client) { 506 struct wpabuf *buf; 507 int res; 508 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 509 if (buf == NULL) 510 return NULL; 511 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), 512 wpabuf_len(in_data), 513 wpabuf_mhead(buf), 514 wpabuf_size(buf)); 515 if (res < 0) { 516 wpabuf_free(buf); 517 return NULL; 518 } 519 wpabuf_put(buf, res); 520 return buf; 521 } 522 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 523 #ifdef CONFIG_TLS_INTERNAL_SERVER 524 if (conn->server) { 525 struct wpabuf *buf; 526 int res; 527 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 528 if (buf == NULL) 529 return NULL; 530 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), 531 wpabuf_len(in_data), 532 wpabuf_mhead(buf), 533 wpabuf_size(buf)); 534 if (res < 0) { 535 wpabuf_free(buf); 536 return NULL; 537 } 538 wpabuf_put(buf, res); 539 return buf; 540 } 541 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 542 return NULL; 543 } 544 545 546 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 547 struct tls_connection *conn, 548 const struct wpabuf *in_data) 549 { 550 return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL); 551 } 552 553 554 struct wpabuf * tls_connection_decrypt2(void *tls_ctx, 555 struct tls_connection *conn, 556 const struct wpabuf *in_data, 557 int *need_more_data) 558 { 559 if (need_more_data) 560 *need_more_data = 0; 561 562 #ifdef CONFIG_TLS_INTERNAL_CLIENT 563 if (conn->client) { 564 return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), 565 wpabuf_len(in_data), 566 need_more_data); 567 } 568 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 569 #ifdef CONFIG_TLS_INTERNAL_SERVER 570 if (conn->server) { 571 struct wpabuf *buf; 572 int res; 573 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 574 if (buf == NULL) 575 return NULL; 576 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), 577 wpabuf_len(in_data), 578 wpabuf_mhead(buf), 579 wpabuf_size(buf)); 580 if (res < 0) { 581 wpabuf_free(buf); 582 return NULL; 583 } 584 wpabuf_put(buf, res); 585 return buf; 586 } 587 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 588 return NULL; 589 } 590 591 592 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) 593 { 594 #ifdef CONFIG_TLS_INTERNAL_CLIENT 595 if (conn->client) 596 return tlsv1_client_resumed(conn->client); 597 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 598 #ifdef CONFIG_TLS_INTERNAL_SERVER 599 if (conn->server) 600 return tlsv1_server_resumed(conn->server); 601 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 602 return -1; 603 } 604 605 606 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 607 u8 *ciphers) 608 { 609 #ifdef CONFIG_TLS_INTERNAL_CLIENT 610 if (conn->client) 611 return tlsv1_client_set_cipher_list(conn->client, ciphers); 612 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 613 #ifdef CONFIG_TLS_INTERNAL_SERVER 614 if (conn->server) 615 return tlsv1_server_set_cipher_list(conn->server, ciphers); 616 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 617 return -1; 618 } 619 620 621 int tls_get_version(void *ssl_ctx, struct tls_connection *conn, 622 char *buf, size_t buflen) 623 { 624 /* TODO */ 625 return -1; 626 } 627 628 629 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, 630 char *buf, size_t buflen) 631 { 632 if (conn == NULL) 633 return -1; 634 #ifdef CONFIG_TLS_INTERNAL_CLIENT 635 if (conn->client) 636 return tlsv1_client_get_cipher(conn->client, buf, buflen); 637 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 638 #ifdef CONFIG_TLS_INTERNAL_SERVER 639 if (conn->server) 640 return tlsv1_server_get_cipher(conn->server, buf, buflen); 641 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 642 return -1; 643 } 644 645 646 int tls_connection_enable_workaround(void *tls_ctx, 647 struct tls_connection *conn) 648 { 649 return -1; 650 } 651 652 653 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, 654 int ext_type, const u8 *data, 655 size_t data_len) 656 { 657 #ifdef CONFIG_TLS_INTERNAL_CLIENT 658 if (conn->client) { 659 return tlsv1_client_hello_ext(conn->client, ext_type, 660 data, data_len); 661 } 662 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 663 return -1; 664 } 665 666 667 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 668 { 669 return 0; 670 } 671 672 673 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 674 { 675 return 0; 676 } 677 678 679 int tls_connection_get_write_alerts(void *tls_ctx, 680 struct tls_connection *conn) 681 { 682 return 0; 683 } 684 685 686 int tls_connection_set_session_ticket_cb(void *tls_ctx, 687 struct tls_connection *conn, 688 tls_session_ticket_cb cb, 689 void *ctx) 690 { 691 #ifdef CONFIG_TLS_INTERNAL_CLIENT 692 if (conn->client) { 693 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); 694 return 0; 695 } 696 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 697 #ifdef CONFIG_TLS_INTERNAL_SERVER 698 if (conn->server) { 699 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); 700 return 0; 701 } 702 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 703 return -1; 704 } 705 706 707 int tls_get_library_version(char *buf, size_t buf_len) 708 { 709 return os_snprintf(buf, buf_len, "internal"); 710 } 711 712 713 void tls_connection_set_success_data(struct tls_connection *conn, 714 struct wpabuf *data) 715 { 716 } 717 718 719 void tls_connection_set_success_data_resumed(struct tls_connection *conn) 720 { 721 } 722 723 724 const struct wpabuf * 725 tls_connection_get_success_data(struct tls_connection *conn) 726 { 727 return NULL; 728 } 729 730 731 void tls_connection_remove_session(struct tls_connection *conn) 732 { 733 } 734