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 }; 32 33 34 void * tls_init(const struct tls_config *conf) 35 { 36 struct tls_global *global; 37 38 if (tls_ref_count == 0) { 39 #ifdef CONFIG_TLS_INTERNAL_CLIENT 40 if (tlsv1_client_global_init()) 41 return NULL; 42 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 43 #ifdef CONFIG_TLS_INTERNAL_SERVER 44 if (tlsv1_server_global_init()) 45 return NULL; 46 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 47 } 48 tls_ref_count++; 49 50 global = os_zalloc(sizeof(*global)); 51 if (global == NULL) 52 return NULL; 53 54 return global; 55 } 56 57 void tls_deinit(void *ssl_ctx) 58 { 59 struct tls_global *global = ssl_ctx; 60 tls_ref_count--; 61 if (tls_ref_count == 0) { 62 #ifdef CONFIG_TLS_INTERNAL_CLIENT 63 tlsv1_client_global_deinit(); 64 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 65 #ifdef CONFIG_TLS_INTERNAL_SERVER 66 tlsv1_cred_free(global->server_cred); 67 tlsv1_server_global_deinit(); 68 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 69 } 70 os_free(global); 71 } 72 73 74 int tls_get_errors(void *tls_ctx) 75 { 76 return 0; 77 } 78 79 80 struct tls_connection * tls_connection_init(void *tls_ctx) 81 { 82 struct tls_connection *conn; 83 struct tls_global *global = tls_ctx; 84 85 conn = os_zalloc(sizeof(*conn)); 86 if (conn == NULL) 87 return NULL; 88 89 #ifdef CONFIG_TLS_INTERNAL_CLIENT 90 if (!global->server) { 91 conn->client = tlsv1_client_init(); 92 if (conn->client == NULL) { 93 os_free(conn); 94 return NULL; 95 } 96 } 97 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 98 #ifdef CONFIG_TLS_INTERNAL_SERVER 99 if (global->server) { 100 conn->server = tlsv1_server_init(global->server_cred); 101 if (conn->server == NULL) { 102 os_free(conn); 103 return NULL; 104 } 105 } 106 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 107 108 return conn; 109 } 110 111 112 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) 113 { 114 if (conn == NULL) 115 return; 116 #ifdef CONFIG_TLS_INTERNAL_CLIENT 117 if (conn->client) 118 tlsv1_client_deinit(conn->client); 119 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 120 #ifdef CONFIG_TLS_INTERNAL_SERVER 121 if (conn->server) 122 tlsv1_server_deinit(conn->server); 123 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 124 os_free(conn); 125 } 126 127 128 int tls_connection_established(void *tls_ctx, struct tls_connection *conn) 129 { 130 #ifdef CONFIG_TLS_INTERNAL_CLIENT 131 if (conn->client) 132 return tlsv1_client_established(conn->client); 133 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 134 #ifdef CONFIG_TLS_INTERNAL_SERVER 135 if (conn->server) 136 return tlsv1_server_established(conn->server); 137 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 138 return 0; 139 } 140 141 142 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) 143 { 144 #ifdef CONFIG_TLS_INTERNAL_CLIENT 145 if (conn->client) 146 return tlsv1_client_shutdown(conn->client); 147 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 148 #ifdef CONFIG_TLS_INTERNAL_SERVER 149 if (conn->server) 150 return tlsv1_server_shutdown(conn->server); 151 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 152 return -1; 153 } 154 155 156 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 157 const struct tls_connection_params *params) 158 { 159 #ifdef CONFIG_TLS_INTERNAL_CLIENT 160 struct tlsv1_credentials *cred; 161 162 if (conn->client == NULL) 163 return -1; 164 165 cred = tlsv1_cred_alloc(); 166 if (cred == NULL) 167 return -1; 168 169 if (tlsv1_set_ca_cert(cred, params->ca_cert, 170 params->ca_cert_blob, params->ca_cert_blob_len, 171 params->ca_path)) { 172 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 173 "certificates"); 174 tlsv1_cred_free(cred); 175 return -1; 176 } 177 178 if (tlsv1_set_cert(cred, params->client_cert, 179 params->client_cert_blob, 180 params->client_cert_blob_len)) { 181 wpa_printf(MSG_INFO, "TLS: Failed to configure client " 182 "certificate"); 183 tlsv1_cred_free(cred); 184 return -1; 185 } 186 187 if (tlsv1_set_private_key(cred, params->private_key, 188 params->private_key_passwd, 189 params->private_key_blob, 190 params->private_key_blob_len)) { 191 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 192 tlsv1_cred_free(cred); 193 return -1; 194 } 195 196 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 197 params->dh_blob_len)) { 198 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 199 tlsv1_cred_free(cred); 200 return -1; 201 } 202 203 if (tlsv1_client_set_cred(conn->client, cred) < 0) { 204 tlsv1_cred_free(cred); 205 return -1; 206 } 207 208 tlsv1_client_set_time_checks( 209 conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS)); 210 211 return 0; 212 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 213 return -1; 214 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 215 } 216 217 218 int tls_global_set_params(void *tls_ctx, 219 const struct tls_connection_params *params) 220 { 221 #ifdef CONFIG_TLS_INTERNAL_SERVER 222 struct tls_global *global = tls_ctx; 223 struct tlsv1_credentials *cred; 224 225 /* Currently, global parameters are only set when running in server 226 * mode. */ 227 global->server = 1; 228 tlsv1_cred_free(global->server_cred); 229 global->server_cred = cred = tlsv1_cred_alloc(); 230 if (cred == NULL) 231 return -1; 232 233 if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, 234 params->ca_cert_blob_len, params->ca_path)) { 235 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " 236 "certificates"); 237 return -1; 238 } 239 240 if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob, 241 params->client_cert_blob_len)) { 242 wpa_printf(MSG_INFO, "TLS: Failed to configure server " 243 "certificate"); 244 return -1; 245 } 246 247 if (tlsv1_set_private_key(cred, params->private_key, 248 params->private_key_passwd, 249 params->private_key_blob, 250 params->private_key_blob_len)) { 251 wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 252 return -1; 253 } 254 255 if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, 256 params->dh_blob_len)) { 257 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); 258 return -1; 259 } 260 261 return 0; 262 #else /* CONFIG_TLS_INTERNAL_SERVER */ 263 return -1; 264 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 265 } 266 267 268 int tls_global_set_verify(void *tls_ctx, int check_crl) 269 { 270 struct tls_global *global = tls_ctx; 271 global->check_crl = check_crl; 272 return 0; 273 } 274 275 276 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, 277 int verify_peer) 278 { 279 #ifdef CONFIG_TLS_INTERNAL_SERVER 280 if (conn->server) 281 return tlsv1_server_set_verify(conn->server, verify_peer); 282 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 283 return -1; 284 } 285 286 287 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn, 288 struct tls_keys *keys) 289 { 290 #ifdef CONFIG_TLS_INTERNAL_CLIENT 291 if (conn->client) 292 return tlsv1_client_get_keys(conn->client, keys); 293 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 294 #ifdef CONFIG_TLS_INTERNAL_SERVER 295 if (conn->server) 296 return tlsv1_server_get_keys(conn->server, keys); 297 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 298 return -1; 299 } 300 301 302 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 303 const char *label, int server_random_first, 304 u8 *out, size_t out_len) 305 { 306 #ifdef CONFIG_TLS_INTERNAL_CLIENT 307 if (conn->client) { 308 return tlsv1_client_prf(conn->client, label, 309 server_random_first, 310 out, out_len); 311 } 312 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 313 #ifdef CONFIG_TLS_INTERNAL_SERVER 314 if (conn->server) { 315 return tlsv1_server_prf(conn->server, label, 316 server_random_first, 317 out, out_len); 318 } 319 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 320 return -1; 321 } 322 323 324 struct wpabuf * tls_connection_handshake(void *tls_ctx, 325 struct tls_connection *conn, 326 const struct wpabuf *in_data, 327 struct wpabuf **appl_data) 328 { 329 return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data, 330 NULL); 331 } 332 333 334 struct wpabuf * tls_connection_handshake2(void *tls_ctx, 335 struct tls_connection *conn, 336 const struct wpabuf *in_data, 337 struct wpabuf **appl_data, 338 int *need_more_data) 339 { 340 #ifdef CONFIG_TLS_INTERNAL_CLIENT 341 u8 *res, *ad; 342 size_t res_len, ad_len; 343 struct wpabuf *out; 344 345 if (conn->client == NULL) 346 return NULL; 347 348 ad = NULL; 349 res = tlsv1_client_handshake(conn->client, 350 in_data ? wpabuf_head(in_data) : NULL, 351 in_data ? wpabuf_len(in_data) : 0, 352 &res_len, &ad, &ad_len, need_more_data); 353 if (res == NULL) 354 return NULL; 355 out = wpabuf_alloc_ext_data(res, res_len); 356 if (out == NULL) { 357 os_free(res); 358 os_free(ad); 359 return NULL; 360 } 361 if (appl_data) { 362 if (ad) { 363 *appl_data = wpabuf_alloc_ext_data(ad, ad_len); 364 if (*appl_data == NULL) 365 os_free(ad); 366 } else 367 *appl_data = NULL; 368 } else 369 os_free(ad); 370 371 return out; 372 #else /* CONFIG_TLS_INTERNAL_CLIENT */ 373 return NULL; 374 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 375 } 376 377 378 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 379 struct tls_connection *conn, 380 const struct wpabuf *in_data, 381 struct wpabuf **appl_data) 382 { 383 #ifdef CONFIG_TLS_INTERNAL_SERVER 384 u8 *res; 385 size_t res_len; 386 struct wpabuf *out; 387 388 if (conn->server == NULL) 389 return NULL; 390 391 if (appl_data) 392 *appl_data = NULL; 393 394 res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), 395 wpabuf_len(in_data), &res_len); 396 if (res == NULL && tlsv1_server_established(conn->server)) 397 return wpabuf_alloc(0); 398 if (res == NULL) 399 return NULL; 400 out = wpabuf_alloc_ext_data(res, res_len); 401 if (out == NULL) { 402 os_free(res); 403 return NULL; 404 } 405 406 return out; 407 #else /* CONFIG_TLS_INTERNAL_SERVER */ 408 return NULL; 409 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 410 } 411 412 413 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 414 struct tls_connection *conn, 415 const struct wpabuf *in_data) 416 { 417 #ifdef CONFIG_TLS_INTERNAL_CLIENT 418 if (conn->client) { 419 struct wpabuf *buf; 420 int res; 421 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 422 if (buf == NULL) 423 return NULL; 424 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), 425 wpabuf_len(in_data), 426 wpabuf_mhead(buf), 427 wpabuf_size(buf)); 428 if (res < 0) { 429 wpabuf_free(buf); 430 return NULL; 431 } 432 wpabuf_put(buf, res); 433 return buf; 434 } 435 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 436 #ifdef CONFIG_TLS_INTERNAL_SERVER 437 if (conn->server) { 438 struct wpabuf *buf; 439 int res; 440 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 441 if (buf == NULL) 442 return NULL; 443 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), 444 wpabuf_len(in_data), 445 wpabuf_mhead(buf), 446 wpabuf_size(buf)); 447 if (res < 0) { 448 wpabuf_free(buf); 449 return NULL; 450 } 451 wpabuf_put(buf, res); 452 return buf; 453 } 454 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 455 return NULL; 456 } 457 458 459 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 460 struct tls_connection *conn, 461 const struct wpabuf *in_data) 462 { 463 return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL); 464 } 465 466 467 struct wpabuf * tls_connection_decrypt2(void *tls_ctx, 468 struct tls_connection *conn, 469 const struct wpabuf *in_data, 470 int *need_more_data) 471 { 472 if (need_more_data) 473 *need_more_data = 0; 474 475 #ifdef CONFIG_TLS_INTERNAL_CLIENT 476 if (conn->client) { 477 return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), 478 wpabuf_len(in_data), 479 need_more_data); 480 } 481 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 482 #ifdef CONFIG_TLS_INTERNAL_SERVER 483 if (conn->server) { 484 struct wpabuf *buf; 485 int res; 486 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 487 if (buf == NULL) 488 return NULL; 489 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), 490 wpabuf_len(in_data), 491 wpabuf_mhead(buf), 492 wpabuf_size(buf)); 493 if (res < 0) { 494 wpabuf_free(buf); 495 return NULL; 496 } 497 wpabuf_put(buf, res); 498 return buf; 499 } 500 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 501 return NULL; 502 } 503 504 505 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) 506 { 507 #ifdef CONFIG_TLS_INTERNAL_CLIENT 508 if (conn->client) 509 return tlsv1_client_resumed(conn->client); 510 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 511 #ifdef CONFIG_TLS_INTERNAL_SERVER 512 if (conn->server) 513 return tlsv1_server_resumed(conn->server); 514 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 515 return -1; 516 } 517 518 519 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 520 u8 *ciphers) 521 { 522 #ifdef CONFIG_TLS_INTERNAL_CLIENT 523 if (conn->client) 524 return tlsv1_client_set_cipher_list(conn->client, ciphers); 525 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 526 #ifdef CONFIG_TLS_INTERNAL_SERVER 527 if (conn->server) 528 return tlsv1_server_set_cipher_list(conn->server, ciphers); 529 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 530 return -1; 531 } 532 533 534 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, 535 char *buf, size_t buflen) 536 { 537 if (conn == NULL) 538 return -1; 539 #ifdef CONFIG_TLS_INTERNAL_CLIENT 540 if (conn->client) 541 return tlsv1_client_get_cipher(conn->client, buf, buflen); 542 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 543 #ifdef CONFIG_TLS_INTERNAL_SERVER 544 if (conn->server) 545 return tlsv1_server_get_cipher(conn->server, buf, buflen); 546 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 547 return -1; 548 } 549 550 551 int tls_connection_enable_workaround(void *tls_ctx, 552 struct tls_connection *conn) 553 { 554 return -1; 555 } 556 557 558 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, 559 int ext_type, const u8 *data, 560 size_t data_len) 561 { 562 #ifdef CONFIG_TLS_INTERNAL_CLIENT 563 if (conn->client) { 564 return tlsv1_client_hello_ext(conn->client, ext_type, 565 data, data_len); 566 } 567 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 568 return -1; 569 } 570 571 572 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) 573 { 574 return 0; 575 } 576 577 578 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) 579 { 580 return 0; 581 } 582 583 584 int tls_connection_get_write_alerts(void *tls_ctx, 585 struct tls_connection *conn) 586 { 587 return 0; 588 } 589 590 591 int tls_connection_get_keyblock_size(void *tls_ctx, 592 struct tls_connection *conn) 593 { 594 #ifdef CONFIG_TLS_INTERNAL_CLIENT 595 if (conn->client) 596 return tlsv1_client_get_keyblock_size(conn->client); 597 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 598 #ifdef CONFIG_TLS_INTERNAL_SERVER 599 if (conn->server) 600 return tlsv1_server_get_keyblock_size(conn->server); 601 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 602 return -1; 603 } 604 605 606 unsigned int tls_capabilities(void *tls_ctx) 607 { 608 return 0; 609 } 610 611 612 int tls_connection_set_session_ticket_cb(void *tls_ctx, 613 struct tls_connection *conn, 614 tls_session_ticket_cb cb, 615 void *ctx) 616 { 617 #ifdef CONFIG_TLS_INTERNAL_CLIENT 618 if (conn->client) { 619 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); 620 return 0; 621 } 622 #endif /* CONFIG_TLS_INTERNAL_CLIENT */ 623 #ifdef CONFIG_TLS_INTERNAL_SERVER 624 if (conn->server) { 625 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); 626 return 0; 627 } 628 #endif /* CONFIG_TLS_INTERNAL_SERVER */ 629 return -1; 630 } 631