1 /* 2 * SSL/TLS interface functions for GnuTLS 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 9 #include "includes.h" 10 #include <gnutls/gnutls.h> 11 #include <gnutls/x509.h> 12 #ifdef PKCS12_FUNCS 13 #include <gnutls/pkcs12.h> 14 #endif /* PKCS12_FUNCS */ 15 #if GNUTLS_VERSION_NUMBER >= 0x030103 16 #include <gnutls/ocsp.h> 17 #endif /* 3.1.3 */ 18 19 #include "common.h" 20 #include "crypto/crypto.h" 21 #include "tls.h" 22 23 24 static int tls_gnutls_ref_count = 0; 25 26 struct tls_global { 27 /* Data for session resumption */ 28 void *session_data; 29 size_t session_data_size; 30 31 int server; 32 33 int params_set; 34 gnutls_certificate_credentials_t xcred; 35 36 void (*event_cb)(void *ctx, enum tls_event ev, 37 union tls_event_data *data); 38 void *cb_ctx; 39 int cert_in_cb; 40 41 char *ocsp_stapling_response; 42 }; 43 44 struct tls_connection { 45 struct tls_global *global; 46 gnutls_session_t session; 47 int read_alerts, write_alerts, failed; 48 49 u8 *pre_shared_secret; 50 size_t pre_shared_secret_len; 51 int established; 52 int verify_peer; 53 unsigned int disable_time_checks:1; 54 55 struct wpabuf *push_buf; 56 struct wpabuf *pull_buf; 57 const u8 *pull_buf_offset; 58 59 int params_set; 60 gnutls_certificate_credentials_t xcred; 61 62 char *suffix_match; 63 char *domain_match; 64 unsigned int flags; 65 }; 66 67 68 static int tls_connection_verify_peer(gnutls_session_t session); 69 70 71 static void tls_log_func(int level, const char *msg) 72 { 73 char *s, *pos; 74 if (level == 6 || level == 7) { 75 /* These levels seem to be mostly I/O debug and msg dumps */ 76 return; 77 } 78 79 s = os_strdup(msg); 80 if (s == NULL) 81 return; 82 83 pos = s; 84 while (*pos != '\0') { 85 if (*pos == '\n') { 86 *pos = '\0'; 87 break; 88 } 89 pos++; 90 } 91 wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG, 92 "gnutls<%d> %s", level, s); 93 os_free(s); 94 } 95 96 97 void * tls_init(const struct tls_config *conf) 98 { 99 struct tls_global *global; 100 101 if (tls_gnutls_ref_count == 0) { 102 wpa_printf(MSG_DEBUG, 103 "GnuTLS: Library version %s (runtime) - %s (build)", 104 gnutls_check_version(NULL), GNUTLS_VERSION); 105 } 106 107 global = os_zalloc(sizeof(*global)); 108 if (global == NULL) 109 return NULL; 110 111 if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) { 112 os_free(global); 113 return NULL; 114 } 115 tls_gnutls_ref_count++; 116 117 gnutls_global_set_log_function(tls_log_func); 118 if (wpa_debug_show_keys) 119 gnutls_global_set_log_level(11); 120 121 if (conf) { 122 global->event_cb = conf->event_cb; 123 global->cb_ctx = conf->cb_ctx; 124 global->cert_in_cb = conf->cert_in_cb; 125 } 126 127 return global; 128 } 129 130 131 void tls_deinit(void *ssl_ctx) 132 { 133 struct tls_global *global = ssl_ctx; 134 if (global) { 135 if (global->params_set) 136 gnutls_certificate_free_credentials(global->xcred); 137 os_free(global->session_data); 138 os_free(global->ocsp_stapling_response); 139 os_free(global); 140 } 141 142 tls_gnutls_ref_count--; 143 if (tls_gnutls_ref_count == 0) 144 gnutls_global_deinit(); 145 } 146 147 148 int tls_get_errors(void *ssl_ctx) 149 { 150 return 0; 151 } 152 153 154 static ssize_t tls_pull_func(gnutls_transport_ptr_t ptr, void *buf, 155 size_t len) 156 { 157 struct tls_connection *conn = (struct tls_connection *) ptr; 158 const u8 *end; 159 if (conn->pull_buf == NULL) { 160 errno = EWOULDBLOCK; 161 return -1; 162 } 163 164 end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf); 165 if ((size_t) (end - conn->pull_buf_offset) < len) 166 len = end - conn->pull_buf_offset; 167 os_memcpy(buf, conn->pull_buf_offset, len); 168 conn->pull_buf_offset += len; 169 if (conn->pull_buf_offset == end) { 170 wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__); 171 wpabuf_free(conn->pull_buf); 172 conn->pull_buf = NULL; 173 conn->pull_buf_offset = NULL; 174 } else { 175 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf", 176 __func__, 177 (unsigned long) (end - conn->pull_buf_offset)); 178 } 179 return len; 180 } 181 182 183 static ssize_t tls_push_func(gnutls_transport_ptr_t ptr, const void *buf, 184 size_t len) 185 { 186 struct tls_connection *conn = (struct tls_connection *) ptr; 187 188 if (wpabuf_resize(&conn->push_buf, len) < 0) { 189 errno = ENOMEM; 190 return -1; 191 } 192 wpabuf_put_data(conn->push_buf, buf, len); 193 194 return len; 195 } 196 197 198 static int tls_gnutls_init_session(struct tls_global *global, 199 struct tls_connection *conn) 200 { 201 const char *err; 202 int ret; 203 204 ret = gnutls_init(&conn->session, 205 global->server ? GNUTLS_SERVER : GNUTLS_CLIENT); 206 if (ret < 0) { 207 wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS " 208 "connection: %s", gnutls_strerror(ret)); 209 return -1; 210 } 211 212 ret = gnutls_set_default_priority(conn->session); 213 if (ret < 0) 214 goto fail; 215 216 ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0", 217 &err); 218 if (ret < 0) { 219 wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at " 220 "'%s'", err); 221 goto fail; 222 } 223 224 gnutls_transport_set_pull_function(conn->session, tls_pull_func); 225 gnutls_transport_set_push_function(conn->session, tls_push_func); 226 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn); 227 gnutls_session_set_ptr(conn->session, conn); 228 229 return 0; 230 231 fail: 232 wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s", 233 gnutls_strerror(ret)); 234 gnutls_deinit(conn->session); 235 return -1; 236 } 237 238 239 struct tls_connection * tls_connection_init(void *ssl_ctx) 240 { 241 struct tls_global *global = ssl_ctx; 242 struct tls_connection *conn; 243 int ret; 244 245 conn = os_zalloc(sizeof(*conn)); 246 if (conn == NULL) 247 return NULL; 248 conn->global = global; 249 250 if (tls_gnutls_init_session(global, conn)) { 251 os_free(conn); 252 return NULL; 253 } 254 255 if (global->params_set) { 256 ret = gnutls_credentials_set(conn->session, 257 GNUTLS_CRD_CERTIFICATE, 258 global->xcred); 259 if (ret < 0) { 260 wpa_printf(MSG_INFO, "Failed to configure " 261 "credentials: %s", gnutls_strerror(ret)); 262 os_free(conn); 263 return NULL; 264 } 265 } 266 267 if (gnutls_certificate_allocate_credentials(&conn->xcred)) { 268 os_free(conn); 269 return NULL; 270 } 271 272 return conn; 273 } 274 275 276 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 277 { 278 if (conn == NULL) 279 return; 280 281 gnutls_certificate_free_credentials(conn->xcred); 282 gnutls_deinit(conn->session); 283 os_free(conn->pre_shared_secret); 284 wpabuf_free(conn->push_buf); 285 wpabuf_free(conn->pull_buf); 286 os_free(conn->suffix_match); 287 os_free(conn->domain_match); 288 os_free(conn); 289 } 290 291 292 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 293 { 294 return conn ? conn->established : 0; 295 } 296 297 298 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 299 { 300 struct tls_global *global = ssl_ctx; 301 int ret; 302 303 if (conn == NULL) 304 return -1; 305 306 /* Shutdown previous TLS connection without notifying the peer 307 * because the connection was already terminated in practice 308 * and "close notify" shutdown alert would confuse AS. */ 309 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); 310 wpabuf_free(conn->push_buf); 311 conn->push_buf = NULL; 312 conn->established = 0; 313 314 gnutls_deinit(conn->session); 315 if (tls_gnutls_init_session(global, conn)) { 316 wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session " 317 "for session resumption use"); 318 return -1; 319 } 320 321 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 322 conn->params_set ? conn->xcred : 323 global->xcred); 324 if (ret < 0) { 325 wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials " 326 "for session resumption: %s", gnutls_strerror(ret)); 327 return -1; 328 } 329 330 if (global->session_data) { 331 ret = gnutls_session_set_data(conn->session, 332 global->session_data, 333 global->session_data_size); 334 if (ret < 0) { 335 wpa_printf(MSG_INFO, "GnuTLS: Failed to set session " 336 "data: %s", gnutls_strerror(ret)); 337 return -1; 338 } 339 } 340 341 return 0; 342 } 343 344 345 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 346 const struct tls_connection_params *params) 347 { 348 int ret; 349 350 if (conn == NULL || params == NULL) 351 return -1; 352 353 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) { 354 wpa_printf(MSG_INFO, 355 "GnuTLS: ocsp=3 not supported"); 356 return -1; 357 } 358 359 if (params->flags & TLS_CONN_EXT_CERT_CHECK) { 360 wpa_printf(MSG_INFO, 361 "GnuTLS: tls_ext_cert_check=1 not supported"); 362 return -1; 363 } 364 365 if (params->subject_match) { 366 wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported"); 367 return -1; 368 } 369 370 if (params->altsubject_match) { 371 wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported"); 372 return -1; 373 } 374 375 os_free(conn->suffix_match); 376 conn->suffix_match = NULL; 377 if (params->suffix_match) { 378 conn->suffix_match = os_strdup(params->suffix_match); 379 if (conn->suffix_match == NULL) 380 return -1; 381 } 382 383 #if GNUTLS_VERSION_NUMBER >= 0x030300 384 os_free(conn->domain_match); 385 conn->domain_match = NULL; 386 if (params->domain_match) { 387 conn->domain_match = os_strdup(params->domain_match); 388 if (conn->domain_match == NULL) 389 return -1; 390 } 391 #else /* < 3.3.0 */ 392 if (params->domain_match) { 393 wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported"); 394 return -1; 395 } 396 #endif /* >= 3.3.0 */ 397 398 conn->flags = params->flags; 399 400 if (params->openssl_ciphers) { 401 wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported"); 402 return -1; 403 } 404 405 /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); 406 * to force peer validation(?) */ 407 408 if (params->ca_cert) { 409 wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format", 410 params->ca_cert); 411 ret = gnutls_certificate_set_x509_trust_file( 412 conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 413 if (ret < 0) { 414 wpa_printf(MSG_DEBUG, 415 "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format", 416 params->ca_cert, 417 gnutls_strerror(ret)); 418 ret = gnutls_certificate_set_x509_trust_file( 419 conn->xcred, params->ca_cert, 420 GNUTLS_X509_FMT_PEM); 421 if (ret < 0) { 422 wpa_printf(MSG_DEBUG, 423 "Failed to read CA cert '%s' in PEM format: %s", 424 params->ca_cert, 425 gnutls_strerror(ret)); 426 return -1; 427 } 428 } 429 } else if (params->ca_cert_blob) { 430 gnutls_datum_t ca; 431 432 ca.data = (unsigned char *) params->ca_cert_blob; 433 ca.size = params->ca_cert_blob_len; 434 435 ret = gnutls_certificate_set_x509_trust_mem( 436 conn->xcred, &ca, GNUTLS_X509_FMT_DER); 437 if (ret < 0) { 438 wpa_printf(MSG_DEBUG, 439 "Failed to parse CA cert in DER format: %s", 440 gnutls_strerror(ret)); 441 ret = gnutls_certificate_set_x509_trust_mem( 442 conn->xcred, &ca, GNUTLS_X509_FMT_PEM); 443 if (ret < 0) { 444 wpa_printf(MSG_DEBUG, 445 "Failed to parse CA cert in PEM format: %s", 446 gnutls_strerror(ret)); 447 return -1; 448 } 449 } 450 } else if (params->ca_path) { 451 wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported"); 452 return -1; 453 } 454 455 conn->disable_time_checks = 0; 456 if (params->ca_cert || params->ca_cert_blob) { 457 conn->verify_peer = 1; 458 gnutls_certificate_set_verify_function( 459 conn->xcred, tls_connection_verify_peer); 460 461 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 462 gnutls_certificate_set_verify_flags( 463 conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 464 } 465 466 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 467 conn->disable_time_checks = 1; 468 gnutls_certificate_set_verify_flags( 469 conn->xcred, 470 GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 471 } 472 } 473 474 if (params->client_cert && params->private_key) { 475 #if GNUTLS_VERSION_NUMBER >= 0x03010b 476 ret = gnutls_certificate_set_x509_key_file2( 477 conn->xcred, params->client_cert, params->private_key, 478 GNUTLS_X509_FMT_DER, params->private_key_passwd, 0); 479 #else 480 /* private_key_passwd not (easily) supported here */ 481 ret = gnutls_certificate_set_x509_key_file( 482 conn->xcred, params->client_cert, params->private_key, 483 GNUTLS_X509_FMT_DER); 484 #endif 485 if (ret < 0) { 486 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 487 "in DER format: %s", gnutls_strerror(ret)); 488 #if GNUTLS_VERSION_NUMBER >= 0x03010b 489 ret = gnutls_certificate_set_x509_key_file2( 490 conn->xcred, params->client_cert, 491 params->private_key, GNUTLS_X509_FMT_PEM, 492 params->private_key_passwd, 0); 493 #else 494 ret = gnutls_certificate_set_x509_key_file( 495 conn->xcred, params->client_cert, 496 params->private_key, GNUTLS_X509_FMT_PEM); 497 #endif 498 if (ret < 0) { 499 wpa_printf(MSG_DEBUG, "Failed to read client " 500 "cert/key in PEM format: %s", 501 gnutls_strerror(ret)); 502 return ret; 503 } 504 } 505 } else if (params->private_key) { 506 int pkcs12_ok = 0; 507 #ifdef PKCS12_FUNCS 508 /* Try to load in PKCS#12 format */ 509 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 510 conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, 511 params->private_key_passwd); 512 if (ret != 0) { 513 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 514 "PKCS#12 format: %s", gnutls_strerror(ret)); 515 return -1; 516 } else 517 pkcs12_ok = 1; 518 #endif /* PKCS12_FUNCS */ 519 520 if (!pkcs12_ok) { 521 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 522 "included"); 523 return -1; 524 } 525 } else if (params->client_cert_blob && params->private_key_blob) { 526 gnutls_datum_t cert, key; 527 528 cert.data = (unsigned char *) params->client_cert_blob; 529 cert.size = params->client_cert_blob_len; 530 key.data = (unsigned char *) params->private_key_blob; 531 key.size = params->private_key_blob_len; 532 533 #if GNUTLS_VERSION_NUMBER >= 0x03010b 534 ret = gnutls_certificate_set_x509_key_mem2( 535 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER, 536 params->private_key_passwd, 0); 537 #else 538 /* private_key_passwd not (easily) supported here */ 539 ret = gnutls_certificate_set_x509_key_mem( 540 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER); 541 #endif 542 if (ret < 0) { 543 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 544 "in DER format: %s", gnutls_strerror(ret)); 545 #if GNUTLS_VERSION_NUMBER >= 0x03010b 546 ret = gnutls_certificate_set_x509_key_mem2( 547 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM, 548 params->private_key_passwd, 0); 549 #else 550 /* private_key_passwd not (easily) supported here */ 551 ret = gnutls_certificate_set_x509_key_mem( 552 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM); 553 #endif 554 if (ret < 0) { 555 wpa_printf(MSG_DEBUG, "Failed to read client " 556 "cert/key in PEM format: %s", 557 gnutls_strerror(ret)); 558 return ret; 559 } 560 } 561 } else if (params->private_key_blob) { 562 #ifdef PKCS12_FUNCS 563 gnutls_datum_t key; 564 565 key.data = (unsigned char *) params->private_key_blob; 566 key.size = params->private_key_blob_len; 567 568 /* Try to load in PKCS#12 format */ 569 ret = gnutls_certificate_set_x509_simple_pkcs12_mem( 570 conn->xcred, &key, GNUTLS_X509_FMT_DER, 571 params->private_key_passwd); 572 if (ret != 0) { 573 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 574 "PKCS#12 format: %s", gnutls_strerror(ret)); 575 return -1; 576 } 577 #else /* PKCS12_FUNCS */ 578 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included"); 579 return -1; 580 #endif /* PKCS12_FUNCS */ 581 } 582 583 #if GNUTLS_VERSION_NUMBER >= 0x030103 584 if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) { 585 ret = gnutls_ocsp_status_request_enable_client(conn->session, 586 NULL, 0, NULL); 587 if (ret != GNUTLS_E_SUCCESS) { 588 wpa_printf(MSG_INFO, 589 "GnuTLS: Failed to enable OCSP client"); 590 return -1; 591 } 592 } 593 #else /* 3.1.3 */ 594 if (params->flags & TLS_CONN_REQUIRE_OCSP) { 595 wpa_printf(MSG_INFO, 596 "GnuTLS: OCSP not supported by this version of GnuTLS"); 597 return -1; 598 } 599 #endif /* 3.1.3 */ 600 601 conn->params_set = 1; 602 603 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 604 conn->xcred); 605 if (ret < 0) { 606 wpa_printf(MSG_INFO, "Failed to configure credentials: %s", 607 gnutls_strerror(ret)); 608 } 609 610 return ret; 611 } 612 613 614 #if GNUTLS_VERSION_NUMBER >= 0x030103 615 static int server_ocsp_status_req(gnutls_session_t session, void *ptr, 616 gnutls_datum_t *resp) 617 { 618 struct tls_global *global = ptr; 619 char *cached; 620 size_t len; 621 622 if (!global->ocsp_stapling_response) { 623 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured"); 624 return GNUTLS_E_NO_CERTIFICATE_STATUS; 625 } 626 627 cached = os_readfile(global->ocsp_stapling_response, &len); 628 if (!cached) { 629 wpa_printf(MSG_DEBUG, 630 "GnuTLS: OCSP status callback - could not read response file (%s)", 631 global->ocsp_stapling_response); 632 return GNUTLS_E_NO_CERTIFICATE_STATUS; 633 } 634 635 wpa_printf(MSG_DEBUG, 636 "GnuTLS: OCSP status callback - send cached response"); 637 resp->data = gnutls_malloc(len); 638 if (!resp->data) { 639 os_free(resp); 640 return GNUTLS_E_MEMORY_ERROR; 641 } 642 643 os_memcpy(resp->data, cached, len); 644 resp->size = len; 645 os_free(cached); 646 647 return GNUTLS_E_SUCCESS; 648 } 649 #endif /* 3.1.3 */ 650 651 652 int tls_global_set_params(void *tls_ctx, 653 const struct tls_connection_params *params) 654 { 655 struct tls_global *global = tls_ctx; 656 int ret; 657 658 /* Currently, global parameters are only set when running in server 659 * mode. */ 660 global->server = 1; 661 662 if (global->params_set) { 663 gnutls_certificate_free_credentials(global->xcred); 664 global->params_set = 0; 665 } 666 667 ret = gnutls_certificate_allocate_credentials(&global->xcred); 668 if (ret) { 669 wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " 670 "%s", gnutls_strerror(ret)); 671 return -1; 672 } 673 674 if (params->ca_cert) { 675 ret = gnutls_certificate_set_x509_trust_file( 676 global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 677 if (ret < 0) { 678 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 679 "in DER format: %s", params->ca_cert, 680 gnutls_strerror(ret)); 681 ret = gnutls_certificate_set_x509_trust_file( 682 global->xcred, params->ca_cert, 683 GNUTLS_X509_FMT_PEM); 684 if (ret < 0) { 685 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 686 "'%s' in PEM format: %s", 687 params->ca_cert, 688 gnutls_strerror(ret)); 689 goto fail; 690 } 691 } 692 693 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 694 gnutls_certificate_set_verify_flags( 695 global->xcred, 696 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 697 } 698 699 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 700 gnutls_certificate_set_verify_flags( 701 global->xcred, 702 GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 703 } 704 } 705 706 if (params->client_cert && params->private_key) { 707 /* TODO: private_key_passwd? */ 708 ret = gnutls_certificate_set_x509_key_file( 709 global->xcred, params->client_cert, 710 params->private_key, GNUTLS_X509_FMT_DER); 711 if (ret < 0) { 712 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 713 "in DER format: %s", gnutls_strerror(ret)); 714 ret = gnutls_certificate_set_x509_key_file( 715 global->xcred, params->client_cert, 716 params->private_key, GNUTLS_X509_FMT_PEM); 717 if (ret < 0) { 718 wpa_printf(MSG_DEBUG, "Failed to read client " 719 "cert/key in PEM format: %s", 720 gnutls_strerror(ret)); 721 goto fail; 722 } 723 } 724 } else if (params->private_key) { 725 int pkcs12_ok = 0; 726 #ifdef PKCS12_FUNCS 727 /* Try to load in PKCS#12 format */ 728 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 729 global->xcred, params->private_key, 730 GNUTLS_X509_FMT_DER, params->private_key_passwd); 731 if (ret != 0) { 732 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 733 "PKCS#12 format: %s", gnutls_strerror(ret)); 734 goto fail; 735 } else 736 pkcs12_ok = 1; 737 #endif /* PKCS12_FUNCS */ 738 739 if (!pkcs12_ok) { 740 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 741 "included"); 742 goto fail; 743 } 744 } 745 746 #if GNUTLS_VERSION_NUMBER >= 0x030103 747 os_free(global->ocsp_stapling_response); 748 if (params->ocsp_stapling_response) 749 global->ocsp_stapling_response = 750 os_strdup(params->ocsp_stapling_response); 751 else 752 global->ocsp_stapling_response = NULL; 753 gnutls_certificate_set_ocsp_status_request_function( 754 global->xcred, server_ocsp_status_req, global); 755 #endif /* 3.1.3 */ 756 757 global->params_set = 1; 758 759 return 0; 760 761 fail: 762 gnutls_certificate_free_credentials(global->xcred); 763 return -1; 764 } 765 766 767 int tls_global_set_verify(void *ssl_ctx, int check_crl) 768 { 769 /* TODO */ 770 return 0; 771 } 772 773 774 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 775 int verify_peer, unsigned int flags, 776 const u8 *session_ctx, size_t session_ctx_len) 777 { 778 if (conn == NULL || conn->session == NULL) 779 return -1; 780 781 conn->verify_peer = verify_peer; 782 gnutls_certificate_server_set_request(conn->session, 783 verify_peer ? GNUTLS_CERT_REQUIRE 784 : GNUTLS_CERT_REQUEST); 785 786 return 0; 787 } 788 789 790 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, 791 struct tls_random *keys) 792 { 793 #if GNUTLS_VERSION_NUMBER >= 0x030012 794 gnutls_datum_t client, server; 795 796 if (conn == NULL || conn->session == NULL || keys == NULL) 797 return -1; 798 799 os_memset(keys, 0, sizeof(*keys)); 800 gnutls_session_get_random(conn->session, &client, &server); 801 keys->client_random = client.data; 802 keys->server_random = server.data; 803 keys->client_random_len = client.size; 804 keys->server_random_len = client.size; 805 806 return 0; 807 #else /* 3.0.18 */ 808 return -1; 809 #endif /* 3.0.18 */ 810 } 811 812 813 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 814 const char *label, int server_random_first, 815 int skip_keyblock, u8 *out, size_t out_len) 816 { 817 if (conn == NULL || conn->session == NULL || skip_keyblock) 818 return -1; 819 820 return gnutls_prf(conn->session, os_strlen(label), label, 821 server_random_first, 0, NULL, out_len, (char *) out); 822 } 823 824 825 static void gnutls_tls_fail_event(struct tls_connection *conn, 826 const gnutls_datum_t *cert, int depth, 827 const char *subject, const char *err_str, 828 enum tls_fail_reason reason) 829 { 830 union tls_event_data ev; 831 struct tls_global *global = conn->global; 832 struct wpabuf *cert_buf = NULL; 833 834 if (global->event_cb == NULL) 835 return; 836 837 os_memset(&ev, 0, sizeof(ev)); 838 ev.cert_fail.depth = depth; 839 ev.cert_fail.subject = subject ? subject : ""; 840 ev.cert_fail.reason = reason; 841 ev.cert_fail.reason_txt = err_str; 842 if (cert) { 843 cert_buf = wpabuf_alloc_copy(cert->data, cert->size); 844 ev.cert_fail.cert = cert_buf; 845 } 846 global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 847 wpabuf_free(cert_buf); 848 } 849 850 851 #if GNUTLS_VERSION_NUMBER < 0x030300 852 static int server_eku_purpose(gnutls_x509_crt_t cert) 853 { 854 unsigned int i; 855 856 for (i = 0; ; i++) { 857 char oid[128]; 858 size_t oid_size = sizeof(oid); 859 int res; 860 861 res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, 862 &oid_size, NULL); 863 if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { 864 if (i == 0) { 865 /* No EKU - assume any use allowed */ 866 return 1; 867 } 868 break; 869 } 870 871 if (res < 0) { 872 wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU"); 873 return 0; 874 } 875 876 wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid); 877 if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 || 878 os_strcmp(oid, GNUTLS_KP_ANY) == 0) 879 return 1; 880 } 881 882 return 0; 883 } 884 #endif /* < 3.3.0 */ 885 886 887 static int check_ocsp(struct tls_connection *conn, gnutls_session_t session, 888 gnutls_alert_description_t *err) 889 { 890 #if GNUTLS_VERSION_NUMBER >= 0x030103 891 gnutls_datum_t response, buf; 892 gnutls_ocsp_resp_t resp; 893 unsigned int cert_status; 894 int res; 895 896 if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP))) 897 return 0; 898 899 if (!gnutls_ocsp_status_request_is_checked(session, 0)) { 900 if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 901 wpa_printf(MSG_INFO, 902 "GnuTLS: No valid OCSP response received"); 903 goto ocsp_error; 904 } 905 906 wpa_printf(MSG_DEBUG, 907 "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required"); 908 return 0; 909 } 910 911 /* 912 * GnuTLS has already verified the OCSP response in 913 * check_ocsp_response() and rejected handshake if the certificate was 914 * found to be revoked. However, if the response indicates that the 915 * status is unknown, handshake continues and reaches here. We need to 916 * re-import the OCSP response to check for unknown certificate status, 917 * but we do not need to repeat gnutls_ocsp_resp_check_crt() and 918 * gnutls_ocsp_resp_verify_direct() calls. 919 */ 920 921 res = gnutls_ocsp_status_request_get(session, &response); 922 if (res != GNUTLS_E_SUCCESS) { 923 wpa_printf(MSG_INFO, 924 "GnuTLS: OCSP response was received, but it was not valid"); 925 goto ocsp_error; 926 } 927 928 if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS) 929 goto ocsp_error; 930 931 res = gnutls_ocsp_resp_import(resp, &response); 932 if (res != GNUTLS_E_SUCCESS) { 933 wpa_printf(MSG_INFO, 934 "GnuTLS: Could not parse received OCSP response: %s", 935 gnutls_strerror(res)); 936 gnutls_ocsp_resp_deinit(resp); 937 goto ocsp_error; 938 } 939 940 res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf); 941 if (res == GNUTLS_E_SUCCESS) { 942 wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data); 943 gnutls_free(buf.data); 944 } 945 946 res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, 947 NULL, &cert_status, NULL, 948 NULL, NULL, NULL); 949 gnutls_ocsp_resp_deinit(resp); 950 if (res != GNUTLS_E_SUCCESS) { 951 wpa_printf(MSG_INFO, 952 "GnuTLS: Failed to extract OCSP information: %s", 953 gnutls_strerror(res)); 954 goto ocsp_error; 955 } 956 957 if (cert_status == GNUTLS_OCSP_CERT_GOOD) { 958 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good"); 959 } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { 960 wpa_printf(MSG_DEBUG, 961 "GnuTLS: OCSP cert status: revoked"); 962 goto ocsp_error; 963 } else { 964 wpa_printf(MSG_DEBUG, 965 "GnuTLS: OCSP cert status: unknown"); 966 if (conn->flags & TLS_CONN_REQUIRE_OCSP) 967 goto ocsp_error; 968 wpa_printf(MSG_DEBUG, 969 "GnuTLS: OCSP was not required, so allow connection to continue"); 970 } 971 972 return 0; 973 974 ocsp_error: 975 gnutls_tls_fail_event(conn, NULL, 0, NULL, 976 "bad certificate status response", 977 TLS_FAIL_REVOKED); 978 *err = GNUTLS_A_CERTIFICATE_REVOKED; 979 return -1; 980 #else /* GnuTLS 3.1.3 or newer */ 981 return 0; 982 #endif /* GnuTLS 3.1.3 or newer */ 983 } 984 985 986 static int tls_connection_verify_peer(gnutls_session_t session) 987 { 988 struct tls_connection *conn; 989 unsigned int status, num_certs, i; 990 struct os_time now; 991 const gnutls_datum_t *certs; 992 gnutls_x509_crt_t cert; 993 gnutls_alert_description_t err; 994 int res; 995 996 conn = gnutls_session_get_ptr(session); 997 if (!conn->verify_peer) { 998 wpa_printf(MSG_DEBUG, 999 "GnuTLS: No peer certificate verification enabled"); 1000 return 0; 1001 } 1002 1003 wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate"); 1004 1005 #if GNUTLS_VERSION_NUMBER >= 0x030300 1006 { 1007 gnutls_typed_vdata_st data[1]; 1008 unsigned int elements = 0; 1009 1010 os_memset(data, 0, sizeof(data)); 1011 if (!conn->global->server) { 1012 data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID; 1013 data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER; 1014 elements++; 1015 } 1016 res = gnutls_certificate_verify_peers(session, data, 1, 1017 &status); 1018 } 1019 #else /* < 3.3.0 */ 1020 res = gnutls_certificate_verify_peers2(session, &status); 1021 #endif 1022 if (res < 0) { 1023 wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 1024 "certificate chain"); 1025 err = GNUTLS_A_INTERNAL_ERROR; 1026 goto out; 1027 } 1028 1029 #if GNUTLS_VERSION_NUMBER >= 0x030104 1030 { 1031 gnutls_datum_t info; 1032 int ret, type; 1033 1034 type = gnutls_certificate_type_get(session); 1035 ret = gnutls_certificate_verification_status_print(status, type, 1036 &info, 0); 1037 if (ret < 0) { 1038 wpa_printf(MSG_DEBUG, 1039 "GnuTLS: Failed to print verification status"); 1040 err = GNUTLS_A_INTERNAL_ERROR; 1041 goto out; 1042 } 1043 wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data); 1044 gnutls_free(info.data); 1045 } 1046 #endif /* GnuTLS 3.1.4 or newer */ 1047 1048 certs = gnutls_certificate_get_peers(session, &num_certs); 1049 if (certs == NULL || num_certs == 0) { 1050 wpa_printf(MSG_INFO, "TLS: No peer certificate chain received"); 1051 err = GNUTLS_A_UNKNOWN_CA; 1052 goto out; 1053 } 1054 1055 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 1056 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 1057 if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { 1058 wpa_printf(MSG_INFO, "TLS: Certificate uses insecure " 1059 "algorithm"); 1060 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1061 "certificate uses insecure algorithm", 1062 TLS_FAIL_BAD_CERTIFICATE); 1063 err = GNUTLS_A_INSUFFICIENT_SECURITY; 1064 goto out; 1065 } 1066 if (status & GNUTLS_CERT_NOT_ACTIVATED) { 1067 wpa_printf(MSG_INFO, "TLS: Certificate not yet " 1068 "activated"); 1069 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1070 "certificate not yet valid", 1071 TLS_FAIL_NOT_YET_VALID); 1072 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1073 goto out; 1074 } 1075 if (status & GNUTLS_CERT_EXPIRED) { 1076 wpa_printf(MSG_INFO, "TLS: Certificate expired"); 1077 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1078 "certificate has expired", 1079 TLS_FAIL_EXPIRED); 1080 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1081 goto out; 1082 } 1083 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1084 "untrusted certificate", 1085 TLS_FAIL_UNTRUSTED); 1086 err = GNUTLS_A_INTERNAL_ERROR; 1087 goto out; 1088 } 1089 1090 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 1091 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 1092 "known issuer"); 1093 gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found", 1094 TLS_FAIL_UNTRUSTED); 1095 err = GNUTLS_A_UNKNOWN_CA; 1096 goto out; 1097 } 1098 1099 if (status & GNUTLS_CERT_REVOKED) { 1100 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 1101 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1102 "certificate revoked", 1103 TLS_FAIL_REVOKED); 1104 err = GNUTLS_A_CERTIFICATE_REVOKED; 1105 goto out; 1106 } 1107 1108 if (status != 0) { 1109 wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d", 1110 status); 1111 err = GNUTLS_A_INTERNAL_ERROR; 1112 goto out; 1113 } 1114 1115 if (check_ocsp(conn, session, &err)) 1116 goto out; 1117 1118 os_get_time(&now); 1119 1120 for (i = 0; i < num_certs; i++) { 1121 char *buf; 1122 size_t len; 1123 if (gnutls_x509_crt_init(&cert) < 0) { 1124 wpa_printf(MSG_INFO, "TLS: Certificate initialization " 1125 "failed"); 1126 err = GNUTLS_A_BAD_CERTIFICATE; 1127 goto out; 1128 } 1129 1130 if (gnutls_x509_crt_import(cert, &certs[i], 1131 GNUTLS_X509_FMT_DER) < 0) { 1132 wpa_printf(MSG_INFO, "TLS: Could not parse peer " 1133 "certificate %d/%d", i + 1, num_certs); 1134 gnutls_x509_crt_deinit(cert); 1135 err = GNUTLS_A_BAD_CERTIFICATE; 1136 goto out; 1137 } 1138 1139 gnutls_x509_crt_get_dn(cert, NULL, &len); 1140 len++; 1141 buf = os_malloc(len + 1); 1142 if (buf) { 1143 buf[0] = buf[len] = '\0'; 1144 gnutls_x509_crt_get_dn(cert, buf, &len); 1145 } 1146 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 1147 i + 1, num_certs, buf); 1148 1149 if (conn->global->event_cb) { 1150 struct wpabuf *cert_buf = NULL; 1151 union tls_event_data ev; 1152 #ifdef CONFIG_SHA256 1153 u8 hash[32]; 1154 const u8 *_addr[1]; 1155 size_t _len[1]; 1156 #endif /* CONFIG_SHA256 */ 1157 1158 os_memset(&ev, 0, sizeof(ev)); 1159 if (conn->global->cert_in_cb) { 1160 cert_buf = wpabuf_alloc_copy(certs[i].data, 1161 certs[i].size); 1162 ev.peer_cert.cert = cert_buf; 1163 } 1164 #ifdef CONFIG_SHA256 1165 _addr[0] = certs[i].data; 1166 _len[0] = certs[i].size; 1167 if (sha256_vector(1, _addr, _len, hash) == 0) { 1168 ev.peer_cert.hash = hash; 1169 ev.peer_cert.hash_len = sizeof(hash); 1170 } 1171 #endif /* CONFIG_SHA256 */ 1172 ev.peer_cert.depth = i; 1173 ev.peer_cert.subject = buf; 1174 conn->global->event_cb(conn->global->cb_ctx, 1175 TLS_PEER_CERTIFICATE, &ev); 1176 wpabuf_free(cert_buf); 1177 } 1178 1179 if (i == 0) { 1180 if (conn->suffix_match && 1181 !gnutls_x509_crt_check_hostname( 1182 cert, conn->suffix_match)) { 1183 wpa_printf(MSG_WARNING, 1184 "TLS: Domain suffix match '%s' not found", 1185 conn->suffix_match); 1186 gnutls_tls_fail_event( 1187 conn, &certs[i], i, buf, 1188 "Domain suffix mismatch", 1189 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 1190 err = GNUTLS_A_BAD_CERTIFICATE; 1191 gnutls_x509_crt_deinit(cert); 1192 os_free(buf); 1193 goto out; 1194 } 1195 1196 #if GNUTLS_VERSION_NUMBER >= 0x030300 1197 if (conn->domain_match && 1198 !gnutls_x509_crt_check_hostname2( 1199 cert, conn->domain_match, 1200 GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) { 1201 wpa_printf(MSG_WARNING, 1202 "TLS: Domain match '%s' not found", 1203 conn->domain_match); 1204 gnutls_tls_fail_event( 1205 conn, &certs[i], i, buf, 1206 "Domain mismatch", 1207 TLS_FAIL_DOMAIN_MISMATCH); 1208 err = GNUTLS_A_BAD_CERTIFICATE; 1209 gnutls_x509_crt_deinit(cert); 1210 os_free(buf); 1211 goto out; 1212 } 1213 #endif /* >= 3.3.0 */ 1214 1215 /* TODO: validate altsubject_match. 1216 * For now, any such configuration is rejected in 1217 * tls_connection_set_params() */ 1218 1219 #if GNUTLS_VERSION_NUMBER < 0x030300 1220 /* 1221 * gnutls_certificate_verify_peers() not available, so 1222 * need to check EKU separately. 1223 */ 1224 if (!conn->global->server && 1225 !server_eku_purpose(cert)) { 1226 wpa_printf(MSG_WARNING, 1227 "GnuTLS: No server EKU"); 1228 gnutls_tls_fail_event( 1229 conn, &certs[i], i, buf, 1230 "No server EKU", 1231 TLS_FAIL_BAD_CERTIFICATE); 1232 err = GNUTLS_A_BAD_CERTIFICATE; 1233 gnutls_x509_crt_deinit(cert); 1234 os_free(buf); 1235 goto out; 1236 } 1237 #endif /* < 3.3.0 */ 1238 } 1239 1240 if (!conn->disable_time_checks && 1241 (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 1242 gnutls_x509_crt_get_activation_time(cert) > now.sec)) { 1243 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 1244 "not valid at this time", 1245 i + 1, num_certs); 1246 gnutls_tls_fail_event( 1247 conn, &certs[i], i, buf, 1248 "Certificate is not valid at this time", 1249 TLS_FAIL_EXPIRED); 1250 gnutls_x509_crt_deinit(cert); 1251 os_free(buf); 1252 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1253 goto out; 1254 } 1255 1256 os_free(buf); 1257 1258 gnutls_x509_crt_deinit(cert); 1259 } 1260 1261 if (conn->global->event_cb != NULL) 1262 conn->global->event_cb(conn->global->cb_ctx, 1263 TLS_CERT_CHAIN_SUCCESS, NULL); 1264 1265 return 0; 1266 1267 out: 1268 conn->failed++; 1269 gnutls_alert_send(session, GNUTLS_AL_FATAL, err); 1270 return GNUTLS_E_CERTIFICATE_ERROR; 1271 } 1272 1273 1274 static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn) 1275 { 1276 int res; 1277 struct wpabuf *ad; 1278 wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data"); 1279 ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3); 1280 if (ad == NULL) 1281 return NULL; 1282 1283 res = gnutls_record_recv(conn->session, wpabuf_mhead(ad), 1284 wpabuf_size(ad)); 1285 wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res); 1286 if (res < 0) { 1287 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1288 "(%s)", __func__, (int) res, 1289 gnutls_strerror(res)); 1290 wpabuf_free(ad); 1291 return NULL; 1292 } 1293 1294 wpabuf_put(ad, res); 1295 wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data", 1296 res); 1297 return ad; 1298 } 1299 1300 1301 struct wpabuf * tls_connection_handshake(void *tls_ctx, 1302 struct tls_connection *conn, 1303 const struct wpabuf *in_data, 1304 struct wpabuf **appl_data) 1305 { 1306 struct tls_global *global = tls_ctx; 1307 struct wpabuf *out_data; 1308 int ret; 1309 1310 if (appl_data) 1311 *appl_data = NULL; 1312 1313 if (in_data && wpabuf_len(in_data) > 0) { 1314 if (conn->pull_buf) { 1315 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1316 "pull_buf", __func__, 1317 (unsigned long) wpabuf_len(conn->pull_buf)); 1318 wpabuf_free(conn->pull_buf); 1319 } 1320 conn->pull_buf = wpabuf_dup(in_data); 1321 if (conn->pull_buf == NULL) 1322 return NULL; 1323 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1324 } 1325 1326 ret = gnutls_handshake(conn->session); 1327 if (ret < 0) { 1328 gnutls_alert_description_t alert; 1329 1330 switch (ret) { 1331 case GNUTLS_E_AGAIN: 1332 if (global->server && conn->established && 1333 conn->push_buf == NULL) { 1334 /* Need to return something to trigger 1335 * completion of EAP-TLS. */ 1336 conn->push_buf = wpabuf_alloc(0); 1337 } 1338 break; 1339 case GNUTLS_E_FATAL_ALERT_RECEIVED: 1340 alert = gnutls_alert_get(conn->session); 1341 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 1342 __func__, gnutls_alert_get_name(alert)); 1343 conn->read_alerts++; 1344 if (conn->global->event_cb != NULL) { 1345 union tls_event_data ev; 1346 1347 os_memset(&ev, 0, sizeof(ev)); 1348 ev.alert.is_local = 0; 1349 ev.alert.type = gnutls_alert_get_name(alert); 1350 ev.alert.description = ev.alert.type; 1351 conn->global->event_cb(conn->global->cb_ctx, 1352 TLS_ALERT, &ev); 1353 } 1354 /* continue */ 1355 default: 1356 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 1357 "-> %s", __func__, gnutls_strerror(ret)); 1358 conn->failed++; 1359 } 1360 } else { 1361 size_t size; 1362 1363 wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); 1364 1365 #if GNUTLS_VERSION_NUMBER >= 0x03010a 1366 { 1367 char *desc; 1368 1369 desc = gnutls_session_get_desc(conn->session); 1370 if (desc) { 1371 wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc); 1372 gnutls_free(desc); 1373 } 1374 } 1375 #endif /* GnuTLS 3.1.10 or newer */ 1376 1377 conn->established = 1; 1378 if (conn->push_buf == NULL) { 1379 /* Need to return something to get final TLS ACK. */ 1380 conn->push_buf = wpabuf_alloc(0); 1381 } 1382 1383 gnutls_session_get_data(conn->session, NULL, &size); 1384 if (global->session_data == NULL || 1385 global->session_data_size < size) { 1386 os_free(global->session_data); 1387 global->session_data = os_malloc(size); 1388 } 1389 if (global->session_data) { 1390 global->session_data_size = size; 1391 gnutls_session_get_data(conn->session, 1392 global->session_data, 1393 &global->session_data_size); 1394 } 1395 1396 if (conn->pull_buf && appl_data) 1397 *appl_data = gnutls_get_appl_data(conn); 1398 } 1399 1400 out_data = conn->push_buf; 1401 conn->push_buf = NULL; 1402 return out_data; 1403 } 1404 1405 1406 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 1407 struct tls_connection *conn, 1408 const struct wpabuf *in_data, 1409 struct wpabuf **appl_data) 1410 { 1411 return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); 1412 } 1413 1414 1415 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 1416 struct tls_connection *conn, 1417 const struct wpabuf *in_data) 1418 { 1419 ssize_t res; 1420 struct wpabuf *buf; 1421 1422 res = gnutls_record_send(conn->session, wpabuf_head(in_data), 1423 wpabuf_len(in_data)); 1424 if (res < 0) { 1425 wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 1426 __func__, gnutls_strerror(res)); 1427 return NULL; 1428 } 1429 1430 buf = conn->push_buf; 1431 conn->push_buf = NULL; 1432 return buf; 1433 } 1434 1435 1436 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 1437 struct tls_connection *conn, 1438 const struct wpabuf *in_data) 1439 { 1440 ssize_t res; 1441 struct wpabuf *out; 1442 1443 if (conn->pull_buf) { 1444 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1445 "pull_buf", __func__, 1446 (unsigned long) wpabuf_len(conn->pull_buf)); 1447 wpabuf_free(conn->pull_buf); 1448 } 1449 conn->pull_buf = wpabuf_dup(in_data); 1450 if (conn->pull_buf == NULL) 1451 return NULL; 1452 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1453 1454 /* 1455 * Even though we try to disable TLS compression, it is possible that 1456 * this cannot be done with all TLS libraries. Add extra buffer space 1457 * to handle the possibility of the decrypted data being longer than 1458 * input data. 1459 */ 1460 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 1461 if (out == NULL) 1462 return NULL; 1463 1464 res = gnutls_record_recv(conn->session, wpabuf_mhead(out), 1465 wpabuf_size(out)); 1466 if (res < 0) { 1467 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1468 "(%s)", __func__, (int) res, gnutls_strerror(res)); 1469 wpabuf_free(out); 1470 return NULL; 1471 } 1472 wpabuf_put(out, res); 1473 1474 return out; 1475 } 1476 1477 1478 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 1479 { 1480 if (conn == NULL) 1481 return 0; 1482 return gnutls_session_is_resumed(conn->session); 1483 } 1484 1485 1486 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 1487 u8 *ciphers) 1488 { 1489 /* TODO */ 1490 return -1; 1491 } 1492 1493 1494 int tls_get_version(void *ssl_ctx, struct tls_connection *conn, 1495 char *buf, size_t buflen) 1496 { 1497 /* TODO */ 1498 return -1; 1499 } 1500 1501 1502 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 1503 char *buf, size_t buflen) 1504 { 1505 /* TODO */ 1506 buf[0] = '\0'; 1507 return 0; 1508 } 1509 1510 1511 int tls_connection_enable_workaround(void *ssl_ctx, 1512 struct tls_connection *conn) 1513 { 1514 gnutls_record_disable_padding(conn->session); 1515 return 0; 1516 } 1517 1518 1519 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 1520 int ext_type, const u8 *data, 1521 size_t data_len) 1522 { 1523 /* TODO */ 1524 return -1; 1525 } 1526 1527 1528 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 1529 { 1530 if (conn == NULL) 1531 return -1; 1532 return conn->failed; 1533 } 1534 1535 1536 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 1537 { 1538 if (conn == NULL) 1539 return -1; 1540 return conn->read_alerts; 1541 } 1542 1543 1544 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 1545 { 1546 if (conn == NULL) 1547 return -1; 1548 return conn->write_alerts; 1549 } 1550 1551 1552 int tls_connection_set_session_ticket_cb(void *tls_ctx, 1553 struct tls_connection *conn, 1554 tls_session_ticket_cb cb, void *ctx) 1555 { 1556 return -1; 1557 } 1558 1559 1560 int tls_get_library_version(char *buf, size_t buf_len) 1561 { 1562 return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s", 1563 GNUTLS_VERSION, gnutls_check_version(NULL)); 1564 } 1565 1566 1567 void tls_connection_set_success_data(struct tls_connection *conn, 1568 struct wpabuf *data) 1569 { 1570 } 1571 1572 1573 void tls_connection_set_success_data_resumed(struct tls_connection *conn) 1574 { 1575 } 1576 1577 1578 const struct wpabuf * 1579 tls_connection_get_success_data(struct tls_connection *conn) 1580 { 1581 return NULL; 1582 } 1583 1584 1585 void tls_connection_remove_session(struct tls_connection *conn) 1586 { 1587 } 1588