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