1 /* 2 * SSL/TLS interface functions for GnuTLS 3 * Copyright (c) 2004-2017, 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 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 char * tls_connection_peer_serial_num(void *tls_ctx, 299 struct tls_connection *conn) 300 { 301 /* TODO */ 302 return NULL; 303 } 304 305 306 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 307 { 308 struct tls_global *global = ssl_ctx; 309 int ret; 310 311 if (conn == NULL) 312 return -1; 313 314 /* Shutdown previous TLS connection without notifying the peer 315 * because the connection was already terminated in practice 316 * and "close notify" shutdown alert would confuse AS. */ 317 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); 318 wpabuf_free(conn->push_buf); 319 conn->push_buf = NULL; 320 conn->established = 0; 321 322 gnutls_deinit(conn->session); 323 if (tls_gnutls_init_session(global, conn)) { 324 wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session " 325 "for session resumption use"); 326 return -1; 327 } 328 329 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 330 conn->params_set ? conn->xcred : 331 global->xcred); 332 if (ret < 0) { 333 wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials " 334 "for session resumption: %s", gnutls_strerror(ret)); 335 return -1; 336 } 337 338 if (global->session_data) { 339 ret = gnutls_session_set_data(conn->session, 340 global->session_data, 341 global->session_data_size); 342 if (ret < 0) { 343 wpa_printf(MSG_INFO, "GnuTLS: Failed to set session " 344 "data: %s", gnutls_strerror(ret)); 345 return -1; 346 } 347 } 348 349 return 0; 350 } 351 352 353 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 354 const struct tls_connection_params *params) 355 { 356 int ret; 357 const char *err; 358 char prio_buf[100]; 359 const char *prio = NULL; 360 361 if (conn == NULL || params == NULL) 362 return -1; 363 364 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) { 365 wpa_printf(MSG_INFO, 366 "GnuTLS: ocsp=3 not supported"); 367 return -1; 368 } 369 370 if (params->flags & TLS_CONN_EXT_CERT_CHECK) { 371 wpa_printf(MSG_INFO, 372 "GnuTLS: tls_ext_cert_check=1 not supported"); 373 return -1; 374 } 375 376 if (params->subject_match) { 377 wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported"); 378 return -1; 379 } 380 381 if (params->altsubject_match) { 382 wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported"); 383 return -1; 384 } 385 386 os_free(conn->suffix_match); 387 conn->suffix_match = NULL; 388 if (params->suffix_match) { 389 conn->suffix_match = os_strdup(params->suffix_match); 390 if (conn->suffix_match == NULL) 391 return -1; 392 } 393 394 #if GNUTLS_VERSION_NUMBER >= 0x030300 395 os_free(conn->domain_match); 396 conn->domain_match = NULL; 397 if (params->domain_match) { 398 conn->domain_match = os_strdup(params->domain_match); 399 if (conn->domain_match == NULL) 400 return -1; 401 } 402 #else /* < 3.3.0 */ 403 if (params->domain_match) { 404 wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported"); 405 return -1; 406 } 407 #endif /* >= 3.3.0 */ 408 409 conn->flags = params->flags; 410 411 if (params->flags & (TLS_CONN_DISABLE_TLSv1_0 | 412 TLS_CONN_DISABLE_TLSv1_1 | 413 TLS_CONN_DISABLE_TLSv1_2)) { 414 os_snprintf(prio_buf, sizeof(prio_buf), 415 "NORMAL:-VERS-SSL3.0%s%s%s", 416 params->flags & TLS_CONN_DISABLE_TLSv1_0 ? 417 ":-VERS-TLS1.0" : "", 418 params->flags & TLS_CONN_DISABLE_TLSv1_1 ? 419 ":-VERS-TLS1.1" : "", 420 params->flags & TLS_CONN_DISABLE_TLSv1_2 ? 421 ":-VERS-TLS1.2" : ""); 422 prio = prio_buf; 423 } 424 425 if (params->openssl_ciphers) { 426 if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { 427 prio = "SUITEB128"; 428 } else if (os_strcmp(params->openssl_ciphers, 429 "SUITEB192") == 0) { 430 prio = "SUITEB192"; 431 } else if ((params->flags & TLS_CONN_SUITEB) && 432 os_strcmp(params->openssl_ciphers, 433 "ECDHE-RSA-AES256-GCM-SHA384") == 0) { 434 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL"; 435 } else if (os_strcmp(params->openssl_ciphers, 436 "ECDHE-RSA-AES256-GCM-SHA384") == 0) { 437 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL"; 438 } else if (os_strcmp(params->openssl_ciphers, 439 "DHE-RSA-AES256-GCM-SHA384") == 0) { 440 prio = "NONE:+VERS-TLS1.2:+AEAD:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH"; 441 } else if (os_strcmp(params->openssl_ciphers, 442 "ECDHE-ECDSA-AES256-GCM-SHA384") == 0) { 443 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL"; 444 } else { 445 wpa_printf(MSG_INFO, 446 "GnuTLS: openssl_ciphers not supported"); 447 return -1; 448 } 449 } else if (params->flags & TLS_CONN_SUITEB) { 450 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH"; 451 } 452 453 if (prio) { 454 wpa_printf(MSG_DEBUG, "GnuTLS: Set priority string: %s", prio); 455 ret = gnutls_priority_set_direct(conn->session, prio, &err); 456 if (ret < 0) { 457 wpa_printf(MSG_ERROR, 458 "GnuTLS: Priority string failure at '%s'", 459 err); 460 return -1; 461 } 462 } 463 464 /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); 465 * to force peer validation(?) */ 466 467 if (params->ca_cert) { 468 wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format", 469 params->ca_cert); 470 ret = gnutls_certificate_set_x509_trust_file( 471 conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 472 if (ret < 0) { 473 wpa_printf(MSG_DEBUG, 474 "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format", 475 params->ca_cert, 476 gnutls_strerror(ret)); 477 ret = gnutls_certificate_set_x509_trust_file( 478 conn->xcred, params->ca_cert, 479 GNUTLS_X509_FMT_PEM); 480 if (ret < 0) { 481 wpa_printf(MSG_DEBUG, 482 "Failed to read CA cert '%s' in PEM format: %s", 483 params->ca_cert, 484 gnutls_strerror(ret)); 485 return -1; 486 } 487 wpa_printf(MSG_DEBUG, 488 "GnuTLS: Successfully read CA cert '%s' in PEM format", 489 params->ca_cert); 490 } else { 491 wpa_printf(MSG_DEBUG, 492 "GnuTLS: Successfully read CA cert '%s' in DER format", 493 params->ca_cert); 494 } 495 } else if (params->ca_cert_blob) { 496 gnutls_datum_t ca; 497 498 ca.data = (unsigned char *) params->ca_cert_blob; 499 ca.size = params->ca_cert_blob_len; 500 501 ret = gnutls_certificate_set_x509_trust_mem( 502 conn->xcred, &ca, GNUTLS_X509_FMT_DER); 503 if (ret < 0) { 504 wpa_printf(MSG_DEBUG, 505 "Failed to parse CA cert in DER format: %s", 506 gnutls_strerror(ret)); 507 ret = gnutls_certificate_set_x509_trust_mem( 508 conn->xcred, &ca, GNUTLS_X509_FMT_PEM); 509 if (ret < 0) { 510 wpa_printf(MSG_DEBUG, 511 "Failed to parse CA cert in PEM format: %s", 512 gnutls_strerror(ret)); 513 return -1; 514 } 515 } 516 } else if (params->ca_path) { 517 wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported"); 518 return -1; 519 } 520 521 conn->disable_time_checks = 0; 522 if (params->ca_cert || params->ca_cert_blob) { 523 conn->verify_peer = 1; 524 gnutls_certificate_set_verify_function( 525 conn->xcred, tls_connection_verify_peer); 526 527 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 528 gnutls_certificate_set_verify_flags( 529 conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 530 } 531 532 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 533 conn->disable_time_checks = 1; 534 gnutls_certificate_set_verify_flags( 535 conn->xcred, 536 GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 537 } 538 } 539 540 if (params->client_cert && params->private_key) { 541 wpa_printf(MSG_DEBUG, 542 "GnuTLS: Try to parse client cert '%s' and key '%s' in DER format", 543 params->client_cert, params->private_key); 544 #if GNUTLS_VERSION_NUMBER >= 0x03010b 545 ret = gnutls_certificate_set_x509_key_file2( 546 conn->xcred, params->client_cert, params->private_key, 547 GNUTLS_X509_FMT_DER, params->private_key_passwd, 0); 548 #else 549 /* private_key_passwd not (easily) supported here */ 550 ret = gnutls_certificate_set_x509_key_file( 551 conn->xcred, params->client_cert, params->private_key, 552 GNUTLS_X509_FMT_DER); 553 #endif 554 if (ret < 0) { 555 wpa_printf(MSG_DEBUG, 556 "GnuTLS: Failed to read client cert/key in DER format (%s) - try in PEM format", 557 gnutls_strerror(ret)); 558 #if GNUTLS_VERSION_NUMBER >= 0x03010b 559 ret = gnutls_certificate_set_x509_key_file2( 560 conn->xcred, params->client_cert, 561 params->private_key, GNUTLS_X509_FMT_PEM, 562 params->private_key_passwd, 0); 563 #else 564 ret = gnutls_certificate_set_x509_key_file( 565 conn->xcred, params->client_cert, 566 params->private_key, GNUTLS_X509_FMT_PEM); 567 #endif 568 if (ret < 0) { 569 wpa_printf(MSG_DEBUG, "Failed to read client " 570 "cert/key in PEM format: %s", 571 gnutls_strerror(ret)); 572 return ret; 573 } 574 wpa_printf(MSG_DEBUG, 575 "GnuTLS: Successfully read client cert/key in PEM format"); 576 } else { 577 wpa_printf(MSG_DEBUG, 578 "GnuTLS: Successfully read client cert/key in DER format"); 579 } 580 } else if (params->private_key) { 581 int pkcs12_ok = 0; 582 #ifdef PKCS12_FUNCS 583 /* Try to load in PKCS#12 format */ 584 wpa_printf(MSG_DEBUG, 585 "GnuTLS: Try to parse client cert/key '%s'in PKCS#12 DER format", 586 params->private_key); 587 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 588 conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, 589 params->private_key_passwd); 590 if (ret != 0) { 591 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 592 "PKCS#12 format: %s", gnutls_strerror(ret)); 593 return -1; 594 } else 595 pkcs12_ok = 1; 596 #endif /* PKCS12_FUNCS */ 597 598 if (!pkcs12_ok) { 599 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 600 "included"); 601 return -1; 602 } 603 } else if (params->client_cert_blob && params->private_key_blob) { 604 gnutls_datum_t cert, key; 605 606 cert.data = (unsigned char *) params->client_cert_blob; 607 cert.size = params->client_cert_blob_len; 608 key.data = (unsigned char *) params->private_key_blob; 609 key.size = params->private_key_blob_len; 610 611 #if GNUTLS_VERSION_NUMBER >= 0x03010b 612 ret = gnutls_certificate_set_x509_key_mem2( 613 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER, 614 params->private_key_passwd, 0); 615 #else 616 /* private_key_passwd not (easily) supported here */ 617 ret = gnutls_certificate_set_x509_key_mem( 618 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER); 619 #endif 620 if (ret < 0) { 621 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 622 "in DER format: %s", gnutls_strerror(ret)); 623 #if GNUTLS_VERSION_NUMBER >= 0x03010b 624 ret = gnutls_certificate_set_x509_key_mem2( 625 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM, 626 params->private_key_passwd, 0); 627 #else 628 /* private_key_passwd not (easily) supported here */ 629 ret = gnutls_certificate_set_x509_key_mem( 630 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM); 631 #endif 632 if (ret < 0) { 633 wpa_printf(MSG_DEBUG, "Failed to read client " 634 "cert/key in PEM format: %s", 635 gnutls_strerror(ret)); 636 return ret; 637 } 638 } 639 } else if (params->private_key_blob) { 640 #ifdef PKCS12_FUNCS 641 gnutls_datum_t key; 642 643 key.data = (unsigned char *) params->private_key_blob; 644 key.size = params->private_key_blob_len; 645 646 /* Try to load in PKCS#12 format */ 647 ret = gnutls_certificate_set_x509_simple_pkcs12_mem( 648 conn->xcred, &key, GNUTLS_X509_FMT_DER, 649 params->private_key_passwd); 650 if (ret != 0) { 651 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 652 "PKCS#12 format: %s", gnutls_strerror(ret)); 653 return -1; 654 } 655 #else /* PKCS12_FUNCS */ 656 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included"); 657 return -1; 658 #endif /* PKCS12_FUNCS */ 659 } 660 661 #if GNUTLS_VERSION_NUMBER >= 0x030103 662 if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) { 663 ret = gnutls_ocsp_status_request_enable_client(conn->session, 664 NULL, 0, NULL); 665 if (ret != GNUTLS_E_SUCCESS) { 666 wpa_printf(MSG_INFO, 667 "GnuTLS: Failed to enable OCSP client"); 668 return -1; 669 } 670 } 671 #else /* 3.1.3 */ 672 if (params->flags & TLS_CONN_REQUIRE_OCSP) { 673 wpa_printf(MSG_INFO, 674 "GnuTLS: OCSP not supported by this version of GnuTLS"); 675 return -1; 676 } 677 #endif /* 3.1.3 */ 678 679 conn->params_set = 1; 680 681 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 682 conn->xcred); 683 if (ret < 0) { 684 wpa_printf(MSG_INFO, "Failed to configure credentials: %s", 685 gnutls_strerror(ret)); 686 } 687 688 return ret; 689 } 690 691 692 #if GNUTLS_VERSION_NUMBER >= 0x030103 693 static int server_ocsp_status_req(gnutls_session_t session, void *ptr, 694 gnutls_datum_t *resp) 695 { 696 struct tls_global *global = ptr; 697 char *cached; 698 size_t len; 699 700 if (!global->ocsp_stapling_response) { 701 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured"); 702 return GNUTLS_E_NO_CERTIFICATE_STATUS; 703 } 704 705 cached = os_readfile(global->ocsp_stapling_response, &len); 706 if (!cached) { 707 wpa_printf(MSG_DEBUG, 708 "GnuTLS: OCSP status callback - could not read response file (%s)", 709 global->ocsp_stapling_response); 710 return GNUTLS_E_NO_CERTIFICATE_STATUS; 711 } 712 713 wpa_printf(MSG_DEBUG, 714 "GnuTLS: OCSP status callback - send cached response"); 715 resp->data = gnutls_malloc(len); 716 if (!resp->data) { 717 os_free(resp); 718 return GNUTLS_E_MEMORY_ERROR; 719 } 720 721 os_memcpy(resp->data, cached, len); 722 resp->size = len; 723 os_free(cached); 724 725 return GNUTLS_E_SUCCESS; 726 } 727 #endif /* 3.1.3 */ 728 729 730 int tls_global_set_params(void *tls_ctx, 731 const struct tls_connection_params *params) 732 { 733 struct tls_global *global = tls_ctx; 734 int ret; 735 736 /* Currently, global parameters are only set when running in server 737 * mode. */ 738 global->server = 1; 739 740 if (global->params_set) { 741 gnutls_certificate_free_credentials(global->xcred); 742 global->params_set = 0; 743 } 744 745 ret = gnutls_certificate_allocate_credentials(&global->xcred); 746 if (ret) { 747 wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " 748 "%s", gnutls_strerror(ret)); 749 return -1; 750 } 751 752 if (params->ca_cert) { 753 ret = gnutls_certificate_set_x509_trust_file( 754 global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 755 if (ret < 0) { 756 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 757 "in DER format: %s", params->ca_cert, 758 gnutls_strerror(ret)); 759 ret = gnutls_certificate_set_x509_trust_file( 760 global->xcred, params->ca_cert, 761 GNUTLS_X509_FMT_PEM); 762 if (ret < 0) { 763 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 764 "'%s' in PEM format: %s", 765 params->ca_cert, 766 gnutls_strerror(ret)); 767 goto fail; 768 } 769 } 770 771 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 772 gnutls_certificate_set_verify_flags( 773 global->xcred, 774 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 775 } 776 777 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 778 gnutls_certificate_set_verify_flags( 779 global->xcred, 780 GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 781 } 782 } 783 784 if (params->client_cert && params->private_key) { 785 /* TODO: private_key_passwd? */ 786 ret = gnutls_certificate_set_x509_key_file( 787 global->xcred, params->client_cert, 788 params->private_key, GNUTLS_X509_FMT_DER); 789 if (ret < 0) { 790 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 791 "in DER format: %s", gnutls_strerror(ret)); 792 ret = gnutls_certificate_set_x509_key_file( 793 global->xcred, params->client_cert, 794 params->private_key, GNUTLS_X509_FMT_PEM); 795 if (ret < 0) { 796 wpa_printf(MSG_DEBUG, "Failed to read client " 797 "cert/key in PEM format: %s", 798 gnutls_strerror(ret)); 799 goto fail; 800 } 801 } 802 } else if (params->private_key) { 803 int pkcs12_ok = 0; 804 #ifdef PKCS12_FUNCS 805 /* Try to load in PKCS#12 format */ 806 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 807 global->xcred, params->private_key, 808 GNUTLS_X509_FMT_DER, params->private_key_passwd); 809 if (ret != 0) { 810 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 811 "PKCS#12 format: %s", gnutls_strerror(ret)); 812 goto fail; 813 } else 814 pkcs12_ok = 1; 815 #endif /* PKCS12_FUNCS */ 816 817 if (!pkcs12_ok) { 818 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 819 "included"); 820 goto fail; 821 } 822 } 823 824 #if GNUTLS_VERSION_NUMBER >= 0x030103 825 os_free(global->ocsp_stapling_response); 826 if (params->ocsp_stapling_response) 827 global->ocsp_stapling_response = 828 os_strdup(params->ocsp_stapling_response); 829 else 830 global->ocsp_stapling_response = NULL; 831 gnutls_certificate_set_ocsp_status_request_function( 832 global->xcred, server_ocsp_status_req, global); 833 #endif /* 3.1.3 */ 834 835 global->params_set = 1; 836 837 return 0; 838 839 fail: 840 gnutls_certificate_free_credentials(global->xcred); 841 return -1; 842 } 843 844 845 int tls_global_set_verify(void *ssl_ctx, int check_crl) 846 { 847 /* TODO */ 848 return 0; 849 } 850 851 852 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 853 int verify_peer, unsigned int flags, 854 const u8 *session_ctx, size_t session_ctx_len) 855 { 856 if (conn == NULL || conn->session == NULL) 857 return -1; 858 859 conn->verify_peer = verify_peer; 860 gnutls_certificate_server_set_request(conn->session, 861 verify_peer ? GNUTLS_CERT_REQUIRE 862 : GNUTLS_CERT_REQUEST); 863 864 return 0; 865 } 866 867 868 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, 869 struct tls_random *keys) 870 { 871 #if GNUTLS_VERSION_NUMBER >= 0x030012 872 gnutls_datum_t client, server; 873 874 if (conn == NULL || conn->session == NULL || keys == NULL) 875 return -1; 876 877 os_memset(keys, 0, sizeof(*keys)); 878 gnutls_session_get_random(conn->session, &client, &server); 879 keys->client_random = client.data; 880 keys->server_random = server.data; 881 keys->client_random_len = client.size; 882 keys->server_random_len = client.size; 883 884 return 0; 885 #else /* 3.0.18 */ 886 return -1; 887 #endif /* 3.0.18 */ 888 } 889 890 891 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, 892 const char *label, u8 *out, size_t out_len) 893 { 894 if (conn == NULL || conn->session == NULL) 895 return -1; 896 897 return gnutls_prf(conn->session, os_strlen(label), label, 898 0 /* client_random first */, 0, NULL, out_len, 899 (char *) out); 900 } 901 902 903 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, 904 u8 *out, size_t out_len) 905 { 906 return -1; 907 } 908 909 910 static void gnutls_tls_fail_event(struct tls_connection *conn, 911 const gnutls_datum_t *cert, int depth, 912 const char *subject, const char *err_str, 913 enum tls_fail_reason reason) 914 { 915 union tls_event_data ev; 916 struct tls_global *global = conn->global; 917 struct wpabuf *cert_buf = NULL; 918 919 if (global->event_cb == NULL) 920 return; 921 922 os_memset(&ev, 0, sizeof(ev)); 923 ev.cert_fail.depth = depth; 924 ev.cert_fail.subject = subject ? subject : ""; 925 ev.cert_fail.reason = reason; 926 ev.cert_fail.reason_txt = err_str; 927 if (cert) { 928 cert_buf = wpabuf_alloc_copy(cert->data, cert->size); 929 ev.cert_fail.cert = cert_buf; 930 } 931 global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 932 wpabuf_free(cert_buf); 933 } 934 935 936 #if GNUTLS_VERSION_NUMBER < 0x030300 937 static int server_eku_purpose(gnutls_x509_crt_t cert) 938 { 939 unsigned int i; 940 941 for (i = 0; ; i++) { 942 char oid[128]; 943 size_t oid_size = sizeof(oid); 944 int res; 945 946 res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, 947 &oid_size, NULL); 948 if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { 949 if (i == 0) { 950 /* No EKU - assume any use allowed */ 951 return 1; 952 } 953 break; 954 } 955 956 if (res < 0) { 957 wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU"); 958 return 0; 959 } 960 961 wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid); 962 if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 || 963 os_strcmp(oid, GNUTLS_KP_ANY) == 0) 964 return 1; 965 } 966 967 return 0; 968 } 969 #endif /* < 3.3.0 */ 970 971 972 static int check_ocsp(struct tls_connection *conn, gnutls_session_t session, 973 gnutls_alert_description_t *err) 974 { 975 #if GNUTLS_VERSION_NUMBER >= 0x030103 976 gnutls_datum_t response, buf; 977 gnutls_ocsp_resp_t resp; 978 unsigned int cert_status; 979 int res; 980 981 if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP))) 982 return 0; 983 984 if (!gnutls_ocsp_status_request_is_checked(session, 0)) { 985 if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 986 wpa_printf(MSG_INFO, 987 "GnuTLS: No valid OCSP response received"); 988 goto ocsp_error; 989 } 990 991 wpa_printf(MSG_DEBUG, 992 "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required"); 993 return 0; 994 } 995 996 /* 997 * GnuTLS has already verified the OCSP response in 998 * check_ocsp_response() and rejected handshake if the certificate was 999 * found to be revoked. However, if the response indicates that the 1000 * status is unknown, handshake continues and reaches here. We need to 1001 * re-import the OCSP response to check for unknown certificate status, 1002 * but we do not need to repeat gnutls_ocsp_resp_check_crt() and 1003 * gnutls_ocsp_resp_verify_direct() calls. 1004 */ 1005 1006 res = gnutls_ocsp_status_request_get(session, &response); 1007 if (res != GNUTLS_E_SUCCESS) { 1008 wpa_printf(MSG_INFO, 1009 "GnuTLS: OCSP response was received, but it was not valid"); 1010 goto ocsp_error; 1011 } 1012 1013 if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS) 1014 goto ocsp_error; 1015 1016 res = gnutls_ocsp_resp_import(resp, &response); 1017 if (res != GNUTLS_E_SUCCESS) { 1018 wpa_printf(MSG_INFO, 1019 "GnuTLS: Could not parse received OCSP response: %s", 1020 gnutls_strerror(res)); 1021 gnutls_ocsp_resp_deinit(resp); 1022 goto ocsp_error; 1023 } 1024 1025 res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf); 1026 if (res == GNUTLS_E_SUCCESS) { 1027 wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data); 1028 gnutls_free(buf.data); 1029 } 1030 1031 res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, 1032 NULL, &cert_status, NULL, 1033 NULL, NULL, NULL); 1034 gnutls_ocsp_resp_deinit(resp); 1035 if (res != GNUTLS_E_SUCCESS) { 1036 wpa_printf(MSG_INFO, 1037 "GnuTLS: Failed to extract OCSP information: %s", 1038 gnutls_strerror(res)); 1039 goto ocsp_error; 1040 } 1041 1042 if (cert_status == GNUTLS_OCSP_CERT_GOOD) { 1043 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good"); 1044 } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { 1045 wpa_printf(MSG_DEBUG, 1046 "GnuTLS: OCSP cert status: revoked"); 1047 goto ocsp_error; 1048 } else { 1049 wpa_printf(MSG_DEBUG, 1050 "GnuTLS: OCSP cert status: unknown"); 1051 if (conn->flags & TLS_CONN_REQUIRE_OCSP) 1052 goto ocsp_error; 1053 wpa_printf(MSG_DEBUG, 1054 "GnuTLS: OCSP was not required, so allow connection to continue"); 1055 } 1056 1057 return 0; 1058 1059 ocsp_error: 1060 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1061 "bad certificate status response", 1062 TLS_FAIL_REVOKED); 1063 *err = GNUTLS_A_CERTIFICATE_REVOKED; 1064 return -1; 1065 #else /* GnuTLS 3.1.3 or newer */ 1066 return 0; 1067 #endif /* GnuTLS 3.1.3 or newer */ 1068 } 1069 1070 1071 static int tls_connection_verify_peer(gnutls_session_t session) 1072 { 1073 struct tls_connection *conn; 1074 unsigned int status, num_certs, i; 1075 struct os_time now; 1076 const gnutls_datum_t *certs; 1077 gnutls_x509_crt_t cert; 1078 gnutls_alert_description_t err; 1079 int res; 1080 1081 conn = gnutls_session_get_ptr(session); 1082 if (!conn->verify_peer) { 1083 wpa_printf(MSG_DEBUG, 1084 "GnuTLS: No peer certificate verification enabled"); 1085 return 0; 1086 } 1087 1088 wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate"); 1089 1090 #if GNUTLS_VERSION_NUMBER >= 0x030300 1091 { 1092 gnutls_typed_vdata_st data[1]; 1093 unsigned int elements = 0; 1094 1095 os_memset(data, 0, sizeof(data)); 1096 if (!conn->global->server) { 1097 data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID; 1098 data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER; 1099 elements++; 1100 } 1101 res = gnutls_certificate_verify_peers(session, data, 1, 1102 &status); 1103 } 1104 #else /* < 3.3.0 */ 1105 res = gnutls_certificate_verify_peers2(session, &status); 1106 #endif 1107 if (res < 0) { 1108 wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 1109 "certificate chain"); 1110 err = GNUTLS_A_INTERNAL_ERROR; 1111 goto out; 1112 } 1113 1114 #if GNUTLS_VERSION_NUMBER >= 0x030104 1115 { 1116 gnutls_datum_t info; 1117 int ret, type; 1118 1119 type = gnutls_certificate_type_get(session); 1120 ret = gnutls_certificate_verification_status_print(status, type, 1121 &info, 0); 1122 if (ret < 0) { 1123 wpa_printf(MSG_DEBUG, 1124 "GnuTLS: Failed to print verification status"); 1125 err = GNUTLS_A_INTERNAL_ERROR; 1126 goto out; 1127 } 1128 wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data); 1129 gnutls_free(info.data); 1130 } 1131 #endif /* GnuTLS 3.1.4 or newer */ 1132 1133 certs = gnutls_certificate_get_peers(session, &num_certs); 1134 if (certs == NULL || num_certs == 0) { 1135 wpa_printf(MSG_INFO, "TLS: No peer certificate chain received"); 1136 err = GNUTLS_A_UNKNOWN_CA; 1137 goto out; 1138 } 1139 1140 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 1141 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 1142 if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { 1143 wpa_printf(MSG_INFO, "TLS: Certificate uses insecure " 1144 "algorithm"); 1145 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1146 "certificate uses insecure algorithm", 1147 TLS_FAIL_BAD_CERTIFICATE); 1148 err = GNUTLS_A_INSUFFICIENT_SECURITY; 1149 goto out; 1150 } 1151 if (status & GNUTLS_CERT_NOT_ACTIVATED) { 1152 wpa_printf(MSG_INFO, "TLS: Certificate not yet " 1153 "activated"); 1154 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1155 "certificate not yet valid", 1156 TLS_FAIL_NOT_YET_VALID); 1157 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1158 goto out; 1159 } 1160 if (status & GNUTLS_CERT_EXPIRED) { 1161 wpa_printf(MSG_INFO, "TLS: Certificate expired"); 1162 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1163 "certificate has expired", 1164 TLS_FAIL_EXPIRED); 1165 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1166 goto out; 1167 } 1168 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1169 "untrusted certificate", 1170 TLS_FAIL_UNTRUSTED); 1171 err = GNUTLS_A_INTERNAL_ERROR; 1172 goto out; 1173 } 1174 1175 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 1176 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 1177 "known issuer"); 1178 gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found", 1179 TLS_FAIL_UNTRUSTED); 1180 err = GNUTLS_A_UNKNOWN_CA; 1181 goto out; 1182 } 1183 1184 if (status & GNUTLS_CERT_REVOKED) { 1185 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 1186 gnutls_tls_fail_event(conn, NULL, 0, NULL, 1187 "certificate revoked", 1188 TLS_FAIL_REVOKED); 1189 err = GNUTLS_A_CERTIFICATE_REVOKED; 1190 goto out; 1191 } 1192 1193 if (status != 0) { 1194 wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d", 1195 status); 1196 err = GNUTLS_A_INTERNAL_ERROR; 1197 goto out; 1198 } 1199 1200 if (check_ocsp(conn, session, &err)) 1201 goto out; 1202 1203 os_get_time(&now); 1204 1205 for (i = 0; i < num_certs; i++) { 1206 char *buf; 1207 size_t len; 1208 if (gnutls_x509_crt_init(&cert) < 0) { 1209 wpa_printf(MSG_INFO, "TLS: Certificate initialization " 1210 "failed"); 1211 err = GNUTLS_A_BAD_CERTIFICATE; 1212 goto out; 1213 } 1214 1215 if (gnutls_x509_crt_import(cert, &certs[i], 1216 GNUTLS_X509_FMT_DER) < 0) { 1217 wpa_printf(MSG_INFO, "TLS: Could not parse peer " 1218 "certificate %d/%d", i + 1, num_certs); 1219 gnutls_x509_crt_deinit(cert); 1220 err = GNUTLS_A_BAD_CERTIFICATE; 1221 goto out; 1222 } 1223 1224 gnutls_x509_crt_get_dn(cert, NULL, &len); 1225 len++; 1226 buf = os_malloc(len + 1); 1227 if (buf) { 1228 buf[0] = buf[len] = '\0'; 1229 gnutls_x509_crt_get_dn(cert, buf, &len); 1230 } 1231 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 1232 i + 1, num_certs, buf); 1233 1234 if (conn->global->event_cb) { 1235 struct wpabuf *cert_buf = NULL; 1236 union tls_event_data ev; 1237 #ifdef CONFIG_SHA256 1238 u8 hash[32]; 1239 const u8 *_addr[1]; 1240 size_t _len[1]; 1241 #endif /* CONFIG_SHA256 */ 1242 1243 os_memset(&ev, 0, sizeof(ev)); 1244 if (conn->global->cert_in_cb) { 1245 cert_buf = wpabuf_alloc_copy(certs[i].data, 1246 certs[i].size); 1247 ev.peer_cert.cert = cert_buf; 1248 } 1249 #ifdef CONFIG_SHA256 1250 _addr[0] = certs[i].data; 1251 _len[0] = certs[i].size; 1252 if (sha256_vector(1, _addr, _len, hash) == 0) { 1253 ev.peer_cert.hash = hash; 1254 ev.peer_cert.hash_len = sizeof(hash); 1255 } 1256 #endif /* CONFIG_SHA256 */ 1257 ev.peer_cert.depth = i; 1258 ev.peer_cert.subject = buf; 1259 conn->global->event_cb(conn->global->cb_ctx, 1260 TLS_PEER_CERTIFICATE, &ev); 1261 wpabuf_free(cert_buf); 1262 } 1263 1264 if (i == 0) { 1265 if (conn->suffix_match && 1266 !gnutls_x509_crt_check_hostname( 1267 cert, conn->suffix_match)) { 1268 wpa_printf(MSG_WARNING, 1269 "TLS: Domain suffix match '%s' not found", 1270 conn->suffix_match); 1271 gnutls_tls_fail_event( 1272 conn, &certs[i], i, buf, 1273 "Domain suffix mismatch", 1274 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 1275 err = GNUTLS_A_BAD_CERTIFICATE; 1276 gnutls_x509_crt_deinit(cert); 1277 os_free(buf); 1278 goto out; 1279 } 1280 1281 #if GNUTLS_VERSION_NUMBER >= 0x030300 1282 if (conn->domain_match && 1283 !gnutls_x509_crt_check_hostname2( 1284 cert, conn->domain_match, 1285 GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) { 1286 wpa_printf(MSG_WARNING, 1287 "TLS: Domain match '%s' not found", 1288 conn->domain_match); 1289 gnutls_tls_fail_event( 1290 conn, &certs[i], i, buf, 1291 "Domain mismatch", 1292 TLS_FAIL_DOMAIN_MISMATCH); 1293 err = GNUTLS_A_BAD_CERTIFICATE; 1294 gnutls_x509_crt_deinit(cert); 1295 os_free(buf); 1296 goto out; 1297 } 1298 #endif /* >= 3.3.0 */ 1299 1300 /* TODO: validate altsubject_match. 1301 * For now, any such configuration is rejected in 1302 * tls_connection_set_params() */ 1303 1304 #if GNUTLS_VERSION_NUMBER < 0x030300 1305 /* 1306 * gnutls_certificate_verify_peers() not available, so 1307 * need to check EKU separately. 1308 */ 1309 if (!conn->global->server && 1310 !server_eku_purpose(cert)) { 1311 wpa_printf(MSG_WARNING, 1312 "GnuTLS: No server EKU"); 1313 gnutls_tls_fail_event( 1314 conn, &certs[i], i, buf, 1315 "No server EKU", 1316 TLS_FAIL_BAD_CERTIFICATE); 1317 err = GNUTLS_A_BAD_CERTIFICATE; 1318 gnutls_x509_crt_deinit(cert); 1319 os_free(buf); 1320 goto out; 1321 } 1322 #endif /* < 3.3.0 */ 1323 } 1324 1325 if (!conn->disable_time_checks && 1326 (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 1327 gnutls_x509_crt_get_activation_time(cert) > now.sec)) { 1328 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 1329 "not valid at this time", 1330 i + 1, num_certs); 1331 gnutls_tls_fail_event( 1332 conn, &certs[i], i, buf, 1333 "Certificate is not valid at this time", 1334 TLS_FAIL_EXPIRED); 1335 gnutls_x509_crt_deinit(cert); 1336 os_free(buf); 1337 err = GNUTLS_A_CERTIFICATE_EXPIRED; 1338 goto out; 1339 } 1340 1341 os_free(buf); 1342 1343 gnutls_x509_crt_deinit(cert); 1344 } 1345 1346 if (conn->global->event_cb != NULL) 1347 conn->global->event_cb(conn->global->cb_ctx, 1348 TLS_CERT_CHAIN_SUCCESS, NULL); 1349 1350 return 0; 1351 1352 out: 1353 conn->failed++; 1354 gnutls_alert_send(session, GNUTLS_AL_FATAL, err); 1355 return GNUTLS_E_CERTIFICATE_ERROR; 1356 } 1357 1358 1359 static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn) 1360 { 1361 int res; 1362 struct wpabuf *ad; 1363 wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data"); 1364 ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3); 1365 if (ad == NULL) 1366 return NULL; 1367 1368 res = gnutls_record_recv(conn->session, wpabuf_mhead(ad), 1369 wpabuf_size(ad)); 1370 wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res); 1371 if (res < 0) { 1372 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1373 "(%s)", __func__, (int) res, 1374 gnutls_strerror(res)); 1375 wpabuf_free(ad); 1376 return NULL; 1377 } 1378 1379 wpabuf_put(ad, res); 1380 wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data", 1381 res); 1382 return ad; 1383 } 1384 1385 1386 struct wpabuf * tls_connection_handshake(void *tls_ctx, 1387 struct tls_connection *conn, 1388 const struct wpabuf *in_data, 1389 struct wpabuf **appl_data) 1390 { 1391 struct tls_global *global = tls_ctx; 1392 struct wpabuf *out_data; 1393 int ret; 1394 1395 if (appl_data) 1396 *appl_data = NULL; 1397 1398 if (in_data && wpabuf_len(in_data) > 0) { 1399 if (conn->pull_buf) { 1400 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1401 "pull_buf", __func__, 1402 (unsigned long) wpabuf_len(conn->pull_buf)); 1403 wpabuf_free(conn->pull_buf); 1404 } 1405 conn->pull_buf = wpabuf_dup(in_data); 1406 if (conn->pull_buf == NULL) 1407 return NULL; 1408 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1409 } 1410 1411 ret = gnutls_handshake(conn->session); 1412 if (ret < 0) { 1413 gnutls_alert_description_t alert; 1414 union tls_event_data ev; 1415 1416 switch (ret) { 1417 case GNUTLS_E_AGAIN: 1418 if (global->server && conn->established && 1419 conn->push_buf == NULL) { 1420 /* Need to return something to trigger 1421 * completion of EAP-TLS. */ 1422 conn->push_buf = wpabuf_alloc(0); 1423 } 1424 break; 1425 case GNUTLS_E_DH_PRIME_UNACCEPTABLE: 1426 wpa_printf(MSG_DEBUG, "GnuTLS: Unacceptable DH prime"); 1427 if (conn->global->event_cb) { 1428 os_memset(&ev, 0, sizeof(ev)); 1429 ev.alert.is_local = 1; 1430 ev.alert.type = "fatal"; 1431 ev.alert.description = "insufficient security"; 1432 conn->global->event_cb(conn->global->cb_ctx, 1433 TLS_ALERT, &ev); 1434 } 1435 /* 1436 * Could send a TLS Alert to the server, but for now, 1437 * simply terminate handshake. 1438 */ 1439 conn->failed++; 1440 conn->write_alerts++; 1441 break; 1442 case GNUTLS_E_FATAL_ALERT_RECEIVED: 1443 alert = gnutls_alert_get(conn->session); 1444 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 1445 __func__, gnutls_alert_get_name(alert)); 1446 conn->read_alerts++; 1447 if (conn->global->event_cb != NULL) { 1448 os_memset(&ev, 0, sizeof(ev)); 1449 ev.alert.is_local = 0; 1450 ev.alert.type = gnutls_alert_get_name(alert); 1451 ev.alert.description = ev.alert.type; 1452 conn->global->event_cb(conn->global->cb_ctx, 1453 TLS_ALERT, &ev); 1454 } 1455 /* continue */ 1456 default: 1457 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 1458 "-> %s", __func__, gnutls_strerror(ret)); 1459 conn->failed++; 1460 } 1461 } else { 1462 size_t size; 1463 1464 wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); 1465 1466 #if GNUTLS_VERSION_NUMBER >= 0x03010a 1467 { 1468 char *desc; 1469 1470 desc = gnutls_session_get_desc(conn->session); 1471 if (desc) { 1472 wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc); 1473 gnutls_free(desc); 1474 } 1475 } 1476 #endif /* GnuTLS 3.1.10 or newer */ 1477 1478 conn->established = 1; 1479 if (conn->push_buf == NULL) { 1480 /* Need to return something to get final TLS ACK. */ 1481 conn->push_buf = wpabuf_alloc(0); 1482 } 1483 1484 gnutls_session_get_data(conn->session, NULL, &size); 1485 if (global->session_data == NULL || 1486 global->session_data_size < size) { 1487 os_free(global->session_data); 1488 global->session_data = os_malloc(size); 1489 } 1490 if (global->session_data) { 1491 global->session_data_size = size; 1492 gnutls_session_get_data(conn->session, 1493 global->session_data, 1494 &global->session_data_size); 1495 } 1496 1497 if (conn->pull_buf && appl_data) 1498 *appl_data = gnutls_get_appl_data(conn); 1499 } 1500 1501 out_data = conn->push_buf; 1502 conn->push_buf = NULL; 1503 return out_data; 1504 } 1505 1506 1507 struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 1508 struct tls_connection *conn, 1509 const struct wpabuf *in_data, 1510 struct wpabuf **appl_data) 1511 { 1512 return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); 1513 } 1514 1515 1516 struct wpabuf * tls_connection_encrypt(void *tls_ctx, 1517 struct tls_connection *conn, 1518 const struct wpabuf *in_data) 1519 { 1520 ssize_t res; 1521 struct wpabuf *buf; 1522 1523 res = gnutls_record_send(conn->session, wpabuf_head(in_data), 1524 wpabuf_len(in_data)); 1525 if (res < 0) { 1526 wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 1527 __func__, gnutls_strerror(res)); 1528 return NULL; 1529 } 1530 1531 buf = conn->push_buf; 1532 conn->push_buf = NULL; 1533 return buf; 1534 } 1535 1536 1537 struct wpabuf * tls_connection_decrypt(void *tls_ctx, 1538 struct tls_connection *conn, 1539 const struct wpabuf *in_data) 1540 { 1541 ssize_t res; 1542 struct wpabuf *out; 1543 1544 if (conn->pull_buf) { 1545 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1546 "pull_buf", __func__, 1547 (unsigned long) wpabuf_len(conn->pull_buf)); 1548 wpabuf_free(conn->pull_buf); 1549 } 1550 conn->pull_buf = wpabuf_dup(in_data); 1551 if (conn->pull_buf == NULL) 1552 return NULL; 1553 conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 1554 1555 /* 1556 * Even though we try to disable TLS compression, it is possible that 1557 * this cannot be done with all TLS libraries. Add extra buffer space 1558 * to handle the possibility of the decrypted data being longer than 1559 * input data. 1560 */ 1561 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 1562 if (out == NULL) 1563 return NULL; 1564 1565 res = gnutls_record_recv(conn->session, wpabuf_mhead(out), 1566 wpabuf_size(out)); 1567 if (res < 0) { 1568 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1569 "(%s)", __func__, (int) res, gnutls_strerror(res)); 1570 wpabuf_free(out); 1571 return NULL; 1572 } 1573 wpabuf_put(out, res); 1574 1575 return out; 1576 } 1577 1578 1579 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 1580 { 1581 if (conn == NULL) 1582 return 0; 1583 return gnutls_session_is_resumed(conn->session); 1584 } 1585 1586 1587 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 1588 u8 *ciphers) 1589 { 1590 /* TODO */ 1591 return -1; 1592 } 1593 1594 1595 int tls_get_version(void *ssl_ctx, struct tls_connection *conn, 1596 char *buf, size_t buflen) 1597 { 1598 gnutls_protocol_t ver; 1599 1600 ver = gnutls_protocol_get_version(conn->session); 1601 if (ver == GNUTLS_TLS1_0) 1602 os_strlcpy(buf, "TLSv1", buflen); 1603 else if (ver == GNUTLS_TLS1_1) 1604 os_strlcpy(buf, "TLSv1.1", buflen); 1605 else if (ver == GNUTLS_TLS1_2) 1606 os_strlcpy(buf, "TLSv1.2", buflen); 1607 else 1608 return -1; 1609 return 0; 1610 } 1611 1612 1613 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 1614 char *buf, size_t buflen) 1615 { 1616 gnutls_cipher_algorithm_t cipher; 1617 gnutls_kx_algorithm_t kx; 1618 gnutls_mac_algorithm_t mac; 1619 const char *kx_str, *cipher_str, *mac_str; 1620 int res; 1621 1622 cipher = gnutls_cipher_get(conn->session); 1623 cipher_str = gnutls_cipher_get_name(cipher); 1624 if (!cipher_str) 1625 cipher_str = ""; 1626 1627 kx = gnutls_kx_get(conn->session); 1628 kx_str = gnutls_kx_get_name(kx); 1629 if (!kx_str) 1630 kx_str = ""; 1631 1632 mac = gnutls_mac_get(conn->session); 1633 mac_str = gnutls_mac_get_name(mac); 1634 if (!mac_str) 1635 mac_str = ""; 1636 1637 if (kx == GNUTLS_KX_RSA) 1638 res = os_snprintf(buf, buflen, "%s-%s", cipher_str, mac_str); 1639 else 1640 res = os_snprintf(buf, buflen, "%s-%s-%s", 1641 kx_str, cipher_str, mac_str); 1642 if (os_snprintf_error(buflen, res)) 1643 return -1; 1644 1645 return 0; 1646 } 1647 1648 1649 int tls_connection_enable_workaround(void *ssl_ctx, 1650 struct tls_connection *conn) 1651 { 1652 gnutls_record_disable_padding(conn->session); 1653 return 0; 1654 } 1655 1656 1657 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 1658 int ext_type, const u8 *data, 1659 size_t data_len) 1660 { 1661 /* TODO */ 1662 return -1; 1663 } 1664 1665 1666 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 1667 { 1668 if (conn == NULL) 1669 return -1; 1670 return conn->failed; 1671 } 1672 1673 1674 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 1675 { 1676 if (conn == NULL) 1677 return -1; 1678 return conn->read_alerts; 1679 } 1680 1681 1682 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 1683 { 1684 if (conn == NULL) 1685 return -1; 1686 return conn->write_alerts; 1687 } 1688 1689 1690 int tls_connection_set_session_ticket_cb(void *tls_ctx, 1691 struct tls_connection *conn, 1692 tls_session_ticket_cb cb, void *ctx) 1693 { 1694 return -1; 1695 } 1696 1697 1698 int tls_get_library_version(char *buf, size_t buf_len) 1699 { 1700 return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s", 1701 GNUTLS_VERSION, gnutls_check_version(NULL)); 1702 } 1703 1704 1705 void tls_connection_set_success_data(struct tls_connection *conn, 1706 struct wpabuf *data) 1707 { 1708 } 1709 1710 1711 void tls_connection_set_success_data_resumed(struct tls_connection *conn) 1712 { 1713 } 1714 1715 1716 const struct wpabuf * 1717 tls_connection_get_success_data(struct tls_connection *conn) 1718 { 1719 return NULL; 1720 } 1721 1722 1723 void tls_connection_remove_session(struct tls_connection *conn) 1724 { 1725 } 1726