1 /* 2 * WPA Supplicant / SSL/TLS interface functions for openssl 3 * Copyright (c) 2004-2007, Jouni Malinen <j@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 - %lu bytes remaining in pull_buf", 258 __func__, 259 (unsigned long) (end - conn->pull_buf_offset)); 260 } 261 return len; 262 } 263 264 265 static ssize_t tls_push_func(gnutls_transport_ptr ptr, const void *buf, 266 size_t len) 267 { 268 struct tls_connection *conn = (struct tls_connection *) ptr; 269 u8 *nbuf; 270 271 nbuf = os_realloc(conn->push_buf, conn->push_buf_len + len); 272 if (nbuf == NULL) { 273 errno = ENOMEM; 274 return -1; 275 } 276 os_memcpy(nbuf + conn->push_buf_len, buf, len); 277 conn->push_buf = nbuf; 278 conn->push_buf_len += len; 279 280 return len; 281 } 282 283 284 static int tls_gnutls_init_session(struct tls_global *global, 285 struct tls_connection *conn) 286 { 287 const int cert_types[2] = { GNUTLS_CRT_X509, 0 }; 288 const int protos[2] = { GNUTLS_TLS1, 0 }; 289 int ret; 290 291 ret = gnutls_init(&conn->session, 292 global->server ? GNUTLS_SERVER : GNUTLS_CLIENT); 293 if (ret < 0) { 294 wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS " 295 "connection: %s", gnutls_strerror(ret)); 296 return -1; 297 } 298 299 ret = gnutls_set_default_priority(conn->session); 300 if (ret < 0) 301 goto fail; 302 303 ret = gnutls_certificate_type_set_priority(conn->session, cert_types); 304 if (ret < 0) 305 goto fail; 306 307 ret = gnutls_protocol_set_priority(conn->session, protos); 308 if (ret < 0) 309 goto fail; 310 311 gnutls_transport_set_pull_function(conn->session, tls_pull_func); 312 gnutls_transport_set_push_function(conn->session, tls_push_func); 313 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr) conn); 314 315 return 0; 316 317 fail: 318 wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s", 319 gnutls_strerror(ret)); 320 gnutls_deinit(conn->session); 321 return -1; 322 } 323 324 325 struct tls_connection * tls_connection_init(void *ssl_ctx) 326 { 327 struct tls_global *global = ssl_ctx; 328 struct tls_connection *conn; 329 int ret; 330 331 conn = os_zalloc(sizeof(*conn)); 332 if (conn == NULL) 333 return NULL; 334 335 if (tls_gnutls_init_session(global, conn)) { 336 os_free(conn); 337 return NULL; 338 } 339 340 if (global->params_set) { 341 ret = gnutls_credentials_set(conn->session, 342 GNUTLS_CRD_CERTIFICATE, 343 global->xcred); 344 if (ret < 0) { 345 wpa_printf(MSG_INFO, "Failed to configure " 346 "credentials: %s", gnutls_strerror(ret)); 347 os_free(conn); 348 return NULL; 349 } 350 } 351 352 if (gnutls_certificate_allocate_credentials(&conn->xcred)) { 353 os_free(conn); 354 return NULL; 355 } 356 357 return conn; 358 } 359 360 361 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 362 { 363 if (conn == NULL) 364 return; 365 366 #ifdef GNUTLS_IA 367 if (conn->iacred_srv) 368 gnutls_ia_free_server_credentials(conn->iacred_srv); 369 if (conn->iacred_cli) 370 gnutls_ia_free_client_credentials(conn->iacred_cli); 371 if (conn->session_keys) { 372 os_memset(conn->session_keys, 0, conn->session_keys_len); 373 os_free(conn->session_keys); 374 } 375 #endif /* GNUTLS_IA */ 376 377 gnutls_certificate_free_credentials(conn->xcred); 378 gnutls_deinit(conn->session); 379 os_free(conn->pre_shared_secret); 380 os_free(conn->subject_match); 381 os_free(conn->altsubject_match); 382 os_free(conn->push_buf); 383 os_free(conn->pull_buf); 384 os_free(conn); 385 } 386 387 388 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 389 { 390 return conn ? conn->established : 0; 391 } 392 393 394 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 395 { 396 struct tls_global *global = ssl_ctx; 397 int ret; 398 399 if (conn == NULL) 400 return -1; 401 402 /* Shutdown previous TLS connection without notifying the peer 403 * because the connection was already terminated in practice 404 * and "close notify" shutdown alert would confuse AS. */ 405 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); 406 os_free(conn->push_buf); 407 conn->push_buf = NULL; 408 conn->push_buf_len = 0; 409 conn->established = 0; 410 conn->final_phase_finished = 0; 411 #ifdef GNUTLS_IA 412 if (conn->session_keys) { 413 os_memset(conn->session_keys, 0, conn->session_keys_len); 414 os_free(conn->session_keys); 415 } 416 conn->session_keys_len = 0; 417 #endif /* GNUTLS_IA */ 418 419 gnutls_deinit(conn->session); 420 if (tls_gnutls_init_session(global, conn)) { 421 wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session " 422 "for session resumption use"); 423 return -1; 424 } 425 426 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 427 conn->params_set ? conn->xcred : 428 global->xcred); 429 if (ret < 0) { 430 wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials " 431 "for session resumption: %s", gnutls_strerror(ret)); 432 return -1; 433 } 434 435 if (global->session_data) { 436 ret = gnutls_session_set_data(conn->session, 437 global->session_data, 438 global->session_data_size); 439 if (ret < 0) { 440 wpa_printf(MSG_INFO, "GnuTLS: Failed to set session " 441 "data: %s", gnutls_strerror(ret)); 442 return -1; 443 } 444 } 445 446 return 0; 447 } 448 449 450 #if 0 451 static int tls_match_altsubject(X509 *cert, const char *match) 452 { 453 GENERAL_NAME *gen; 454 char *field, *tmp; 455 void *ext; 456 int i, found = 0; 457 size_t len; 458 459 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 460 461 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 462 gen = sk_GENERAL_NAME_value(ext, i); 463 switch (gen->type) { 464 case GEN_EMAIL: 465 field = "EMAIL"; 466 break; 467 case GEN_DNS: 468 field = "DNS"; 469 break; 470 case GEN_URI: 471 field = "URI"; 472 break; 473 default: 474 field = NULL; 475 wpa_printf(MSG_DEBUG, "TLS: altSubjectName: " 476 "unsupported type=%d", gen->type); 477 break; 478 } 479 480 if (!field) 481 continue; 482 483 wpa_printf(MSG_DEBUG, "TLS: altSubjectName: %s:%s", 484 field, gen->d.ia5->data); 485 len = os_strlen(field) + 1 + 486 strlen((char *) gen->d.ia5->data) + 1; 487 tmp = os_malloc(len); 488 if (tmp == NULL) 489 continue; 490 snprintf(tmp, len, "%s:%s", field, gen->d.ia5->data); 491 if (strstr(tmp, match)) 492 found++; 493 os_free(tmp); 494 } 495 496 return found; 497 } 498 #endif 499 500 501 #if 0 502 static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 503 { 504 char buf[256]; 505 X509 *err_cert; 506 int err, depth; 507 SSL *ssl; 508 struct tls_connection *conn; 509 char *match, *altmatch; 510 511 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 512 err = X509_STORE_CTX_get_error(x509_ctx); 513 depth = X509_STORE_CTX_get_error_depth(x509_ctx); 514 ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 515 SSL_get_ex_data_X509_STORE_CTX_idx()); 516 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 517 518 conn = SSL_get_app_data(ssl); 519 match = conn ? conn->subject_match : NULL; 520 altmatch = conn ? conn->altsubject_match : NULL; 521 522 if (!preverify_ok) { 523 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 524 " error %d (%s) depth %d for '%s'", err, 525 X509_verify_cert_error_string(err), depth, buf); 526 } else { 527 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - " 528 "preverify_ok=%d err=%d (%s) depth=%d buf='%s'", 529 preverify_ok, err, 530 X509_verify_cert_error_string(err), depth, buf); 531 if (depth == 0 && match && strstr(buf, match) == NULL) { 532 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 533 "match with '%s'", buf, match); 534 preverify_ok = 0; 535 } else if (depth == 0 && altmatch && 536 !tls_match_altsubject(err_cert, altmatch)) { 537 wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 538 "'%s' not found", altmatch); 539 preverify_ok = 0; 540 } 541 } 542 543 return preverify_ok; 544 } 545 #endif 546 547 548 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 549 const struct tls_connection_params *params) 550 { 551 int ret; 552 553 if (conn == NULL || params == NULL) 554 return -1; 555 556 os_free(conn->subject_match); 557 conn->subject_match = NULL; 558 if (params->subject_match) { 559 conn->subject_match = os_strdup(params->subject_match); 560 if (conn->subject_match == NULL) 561 return -1; 562 } 563 564 os_free(conn->altsubject_match); 565 conn->altsubject_match = NULL; 566 if (params->altsubject_match) { 567 conn->altsubject_match = os_strdup(params->altsubject_match); 568 if (conn->altsubject_match == NULL) 569 return -1; 570 } 571 572 /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); 573 * to force peer validation(?) */ 574 575 if (params->ca_cert) { 576 conn->verify_peer = 1; 577 ret = gnutls_certificate_set_x509_trust_file( 578 conn->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); 579 if (ret < 0) { 580 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 581 "in PEM format: %s", params->ca_cert, 582 gnutls_strerror(ret)); 583 ret = gnutls_certificate_set_x509_trust_file( 584 conn->xcred, params->ca_cert, 585 GNUTLS_X509_FMT_DER); 586 if (ret < 0) { 587 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 588 "'%s' in DER format: %s", 589 params->ca_cert, 590 gnutls_strerror(ret)); 591 return -1; 592 } 593 } 594 } 595 596 if (params->client_cert && params->private_key) { 597 /* TODO: private_key_passwd? */ 598 ret = gnutls_certificate_set_x509_key_file( 599 conn->xcred, params->client_cert, params->private_key, 600 GNUTLS_X509_FMT_PEM); 601 if (ret < 0) { 602 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 603 "in PEM format: %s", gnutls_strerror(ret)); 604 ret = gnutls_certificate_set_x509_key_file( 605 conn->xcred, params->client_cert, 606 params->private_key, GNUTLS_X509_FMT_DER); 607 if (ret < 0) { 608 wpa_printf(MSG_DEBUG, "Failed to read client " 609 "cert/key in DER format: %s", 610 gnutls_strerror(ret)); 611 return ret; 612 } 613 } 614 } else if (params->private_key) { 615 int pkcs12_ok = 0; 616 #ifdef PKCS12_FUNCS 617 /* Try to load in PKCS#12 format */ 618 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 619 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 620 conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, 621 params->private_key_passwd); 622 if (ret != 0) { 623 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 624 "PKCS#12 format: %s", gnutls_strerror(ret)); 625 return -1; 626 } else 627 pkcs12_ok = 1; 628 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 629 #endif /* PKCS12_FUNCS */ 630 631 if (!pkcs12_ok) { 632 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 633 "included"); 634 return -1; 635 } 636 } 637 638 conn->tls_ia = params->tls_ia; 639 conn->params_set = 1; 640 641 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 642 conn->xcred); 643 if (ret < 0) { 644 wpa_printf(MSG_INFO, "Failed to configure credentials: %s", 645 gnutls_strerror(ret)); 646 } 647 648 #ifdef GNUTLS_IA 649 if (conn->iacred_cli) 650 gnutls_ia_free_client_credentials(conn->iacred_cli); 651 652 ret = gnutls_ia_allocate_client_credentials(&conn->iacred_cli); 653 if (ret) { 654 wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", 655 gnutls_strerror(ret)); 656 return -1; 657 } 658 659 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, 660 conn->iacred_cli); 661 if (ret) { 662 wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", 663 gnutls_strerror(ret)); 664 gnutls_ia_free_client_credentials(conn->iacred_cli); 665 conn->iacred_cli = NULL; 666 return -1; 667 } 668 #endif /* GNUTLS_IE */ 669 670 return ret; 671 } 672 673 674 int tls_global_set_params(void *tls_ctx, 675 const struct tls_connection_params *params) 676 { 677 struct tls_global *global = tls_ctx; 678 int ret; 679 680 /* Currently, global parameters are only set when running in server 681 * mode. */ 682 global->server = 1; 683 684 if (global->params_set) { 685 gnutls_certificate_free_credentials(global->xcred); 686 global->params_set = 0; 687 } 688 689 ret = gnutls_certificate_allocate_credentials(&global->xcred); 690 if (ret) { 691 wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " 692 "%s", gnutls_strerror(ret)); 693 return -1; 694 } 695 696 if (params->ca_cert) { 697 ret = gnutls_certificate_set_x509_trust_file( 698 global->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); 699 if (ret < 0) { 700 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 701 "in PEM format: %s", params->ca_cert, 702 gnutls_strerror(ret)); 703 ret = gnutls_certificate_set_x509_trust_file( 704 global->xcred, params->ca_cert, 705 GNUTLS_X509_FMT_DER); 706 if (ret < 0) { 707 wpa_printf(MSG_DEBUG, "Failed to read CA cert " 708 "'%s' in DER format: %s", 709 params->ca_cert, 710 gnutls_strerror(ret)); 711 goto fail; 712 } 713 } 714 } 715 716 if (params->client_cert && params->private_key) { 717 /* TODO: private_key_passwd? */ 718 ret = gnutls_certificate_set_x509_key_file( 719 global->xcred, params->client_cert, 720 params->private_key, GNUTLS_X509_FMT_PEM); 721 if (ret < 0) { 722 wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 723 "in PEM format: %s", gnutls_strerror(ret)); 724 ret = gnutls_certificate_set_x509_key_file( 725 global->xcred, params->client_cert, 726 params->private_key, GNUTLS_X509_FMT_DER); 727 if (ret < 0) { 728 wpa_printf(MSG_DEBUG, "Failed to read client " 729 "cert/key in DER format: %s", 730 gnutls_strerror(ret)); 731 goto fail; 732 } 733 } 734 } else if (params->private_key) { 735 int pkcs12_ok = 0; 736 #ifdef PKCS12_FUNCS 737 /* Try to load in PKCS#12 format */ 738 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 739 ret = gnutls_certificate_set_x509_simple_pkcs12_file( 740 global->xcred, params->private_key, 741 GNUTLS_X509_FMT_DER, params->private_key_passwd); 742 if (ret != 0) { 743 wpa_printf(MSG_DEBUG, "Failed to load private_key in " 744 "PKCS#12 format: %s", gnutls_strerror(ret)); 745 goto fail; 746 } else 747 pkcs12_ok = 1; 748 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 749 #endif /* PKCS12_FUNCS */ 750 751 if (!pkcs12_ok) { 752 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 753 "included"); 754 goto fail; 755 } 756 } 757 758 global->params_set = 1; 759 760 return 0; 761 762 fail: 763 gnutls_certificate_free_credentials(global->xcred); 764 return -1; 765 } 766 767 768 int tls_global_set_verify(void *ssl_ctx, int check_crl) 769 { 770 /* TODO */ 771 return 0; 772 } 773 774 775 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 776 int verify_peer) 777 { 778 if (conn == NULL || conn->session == NULL) 779 return -1; 780 781 conn->verify_peer = verify_peer; 782 gnutls_certificate_server_set_request(conn->session, 783 verify_peer ? GNUTLS_CERT_REQUIRE 784 : GNUTLS_CERT_REQUEST); 785 786 return 0; 787 } 788 789 790 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 791 struct tls_keys *keys) 792 { 793 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 794 security_parameters_st *sec; 795 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 796 797 if (conn == NULL || conn->session == NULL || keys == NULL) 798 return -1; 799 800 os_memset(keys, 0, sizeof(*keys)); 801 802 #ifdef GNUTLS_INTERNAL_STRUCTURE_HACK 803 sec = &conn->session->security_parameters; 804 keys->master_key = sec->master_secret; 805 keys->master_key_len = TLS_MASTER_SIZE; 806 keys->client_random = sec->client_random; 807 keys->server_random = sec->server_random; 808 #else /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 809 keys->client_random = 810 (u8 *) gnutls_session_get_client_random(conn->session); 811 keys->server_random = 812 (u8 *) gnutls_session_get_server_random(conn->session); 813 /* No access to master_secret */ 814 #endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */ 815 816 #ifdef GNUTLS_IA 817 gnutls_ia_extract_inner_secret(conn->session, 818 (char *) conn->inner_secret); 819 keys->inner_secret = conn->inner_secret; 820 keys->inner_secret_len = TLS_MASTER_SIZE; 821 #endif /* GNUTLS_IA */ 822 823 keys->client_random_len = TLS_RANDOM_SIZE; 824 keys->server_random_len = TLS_RANDOM_SIZE; 825 826 return 0; 827 } 828 829 830 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 831 const char *label, int server_random_first, 832 u8 *out, size_t out_len) 833 { 834 #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 835 if (conn == NULL || conn->session == NULL) 836 return -1; 837 838 return gnutls_prf(conn->session, os_strlen(label), label, 839 server_random_first, 0, NULL, out_len, (char *) out); 840 #else /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 841 return -1; 842 #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ 843 } 844 845 846 static int tls_connection_verify_peer(struct tls_connection *conn) 847 { 848 unsigned int status, num_certs, i; 849 struct os_time now; 850 const gnutls_datum_t *certs; 851 gnutls_x509_crt_t cert; 852 853 if (gnutls_certificate_verify_peers2(conn->session, &status) < 0) { 854 wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 855 "certificate chain"); 856 return -1; 857 } 858 859 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 860 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 861 return -1; 862 } 863 864 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 865 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 866 "known issuer"); 867 return -1; 868 } 869 870 if (status & GNUTLS_CERT_REVOKED) { 871 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 872 return -1; 873 } 874 875 os_get_time(&now); 876 877 certs = gnutls_certificate_get_peers(conn->session, &num_certs); 878 if (certs == NULL) { 879 wpa_printf(MSG_INFO, "TLS: No peer certificate chain " 880 "received"); 881 return -1; 882 } 883 884 for (i = 0; i < num_certs; i++) { 885 char *buf; 886 size_t len; 887 if (gnutls_x509_crt_init(&cert) < 0) { 888 wpa_printf(MSG_INFO, "TLS: Certificate initialization " 889 "failed"); 890 return -1; 891 } 892 893 if (gnutls_x509_crt_import(cert, &certs[i], 894 GNUTLS_X509_FMT_DER) < 0) { 895 wpa_printf(MSG_INFO, "TLS: Could not parse peer " 896 "certificate %d/%d", i + 1, num_certs); 897 gnutls_x509_crt_deinit(cert); 898 return -1; 899 } 900 901 gnutls_x509_crt_get_dn(cert, NULL, &len); 902 len++; 903 buf = os_malloc(len + 1); 904 if (buf) { 905 buf[0] = buf[len] = '\0'; 906 gnutls_x509_crt_get_dn(cert, buf, &len); 907 } 908 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 909 i + 1, num_certs, buf); 910 911 if (i == 0) { 912 /* TODO: validate subject_match and altsubject_match */ 913 } 914 915 os_free(buf); 916 917 if (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 918 gnutls_x509_crt_get_activation_time(cert) > now.sec) { 919 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 920 "not valid at this time", 921 i + 1, num_certs); 922 gnutls_x509_crt_deinit(cert); 923 return -1; 924 } 925 926 gnutls_x509_crt_deinit(cert); 927 } 928 929 return 0; 930 } 931 932 933 u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 934 const u8 *in_data, size_t in_len, 935 size_t *out_len, u8 **appl_data, 936 size_t *appl_data_len) 937 { 938 struct tls_global *global = ssl_ctx; 939 u8 *out_data; 940 int ret; 941 942 if (appl_data) 943 *appl_data = NULL; 944 945 if (in_data && in_len) { 946 if (conn->pull_buf) { 947 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 948 "pull_buf", __func__, 949 (unsigned long) conn->pull_buf_len); 950 os_free(conn->pull_buf); 951 } 952 conn->pull_buf = os_malloc(in_len); 953 if (conn->pull_buf == NULL) 954 return NULL; 955 os_memcpy(conn->pull_buf, in_data, in_len); 956 conn->pull_buf_offset = conn->pull_buf; 957 conn->pull_buf_len = in_len; 958 } 959 960 ret = gnutls_handshake(conn->session); 961 if (ret < 0) { 962 switch (ret) { 963 case GNUTLS_E_AGAIN: 964 if (global->server && conn->established && 965 conn->push_buf == NULL) { 966 /* Need to return something to trigger 967 * completion of EAP-TLS. */ 968 conn->push_buf = os_malloc(1); 969 } 970 break; 971 case GNUTLS_E_FATAL_ALERT_RECEIVED: 972 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 973 __func__, gnutls_alert_get_name( 974 gnutls_alert_get(conn->session))); 975 conn->read_alerts++; 976 /* continue */ 977 default: 978 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 979 "-> %s", __func__, gnutls_strerror(ret)); 980 conn->failed++; 981 } 982 } else { 983 size_t size; 984 985 if (conn->verify_peer && tls_connection_verify_peer(conn)) { 986 wpa_printf(MSG_INFO, "TLS: Peer certificate chain " 987 "failed validation"); 988 conn->failed++; 989 return NULL; 990 } 991 992 if (conn->tls_ia && !gnutls_ia_handshake_p(conn->session)) { 993 wpa_printf(MSG_INFO, "TLS: No TLS/IA negotiation"); 994 conn->failed++; 995 return NULL; 996 } 997 998 if (conn->tls_ia) 999 wpa_printf(MSG_DEBUG, "TLS: Start TLS/IA handshake"); 1000 else { 1001 wpa_printf(MSG_DEBUG, "TLS: Handshake completed " 1002 "successfully"); 1003 } 1004 conn->established = 1; 1005 if (conn->push_buf == NULL) { 1006 /* Need to return something to get final TLS ACK. */ 1007 conn->push_buf = os_malloc(1); 1008 } 1009 1010 gnutls_session_get_data(conn->session, NULL, &size); 1011 if (global->session_data == NULL || 1012 global->session_data_size < size) { 1013 os_free(global->session_data); 1014 global->session_data = os_malloc(size); 1015 } 1016 if (global->session_data) { 1017 global->session_data_size = size; 1018 gnutls_session_get_data(conn->session, 1019 global->session_data, 1020 &global->session_data_size); 1021 } 1022 } 1023 1024 out_data = conn->push_buf; 1025 *out_len = conn->push_buf_len; 1026 conn->push_buf = NULL; 1027 conn->push_buf_len = 0; 1028 return out_data; 1029 } 1030 1031 1032 u8 * tls_connection_server_handshake(void *ssl_ctx, 1033 struct tls_connection *conn, 1034 const u8 *in_data, size_t in_len, 1035 size_t *out_len) 1036 { 1037 return tls_connection_handshake(ssl_ctx, conn, in_data, in_len, 1038 out_len, NULL, NULL); 1039 } 1040 1041 1042 int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn, 1043 const u8 *in_data, size_t in_len, 1044 u8 *out_data, size_t out_len) 1045 { 1046 ssize_t res; 1047 1048 #ifdef GNUTLS_IA 1049 if (conn->tls_ia) 1050 res = gnutls_ia_send(conn->session, (char *) in_data, in_len); 1051 else 1052 #endif /* GNUTLS_IA */ 1053 res = gnutls_record_send(conn->session, in_data, in_len); 1054 if (res < 0) { 1055 wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 1056 __func__, gnutls_strerror(res)); 1057 return -1; 1058 } 1059 if (conn->push_buf == NULL) 1060 return -1; 1061 if (conn->push_buf_len < out_len) 1062 out_len = conn->push_buf_len; 1063 else if (conn->push_buf_len > out_len) { 1064 wpa_printf(MSG_INFO, "GnuTLS: Not enough buffer space for " 1065 "encrypted message (in_len=%lu push_buf_len=%lu " 1066 "out_len=%lu", 1067 (unsigned long) in_len, 1068 (unsigned long) conn->push_buf_len, 1069 (unsigned long) out_len); 1070 } 1071 os_memcpy(out_data, conn->push_buf, out_len); 1072 os_free(conn->push_buf); 1073 conn->push_buf = NULL; 1074 conn->push_buf_len = 0; 1075 return out_len; 1076 } 1077 1078 1079 int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, 1080 const u8 *in_data, size_t in_len, 1081 u8 *out_data, size_t out_len) 1082 { 1083 ssize_t res; 1084 1085 if (conn->pull_buf) { 1086 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 1087 "pull_buf", __func__, 1088 (unsigned long) conn->pull_buf_len); 1089 os_free(conn->pull_buf); 1090 } 1091 conn->pull_buf = os_malloc(in_len); 1092 if (conn->pull_buf == NULL) 1093 return -1; 1094 os_memcpy(conn->pull_buf, in_data, in_len); 1095 conn->pull_buf_offset = conn->pull_buf; 1096 conn->pull_buf_len = in_len; 1097 1098 #ifdef GNUTLS_IA 1099 if (conn->tls_ia) { 1100 res = gnutls_ia_recv(conn->session, (char *) out_data, 1101 out_len); 1102 if (out_len >= 12 && 1103 (res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || 1104 res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)) { 1105 int final = res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED; 1106 wpa_printf(MSG_DEBUG, "%s: Received %sPhaseFinished", 1107 __func__, final ? "Final" : "Intermediate"); 1108 1109 res = gnutls_ia_permute_inner_secret( 1110 conn->session, conn->session_keys_len, 1111 (char *) conn->session_keys); 1112 if (conn->session_keys) { 1113 os_memset(conn->session_keys, 0, 1114 conn->session_keys_len); 1115 os_free(conn->session_keys); 1116 } 1117 conn->session_keys = NULL; 1118 conn->session_keys_len = 0; 1119 if (res) { 1120 wpa_printf(MSG_DEBUG, "%s: Failed to permute " 1121 "inner secret: %s", 1122 __func__, gnutls_strerror(res)); 1123 return -1; 1124 } 1125 1126 res = gnutls_ia_verify_endphase(conn->session, 1127 (char *) out_data); 1128 if (res == 0) { 1129 wpa_printf(MSG_DEBUG, "%s: Correct endphase " 1130 "checksum", __func__); 1131 } else { 1132 wpa_printf(MSG_INFO, "%s: Endphase " 1133 "verification failed: %s", 1134 __func__, gnutls_strerror(res)); 1135 return -1; 1136 } 1137 1138 if (final) 1139 conn->final_phase_finished = 1; 1140 1141 return 0; 1142 } 1143 1144 if (res < 0) { 1145 wpa_printf(MSG_DEBUG, "%s - gnutls_ia_recv failed: %d " 1146 "(%s)", __func__, (int) res, 1147 gnutls_strerror(res)); 1148 } 1149 return res; 1150 } 1151 #endif /* GNUTLS_IA */ 1152 1153 res = gnutls_record_recv(conn->session, out_data, out_len); 1154 if (res < 0) { 1155 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 1156 "(%s)", __func__, (int) res, gnutls_strerror(res)); 1157 } 1158 1159 return res; 1160 } 1161 1162 1163 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 1164 { 1165 if (conn == NULL) 1166 return 0; 1167 return gnutls_session_is_resumed(conn->session); 1168 } 1169 1170 1171 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 1172 u8 *ciphers) 1173 { 1174 /* TODO */ 1175 return -1; 1176 } 1177 1178 1179 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 1180 char *buf, size_t buflen) 1181 { 1182 /* TODO */ 1183 buf[0] = '\0'; 1184 return 0; 1185 } 1186 1187 1188 int tls_connection_enable_workaround(void *ssl_ctx, 1189 struct tls_connection *conn) 1190 { 1191 /* TODO: set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ 1192 return 0; 1193 } 1194 1195 1196 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 1197 int ext_type, const u8 *data, 1198 size_t data_len) 1199 { 1200 /* TODO */ 1201 return -1; 1202 } 1203 1204 1205 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 1206 { 1207 if (conn == NULL) 1208 return -1; 1209 return conn->failed; 1210 } 1211 1212 1213 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 1214 { 1215 if (conn == NULL) 1216 return -1; 1217 return conn->read_alerts; 1218 } 1219 1220 1221 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 1222 { 1223 if (conn == NULL) 1224 return -1; 1225 return conn->write_alerts; 1226 } 1227 1228 1229 int tls_connection_get_keyblock_size(void *tls_ctx, 1230 struct tls_connection *conn) 1231 { 1232 /* TODO */ 1233 return -1; 1234 } 1235 1236 1237 unsigned int tls_capabilities(void *tls_ctx) 1238 { 1239 unsigned int capa = 0; 1240 1241 #ifdef GNUTLS_IA 1242 capa |= TLS_CAPABILITY_IA; 1243 #endif /* GNUTLS_IA */ 1244 1245 return capa; 1246 } 1247 1248 1249 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 1250 int tls_ia) 1251 { 1252 #ifdef GNUTLS_IA 1253 int ret; 1254 1255 if (conn == NULL) 1256 return -1; 1257 1258 conn->tls_ia = tls_ia; 1259 if (!tls_ia) 1260 return 0; 1261 1262 ret = gnutls_ia_allocate_server_credentials(&conn->iacred_srv); 1263 if (ret) { 1264 wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", 1265 gnutls_strerror(ret)); 1266 return -1; 1267 } 1268 1269 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, 1270 conn->iacred_srv); 1271 if (ret) { 1272 wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", 1273 gnutls_strerror(ret)); 1274 gnutls_ia_free_server_credentials(conn->iacred_srv); 1275 conn->iacred_srv = NULL; 1276 return -1; 1277 } 1278 1279 return 0; 1280 #else /* GNUTLS_IA */ 1281 return -1; 1282 #endif /* GNUTLS_IA */ 1283 } 1284 1285 1286 int tls_connection_ia_send_phase_finished(void *tls_ctx, 1287 struct tls_connection *conn, 1288 int final, 1289 u8 *out_data, size_t out_len) 1290 { 1291 #ifdef GNUTLS_IA 1292 int ret; 1293 1294 if (conn == NULL || conn->session == NULL || !conn->tls_ia) 1295 return -1; 1296 1297 ret = gnutls_ia_permute_inner_secret(conn->session, 1298 conn->session_keys_len, 1299 (char *) conn->session_keys); 1300 if (conn->session_keys) { 1301 os_memset(conn->session_keys, 0, conn->session_keys_len); 1302 os_free(conn->session_keys); 1303 } 1304 conn->session_keys = NULL; 1305 conn->session_keys_len = 0; 1306 if (ret) { 1307 wpa_printf(MSG_DEBUG, "%s: Failed to permute inner secret: %s", 1308 __func__, gnutls_strerror(ret)); 1309 return -1; 1310 } 1311 1312 ret = gnutls_ia_endphase_send(conn->session, final); 1313 if (ret) { 1314 wpa_printf(MSG_DEBUG, "%s: Failed to send endphase: %s", 1315 __func__, gnutls_strerror(ret)); 1316 return -1; 1317 } 1318 1319 if (conn->push_buf == NULL) 1320 return -1; 1321 if (conn->push_buf_len < out_len) 1322 out_len = conn->push_buf_len; 1323 os_memcpy(out_data, conn->push_buf, out_len); 1324 os_free(conn->push_buf); 1325 conn->push_buf = NULL; 1326 conn->push_buf_len = 0; 1327 return out_len; 1328 #else /* GNUTLS_IA */ 1329 return -1; 1330 #endif /* GNUTLS_IA */ 1331 } 1332 1333 1334 int tls_connection_ia_final_phase_finished(void *tls_ctx, 1335 struct tls_connection *conn) 1336 { 1337 if (conn == NULL) 1338 return -1; 1339 1340 return conn->final_phase_finished; 1341 } 1342 1343 1344 int tls_connection_ia_permute_inner_secret(void *tls_ctx, 1345 struct tls_connection *conn, 1346 const u8 *key, size_t key_len) 1347 { 1348 #ifdef GNUTLS_IA 1349 if (conn == NULL || !conn->tls_ia) 1350 return -1; 1351 1352 if (conn->session_keys) { 1353 os_memset(conn->session_keys, 0, conn->session_keys_len); 1354 os_free(conn->session_keys); 1355 } 1356 conn->session_keys_len = 0; 1357 1358 if (key) { 1359 conn->session_keys = os_malloc(key_len); 1360 if (conn->session_keys == NULL) 1361 return -1; 1362 os_memcpy(conn->session_keys, key, key_len); 1363 conn->session_keys_len = key_len; 1364 } else { 1365 conn->session_keys = NULL; 1366 conn->session_keys_len = 0; 1367 } 1368 1369 return 0; 1370 #else /* GNUTLS_IA */ 1371 return -1; 1372 #endif /* GNUTLS_IA */ 1373 } 1374