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