1/* 2 * SSL/TLS interface functions for GnuTLS 3 * Copyright (c) 2004-2011, Jouni Malinen <j@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 24static int tls_gnutls_ref_count = 0; 25 26struct 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 44struct 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 68static int tls_connection_verify_peer(gnutls_session_t session); 69 70 71static 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 97void * 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 131void 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 148int tls_get_errors(void *ssl_ctx) 149{ 150 return 0; 151} 152 153 154static 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 183static 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 198static 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 231fail: 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 239struct 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 276void 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 292int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 293{ 294 return conn ? conn->established : 0; 295} 296 297 298int 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 345int 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 615static 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 652int 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 761fail: 762 gnutls_certificate_free_credentials(global->xcred); 763 return -1; 764} 765 766 767int tls_global_set_verify(void *ssl_ctx, int check_crl) 768{ 769 /* TODO */ 770 return 0; 771} 772 773 774int 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 790int 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 813int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, 814 const char *label, u8 *out, size_t out_len) 815{ 816 if (conn == NULL || conn->session == NULL) 817 return -1; 818 819 return gnutls_prf(conn->session, os_strlen(label), label, 820 0 /* client_random first */, 0, NULL, out_len, 821 (char *) out); 822} 823 824 825int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, 826 u8 *out, size_t out_len) 827{ 828 return -1; 829} 830 831 832static void gnutls_tls_fail_event(struct tls_connection *conn, 833 const gnutls_datum_t *cert, int depth, 834 const char *subject, const char *err_str, 835 enum tls_fail_reason reason) 836{ 837 union tls_event_data ev; 838 struct tls_global *global = conn->global; 839 struct wpabuf *cert_buf = NULL; 840 841 if (global->event_cb == NULL) 842 return; 843 844 os_memset(&ev, 0, sizeof(ev)); 845 ev.cert_fail.depth = depth; 846 ev.cert_fail.subject = subject ? subject : ""; 847 ev.cert_fail.reason = reason; 848 ev.cert_fail.reason_txt = err_str; 849 if (cert) { 850 cert_buf = wpabuf_alloc_copy(cert->data, cert->size); 851 ev.cert_fail.cert = cert_buf; 852 } 853 global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 854 wpabuf_free(cert_buf); 855} 856 857 858#if GNUTLS_VERSION_NUMBER < 0x030300 859static int server_eku_purpose(gnutls_x509_crt_t cert) 860{ 861 unsigned int i; 862 863 for (i = 0; ; i++) { 864 char oid[128]; 865 size_t oid_size = sizeof(oid); 866 int res; 867 868 res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, 869 &oid_size, NULL); 870 if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { 871 if (i == 0) { 872 /* No EKU - assume any use allowed */ 873 return 1; 874 } 875 break; 876 } 877 878 if (res < 0) { 879 wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU"); 880 return 0; 881 } 882 883 wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid); 884 if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 || 885 os_strcmp(oid, GNUTLS_KP_ANY) == 0) 886 return 1; 887 } 888 889 return 0; 890} 891#endif /* < 3.3.0 */ 892 893 894static int check_ocsp(struct tls_connection *conn, gnutls_session_t session, 895 gnutls_alert_description_t *err) 896{ 897#if GNUTLS_VERSION_NUMBER >= 0x030103 898 gnutls_datum_t response, buf; 899 gnutls_ocsp_resp_t resp; 900 unsigned int cert_status; 901 int res; 902 903 if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP))) 904 return 0; 905 906 if (!gnutls_ocsp_status_request_is_checked(session, 0)) { 907 if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 908 wpa_printf(MSG_INFO, 909 "GnuTLS: No valid OCSP response received"); 910 goto ocsp_error; 911 } 912 913 wpa_printf(MSG_DEBUG, 914 "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required"); 915 return 0; 916 } 917 918 /* 919 * GnuTLS has already verified the OCSP response in 920 * check_ocsp_response() and rejected handshake if the certificate was 921 * found to be revoked. However, if the response indicates that the 922 * status is unknown, handshake continues and reaches here. We need to 923 * re-import the OCSP response to check for unknown certificate status, 924 * but we do not need to repeat gnutls_ocsp_resp_check_crt() and 925 * gnutls_ocsp_resp_verify_direct() calls. 926 */ 927 928 res = gnutls_ocsp_status_request_get(session, &response); 929 if (res != GNUTLS_E_SUCCESS) { 930 wpa_printf(MSG_INFO, 931 "GnuTLS: OCSP response was received, but it was not valid"); 932 goto ocsp_error; 933 } 934 935 if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS) 936 goto ocsp_error; 937 938 res = gnutls_ocsp_resp_import(resp, &response); 939 if (res != GNUTLS_E_SUCCESS) { 940 wpa_printf(MSG_INFO, 941 "GnuTLS: Could not parse received OCSP response: %s", 942 gnutls_strerror(res)); 943 gnutls_ocsp_resp_deinit(resp); 944 goto ocsp_error; 945 } 946 947 res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf); 948 if (res == GNUTLS_E_SUCCESS) { 949 wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data); 950 gnutls_free(buf.data); 951 } 952 953 res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, 954 NULL, &cert_status, NULL, 955 NULL, NULL, NULL); 956 gnutls_ocsp_resp_deinit(resp); 957 if (res != GNUTLS_E_SUCCESS) { 958 wpa_printf(MSG_INFO, 959 "GnuTLS: Failed to extract OCSP information: %s", 960 gnutls_strerror(res)); 961 goto ocsp_error; 962 } 963 964 if (cert_status == GNUTLS_OCSP_CERT_GOOD) { 965 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good"); 966 } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { 967 wpa_printf(MSG_DEBUG, 968 "GnuTLS: OCSP cert status: revoked"); 969 goto ocsp_error; 970 } else { 971 wpa_printf(MSG_DEBUG, 972 "GnuTLS: OCSP cert status: unknown"); 973 if (conn->flags & TLS_CONN_REQUIRE_OCSP) 974 goto ocsp_error; 975 wpa_printf(MSG_DEBUG, 976 "GnuTLS: OCSP was not required, so allow connection to continue"); 977 } 978 979 return 0; 980 981ocsp_error: 982 gnutls_tls_fail_event(conn, NULL, 0, NULL, 983 "bad certificate status response", 984 TLS_FAIL_REVOKED); 985 *err = GNUTLS_A_CERTIFICATE_REVOKED; 986 return -1; 987#else /* GnuTLS 3.1.3 or newer */ 988 return 0; 989#endif /* GnuTLS 3.1.3 or newer */ 990} 991 992 993static int tls_connection_verify_peer(gnutls_session_t session) 994{ 995 struct tls_connection *conn; 996 unsigned int status, num_certs, i; 997 struct os_time now; 998 const gnutls_datum_t *certs; 999 gnutls_x509_crt_t cert; 1000 gnutls_alert_description_t err; 1001 int res; 1002 1003 conn = gnutls_session_get_ptr(session); 1004 if (!conn->verify_peer) { 1005 wpa_printf(MSG_DEBUG, 1006 "GnuTLS: No peer certificate verification enabled"); 1007 return 0; 1008 } 1009 1010 wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate"); 1011 1012#if GNUTLS_VERSION_NUMBER >= 0x030300 1013 { 1014 gnutls_typed_vdata_st data[1]; 1015 unsigned int elements = 0; 1016 1017 os_memset(data, 0, sizeof(data)); 1018 if (!conn->global->server) { 1019 data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID; 1020 data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER; 1021 elements++; 1022 } 1023 res = gnutls_certificate_verify_peers(session, data, 1, 1024 &status); 1025 } 1026#else /* < 3.3.0 */ 1027 res = gnutls_certificate_verify_peers2(session, &status); 1028#endif 1029 if (res < 0) { 1030 wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 1031 "certificate chain"); 1032 err = GNUTLS_A_INTERNAL_ERROR; 1033 goto out; 1034 } 1035 1036#if GNUTLS_VERSION_NUMBER >= 0x030104 1037 { 1038 gnutls_datum_t info; 1039 int ret, type; 1040 1041 type = gnutls_certificate_type_get(session); 1042 ret = gnutls_certificate_verification_status_print(status, type, 1043 &info, 0); 1044 if (ret < 0) { 1045 wpa_printf(MSG_DEBUG, 1046 "GnuTLS: Failed to print verification status"); 1047 err = GNUTLS_A_INTERNAL_ERROR; 1048 goto out; 1049 } 1050 wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data); 1051 gnutls_free(info.data); 1052 } 1053#endif /* GnuTLS 3.1.4 or newer */ 1054 1055 certs = gnutls_certificate_get_peers(session, &num_certs); 1056 if (certs == NULL || num_certs == 0) { 1057 wpa_printf(MSG_INFO, "TLS: No peer certificate chain received"); 1058 err = GNUTLS_A_UNKNOWN_CA; 1059 goto out; 1060 } 1061 1062 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 1063 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 1064 if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { 1065 wpa_printf(MSG_INFO, "TLS: Certificate uses insecure " 1066 "algorithm"); 1067 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1068 "certificate uses insecure algorithm", 1069 TLS_FAIL_BAD_CERTIFICATE); 1070 err = GNUTLS_A_INSUFFICIENT_SECURITY; 1071 goto out; 1072 } 1073 if (status & GNUTLS_CERT_NOT_ACTIVATED) { 1074 wpa_printf(MSG_INFO, "TLS: Certificate not yet " 1075 "activated"); 1076 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1077 "certificate not yet valid", 1078 TLS_FAIL_NOT_YET_VALID); 1079 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1080 goto out; 1081 } 1082 if (status & GNUTLS_CERT_EXPIRED) { 1083 wpa_printf(MSG_INFO, "TLS: Certificate expired"); 1084 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1085 "certificate has expired", 1086 TLS_FAIL_EXPIRED); 1087 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1088 goto out; 1089 } 1090 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1091 "untrusted certificate", 1092 TLS_FAIL_UNTRUSTED); 1093 err = GNUTLS_A_INTERNAL_ERROR; 1094 goto out; 1095 } 1096 1097 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 1098 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 1099 "known issuer"); 1100 gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found", 1101 TLS_FAIL_UNTRUSTED); 1102 err = GNUTLS_A_UNKNOWN_CA; 1103 goto out; 1104 } 1105 1106 if (status & GNUTLS_CERT_REVOKED) { 1107 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 1108 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1109 "certificate revoked", 1110 TLS_FAIL_REVOKED); 1111 err = GNUTLS_A_CERTIFICATE_REVOKED; 1112 goto out; 1113 } 1114 1115 if (status != 0) { 1116 wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d", 1117 status); 1118 err = GNUTLS_A_INTERNAL_ERROR; 1119 goto out; 1120 } 1121 1122 if (check_ocsp(conn, session, &err)) 1123 goto out; 1124 1125 os_get_time(&now); 1126 1127 for (i = 0; i < num_certs; i++) { 1128 char *buf; 1129 size_t len; 1130 if (gnutls_x509_crt_init(&cert) < 0) { 1131 wpa_printf(MSG_INFO, "TLS: Certificate initialization " 1132 "failed"); 1133 err = GNUTLS_A_BAD_CERTIFICATE; 1134 goto out; 1135 } 1136 1137 if (gnutls_x509_crt_import(cert, &certs[i], 1138 GNUTLS_X509_FMT_DER) < 0) { 1139 wpa_printf(MSG_INFO, "TLS: Could not parse peer " 1140 "certificate %d/%d", i + 1, num_certs); 1141 gnutls_x509_crt_deinit(cert); 1142 err = GNUTLS_A_BAD_CERTIFICATE; 1143 goto out; 1144 } 1145 1146 gnutls_x509_crt_get_dn(cert, NULL, &len); 1147 len++; 1148 buf = os_malloc(len + 1); 1149 if (buf) { 1150 buf[0] = buf[len] = '\0'; 1151 gnutls_x509_crt_get_dn(cert, buf, &len); 1152 } 1153 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 1154 i + 1, num_certs, buf); 1155 1156 if (conn->global->event_cb) { 1157 struct wpabuf *cert_buf = NULL; 1158 union tls_event_data ev; 1159#ifdef CONFIG_SHA256 1160 u8 hash[32]; 1161 const u8 *_addr[1]; 1162 size_t _len[1]; 1163#endif /* CONFIG_SHA256 */ 1164 1165 os_memset(&ev, 0, sizeof(ev)); 1166 if (conn->global->cert_in_cb) { 1167 cert_buf = wpabuf_alloc_copy(certs[i].data, 1168 certs[i].size); 1169 ev.peer_cert.cert = cert_buf; 1170 } 1171#ifdef CONFIG_SHA256 1172 _addr[0] = certs[i].data; 1173 _len[0] = certs[i].size; 1174 if (sha256_vector(1, _addr, _len, hash) == 0) { 1175 ev.peer_cert.hash = hash; 1176 ev.peer_cert.hash_len = sizeof(hash); 1177 } 1178#endif /* CONFIG_SHA256 */ 1179 ev.peer_cert.depth = i; 1180 ev.peer_cert.subject = buf; 1181 conn->global->event_cb(conn->global->cb_ctx, 1182 TLS_PEER_CERTIFICATE, &ev); 1183 wpabuf_free(cert_buf); 1184 } 1185 1186 if (i == 0) { 1187 if (conn->suffix_match && 1188 !gnutls_x509_crt_check_hostname( 1189 cert, conn->suffix_match)) { 1190 wpa_printf(MSG_WARNING, 1191 "TLS: Domain suffix match '%s' not found", 1192 conn->suffix_match); 1193 gnutls_tls_fail_event( 1194 conn, &certs[i], i, buf, 1195 "Domain suffix mismatch", 1196 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 1197 err = GNUTLS_A_BAD_CERTIFICATE; 1198 gnutls_x509_crt_deinit(cert); 1199 os_free(buf); 1200 goto out; 1201 } 1202 1203#if GNUTLS_VERSION_NUMBER >= 0x030300 1204 if (conn->domain_match && 1205 !gnutls_x509_crt_check_hostname2( 1206 cert, conn->domain_match, 1207 GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) { 1208 wpa_printf(MSG_WARNING, 1209 "TLS: Domain match '%s' not found", 1210 conn->domain_match); 1211 gnutls_tls_fail_event( 1212 conn, &certs[i], i, buf, 1213 "Domain mismatch", 1214 TLS_FAIL_DOMAIN_MISMATCH); 1215 err = GNUTLS_A_BAD_CERTIFICATE; 1216 gnutls_x509_crt_deinit(cert); 1217 os_free(buf); 1218 goto out; 1219 } 1220#endif /* >= 3.3.0 */ 1221 1222 /* TODO: validate altsubject_match. 1223 * For now, any such configuration is rejected in 1224 * tls_connection_set_params() */ 1225 1226#if GNUTLS_VERSION_NUMBER < 0x030300 1227 /* 1228 * gnutls_certificate_verify_peers() not available, so 1229 * need to check EKU separately. 1230 */ 1231 if (!conn->global->server && 1232 !server_eku_purpose(cert)) { 1233 wpa_printf(MSG_WARNING, 1234 "GnuTLS: No server EKU"); 1235 gnutls_tls_fail_event( 1236 conn, &certs[i], i, buf, 1237 "No server EKU", 1238 TLS_FAIL_BAD_CERTIFICATE); 1239 err = GNUTLS_A_BAD_CERTIFICATE; 1240 gnutls_x509_crt_deinit(cert); 1241 os_free(buf); 1242 goto out; 1243 } 1244#endif /* < 3.3.0 */ 1245 } 1246 1247 if (!conn->disable_time_checks && 1248 (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 1249 gnutls_x509_crt_get_activation_time(cert) > now.sec)) { 1250 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 1251 "not valid at this time", 1252 i + 1, num_certs); 1253 gnutls_tls_fail_event( 1254 conn, &certs[i], i, buf, 1255 "Certificate is not valid at this time", 1256 TLS_FAIL_EXPIRED); 1257 gnutls_x509_crt_deinit(cert); 1258 os_free(buf); 1259 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1260 goto out; 1261 } 1262 1263 os_free(buf); 1264 1265 gnutls_x509_crt_deinit(cert); 1266 } 1267 1268 if (conn->global->event_cb != NULL) 1269 conn->global->event_cb(conn->global->cb_ctx, 1270 TLS_CERT_CHAIN_SUCCESS, NULL); 1271 1272 return 0; 1273 1274out: 1275 conn->failed++; 1276 gnutls_alert_send(session, GNUTLS_AL_FATAL, err); 1277 return GNUTLS_E_CERTIFICATE_ERROR; 1278} 1279 1280 1281static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn) 1282{ 1283 int res; 1284 struct wpabuf *ad; 1285 wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data"); 1286 ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3); 1287 if (ad == NULL) 1288 return NULL; 1289 1290 res = gnutls_record_recv(conn->session, wpabuf_mhead(ad), 1291 wpabuf_size(ad)); 1292 wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res); 1293 if (res < 0) { 1294 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1295 "(%s)", __func__, (int) res, 1296 gnutls_strerror(res)); 1297 wpabuf_free(ad); 1298 return NULL; 1299 } 1300 1301 wpabuf_put(ad, res); 1302 wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data", 1303 res); 1304 return ad; 1305} 1306 1307 1308struct wpabuf * tls_connection_handshake(void *tls_ctx, 1309 struct tls_connection *conn, 1310 const struct wpabuf *in_data, 1311 struct wpabuf **appl_data) 1312{ 1313 struct tls_global *global = tls_ctx; 1314 struct wpabuf *out_data; 1315 int ret; 1316 1317 if (appl_data) 1318 *appl_data = NULL; 1319 1320 if (in_data && wpabuf_len(in_data) > 0) { 1321 if (conn->pull_buf) { 1322 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1323 "pull_buf", __func__, 1324 (unsigned long) wpabuf_len(conn->pull_buf)); 1325 wpabuf_free(conn->pull_buf); 1326 } 1327 conn->pull_buf = wpabuf_dup(in_data); 1328 if (conn->pull_buf == NULL) 1329 return NULL; 1330 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1331 } 1332 1333 ret = gnutls_handshake(conn->session); 1334 if (ret < 0) { 1335 gnutls_alert_description_t alert; 1336 1337 switch (ret) { 1338 case GNUTLS_E_AGAIN: 1339 if (global->server && conn->established && 1340 conn->push_buf == NULL) { 1341 /* Need to return something to trigger 1342 * completion of EAP-TLS. */ 1343 conn->push_buf = wpabuf_alloc(0); 1344 } 1345 break; 1346 case GNUTLS_E_FATAL_ALERT_RECEIVED: 1347 alert = gnutls_alert_get(conn->session); 1348 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 1349 __func__, gnutls_alert_get_name(alert)); 1350 conn->read_alerts++; 1351 if (conn->global->event_cb != NULL) { 1352 union tls_event_data ev; 1353 1354 os_memset(&ev, 0, sizeof(ev)); 1355 ev.alert.is_local = 0; 1356 ev.alert.type = gnutls_alert_get_name(alert); 1357 ev.alert.description = ev.alert.type; 1358 conn->global->event_cb(conn->global->cb_ctx, 1359 TLS_ALERT, &ev); 1360 } 1361 /* continue */ 1362 default: 1363 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 1364 "-> %s", __func__, gnutls_strerror(ret)); 1365 conn->failed++; 1366 } 1367 } else { 1368 size_t size; 1369 1370 wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); 1371 1372#if GNUTLS_VERSION_NUMBER >= 0x03010a 1373 { 1374 char *desc; 1375 1376 desc = gnutls_session_get_desc(conn->session); 1377 if (desc) { 1378 wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc); 1379 gnutls_free(desc); 1380 } 1381 } 1382#endif /* GnuTLS 3.1.10 or newer */ 1383 1384 conn->established = 1; 1385 if (conn->push_buf == NULL) { 1386 /* Need to return something to get final TLS ACK. */ 1387 conn->push_buf = wpabuf_alloc(0); 1388 } 1389 1390 gnutls_session_get_data(conn->session, NULL, &size); 1391 if (global->session_data == NULL || 1392 global->session_data_size < size) { 1393 os_free(global->session_data); 1394 global->session_data = os_malloc(size); 1395 } 1396 if (global->session_data) { 1397 global->session_data_size = size; 1398 gnutls_session_get_data(conn->session, 1399 global->session_data, 1400 &global->session_data_size); 1401 } 1402 1403 if (conn->pull_buf && appl_data) 1404 *appl_data = gnutls_get_appl_data(conn); 1405 } 1406 1407 out_data = conn->push_buf; 1408 conn->push_buf = NULL; 1409 return out_data; 1410} 1411 1412 1413struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 1414 struct tls_connection *conn, 1415 const struct wpabuf *in_data, 1416 struct wpabuf **appl_data) 1417{ 1418 return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); 1419} 1420 1421 1422struct wpabuf * tls_connection_encrypt(void *tls_ctx, 1423 struct tls_connection *conn, 1424 const struct wpabuf *in_data) 1425{ 1426 ssize_t res; 1427 struct wpabuf *buf; 1428 1429 res = gnutls_record_send(conn->session, wpabuf_head(in_data), 1430 wpabuf_len(in_data)); 1431 if (res < 0) { 1432 wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 1433 __func__, gnutls_strerror(res)); 1434 return NULL; 1435 } 1436 1437 buf = conn->push_buf; 1438 conn->push_buf = NULL; 1439 return buf; 1440} 1441 1442 1443struct wpabuf * tls_connection_decrypt(void *tls_ctx, 1444 struct tls_connection *conn, 1445 const struct wpabuf *in_data) 1446{ 1447 ssize_t res; 1448 struct wpabuf *out; 1449 1450 if (conn->pull_buf) { 1451 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1452 "pull_buf", __func__, 1453 (unsigned long) wpabuf_len(conn->pull_buf)); 1454 wpabuf_free(conn->pull_buf); 1455 } 1456 conn->pull_buf = wpabuf_dup(in_data); 1457 if (conn->pull_buf == NULL) 1458 return NULL; 1459 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1460 1461 /* 1462 * Even though we try to disable TLS compression, it is possible that 1463 * this cannot be done with all TLS libraries. Add extra buffer space 1464 * to handle the possibility of the decrypted data being longer than 1465 * input data. 1466 */ 1467 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 1468 if (out == NULL) 1469 return NULL; 1470 1471 res = gnutls_record_recv(conn->session, wpabuf_mhead(out), 1472 wpabuf_size(out)); 1473 if (res < 0) { 1474 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1475 "(%s)", __func__, (int) res, gnutls_strerror(res)); 1476 wpabuf_free(out); 1477 return NULL; 1478 } 1479 wpabuf_put(out, res); 1480 1481 return out; 1482} 1483 1484 1485int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 1486{ 1487 if (conn == NULL) 1488 return 0; 1489 return gnutls_session_is_resumed(conn->session); 1490} 1491 1492 1493int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 1494 u8 *ciphers) 1495{ 1496 /* TODO */ 1497 return -1; 1498} 1499 1500 1501int tls_get_version(void *ssl_ctx, struct tls_connection *conn, 1502 char *buf, size_t buflen) 1503{ 1504 /* TODO */ 1505 return -1; 1506} 1507 1508 1509int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 1510 char *buf, size_t buflen) 1511{ 1512 /* TODO */ 1513 buf[0] = '\0'; 1514 return 0; 1515} 1516 1517 1518int tls_connection_enable_workaround(void *ssl_ctx, 1519 struct tls_connection *conn) 1520{ 1521 gnutls_record_disable_padding(conn->session); 1522 return 0; 1523} 1524 1525 1526int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 1527 int ext_type, const u8 *data, 1528 size_t data_len) 1529{ 1530 /* TODO */ 1531 return -1; 1532} 1533 1534 1535int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 1536{ 1537 if (conn == NULL) 1538 return -1; 1539 return conn->failed; 1540} 1541 1542 1543int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 1544{ 1545 if (conn == NULL) 1546 return -1; 1547 return conn->read_alerts; 1548} 1549 1550 1551int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 1552{ 1553 if (conn == NULL) 1554 return -1; 1555 return conn->write_alerts; 1556} 1557 1558 1559int tls_connection_set_session_ticket_cb(void *tls_ctx, 1560 struct tls_connection *conn, 1561 tls_session_ticket_cb cb, void *ctx) 1562{ 1563 return -1; 1564} 1565 1566 1567int tls_get_library_version(char *buf, size_t buf_len) 1568{ 1569 return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s", 1570 GNUTLS_VERSION, gnutls_check_version(NULL)); 1571} 1572 1573 1574void tls_connection_set_success_data(struct tls_connection *conn, 1575 struct wpabuf *data) 1576{ 1577} 1578 1579 1580void tls_connection_set_success_data_resumed(struct tls_connection *conn) 1581{ 1582} 1583 1584 1585const struct wpabuf * 1586tls_connection_get_success_data(struct tls_connection *conn) 1587{ 1588 return NULL; 1589} 1590 1591 1592void tls_connection_remove_session(struct tls_connection *conn) 1593{ 1594} 1595