1 /* 2 * WPA Supplicant / SSL/TLS interface functions for openssl 3 * Copyright (c) 2004-2007, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 #include <gnutls/gnutls.h> 17 #include <gnutls/x509.h> 18 #ifdef PKCS12_FUNCS 19 #include <gnutls/pkcs12.h> 20 #endif /* PKCS12_FUNCS */ 21 22 #ifdef CONFIG_GNUTLS_EXTRA 23 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 24 #define GNUTLS_IA 25 #include <gnutls/extra.h> 26 #if LIBGNUTLS_VERSION_NUMBER == 0x010302 27 /* This function is not included in the current gnutls/extra.h even though it 28 * should be, so define it here as a workaround for the time being. */ 29 int gnutls_ia_verify_endphase(gnutls_session_t session, char *checksum); 30 #endif /* LIBGNUTLS_VERSION_NUMBER == 0x010302 */ 31 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 32 #endif /* CONFIG_GNUTLS_EXTRA */ 33 34 #include "common.h" 35 #include "tls.h" 36 37 38 #define TLS_RANDOM_SIZE 32 39 #define TLS_MASTER_SIZE 48 40 41 42 #if LIBGNUTLS_VERSION_NUMBER < 0x010302 43 /* GnuTLS 1.3.2 added functions for using master secret. Older versions require 44 * use of internal structures to get the master_secret and 45 * {server,client}_random. 46 */ 47 #define GNUTLS_INTERNAL_STRUCTURE_HACK 48 #endif /* LIBGNUTLS_VERSION_NUMBER < 0x010302 */ 49 50 51 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 52 /* 53 * It looks like gnutls does not provide access to client/server_random and 54 * master_key. This is somewhat unfortunate since these are needed for key 55 * derivation in EAP-{TLS,TTLS,PEAP,FAST}. Workaround for now is a horrible 56 * hack that copies the gnutls_session_int definition from gnutls_int.h so that 57 * we can get the needed information. 58 */ 59 60 typedef u8 uint8; 61 typedef unsigned char opaque; 62 typedef struct { 63 uint8 suite[2]; 64 } cipher_suite_st; 65 66 typedef struct { 67 gnutls_connection_end_t entity; 68 gnutls_kx_algorithm_t kx_algorithm; 69 gnutls_cipher_algorithm_t read_bulk_cipher_algorithm; 70 gnutls_mac_algorithm_t read_mac_algorithm; 71 gnutls_compression_method_t read_compression_algorithm; 72 gnutls_cipher_algorithm_t write_bulk_cipher_algorithm; 73 gnutls_mac_algorithm_t write_mac_algorithm; 74 gnutls_compression_method_t write_compression_algorithm; 75 cipher_suite_st current_cipher_suite; 76 opaque master_secret[TLS_MASTER_SIZE]; 77 opaque client_random[TLS_RANDOM_SIZE]; 78 opaque server_random[TLS_RANDOM_SIZE]; 79 /* followed by stuff we are not interested in */ 80 } security_parameters_st; 81 82 struct gnutls_session_int { 83 security_parameters_st security_parameters; 84 /* followed by things we are not interested in */ 85 }; 86 #endif /* LIBGNUTLS_VERSION_NUMBER < 0x010302 */ 87 88 static int tls_gnutls_ref_count = 0; 89 90 struct tls_global { 91 /* Data for session resumption */ 92 void *session_data; 93 size_t session_data_size; 94 95 int server; 96 97 int params_set; 98 gnutls_certificate_credentials_t xcred; 99 }; 100 101 struct tls_connection { 102 gnutls_session session; 103 char *subject_match, *altsubject_match; 104 int read_alerts, write_alerts, failed; 105 106 u8 *pre_shared_secret; 107 size_t pre_shared_secret_len; 108 int established; 109 int verify_peer; 110 111 u8 *push_buf, *pull_buf, *pull_buf_offset; 112 size_t push_buf_len, pull_buf_len; 113 114 int params_set; 115 gnutls_certificate_credentials_t xcred; 116 117 int tls_ia; 118 int final_phase_finished; 119 120 #ifdef GNUTLS_IA 121 gnutls_ia_server_credentials_t iacred_srv; 122 gnutls_ia_client_credentials_t iacred_cli; 123 124 /* Session keys generated in the current phase for inner secret 125 * permutation before generating/verifying PhaseFinished. */ 126 u8 *session_keys; 127 size_t session_keys_len; 128 129 u8 inner_secret[TLS_MASTER_SIZE]; 130 #endif /* GNUTLS_IA */ 131 }; 132 133 134 static void tls_log_func(int level, const char *msg) 135 { 136 char *s, *pos; 137 if (level == 6 || level == 7) { 138 /* These levels seem to be mostly I/O debug and msg dumps */ 139 return; 140 } 141 142 s = os_strdup(msg); 143 if (s == NULL) 144 return; 145 146 pos = s; 147 while (*pos != '\0') { 148 if (*pos == '\n') { 149 *pos = '\0'; 150 break; 151 } 152 pos++; 153 } 154 wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG, 155 "gnutls<%d> %s", level, s); 156 os_free(s); 157 } 158 159 160 extern int wpa_debug_show_keys; 161 162 void * tls_init(const struct tls_config *conf) 163 { 164 struct tls_global *global; 165 166 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 167 /* Because of the horrible hack to get master_secret and client/server 168 * random, we need to make sure that the gnutls version is something 169 * that is expected to have same structure definition for the session 170 * data.. */ 171 const char *ver; 172 const char *ok_ver[] = { "1.2.3", "1.2.4", "1.2.5", "1.2.6", "1.2.9", 173 "1.3.2", 174 NULL }; 175 int i; 176 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 177 178 global = os_zalloc(sizeof(*global)); 179 if (global == NULL) 180 return NULL; 181 182 if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) { 183 os_free(global); 184 return NULL; 185 } 186 tls_gnutls_ref_count++; 187 188 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 189 ver = gnutls_check_version(NULL); 190 if (ver == NULL) { 191 tls_deinit(global); 192 return NULL; 193 } 194 wpa_printf(MSG_DEBUG, "%s - gnutls version %s", __func__, ver); 195 for (i = 0; ok_ver[i]; i++) { 196 if (strcmp(ok_ver[i], ver) == 0) 197 break; 198 } 199 if (ok_ver[i] == NULL) { 200 wpa_printf(MSG_INFO, "Untested gnutls version %s - this needs " 201 "to be tested and enabled in tls_gnutls.c", ver); 202 tls_deinit(global); 203 return NULL; 204 } 205 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 206 207 gnutls_global_set_log_function(tls_log_func); 208 if (wpa_debug_show_keys) 209 gnutls_global_set_log_level(11); 210 return global; 211 } 212 213 214 void tls_deinit(void *ssl_ctx) 215 { 216 struct tls_global *global = ssl_ctx; 217 if (global) { 218 if (global->params_set) 219 gnutls_certificate_free_credentials(global->xcred); 220 os_free(global->session_data); 221 os_free(global); 222 } 223 224 tls_gnutls_ref_count--; 225 if (tls_gnutls_ref_count == 0) 226 gnutls_global_deinit(); 227 } 228 229 230 int tls_get_errors(void *ssl_ctx) 231 { 232 return 0; 233 } 234 235 236 static ssize_t tls_pull_func(gnutls_transport_ptr ptr, void *buf, 237 size_t len) 238 { 239 struct tls_connection *conn = (struct tls_connection *) ptr; 240 u8 *end; 241 if (conn->pull_buf == NULL) { 242 errno = EWOULDBLOCK; 243 return -1; 244 } 245 246 end = conn->pull_buf + conn->pull_buf_len; 247 if ((size_t) (end - conn->pull_buf_offset) < len) 248 len = end - conn->pull_buf_offset; 249 os_memcpy(buf, conn->pull_buf_offset, len); 250 conn->pull_buf_offset += len; 251 if (conn->pull_buf_offset == end) { 252 wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__); 253 os_free(conn->pull_buf); 254 conn->pull_buf = conn->pull_buf_offset = NULL; 255 conn->pull_buf_len = 0; 256 } else { 257 wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in pull_buf", 258 __func__, end - conn->pull_buf_offset); 259 } 260 return len; 261 } 262 263 264 static ssize_t tls_push_func(gnutls_transport_ptr ptr, const void *buf, 265 size_t len) 266 { 267 struct tls_connection *conn = (struct tls_connection *) ptr; 268 u8 *nbuf; 269 270 nbuf = os_realloc(conn->push_buf, conn->push_buf_len + len); 271 if (nbuf == NULL) { 272 errno = ENOMEM; 273 return -1; 274 } 275 os_memcpy(nbuf + conn->push_buf_len, buf, len); 276 conn->push_buf = nbuf; 277 conn->push_buf_len += len; 278 279 return len; 280 } 281 282 283 static int tls_gnutls_init_session(struct tls_global *global, 284 struct tls_connection *conn) 285 { 286 const int cert_types[2] = { GNUTLS_CRT_X509, 0 }; 287 const int protos[2] = { GNUTLS_TLS1, 0 }; 288 int ret; 289 290 ret = gnutls_init(&conn->session, 291 global->server ? GNUTLS_SERVER : GNUTLS_CLIENT); 292 if (ret < 0) { 293 wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS " 294 "connection: %s", gnutls_strerror(ret)); 295 return -1; 296 } 297 298 ret = gnutls_set_default_priority(conn->session); 299 if (ret < 0) 300 goto fail; 301 302 ret = gnutls_certificate_type_set_priority(conn->session, cert_types); 303 if (ret < 0) 304 goto fail; 305 306 ret = gnutls_protocol_set_priority(conn->session, protos); 307 if (ret < 0) 308 goto fail; 309 310 gnutls_transport_set_pull_function(conn->session, tls_pull_func); 311 gnutls_transport_set_push_function(conn->session, tls_push_func); 312 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr) conn); 313 314 return 0; 315 316 fail: 317 wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s", 318 gnutls_strerror(ret)); 319 gnutls_deinit(conn->session); 320 return -1; 321 } 322 323 324 struct tls_connection * tls_connection_init(void *ssl_ctx) 325 { 326 struct tls_global *global = ssl_ctx; 327 struct tls_connection *conn; 328 int ret; 329 330 conn = os_zalloc(sizeof(*conn)); 331 if (conn == NULL) 332 return NULL; 333 334 if (tls_gnutls_init_session(global, conn)) { 335 os_free(conn); 336 return NULL; 337 } 338 339 if (global->params_set) { 340 ret = gnutls_credentials_set(conn->session, 341 GNUTLS_CRD_CERTIFICATE, 342 global->xcred); 343 if (ret < 0) { 344 wpa_printf(MSG_INFO, "Failed to configure " 345 "credentials: %s", gnutls_strerror(ret)); 346 os_free(conn); 347 return NULL; 348 } 349 } 350 351 if (gnutls_certificate_allocate_credentials(&conn->xcred)) { 352 os_free(conn); 353 return NULL; 354 } 355 356 return conn; 357 } 358 359 360 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 361 { 362 if (conn == NULL) 363 return; 364 365 #ifdef GNUTLS_IA 366 if (conn->iacred_srv) 367 gnutls_ia_free_server_credentials(conn->iacred_srv); 368 if (conn->iacred_cli) 369 gnutls_ia_free_client_credentials(conn->iacred_cli); 370 if (conn->session_keys) { 371 os_memset(conn->session_keys, 0, conn->session_keys_len); 372 os_free(conn->session_keys); 373 } 374 #endif /* GNUTLS_IA */ 375 376 gnutls_certificate_free_credentials(conn->xcred); 377 gnutls_deinit(conn->session); 378 os_free(conn->pre_shared_secret); 379 os_free(conn->subject_match); 380 os_free(conn->altsubject_match); 381 os_free(conn->push_buf); 382 os_free(conn->pull_buf); 383 os_free(conn); 384 } 385 386 387 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 388 { 389 return conn ? conn->established : 0; 390 } 391 392 393 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 394 { 395 struct tls_global *global = ssl_ctx; 396 int ret; 397 398 if (conn == NULL) 399 return -1; 400 401 /* Shutdown previous TLS connection without notifying the peer 402 * because the connection was already terminated in practice 403 * and "close notify" shutdown alert would confuse AS. */ 404 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); 405 os_free(conn->push_buf); 406 conn->push_buf = NULL; 407 conn->push_buf_len = 0; 408 conn->established = 0; 409 conn->final_phase_finished = 0; 410 #ifdef GNUTLS_IA 411 if (conn->session_keys) { 412 os_memset(conn->session_keys, 0, conn->session_keys_len); 413 os_free(conn->session_keys); 414 } 415 conn->session_keys_len = 0; 416 #endif /* GNUTLS_IA */ 417 418 gnutls_deinit(conn->session); 419 if (tls_gnutls_init_session(global, conn)) { 420 wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session " 421 "for session resumption use"); 422 return -1; 423 } 424 425 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 426 conn->params_set ? conn->xcred : 427 global->xcred); 428 if (ret < 0) { 429 wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials " 430 "for session resumption: %s", gnutls_strerror(ret)); 431 return -1; 432 } 433 434 if (global->session_data) { 435 ret = gnutls_session_set_data(conn->session, 436 global->session_data, 437 global->session_data_size); 438 if (ret < 0) { 439 wpa_printf(MSG_INFO, "GnuTLS: Failed to set session " 440 "data: %s", gnutls_strerror(ret)); 441 return -1; 442 } 443 } 444 445 return 0; 446 } 447 448 449 #if 0 450 static int tls_match_altsubject(X509 *cert, const char *match) 451 { 452 GENERAL_NAME *gen; 453 char *field, *tmp; 454 void *ext; 455 int i, found = 0; 456 size_t len; 457 458 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 459 460 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 461 gen = sk_GENERAL_NAME_value(ext, i); 462 switch (gen->type) { 463 case GEN_EMAIL: 464 field = "EMAIL"; 465 break; 466 case GEN_DNS: 467 field = "DNS"; 468 break; 469 case GEN_URI: 470 field = "URI"; 471 break; 472 default: 473 field = NULL; 474 wpa_printf(MSG_DEBUG, "TLS: altSubjectName: " 475 "unsupported type=%d", gen->type); 476 break; 477 } 478 479 if (!field) 480 continue; 481 482 wpa_printf(MSG_DEBUG, "TLS: altSubjectName: %s:%s", 483 field, gen->d.ia5->data); 484 len = os_strlen(field) + 1 + 485 strlen((char *) gen->d.ia5->data) + 1; 486 tmp = os_malloc(len); 487 if (tmp == NULL) 488 continue; 489 snprintf(tmp, len, "%s:%s", field, gen->d.ia5->data); 490 if (strstr(tmp, match)) 491 found++; 492 os_free(tmp); 493 } 494 495 return found; 496 } 497 #endif 498 499 500 #if 0 501 static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 502 { 503 char buf[256]; 504 X509 *err_cert; 505 int err, depth; 506 SSL *ssl; 507 struct tls_connection *conn; 508 char *match, *altmatch; 509 510 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 511 err = X509_STORE_CTX_get_error(x509_ctx); 512 depth = X509_STORE_CTX_get_error_depth(x509_ctx); 513 ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 514 SSL_get_ex_data_X509_STORE_CTX_idx()); 515 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 516 517 conn = SSL_get_app_data(ssl); 518 match = conn ? conn->subject_match : NULL; 519 altmatch = conn ? conn->altsubject_match : NULL; 520 521 if (!preverify_ok) { 522 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 523 " error %d (%s) depth %d for '%s'", err, 524 X509_verify_cert_error_string(err), depth, buf); 525 } else { 526 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - " 527 "preverify_ok=%d err=%d (%s) depth=%d buf='%s'", 528 preverify_ok, err, 529 X509_verify_cert_error_string(err), depth, buf); 530 if (depth == 0 && match && strstr(buf, match) == NULL) { 531 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 532 "match with '%s'", buf, match); 533 preverify_ok = 0; 534 } else if (depth == 0 && altmatch && 535 !tls_match_altsubject(err_cert, altmatch)) { 536 wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 537 "'%s' not found", altmatch); 538 preverify_ok = 0; 539 } 540 } 541 542 return preverify_ok; 543 } 544 #endif 545 546 547 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 548 const struct tls_connection_params *params) 549 { 550 int ret; 551 552 if (conn == NULL || params == NULL) 553 return -1; 554 555 os_free(conn->subject_match); 556 conn->subject_match = NULL; 557 if (params->subject_match) { 558 conn->subject_match = os_strdup(params->subject_match); 559 if (conn->subject_match == NULL) 560 return -1; 561 } 562 563 os_free(conn->altsubject_match); 564 conn->altsubject_match = NULL; 565 if (params->altsubject_match) { 566 conn->altsubject_match = os_strdup(params->altsubject_match); 567 if (conn->altsubject_match == NULL) 568 return -1; 569 } 570 571 /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); 572 * to force peer validation(?) */ 573 574 if (params->ca_cert) { 575 conn->verify_peer = 1; 576 ret = gnutls_certificate_set_x509_trust_file( 577 conn->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); 578 if (ret < 0) { 579 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 580 "in PEM format: %s", params->ca_cert, 581 gnutls_strerror(ret)); 582 ret = gnutls_certificate_set_x509_trust_file( 583 conn->xcred, params->ca_cert, 584 GNUTLS_X509_FMT_DER); 585 if (ret < 0) { 586 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 587 "'%s' in DER format: %s", 588 params->ca_cert, 589 gnutls_strerror(ret)); 590 return -1; 591 } 592 } 593 } 594 595 if (params->client_cert && params->private_key) { 596 /* TODO: private_key_passwd? */ 597 ret = gnutls_certificate_set_x509_key_file( 598 conn->xcred, params->client_cert, params->private_key, 599 GNUTLS_X509_FMT_PEM); 600 if (ret < 0) { 601 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 602 "in PEM format: %s", gnutls_strerror(ret)); 603 ret = gnutls_certificate_set_x509_key_file( 604 conn->xcred, params->client_cert, 605 params->private_key, GNUTLS_X509_FMT_DER); 606 if (ret < 0) { 607 wpa_printf(MSG_DEBUG, "Failed to read client " 608 "cert/key in DER format: %s", 609 gnutls_strerror(ret)); 610 return ret; 611 } 612 } 613 } else if (params->private_key) { 614 int pkcs12_ok = 0; 615 #ifdef PKCS12_FUNCS 616 /* Try to load in PKCS#12 format */ 617 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 618 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 619 conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, 620 params->private_key_passwd); 621 if (ret != 0) { 622 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 623 "PKCS#12 format: %s", gnutls_strerror(ret)); 624 return -1; 625 } else 626 pkcs12_ok = 1; 627 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 628 #endif /* PKCS12_FUNCS */ 629 630 if (!pkcs12_ok) { 631 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 632 "included"); 633 return -1; 634 } 635 } 636 637 conn->tls_ia = params->tls_ia; 638 conn->params_set = 1; 639 640 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 641 conn->xcred); 642 if (ret < 0) { 643 wpa_printf(MSG_INFO, "Failed to configure credentials: %s", 644 gnutls_strerror(ret)); 645 } 646 647 #ifdef GNUTLS_IA 648 if (conn->iacred_cli) 649 gnutls_ia_free_client_credentials(conn->iacred_cli); 650 651 ret = gnutls_ia_allocate_client_credentials(&conn->iacred_cli); 652 if (ret) { 653 wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", 654 gnutls_strerror(ret)); 655 return -1; 656 } 657 658 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, 659 conn->iacred_cli); 660 if (ret) { 661 wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", 662 gnutls_strerror(ret)); 663 gnutls_ia_free_client_credentials(conn->iacred_cli); 664 conn->iacred_cli = NULL; 665 return -1; 666 } 667 #endif /* GNUTLS_IE */ 668 669 return ret; 670 } 671 672 673 int tls_global_set_params(void *tls_ctx, 674 const struct tls_connection_params *params) 675 { 676 struct tls_global *global = tls_ctx; 677 int ret; 678 679 /* Currently, global parameters are only set when running in server 680 * mode. */ 681 global->server = 1; 682 683 if (global->params_set) { 684 gnutls_certificate_free_credentials(global->xcred); 685 global->params_set = 0; 686 } 687 688 ret = gnutls_certificate_allocate_credentials(&global->xcred); 689 if (ret) { 690 wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " 691 "%s", gnutls_strerror(ret)); 692 return -1; 693 } 694 695 if (params->ca_cert) { 696 ret = gnutls_certificate_set_x509_trust_file( 697 global->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); 698 if (ret < 0) { 699 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 700 "in PEM format: %s", params->ca_cert, 701 gnutls_strerror(ret)); 702 ret = gnutls_certificate_set_x509_trust_file( 703 global->xcred, params->ca_cert, 704 GNUTLS_X509_FMT_DER); 705 if (ret < 0) { 706 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 707 "'%s' in DER format: %s", 708 params->ca_cert, 709 gnutls_strerror(ret)); 710 goto fail; 711 } 712 } 713 } 714 715 if (params->client_cert && params->private_key) { 716 /* TODO: private_key_passwd? */ 717 ret = gnutls_certificate_set_x509_key_file( 718 global->xcred, params->client_cert, 719 params->private_key, GNUTLS_X509_FMT_PEM); 720 if (ret < 0) { 721 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 722 "in PEM format: %s", gnutls_strerror(ret)); 723 ret = gnutls_certificate_set_x509_key_file( 724 global->xcred, params->client_cert, 725 params->private_key, GNUTLS_X509_FMT_DER); 726 if (ret < 0) { 727 wpa_printf(MSG_DEBUG, "Failed to read client " 728 "cert/key in DER format: %s", 729 gnutls_strerror(ret)); 730 goto fail; 731 } 732 } 733 } else if (params->private_key) { 734 int pkcs12_ok = 0; 735 #ifdef PKCS12_FUNCS 736 /* Try to load in PKCS#12 format */ 737 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 738 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 739 global->xcred, params->private_key, 740 GNUTLS_X509_FMT_DER, params->private_key_passwd); 741 if (ret != 0) { 742 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 743 "PKCS#12 format: %s", gnutls_strerror(ret)); 744 goto fail; 745 } else 746 pkcs12_ok = 1; 747 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 748 #endif /* PKCS12_FUNCS */ 749 750 if (!pkcs12_ok) { 751 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 752 "included"); 753 goto fail; 754 } 755 } 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) 776 { 777 if (conn == NULL || conn->session == NULL) 778 return -1; 779 780 conn->verify_peer = verify_peer; 781 gnutls_certificate_server_set_request(conn->session, 782 verify_peer ? GNUTLS_CERT_REQUIRE 783 : GNUTLS_CERT_REQUEST); 784 785 return 0; 786 } 787 788 789 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 790 struct tls_keys *keys) 791 { 792 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 793 security_parameters_st *sec; 794 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 795 796 if (conn == NULL || conn->session == NULL || keys == NULL) 797 return -1; 798 799 os_memset(keys, 0, sizeof(*keys)); 800 801 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 802 sec = &conn->session->security_parameters; 803 keys->master_key = sec->master_secret; 804 keys->master_key_len = TLS_MASTER_SIZE; 805 keys->client_random = sec->client_random; 806 keys->server_random = sec->server_random; 807 #else /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 808 keys->client_random = 809 (u8 *) gnutls_session_get_client_random(conn->session); 810 keys->server_random = 811 (u8 *) gnutls_session_get_server_random(conn->session); 812 /* No access to master_secret */ 813 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 814 815 #ifdef GNUTLS_IA 816 gnutls_ia_extract_inner_secret(conn->session, 817 (char *) conn->inner_secret); 818 keys->inner_secret = conn->inner_secret; 819 keys->inner_secret_len = TLS_MASTER_SIZE; 820 #endif /* GNUTLS_IA */ 821 822 keys->client_random_len = TLS_RANDOM_SIZE; 823 keys->server_random_len = TLS_RANDOM_SIZE; 824 825 return 0; 826 } 827 828 829 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 830 const char *label, int server_random_first, 831 u8 *out, size_t out_len) 832 { 833 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 834 if (conn == NULL || conn->session == NULL) 835 return -1; 836 837 return gnutls_prf(conn->session, os_strlen(label), label, 838 server_random_first, 0, NULL, out_len, (char *) out); 839 #else /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 840 return -1; 841 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 842 } 843 844 845 static int tls_connection_verify_peer(struct tls_connection *conn) 846 { 847 unsigned int status, num_certs, i; 848 struct os_time now; 849 const gnutls_datum_t *certs; 850 gnutls_x509_crt_t cert; 851 852 if (gnutls_certificate_verify_peers2(conn->session, &status) < 0) { 853 wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 854 "certificate chain"); 855 return -1; 856 } 857 858 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 859 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 860 return -1; 861 } 862 863 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 864 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 865 "known issuer"); 866 return -1; 867 } 868 869 if (status & GNUTLS_CERT_REVOKED) { 870 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 871 return -1; 872 } 873 874 os_get_time(&now); 875 876 certs = gnutls_certificate_get_peers(conn->session, &num_certs); 877 if (certs == NULL) { 878 wpa_printf(MSG_INFO, "TLS: No peer certificate chain " 879 "received"); 880 return -1; 881 } 882 883 for (i = 0; i < num_certs; i++) { 884 char *buf; 885 size_t len; 886 if (gnutls_x509_crt_init(&cert) < 0) { 887 wpa_printf(MSG_INFO, "TLS: Certificate initialization " 888 "failed"); 889 return -1; 890 } 891 892 if (gnutls_x509_crt_import(cert, &certs[i], 893 GNUTLS_X509_FMT_DER) < 0) { 894 wpa_printf(MSG_INFO, "TLS: Could not parse peer " 895 "certificate %d/%d", i + 1, num_certs); 896 gnutls_x509_crt_deinit(cert); 897 return -1; 898 } 899 900 gnutls_x509_crt_get_dn(cert, NULL, &len); 901 len++; 902 buf = os_malloc(len + 1); 903 if (buf) { 904 buf[0] = buf[len] = '\0'; 905 gnutls_x509_crt_get_dn(cert, buf, &len); 906 } 907 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 908 i + 1, num_certs, buf); 909 910 if (i == 0) { 911 /* TODO: validate subject_match and altsubject_match */ 912 } 913 914 os_free(buf); 915 916 if (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 917 gnutls_x509_crt_get_activation_time(cert) > now.sec) { 918 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 919 "not valid at this time", 920 i + 1, num_certs); 921 gnutls_x509_crt_deinit(cert); 922 return -1; 923 } 924 925 gnutls_x509_crt_deinit(cert); 926 } 927 928 return 0; 929 } 930 931 932 u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 933 const u8 *in_data, size_t in_len, 934 size_t *out_len, u8 **appl_data, 935 size_t *appl_data_len) 936 { 937 struct tls_global *global = ssl_ctx; 938 u8 *out_data; 939 int ret; 940 941 if (appl_data) 942 *appl_data = NULL; 943 944 if (in_data && in_len) { 945 if (conn->pull_buf) { 946 wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in " 947 "pull_buf", __func__, conn->pull_buf_len); 948 os_free(conn->pull_buf); 949 } 950 conn->pull_buf = os_malloc(in_len); 951 if (conn->pull_buf == NULL) 952 return NULL; 953 os_memcpy(conn->pull_buf, in_data, in_len); 954 conn->pull_buf_offset = conn->pull_buf; 955 conn->pull_buf_len = in_len; 956 } 957 958 ret = gnutls_handshake(conn->session); 959 if (ret < 0) { 960 switch (ret) { 961 case GNUTLS_E_AGAIN: 962 if (global->server && conn->established && 963 conn->push_buf == NULL) { 964 /* Need to return something to trigger 965 * completion of EAP-TLS. */ 966 conn->push_buf = os_malloc(1); 967 } 968 break; 969 case GNUTLS_E_FATAL_ALERT_RECEIVED: 970 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 971 __func__, gnutls_alert_get_name( 972 gnutls_alert_get(conn->session))); 973 conn->read_alerts++; 974 /* continue */ 975 default: 976 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 977 "-> %s", __func__, gnutls_strerror(ret)); 978 conn->failed++; 979 } 980 } else { 981 size_t size; 982 983 if (conn->verify_peer && tls_connection_verify_peer(conn)) { 984 wpa_printf(MSG_INFO, "TLS: Peer certificate chain " 985 "failed validation"); 986 conn->failed++; 987 return NULL; 988 } 989 990 if (conn->tls_ia && !gnutls_ia_handshake_p(conn->session)) { 991 wpa_printf(MSG_INFO, "TLS: No TLS/IA negotiation"); 992 conn->failed++; 993 return NULL; 994 } 995 996 if (conn->tls_ia) 997 wpa_printf(MSG_DEBUG, "TLS: Start TLS/IA handshake"); 998 else { 999 wpa_printf(MSG_DEBUG, "TLS: Handshake completed " 1000 "successfully"); 1001 } 1002 conn->established = 1; 1003 if (conn->push_buf == NULL) { 1004 /* Need to return something to get final TLS ACK. */ 1005 conn->push_buf = os_malloc(1); 1006 } 1007 1008 gnutls_session_get_data(conn->session, NULL, &size); 1009 if (global->session_data == NULL || 1010 global->session_data_size < size) { 1011 os_free(global->session_data); 1012 global->session_data = os_malloc(size); 1013 } 1014 if (global->session_data) { 1015 global->session_data_size = size; 1016 gnutls_session_get_data(conn->session, 1017 global->session_data, 1018 &global->session_data_size); 1019 } 1020 } 1021 1022 out_data = conn->push_buf; 1023 *out_len = conn->push_buf_len; 1024 conn->push_buf = NULL; 1025 conn->push_buf_len = 0; 1026 return out_data; 1027 } 1028 1029 1030 u8 * tls_connection_server_handshake(void *ssl_ctx, 1031 struct tls_connection *conn, 1032 const u8 *in_data, size_t in_len, 1033 size_t *out_len) 1034 { 1035 return tls_connection_handshake(ssl_ctx, conn, in_data, in_len, 1036 out_len, NULL, NULL); 1037 } 1038 1039 1040 int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn, 1041 const u8 *in_data, size_t in_len, 1042 u8 *out_data, size_t out_len) 1043 { 1044 ssize_t res; 1045 1046 #ifdef GNUTLS_IA 1047 if (conn->tls_ia) 1048 res = gnutls_ia_send(conn->session, (char *) in_data, in_len); 1049 else 1050 #endif /* GNUTLS_IA */ 1051 res = gnutls_record_send(conn->session, in_data, in_len); 1052 if (res < 0) { 1053 wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 1054 __func__, gnutls_strerror(res)); 1055 return -1; 1056 } 1057 if (conn->push_buf == NULL) 1058 return -1; 1059 if (conn->push_buf_len < out_len) 1060 out_len = conn->push_buf_len; 1061 os_memcpy(out_data, conn->push_buf, out_len); 1062 os_free(conn->push_buf); 1063 conn->push_buf = NULL; 1064 conn->push_buf_len = 0; 1065 return out_len; 1066 } 1067 1068 1069 int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, 1070 const u8 *in_data, size_t in_len, 1071 u8 *out_data, size_t out_len) 1072 { 1073 ssize_t res; 1074 1075 if (conn->pull_buf) { 1076 wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in " 1077 "pull_buf", __func__, conn->pull_buf_len); 1078 os_free(conn->pull_buf); 1079 } 1080 conn->pull_buf = os_malloc(in_len); 1081 if (conn->pull_buf == NULL) 1082 return -1; 1083 os_memcpy(conn->pull_buf, in_data, in_len); 1084 conn->pull_buf_offset = conn->pull_buf; 1085 conn->pull_buf_len = in_len; 1086 1087 #ifdef GNUTLS_IA 1088 if (conn->tls_ia) { 1089 res = gnutls_ia_recv(conn->session, (char *) out_data, 1090 out_len); 1091 if (out_len >= 12 && 1092 (res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || 1093 res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)) { 1094 int final = res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED; 1095 wpa_printf(MSG_DEBUG, "%s: Received %sPhaseFinished", 1096 __func__, final ? "Final" : "Intermediate"); 1097 1098 res = gnutls_ia_permute_inner_secret( 1099 conn->session, conn->session_keys_len, 1100 (char *) conn->session_keys); 1101 if (conn->session_keys) { 1102 os_memset(conn->session_keys, 0, 1103 conn->session_keys_len); 1104 os_free(conn->session_keys); 1105 } 1106 conn->session_keys = NULL; 1107 conn->session_keys_len = 0; 1108 if (res) { 1109 wpa_printf(MSG_DEBUG, "%s: Failed to permute " 1110 "inner secret: %s", 1111 __func__, gnutls_strerror(res)); 1112 return -1; 1113 } 1114 1115 res = gnutls_ia_verify_endphase(conn->session, 1116 (char *) out_data); 1117 if (res == 0) { 1118 wpa_printf(MSG_DEBUG, "%s: Correct endphase " 1119 "checksum", __func__); 1120 } else { 1121 wpa_printf(MSG_INFO, "%s: Endphase " 1122 "verification failed: %s", 1123 __func__, gnutls_strerror(res)); 1124 return -1; 1125 } 1126 1127 if (final) 1128 conn->final_phase_finished = 1; 1129 1130 return 0; 1131 } 1132 1133 if (res < 0) { 1134 wpa_printf(MSG_DEBUG, "%s - gnutls_ia_recv failed: %d " 1135 "(%s)", __func__, res, 1136 gnutls_strerror(res)); 1137 } 1138 return res; 1139 } 1140 #endif /* GNUTLS_IA */ 1141 1142 res = gnutls_record_recv(conn->session, out_data, out_len); 1143 if (res < 0) { 1144 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1145 "(%s)", __func__, res, gnutls_strerror(res)); 1146 } 1147 1148 return res; 1149 } 1150 1151 1152 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 1153 { 1154 if (conn == NULL) 1155 return 0; 1156 return gnutls_session_is_resumed(conn->session); 1157 } 1158 1159 1160 int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn, 1161 const u8 *key, size_t key_len) 1162 { 1163 /* TODO */ 1164 return -1; 1165 } 1166 1167 1168 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 1169 u8 *ciphers) 1170 { 1171 /* TODO */ 1172 return -1; 1173 } 1174 1175 1176 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 1177 char *buf, size_t buflen) 1178 { 1179 /* TODO */ 1180 buf[0] = '\0'; 1181 return 0; 1182 } 1183 1184 1185 int tls_connection_enable_workaround(void *ssl_ctx, 1186 struct tls_connection *conn) 1187 { 1188 /* TODO: set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ 1189 return 0; 1190 } 1191 1192 1193 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 1194 int ext_type, const u8 *data, 1195 size_t data_len) 1196 { 1197 /* TODO */ 1198 return -1; 1199 } 1200 1201 1202 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 1203 { 1204 if (conn == NULL) 1205 return -1; 1206 return conn->failed; 1207 } 1208 1209 1210 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 1211 { 1212 if (conn == NULL) 1213 return -1; 1214 return conn->read_alerts; 1215 } 1216 1217 1218 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 1219 { 1220 if (conn == NULL) 1221 return -1; 1222 return conn->write_alerts; 1223 } 1224 1225 1226 int tls_connection_get_keyblock_size(void *tls_ctx, 1227 struct tls_connection *conn) 1228 { 1229 /* TODO */ 1230 return -1; 1231 } 1232 1233 1234 unsigned int tls_capabilities(void *tls_ctx) 1235 { 1236 unsigned int capa = 0; 1237 1238 #ifdef GNUTLS_IA 1239 capa |= TLS_CAPABILITY_IA; 1240 #endif /* GNUTLS_IA */ 1241 1242 return capa; 1243 } 1244 1245 1246 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 1247 int tls_ia) 1248 { 1249 #ifdef GNUTLS_IA 1250 int ret; 1251 1252 if (conn == NULL) 1253 return -1; 1254 1255 conn->tls_ia = tls_ia; 1256 if (!tls_ia) 1257 return 0; 1258 1259 ret = gnutls_ia_allocate_server_credentials(&conn->iacred_srv); 1260 if (ret) { 1261 wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", 1262 gnutls_strerror(ret)); 1263 return -1; 1264 } 1265 1266 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, 1267 conn->iacred_srv); 1268 if (ret) { 1269 wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", 1270 gnutls_strerror(ret)); 1271 gnutls_ia_free_server_credentials(conn->iacred_srv); 1272 conn->iacred_srv = NULL; 1273 return -1; 1274 } 1275 1276 return 0; 1277 #else /* GNUTLS_IA */ 1278 return -1; 1279 #endif /* GNUTLS_IA */ 1280 } 1281 1282 1283 int tls_connection_ia_send_phase_finished(void *tls_ctx, 1284 struct tls_connection *conn, 1285 int final, 1286 u8 *out_data, size_t out_len) 1287 { 1288 #ifdef GNUTLS_IA 1289 int ret; 1290 1291 if (conn == NULL || conn->session == NULL || !conn->tls_ia) 1292 return -1; 1293 1294 ret = gnutls_ia_permute_inner_secret(conn->session, 1295 conn->session_keys_len, 1296 (char *) conn->session_keys); 1297 if (conn->session_keys) { 1298 os_memset(conn->session_keys, 0, conn->session_keys_len); 1299 os_free(conn->session_keys); 1300 } 1301 conn->session_keys = NULL; 1302 conn->session_keys_len = 0; 1303 if (ret) { 1304 wpa_printf(MSG_DEBUG, "%s: Failed to permute inner secret: %s", 1305 __func__, gnutls_strerror(ret)); 1306 return -1; 1307 } 1308 1309 ret = gnutls_ia_endphase_send(conn->session, final); 1310 if (ret) { 1311 wpa_printf(MSG_DEBUG, "%s: Failed to send endphase: %s", 1312 __func__, gnutls_strerror(ret)); 1313 return -1; 1314 } 1315 1316 if (conn->push_buf == NULL) 1317 return -1; 1318 if (conn->push_buf_len < out_len) 1319 out_len = conn->push_buf_len; 1320 os_memcpy(out_data, conn->push_buf, out_len); 1321 os_free(conn->push_buf); 1322 conn->push_buf = NULL; 1323 conn->push_buf_len = 0; 1324 return out_len; 1325 #else /* GNUTLS_IA */ 1326 return -1; 1327 #endif /* GNUTLS_IA */ 1328 } 1329 1330 1331 int tls_connection_ia_final_phase_finished(void *tls_ctx, 1332 struct tls_connection *conn) 1333 { 1334 if (conn == NULL) 1335 return -1; 1336 1337 return conn->final_phase_finished; 1338 } 1339 1340 1341 int tls_connection_ia_permute_inner_secret(void *tls_ctx, 1342 struct tls_connection *conn, 1343 const u8 *key, size_t key_len) 1344 { 1345 #ifdef GNUTLS_IA 1346 if (conn == NULL || !conn->tls_ia) 1347 return -1; 1348 1349 if (conn->session_keys) { 1350 os_memset(conn->session_keys, 0, conn->session_keys_len); 1351 os_free(conn->session_keys); 1352 } 1353 conn->session_keys_len = 0; 1354 1355 if (key) { 1356 conn->session_keys = os_malloc(key_len); 1357 if (conn->session_keys == NULL) 1358 return -1; 1359 os_memcpy(conn->session_keys, key, key_len); 1360 conn->session_keys_len = key_len; 1361 } else { 1362 conn->session_keys = NULL; 1363 conn->session_keys_len = 0; 1364 } 1365 1366 return 0; 1367 #else /* GNUTLS_IA */ 1368 return -1; 1369 #endif /* GNUTLS_IA */ 1370 } 1371