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