gtls.c (71376B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 /* 26 * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code 27 * but vtls.c should ever call or use these functions. 28 * 29 * Note: do not use the GnuTLS' *_t variable type names in this source code, 30 * since they were not present in 1.0.X. 31 */ 32 33 #include "../curl_setup.h" 34 35 #ifdef USE_GNUTLS 36 37 #include <gnutls/abstract.h> 38 #include <gnutls/gnutls.h> 39 #include <gnutls/x509.h> 40 #include <gnutls/crypto.h> 41 #include <nettle/sha2.h> 42 43 #include "../urldata.h" 44 #include "../sendf.h" 45 #include "../curlx/inet_pton.h" 46 #include "keylog.h" 47 #include "gtls.h" 48 #include "vtls.h" 49 #include "vtls_int.h" 50 #include "vtls_scache.h" 51 #include "../vauth/vauth.h" 52 #include "../parsedate.h" 53 #include "../connect.h" /* for the connect timeout */ 54 #include "../progress.h" 55 #include "../select.h" 56 #include "../strdup.h" 57 #include "../curlx/warnless.h" 58 #include "x509asn1.h" 59 #include "../multiif.h" 60 #include "../curl_printf.h" 61 #include "../curl_memory.h" 62 /* The last #include file should be: */ 63 #include "../memdebug.h" 64 65 /* Enable GnuTLS debugging by defining GTLSDEBUG */ 66 /*#define GTLSDEBUG */ 67 68 #ifdef GTLSDEBUG 69 static void tls_log_func(int level, const char *str) 70 { 71 fprintf(stderr, "|<%d>| %s", level, str); 72 } 73 #endif 74 static bool gtls_inited = FALSE; 75 76 #if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a) 77 #error "too old GnuTLS version" 78 #endif 79 80 # include <gnutls/ocsp.h> 81 82 struct gtls_ssl_backend_data { 83 struct gtls_ctx gtls; 84 }; 85 86 static ssize_t gtls_push(void *s, const void *buf, size_t blen) 87 { 88 struct Curl_cfilter *cf = s; 89 struct ssl_connect_data *connssl = cf->ctx; 90 struct gtls_ssl_backend_data *backend = 91 (struct gtls_ssl_backend_data *)connssl->backend; 92 struct Curl_easy *data = CF_DATA_CURRENT(cf); 93 size_t nwritten; 94 CURLcode result; 95 96 DEBUGASSERT(data); 97 result = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &nwritten); 98 CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %d, %zu", 99 blen, result, nwritten); 100 backend->gtls.io_result = result; 101 if(result) { 102 /* !checksrc! disable ERRNOVAR 1 */ 103 gnutls_transport_set_errno(backend->gtls.session, 104 (CURLE_AGAIN == result) ? EAGAIN : EINVAL); 105 return -1; 106 } 107 return (ssize_t)nwritten; 108 } 109 110 static ssize_t gtls_pull(void *s, void *buf, size_t blen) 111 { 112 struct Curl_cfilter *cf = s; 113 struct ssl_connect_data *connssl = cf->ctx; 114 struct gtls_ssl_backend_data *backend = 115 (struct gtls_ssl_backend_data *)connssl->backend; 116 struct Curl_easy *data = CF_DATA_CURRENT(cf); 117 size_t nread; 118 CURLcode result; 119 120 DEBUGASSERT(data); 121 if(!backend->gtls.shared_creds->trust_setup) { 122 result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls); 123 if(result) { 124 /* !checksrc! disable ERRNOVAR 1 */ 125 gnutls_transport_set_errno(backend->gtls.session, EINVAL); 126 backend->gtls.io_result = result; 127 return -1; 128 } 129 } 130 131 result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); 132 CURL_TRC_CF(data, cf, "glts_pull(len=%zu) -> %d, %zd", 133 blen, result, nread); 134 backend->gtls.io_result = result; 135 if(result) { 136 /* !checksrc! disable ERRNOVAR 1 */ 137 gnutls_transport_set_errno(backend->gtls.session, 138 (CURLE_AGAIN == result) ? EAGAIN : EINVAL); 139 return -1; 140 } 141 else if(nread == 0) 142 connssl->peer_closed = TRUE; 143 return (ssize_t)nread; 144 } 145 146 /* gtls_init() 147 * 148 * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that 149 * are not thread-safe and thus this function itself is not thread-safe and 150 * must only be called from within curl_global_init() to keep the thread 151 * situation under control! 152 */ 153 static int gtls_init(void) 154 { 155 int ret = 1; 156 if(!gtls_inited) { 157 ret = gnutls_global_init() ? 0 : 1; 158 #ifdef GTLSDEBUG 159 gnutls_global_set_log_function(tls_log_func); 160 gnutls_global_set_log_level(2); 161 #endif 162 gtls_inited = TRUE; 163 } 164 return ret; 165 } 166 167 static void gtls_cleanup(void) 168 { 169 if(gtls_inited) { 170 gnutls_global_deinit(); 171 gtls_inited = FALSE; 172 } 173 } 174 175 #ifndef CURL_DISABLE_VERBOSE_STRINGS 176 static void showtime(struct Curl_easy *data, 177 const char *text, 178 time_t stamp) 179 { 180 struct tm buffer; 181 const struct tm *tm = &buffer; 182 char str[96]; 183 CURLcode result = Curl_gmtime(stamp, &buffer); 184 if(result) 185 return; 186 187 msnprintf(str, 188 sizeof(str), 189 " %s: %s, %02d %s %4d %02d:%02d:%02d GMT", 190 text, 191 Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6], 192 tm->tm_mday, 193 Curl_month[tm->tm_mon], 194 tm->tm_year + 1900, 195 tm->tm_hour, 196 tm->tm_min, 197 tm->tm_sec); 198 infof(data, "%s", str); 199 } 200 #endif 201 202 static gnutls_datum_t load_file(const char *file) 203 { 204 FILE *f; 205 gnutls_datum_t loaded_file = { NULL, 0 }; 206 long filelen; 207 void *ptr; 208 209 f = fopen(file, "rb"); 210 if(!f) 211 return loaded_file; 212 if(fseek(f, 0, SEEK_END) != 0 213 || (filelen = ftell(f)) < 0 214 || fseek(f, 0, SEEK_SET) != 0 215 || !(ptr = malloc((size_t)filelen))) 216 goto out; 217 if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) { 218 free(ptr); 219 goto out; 220 } 221 222 loaded_file.data = ptr; 223 loaded_file.size = (unsigned int)filelen; 224 out: 225 fclose(f); 226 return loaded_file; 227 } 228 229 static void unload_file(gnutls_datum_t data) 230 { 231 free(data.data); 232 } 233 234 235 /* this function does an SSL/TLS (re-)handshake */ 236 static CURLcode handshake(struct Curl_cfilter *cf, 237 struct Curl_easy *data) 238 { 239 struct ssl_connect_data *connssl = cf->ctx; 240 struct gtls_ssl_backend_data *backend = 241 (struct gtls_ssl_backend_data *)connssl->backend; 242 gnutls_session_t session; 243 int rc; 244 245 DEBUGASSERT(backend); 246 session = backend->gtls.session; 247 248 connssl->io_need = CURL_SSL_IO_NEED_NONE; 249 backend->gtls.io_result = CURLE_OK; 250 rc = gnutls_handshake(session); 251 252 if(!backend->gtls.shared_creds->trust_setup) { 253 /* After having send off the ClientHello, we prepare the trust 254 * store to verify the coming certificate from the server */ 255 CURLcode result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls); 256 if(result) 257 return result; 258 } 259 260 if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) { 261 connssl->io_need = 262 gnutls_record_get_direction(session) ? 263 CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; 264 return CURLE_AGAIN; 265 } 266 else if((rc < 0) && !gnutls_error_is_fatal(rc)) { 267 const char *strerr = NULL; 268 269 if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { 270 gnutls_alert_description_t alert = gnutls_alert_get(session); 271 strerr = gnutls_alert_get_name(alert); 272 } 273 274 if(!strerr) 275 strerr = gnutls_strerror(rc); 276 277 infof(data, "gnutls_handshake() warning: %s", strerr); 278 return CURLE_AGAIN; 279 } 280 else if((rc < 0) && backend->gtls.io_result) { 281 return backend->gtls.io_result; 282 } 283 else if(rc < 0) { 284 const char *strerr = NULL; 285 286 if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { 287 gnutls_alert_description_t alert = gnutls_alert_get(session); 288 strerr = gnutls_alert_get_name(alert); 289 } 290 291 if(!strerr) 292 strerr = gnutls_strerror(rc); 293 294 failf(data, "GnuTLS, handshake failed: %s", strerr); 295 return CURLE_SSL_CONNECT_ERROR; 296 } 297 298 return CURLE_OK; 299 } 300 301 static gnutls_x509_crt_fmt_t gnutls_do_file_type(const char *type) 302 { 303 if(!type || !type[0]) 304 return GNUTLS_X509_FMT_PEM; 305 if(curl_strequal(type, "PEM")) 306 return GNUTLS_X509_FMT_PEM; 307 if(curl_strequal(type, "DER")) 308 return GNUTLS_X509_FMT_DER; 309 return GNUTLS_X509_FMT_PEM; /* default to PEM */ 310 } 311 312 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509" 313 /* If GnuTLS was compiled without support for SRP it will error out if SRP is 314 requested in the priority string, so treat it specially 315 */ 316 #define GNUTLS_SRP "+SRP" 317 318 #define QUIC_PRIORITY \ 319 "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \ 320 "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \ 321 "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \ 322 "%DISABLE_TLS13_COMPAT_MODE" 323 324 static CURLcode 325 gnutls_set_ssl_version_min_max(struct Curl_easy *data, 326 struct ssl_peer *peer, 327 struct ssl_primary_config *conn_config, 328 const char **prioritylist, 329 bool tls13support) 330 { 331 long ssl_version = conn_config->version; 332 long ssl_version_max = conn_config->version_max; 333 334 if((ssl_version == CURL_SSLVERSION_DEFAULT) || 335 (ssl_version == CURL_SSLVERSION_TLSv1)) 336 ssl_version = CURL_SSLVERSION_TLSv1_0; 337 if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) 338 ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; 339 340 if(peer->transport == TRNSPRT_QUIC) { 341 if((ssl_version_max != CURL_SSLVERSION_MAX_DEFAULT) && 342 (ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3)) { 343 failf(data, "QUIC needs at least TLS version 1.3"); 344 return CURLE_SSL_CONNECT_ERROR; 345 } 346 *prioritylist = QUIC_PRIORITY; 347 return CURLE_OK; 348 } 349 350 if(!tls13support) { 351 /* If the running GnuTLS does not support TLS 1.3, we must not specify a 352 prioritylist involving that since it will make GnuTLS return an en 353 error back at us */ 354 if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) || 355 (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) { 356 ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; 357 } 358 } 359 else if(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT) { 360 ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; 361 } 362 363 switch(ssl_version | ssl_version_max) { 364 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: 365 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 366 "+VERS-TLS1.0"; 367 return CURLE_OK; 368 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: 369 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 370 "+VERS-TLS1.1:+VERS-TLS1.0"; 371 return CURLE_OK; 372 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: 373 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 374 "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0"; 375 return CURLE_OK; 376 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: 377 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 378 "+VERS-TLS1.1"; 379 return CURLE_OK; 380 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: 381 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 382 "+VERS-TLS1.2:+VERS-TLS1.1"; 383 return CURLE_OK; 384 case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: 385 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 386 "+VERS-TLS1.2"; 387 return CURLE_OK; 388 case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: 389 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 390 "+VERS-TLS1.3"; 391 return CURLE_OK; 392 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_3: 393 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"; 394 return CURLE_OK; 395 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_3: 396 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 397 "+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1"; 398 return CURLE_OK; 399 case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3: 400 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" 401 "+VERS-TLS1.3:+VERS-TLS1.2"; 402 return CURLE_OK; 403 } 404 405 failf(data, "GnuTLS: cannot set ssl protocol"); 406 return CURLE_SSL_CONNECT_ERROR; 407 } 408 409 CURLcode Curl_gtls_shared_creds_create(struct Curl_easy *data, 410 struct gtls_shared_creds **pcreds) 411 { 412 struct gtls_shared_creds *shared; 413 int rc; 414 415 *pcreds = NULL; 416 shared = calloc(1, sizeof(*shared)); 417 if(!shared) 418 return CURLE_OUT_OF_MEMORY; 419 420 rc = gnutls_certificate_allocate_credentials(&shared->creds); 421 if(rc != GNUTLS_E_SUCCESS) { 422 failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); 423 free(shared); 424 return CURLE_SSL_CONNECT_ERROR; 425 } 426 427 shared->refcount = 1; 428 shared->time = curlx_now(); 429 *pcreds = shared; 430 return CURLE_OK; 431 } 432 433 CURLcode Curl_gtls_shared_creds_up_ref(struct gtls_shared_creds *creds) 434 { 435 DEBUGASSERT(creds); 436 if(creds->refcount < SIZE_T_MAX) { 437 ++creds->refcount; 438 return CURLE_OK; 439 } 440 return CURLE_BAD_FUNCTION_ARGUMENT; 441 } 442 443 void Curl_gtls_shared_creds_free(struct gtls_shared_creds **pcreds) 444 { 445 struct gtls_shared_creds *shared = *pcreds; 446 *pcreds = NULL; 447 if(shared) { 448 --shared->refcount; 449 if(!shared->refcount) { 450 gnutls_certificate_free_credentials(shared->creds); 451 free(shared->CAfile); 452 free(shared); 453 } 454 } 455 } 456 457 static CURLcode gtls_populate_creds(struct Curl_cfilter *cf, 458 struct Curl_easy *data, 459 gnutls_certificate_credentials_t creds) 460 { 461 struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf); 462 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 463 int rc; 464 465 if(config->verifypeer) { 466 bool imported_native_ca = FALSE; 467 468 if(ssl_config->native_ca_store) { 469 rc = gnutls_certificate_set_x509_system_trust(creds); 470 if(rc < 0) 471 infof(data, "error reading native ca store (%s), continuing anyway", 472 gnutls_strerror(rc)); 473 else { 474 infof(data, "found %d certificates in native ca store", rc); 475 if(rc > 0) 476 imported_native_ca = TRUE; 477 } 478 } 479 480 if(config->CAfile) { 481 /* set the trusted CA cert bundle file */ 482 gnutls_certificate_set_verify_flags(creds, 483 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); 484 485 rc = gnutls_certificate_set_x509_trust_file(creds, 486 config->CAfile, 487 GNUTLS_X509_FMT_PEM); 488 if(rc < 0) { 489 infof(data, "error reading ca cert file %s (%s)%s", 490 config->CAfile, gnutls_strerror(rc), 491 (imported_native_ca ? ", continuing anyway" : "")); 492 if(!imported_native_ca) { 493 ssl_config->certverifyresult = rc; 494 return CURLE_SSL_CACERT_BADFILE; 495 } 496 } 497 else 498 infof(data, "found %d certificates in %s", rc, config->CAfile); 499 } 500 501 if(config->CApath) { 502 /* set the trusted CA cert directory */ 503 rc = gnutls_certificate_set_x509_trust_dir(creds, config->CApath, 504 GNUTLS_X509_FMT_PEM); 505 if(rc < 0) { 506 infof(data, "error reading ca cert file %s (%s)%s", 507 config->CApath, gnutls_strerror(rc), 508 (imported_native_ca ? ", continuing anyway" : "")); 509 if(!imported_native_ca) { 510 ssl_config->certverifyresult = rc; 511 return CURLE_SSL_CACERT_BADFILE; 512 } 513 } 514 else 515 infof(data, "found %d certificates in %s", rc, config->CApath); 516 } 517 } 518 519 if(config->CRLfile) { 520 /* set the CRL list file */ 521 rc = gnutls_certificate_set_x509_crl_file(creds, config->CRLfile, 522 GNUTLS_X509_FMT_PEM); 523 if(rc < 0) { 524 failf(data, "error reading crl file %s (%s)", 525 config->CRLfile, gnutls_strerror(rc)); 526 return CURLE_SSL_CRL_BADFILE; 527 } 528 else 529 infof(data, "found %d CRL in %s", rc, config->CRLfile); 530 } 531 532 return CURLE_OK; 533 } 534 535 /* key to use at `multi->proto_hash` */ 536 #define MPROTO_GTLS_X509_KEY "tls:gtls:x509:share" 537 538 static bool gtls_shared_creds_expired(const struct Curl_easy *data, 539 const struct gtls_shared_creds *sc) 540 { 541 const struct ssl_general_config *cfg = &data->set.general_ssl; 542 struct curltime now = curlx_now(); 543 timediff_t elapsed_ms = curlx_timediff(now, sc->time); 544 timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; 545 546 if(timeout_ms < 0) 547 return FALSE; 548 549 return elapsed_ms >= timeout_ms; 550 } 551 552 static bool gtls_shared_creds_different(struct Curl_cfilter *cf, 553 const struct gtls_shared_creds *sc) 554 { 555 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 556 if(!sc->CAfile || !conn_config->CAfile) 557 return sc->CAfile != conn_config->CAfile; 558 559 return strcmp(sc->CAfile, conn_config->CAfile); 560 } 561 562 static struct gtls_shared_creds* 563 gtls_get_cached_creds(struct Curl_cfilter *cf, struct Curl_easy *data) 564 { 565 struct gtls_shared_creds *shared_creds; 566 567 if(data->multi) { 568 shared_creds = Curl_hash_pick(&data->multi->proto_hash, 569 CURL_UNCONST(MPROTO_GTLS_X509_KEY), 570 sizeof(MPROTO_GTLS_X509_KEY)-1); 571 if(shared_creds && shared_creds->creds && 572 !gtls_shared_creds_expired(data, shared_creds) && 573 !gtls_shared_creds_different(cf, shared_creds)) { 574 return shared_creds; 575 } 576 } 577 return NULL; 578 } 579 580 static void gtls_shared_creds_hash_free(void *key, size_t key_len, void *p) 581 { 582 struct gtls_shared_creds *sc = p; 583 DEBUGASSERT(key_len == (sizeof(MPROTO_GTLS_X509_KEY)-1)); 584 DEBUGASSERT(!memcmp(MPROTO_GTLS_X509_KEY, key, key_len)); 585 (void)key; 586 (void)key_len; 587 Curl_gtls_shared_creds_free(&sc); /* down reference */ 588 } 589 590 static void gtls_set_cached_creds(struct Curl_cfilter *cf, 591 struct Curl_easy *data, 592 struct gtls_shared_creds *sc) 593 { 594 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 595 596 DEBUGASSERT(sc); 597 DEBUGASSERT(sc->creds); 598 DEBUGASSERT(!sc->CAfile); 599 DEBUGASSERT(sc->refcount == 1); 600 if(!data->multi) 601 return; 602 603 if(conn_config->CAfile) { 604 sc->CAfile = strdup(conn_config->CAfile); 605 if(!sc->CAfile) 606 return; 607 } 608 609 if(Curl_gtls_shared_creds_up_ref(sc)) 610 return; 611 612 if(!Curl_hash_add2(&data->multi->proto_hash, 613 CURL_UNCONST(MPROTO_GTLS_X509_KEY), 614 sizeof(MPROTO_GTLS_X509_KEY)-1, 615 sc, gtls_shared_creds_hash_free)) { 616 Curl_gtls_shared_creds_free(&sc); /* down reference again */ 617 return; 618 } 619 } 620 621 CURLcode Curl_gtls_client_trust_setup(struct Curl_cfilter *cf, 622 struct Curl_easy *data, 623 struct gtls_ctx *gtls) 624 { 625 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 626 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 627 struct gtls_shared_creds *cached_creds = NULL; 628 bool cache_criteria_met; 629 CURLcode result; 630 int rc; 631 632 633 /* Consider the X509 store cacheable if it comes exclusively from a CAfile, 634 or no source is provided and we are falling back to OpenSSL's built-in 635 default. */ 636 cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) && 637 conn_config->verifypeer && 638 !conn_config->CApath && 639 !conn_config->ca_info_blob && 640 !ssl_config->primary.CRLfile && 641 !ssl_config->native_ca_store && 642 !conn_config->clientcert; /* GnuTLS adds client cert to its credentials! */ 643 644 if(cache_criteria_met) 645 cached_creds = gtls_get_cached_creds(cf, data); 646 647 if(cached_creds && !Curl_gtls_shared_creds_up_ref(cached_creds)) { 648 CURL_TRC_CF(data, cf, "using shared trust anchors and CRLs"); 649 Curl_gtls_shared_creds_free(>ls->shared_creds); 650 gtls->shared_creds = cached_creds; 651 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE, 652 gtls->shared_creds->creds); 653 if(rc != GNUTLS_E_SUCCESS) { 654 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); 655 return CURLE_SSL_CONNECT_ERROR; 656 } 657 } 658 else { 659 CURL_TRC_CF(data, cf, "loading trust anchors and CRLs"); 660 result = gtls_populate_creds(cf, data, gtls->shared_creds->creds); 661 if(result) 662 return result; 663 gtls->shared_creds->trust_setup = TRUE; 664 if(cache_criteria_met) 665 gtls_set_cached_creds(cf, data, gtls->shared_creds); 666 } 667 return CURLE_OK; 668 } 669 670 CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, 671 struct Curl_easy *data, 672 const char *ssl_peer_key, 673 gnutls_session_t session, 674 curl_off_t valid_until, 675 const char *alpn, 676 unsigned char *quic_tp, 677 size_t quic_tp_len) 678 { 679 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 680 struct Curl_ssl_session *sc_session; 681 unsigned char *sdata, *qtp_clone = NULL; 682 size_t sdata_len = 0; 683 size_t earlydata_max = 0; 684 CURLcode result = CURLE_OK; 685 686 if(!ssl_config->primary.cache_session) 687 return CURLE_OK; 688 689 /* we always unconditionally get the session id here, as even if we 690 already got it from the cache and asked to use it in the connection, it 691 might've been rejected and then a new one is in use now and we need to 692 detect that. */ 693 694 /* get the session ID data size */ 695 gnutls_session_get_data(session, NULL, &sdata_len); 696 if(!sdata_len) /* gnutls does this for some version combinations */ 697 return CURLE_OK; 698 699 sdata = malloc(sdata_len); /* get a buffer for it */ 700 if(!sdata) 701 return CURLE_OUT_OF_MEMORY; 702 703 /* extract session ID to the allocated buffer */ 704 gnutls_session_get_data(session, sdata, &sdata_len); 705 earlydata_max = gnutls_record_get_max_early_data_size(session); 706 707 CURL_TRC_CF(data, cf, "get session id (len=%zu, alpn=%s, earlymax=%zu) " 708 "and store in cache", sdata_len, alpn ? alpn : "-", 709 earlydata_max); 710 if(quic_tp && quic_tp_len) { 711 qtp_clone = Curl_memdup0((char *)quic_tp, quic_tp_len); 712 if(!qtp_clone) { 713 free(sdata); 714 return CURLE_OUT_OF_MEMORY; 715 } 716 } 717 718 result = Curl_ssl_session_create2(sdata, sdata_len, 719 Curl_glts_get_ietf_proto(session), 720 alpn, valid_until, earlydata_max, 721 qtp_clone, quic_tp_len, 722 &sc_session); 723 /* call took ownership of `sdata` and `qtp_clone` */ 724 if(!result) { 725 result = Curl_ssl_scache_put(cf, data, ssl_peer_key, sc_session); 726 /* took ownership of `sc_session` */ 727 } 728 return result; 729 } 730 731 int Curl_glts_get_ietf_proto(gnutls_session_t session) 732 { 733 switch(gnutls_protocol_get_version(session)) { 734 case GNUTLS_SSL3: 735 return CURL_IETF_PROTO_SSL3; 736 case GNUTLS_TLS1_0: 737 return CURL_IETF_PROTO_TLS1; 738 case GNUTLS_TLS1_1: 739 return CURL_IETF_PROTO_TLS1_1; 740 case GNUTLS_TLS1_2: 741 return CURL_IETF_PROTO_TLS1_2; 742 case GNUTLS_TLS1_3: 743 return CURL_IETF_PROTO_TLS1_3; 744 default: 745 return CURL_IETF_PROTO_UNKNOWN; 746 } 747 } 748 749 static CURLcode cf_gtls_update_session_id(struct Curl_cfilter *cf, 750 struct Curl_easy *data, 751 gnutls_session_t session) 752 { 753 struct ssl_connect_data *connssl = cf->ctx; 754 return Curl_gtls_cache_session(cf, data, connssl->peer.scache_key, 755 session, 0, connssl->negotiated.alpn, 756 NULL, 0); 757 } 758 759 static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype, 760 unsigned when, unsigned int incoming, 761 const gnutls_datum_t *msg) 762 { 763 struct Curl_cfilter *cf = gnutls_session_get_ptr(session); 764 765 (void)msg; 766 (void)incoming; 767 if(when) { /* after message has been processed */ 768 struct Curl_easy *data = CF_DATA_CURRENT(cf); 769 if(data) { 770 CURL_TRC_CF(data, cf, "handshake: %s message type %d", 771 incoming ? "incoming" : "outgoing", htype); 772 switch(htype) { 773 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: { 774 cf_gtls_update_session_id(cf, data, session); 775 break; 776 } 777 default: 778 break; 779 } 780 } 781 } 782 return 0; 783 } 784 785 static CURLcode gtls_set_priority(struct Curl_cfilter *cf, 786 struct Curl_easy *data, 787 struct gtls_ctx *gtls, 788 const char *priority) 789 { 790 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 791 struct dynbuf buf; 792 const char *err = NULL; 793 CURLcode result = CURLE_OK; 794 int rc; 795 796 curlx_dyn_init(&buf, 4096); 797 798 #ifdef USE_GNUTLS_SRP 799 if(conn_config->username) { 800 /* Only add SRP to the cipher list if SRP is requested. Otherwise 801 * GnuTLS will disable TLS 1.3 support. */ 802 result = curlx_dyn_add(&buf, priority); 803 if(!result) 804 result = curlx_dyn_add(&buf, ":" GNUTLS_SRP); 805 if(result) 806 goto out; 807 priority = curlx_dyn_ptr(&buf); 808 } 809 #endif 810 811 if(conn_config->cipher_list) { 812 if((conn_config->cipher_list[0] == '+') || 813 (conn_config->cipher_list[0] == '-') || 814 (conn_config->cipher_list[0] == '!')) { 815 /* add it to out own */ 816 if(!curlx_dyn_len(&buf)) { /* not added yet */ 817 result = curlx_dyn_add(&buf, priority); 818 if(result) 819 goto out; 820 } 821 result = curlx_dyn_addf(&buf, ":%s", conn_config->cipher_list); 822 if(result) 823 goto out; 824 priority = curlx_dyn_ptr(&buf); 825 } 826 else /* replace our own completely */ 827 priority = conn_config->cipher_list; 828 } 829 830 infof(data, "GnuTLS priority: %s", priority); 831 rc = gnutls_priority_set_direct(gtls->session, priority, &err); 832 if(rc != GNUTLS_E_SUCCESS) { 833 failf(data, "Error %d setting GnuTLS priority: %s", rc, err); 834 result = CURLE_SSL_CONNECT_ERROR; 835 } 836 837 out: 838 curlx_dyn_free(&buf); 839 return result; 840 } 841 842 static CURLcode gtls_client_init(struct Curl_cfilter *cf, 843 struct Curl_easy *data, 844 struct ssl_peer *peer, 845 size_t earlydata_max, 846 struct gtls_ctx *gtls) 847 { 848 struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf); 849 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 850 unsigned int init_flags; 851 int rc; 852 bool sni = TRUE; /* default is SNI enabled */ 853 const char *prioritylist; 854 bool tls13support; 855 CURLcode result; 856 857 if(!gtls_inited) 858 gtls_init(); 859 860 if(config->version == CURL_SSLVERSION_SSLv2) { 861 failf(data, "GnuTLS does not support SSLv2"); 862 return CURLE_SSL_CONNECT_ERROR; 863 } 864 else if(config->version == CURL_SSLVERSION_SSLv3) 865 sni = FALSE; /* SSLv3 has no SNI */ 866 867 /* allocate a shared creds struct */ 868 result = Curl_gtls_shared_creds_create(data, >ls->shared_creds); 869 if(result) 870 return result; 871 872 #ifdef USE_GNUTLS_SRP 873 if(config->username && Curl_auth_allowed_to_host(data)) { 874 infof(data, "Using TLS-SRP username: %s", config->username); 875 876 rc = gnutls_srp_allocate_client_credentials(>ls->srp_client_cred); 877 if(rc != GNUTLS_E_SUCCESS) { 878 failf(data, "gnutls_srp_allocate_client_cred() failed: %s", 879 gnutls_strerror(rc)); 880 return CURLE_OUT_OF_MEMORY; 881 } 882 883 rc = gnutls_srp_set_client_credentials(gtls->srp_client_cred, 884 config->username, 885 config->password); 886 if(rc != GNUTLS_E_SUCCESS) { 887 failf(data, "gnutls_srp_set_client_cred() failed: %s", 888 gnutls_strerror(rc)); 889 return CURLE_BAD_FUNCTION_ARGUMENT; 890 } 891 } 892 #endif 893 894 ssl_config->certverifyresult = 0; 895 896 /* Initialize TLS session as a client */ 897 init_flags = GNUTLS_CLIENT; 898 if(peer->transport == TRNSPRT_QUIC && earlydata_max > 0) 899 init_flags |= GNUTLS_ENABLE_EARLY_DATA | GNUTLS_NO_END_OF_EARLY_DATA; 900 else if(earlydata_max > 0 && earlydata_max != 0xFFFFFFFFUL) 901 /* See https://gitlab.com/gnutls/gnutls/-/issues/1619 902 * We cannot differentiate between a session announcing no earldata 903 * and one announcing 0xFFFFFFFFUL. On TCP+TLS, this is unlikely, but 904 * on QUIC this is common. */ 905 init_flags |= GNUTLS_ENABLE_EARLY_DATA; 906 907 #if defined(GNUTLS_FORCE_CLIENT_CERT) 908 init_flags |= GNUTLS_FORCE_CLIENT_CERT; 909 #endif 910 911 #if defined(GNUTLS_NO_TICKETS_TLS12) 912 init_flags |= GNUTLS_NO_TICKETS_TLS12; 913 #elif defined(GNUTLS_NO_TICKETS) 914 /* Disable TLS session tickets for non 1.3 connections */ 915 if((config->version != CURL_SSLVERSION_TLSv1_3) && 916 (config->version != CURL_SSLVERSION_DEFAULT)) 917 init_flags |= GNUTLS_NO_TICKETS; 918 #endif 919 920 #if defined(GNUTLS_NO_STATUS_REQUEST) 921 if(!config->verifystatus) 922 /* Disable the "status_request" TLS extension, enabled by default since 923 GnuTLS 3.8.0. */ 924 init_flags |= GNUTLS_NO_STATUS_REQUEST; 925 #endif 926 927 CURL_TRC_CF(data, cf, "gnutls_init(flags=%x), earlydata=%zu", 928 init_flags, earlydata_max); 929 rc = gnutls_init(>ls->session, init_flags); 930 if(rc != GNUTLS_E_SUCCESS) { 931 failf(data, "gnutls_init() failed: %d", rc); 932 return CURLE_SSL_CONNECT_ERROR; 933 } 934 935 if(sni && peer->sni) { 936 if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS, 937 peer->sni, strlen(peer->sni)) < 0) { 938 failf(data, "Failed to set SNI"); 939 return CURLE_SSL_CONNECT_ERROR; 940 } 941 } 942 943 /* Use default priorities */ 944 rc = gnutls_set_default_priority(gtls->session); 945 if(rc != GNUTLS_E_SUCCESS) 946 return CURLE_SSL_CONNECT_ERROR; 947 948 /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ 949 tls13support = !!gnutls_check_version("3.6.5"); 950 951 /* Ensure +SRP comes at the *end* of all relevant strings so that it can be 952 * removed if a runtime error indicates that SRP is not supported by this 953 * GnuTLS version */ 954 955 if(config->version == CURL_SSLVERSION_SSLv2 || 956 config->version == CURL_SSLVERSION_SSLv3) { 957 failf(data, "GnuTLS does not support SSLv2 or SSLv3"); 958 return CURLE_SSL_CONNECT_ERROR; 959 } 960 961 if(config->version == CURL_SSLVERSION_TLSv1_3) { 962 if(!tls13support) { 963 failf(data, "This GnuTLS installation does not support TLS 1.3"); 964 return CURLE_SSL_CONNECT_ERROR; 965 } 966 } 967 968 /* At this point we know we have a supported TLS version, so set it */ 969 result = gnutls_set_ssl_version_min_max(data, peer, 970 config, &prioritylist, tls13support); 971 if(result) 972 return result; 973 974 result = gtls_set_priority(cf, data, gtls, prioritylist); 975 if(result) 976 return result; 977 978 if(config->clientcert) { 979 if(!gtls->shared_creds->trust_setup) { 980 result = Curl_gtls_client_trust_setup(cf, data, gtls); 981 if(result) 982 return result; 983 } 984 if(ssl_config->cert_type && curl_strequal(ssl_config->cert_type, "P12")) { 985 rc = gnutls_certificate_set_x509_simple_pkcs12_file( 986 gtls->shared_creds->creds, config->clientcert, GNUTLS_X509_FMT_DER, 987 ssl_config->key_passwd ? ssl_config->key_passwd : ""); 988 if(rc != GNUTLS_E_SUCCESS) { 989 failf(data, 990 "error reading X.509 potentially-encrypted key or certificate " 991 "file: %s", 992 gnutls_strerror(rc)); 993 return CURLE_SSL_CONNECT_ERROR; 994 } 995 } 996 else { 997 const unsigned int supported_key_encryption_algorithms = 998 GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | 999 GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES | 1000 GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 | 1001 GNUTLS_PKCS_USE_PBES2_AES_256; 1002 rc = gnutls_certificate_set_x509_key_file2( 1003 gtls->shared_creds->creds, 1004 config->clientcert, 1005 ssl_config->key ? ssl_config->key : config->clientcert, 1006 gnutls_do_file_type(ssl_config->cert_type), 1007 ssl_config->key_passwd, 1008 supported_key_encryption_algorithms); 1009 if(rc != GNUTLS_E_SUCCESS) { 1010 failf(data, 1011 "error reading X.509 %skey file: %s", 1012 ssl_config->key_passwd ? "potentially-encrypted " : "", 1013 gnutls_strerror(rc)); 1014 return CURLE_SSL_CONNECT_ERROR; 1015 } 1016 } 1017 } 1018 1019 #ifdef USE_GNUTLS_SRP 1020 /* put the credentials to the current session */ 1021 if(config->username) { 1022 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_SRP, 1023 gtls->srp_client_cred); 1024 if(rc != GNUTLS_E_SUCCESS) { 1025 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); 1026 return CURLE_SSL_CONNECT_ERROR; 1027 } 1028 } 1029 else 1030 #endif 1031 { 1032 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE, 1033 gtls->shared_creds->creds); 1034 if(rc != GNUTLS_E_SUCCESS) { 1035 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); 1036 return CURLE_SSL_CONNECT_ERROR; 1037 } 1038 } 1039 1040 if(config->verifystatus) { 1041 rc = gnutls_ocsp_status_request_enable_client(gtls->session, 1042 NULL, 0, NULL); 1043 if(rc != GNUTLS_E_SUCCESS) { 1044 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc); 1045 return CURLE_SSL_CONNECT_ERROR; 1046 } 1047 } 1048 1049 return CURLE_OK; 1050 } 1051 1052 static int keylog_callback(gnutls_session_t session, const char *label, 1053 const gnutls_datum_t *secret) 1054 { 1055 gnutls_datum_t crandom; 1056 gnutls_datum_t srandom; 1057 1058 gnutls_session_get_random(session, &crandom, &srandom); 1059 if(crandom.size != 32) { 1060 return -1; 1061 } 1062 1063 Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size); 1064 return 0; 1065 } 1066 1067 static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf, 1068 struct Curl_easy *data, 1069 struct alpn_spec *alpns, 1070 struct Curl_ssl_session *scs, 1071 bool *do_early_data) 1072 { 1073 struct ssl_connect_data *connssl = cf->ctx; 1074 struct gtls_ssl_backend_data *backend = 1075 (struct gtls_ssl_backend_data *)connssl->backend; 1076 CURLcode result = CURLE_OK; 1077 1078 *do_early_data = FALSE; 1079 connssl->earlydata_max = 1080 gnutls_record_get_max_early_data_size(backend->gtls.session); 1081 if((!connssl->earlydata_max || connssl->earlydata_max == 0xFFFFFFFFUL)) { 1082 /* Seems to be no GnuTLS way to signal no EarlyData in session */ 1083 CURL_TRC_CF(data, cf, "SSL session does not allow earlydata"); 1084 } 1085 else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) { 1086 CURL_TRC_CF(data, cf, "SSL session has different ALPN, no early data"); 1087 } 1088 else { 1089 infof(data, "SSL session allows %zu bytes of early data, " 1090 "reusing ALPN '%s'", connssl->earlydata_max, scs->alpn); 1091 connssl->earlydata_state = ssl_earlydata_await; 1092 connssl->state = ssl_connection_deferred; 1093 result = Curl_alpn_set_negotiated(cf, data, connssl, 1094 (const unsigned char *)scs->alpn, 1095 scs->alpn ? strlen(scs->alpn) : 0); 1096 *do_early_data = !result; 1097 } 1098 return result; 1099 } 1100 1101 CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, 1102 struct Curl_cfilter *cf, 1103 struct Curl_easy *data, 1104 struct ssl_peer *peer, 1105 const struct alpn_spec *alpns_requested, 1106 Curl_gtls_ctx_setup_cb *cb_setup, 1107 void *cb_user_data, 1108 void *ssl_user_data, 1109 Curl_gtls_init_session_reuse_cb *sess_reuse_cb) 1110 { 1111 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 1112 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 1113 struct Curl_ssl_session *scs = NULL; 1114 gnutls_datum_t gtls_alpns[ALPN_ENTRIES_MAX]; 1115 size_t gtls_alpns_count = 0; 1116 bool gtls_session_setup = FALSE; 1117 struct alpn_spec alpns; 1118 CURLcode result = CURLE_OK; 1119 int rc; 1120 1121 DEBUGASSERT(gctx); 1122 Curl_alpn_copy(&alpns, alpns_requested); 1123 1124 /* This might be a reconnect, so we check for a session ID in the cache 1125 to speed up things. We need to do this before constructing the gnutls 1126 session since we need to set flags depending on the kind of reuse. */ 1127 if(conn_config->cache_session) { 1128 result = Curl_ssl_scache_take(cf, data, peer->scache_key, &scs); 1129 if(result) 1130 goto out; 1131 1132 if(scs && scs->sdata && scs->sdata_len && 1133 (!scs->alpn || Curl_alpn_contains_proto(&alpns, scs->alpn))) { 1134 /* we got a cached session, use it! */ 1135 1136 result = gtls_client_init(cf, data, peer, scs->earlydata_max, gctx); 1137 if(result) 1138 goto out; 1139 gtls_session_setup = TRUE; 1140 1141 rc = gnutls_session_set_data(gctx->session, scs->sdata, scs->sdata_len); 1142 if(rc < 0) 1143 infof(data, "SSL session not accepted by GnuTLS, continuing without"); 1144 else { 1145 infof(data, "SSL reusing session with ALPN '%s'", 1146 scs->alpn ? scs->alpn : "-"); 1147 if(ssl_config->earlydata && scs->alpn && 1148 !cf->conn->connect_only && 1149 (gnutls_protocol_get_version(gctx->session) == GNUTLS_TLS1_3)) { 1150 bool do_early_data = FALSE; 1151 if(sess_reuse_cb) { 1152 result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data); 1153 if(result) 1154 goto out; 1155 } 1156 if(do_early_data) { 1157 /* We only try the ALPN protocol the session used before, 1158 * otherwise we might send early data for the wrong protocol */ 1159 Curl_alpn_restrict_to(&alpns, scs->alpn); 1160 } 1161 } 1162 } 1163 } 1164 } 1165 1166 if(!gtls_session_setup) { 1167 result = gtls_client_init(cf, data, peer, 0, gctx); 1168 if(result) 1169 goto out; 1170 } 1171 1172 gnutls_session_set_ptr(gctx->session, ssl_user_data); 1173 1174 if(cb_setup) { 1175 result = cb_setup(cf, data, cb_user_data); 1176 if(result) 1177 goto out; 1178 } 1179 1180 /* Open the file if a TLS or QUIC backend has not done this before. */ 1181 Curl_tls_keylog_open(); 1182 if(Curl_tls_keylog_enabled()) { 1183 gnutls_session_set_keylog_function(gctx->session, keylog_callback); 1184 } 1185 1186 /* convert the ALPN string from our arguments to a list of strings that 1187 * gnutls wants and will convert internally back to this string for sending 1188 * to the server. nice. */ 1189 if(!gtls_alpns_count && alpns.count) { 1190 size_t i; 1191 DEBUGASSERT(CURL_ARRAYSIZE(gtls_alpns) >= alpns.count); 1192 for(i = 0; i < alpns.count; ++i) { 1193 gtls_alpns[i].data = (unsigned char *)alpns.entries[i]; 1194 gtls_alpns[i].size = (unsigned int)strlen(alpns.entries[i]); 1195 } 1196 gtls_alpns_count = alpns.count; 1197 } 1198 1199 if(gtls_alpns_count && 1200 gnutls_alpn_set_protocols(gctx->session, 1201 gtls_alpns, (unsigned int)gtls_alpns_count, 1202 GNUTLS_ALPN_MANDATORY)) { 1203 failf(data, "failed setting ALPN"); 1204 result = CURLE_SSL_CONNECT_ERROR; 1205 } 1206 1207 out: 1208 Curl_ssl_scache_return(cf, data, peer->scache_key, scs); 1209 return result; 1210 } 1211 1212 static CURLcode 1213 gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) 1214 { 1215 struct ssl_connect_data *connssl = cf->ctx; 1216 struct gtls_ssl_backend_data *backend = 1217 (struct gtls_ssl_backend_data *)connssl->backend; 1218 CURLcode result; 1219 1220 DEBUGASSERT(backend); 1221 1222 if(connssl->state == ssl_connection_complete) 1223 /* to make us tolerant against being called more than once for the 1224 same connection */ 1225 return CURLE_OK; 1226 1227 result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer, 1228 connssl->alpn, NULL, NULL, cf, 1229 gtls_on_session_reuse); 1230 if(result) 1231 return result; 1232 1233 if(connssl->alpn && (connssl->state != ssl_connection_deferred)) { 1234 struct alpn_proto_buf proto; 1235 memset(&proto, 0, sizeof(proto)); 1236 Curl_alpn_to_proto_str(&proto, connssl->alpn); 1237 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); 1238 } 1239 1240 gnutls_handshake_set_hook_function(backend->gtls.session, 1241 GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, 1242 gtls_handshake_cb); 1243 1244 /* register callback functions and handle to send and receive data. */ 1245 gnutls_transport_set_ptr(backend->gtls.session, cf); 1246 gnutls_transport_set_push_function(backend->gtls.session, gtls_push); 1247 gnutls_transport_set_pull_function(backend->gtls.session, gtls_pull); 1248 1249 return CURLE_OK; 1250 } 1251 1252 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, 1253 gnutls_x509_crt_t cert, 1254 const char *pinnedpubkey) 1255 { 1256 /* Scratch */ 1257 size_t len1 = 0, len2 = 0; 1258 unsigned char *buff1 = NULL; 1259 1260 gnutls_pubkey_t key = NULL; 1261 1262 /* Result is returned to caller */ 1263 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; 1264 1265 /* if a path was not specified, do not pin */ 1266 if(!pinnedpubkey) 1267 return CURLE_OK; 1268 1269 if(!cert) 1270 return result; 1271 1272 do { 1273 int ret; 1274 1275 /* Begin Gyrations to get the public key */ 1276 gnutls_pubkey_init(&key); 1277 1278 ret = gnutls_pubkey_import_x509(key, cert, 0); 1279 if(ret < 0) 1280 break; /* failed */ 1281 1282 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1); 1283 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0) 1284 break; /* failed */ 1285 1286 buff1 = malloc(len1); 1287 if(!buff1) 1288 break; /* failed */ 1289 1290 len2 = len1; 1291 1292 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2); 1293 if(ret < 0 || len1 != len2) 1294 break; /* failed */ 1295 1296 /* End Gyrations */ 1297 1298 /* The one good exit point */ 1299 result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); 1300 } while(0); 1301 1302 if(key) 1303 gnutls_pubkey_deinit(key); 1304 1305 Curl_safefree(buff1); 1306 1307 return result; 1308 } 1309 1310 void Curl_gtls_report_handshake(struct Curl_easy *data, 1311 struct gtls_ctx *gctx) 1312 { 1313 #ifndef CURL_DISABLE_VERBOSE_STRINGS 1314 if(Curl_trc_is_verbose(data)) { 1315 const char *ptr; 1316 gnutls_protocol_t version = gnutls_protocol_get_version(gctx->session); 1317 1318 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ 1319 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(gctx->session), 1320 gnutls_cipher_get(gctx->session), 1321 gnutls_mac_get(gctx->session)); 1322 1323 infof(data, "SSL connection using %s / %s", 1324 gnutls_protocol_get_name(version), ptr); 1325 } 1326 #else 1327 (void)data; 1328 (void)gctx; 1329 #endif 1330 } 1331 1332 CURLcode 1333 Curl_gtls_verifyserver(struct Curl_easy *data, 1334 gnutls_session_t session, 1335 struct ssl_primary_config *config, 1336 struct ssl_config_data *ssl_config, 1337 struct ssl_peer *peer, 1338 const char *pinned_key) 1339 { 1340 unsigned int cert_list_size; 1341 const gnutls_datum_t *chainp; 1342 unsigned int verify_status = 0; 1343 gnutls_x509_crt_t x509_cert, x509_issuer; 1344 gnutls_datum_t issuerp; 1345 gnutls_datum_t certfields; 1346 char certname[65] = ""; /* limited to 64 chars by ASN.1 */ 1347 size_t size; 1348 time_t certclock; 1349 int rc; 1350 CURLcode result = CURLE_OK; 1351 #ifndef CURL_DISABLE_VERBOSE_STRINGS 1352 int algo; 1353 unsigned int bits; 1354 #endif 1355 long * const certverifyresult = &ssl_config->certverifyresult; 1356 1357 /* This function will return the peer's raw certificate (chain) as sent by 1358 the peer. These certificates are in raw format (DER encoded for 1359 X.509). In case of a X.509 then a certificate list may be present. The 1360 first certificate in the list is the peer's certificate, following the 1361 issuer's certificate, then the issuer's issuer etc. */ 1362 1363 chainp = gnutls_certificate_get_peers(session, &cert_list_size); 1364 if(!chainp) { 1365 if(config->verifypeer || 1366 config->verifyhost || 1367 config->issuercert) { 1368 #ifdef USE_GNUTLS_SRP 1369 if(ssl_config->primary.username && !config->verifypeer && 1370 gnutls_cipher_get(session)) { 1371 /* no peer cert, but auth is ok if we have SRP user and cipher and no 1372 peer verify */ 1373 } 1374 else { 1375 #endif 1376 failf(data, "failed to get server cert"); 1377 *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; 1378 return CURLE_PEER_FAILED_VERIFICATION; 1379 #ifdef USE_GNUTLS_SRP 1380 } 1381 #endif 1382 } 1383 infof(data, " common name: WARNING could not obtain"); 1384 } 1385 1386 if(data->set.ssl.certinfo && chainp) { 1387 unsigned int i; 1388 1389 result = Curl_ssl_init_certinfo(data, (int)cert_list_size); 1390 if(result) 1391 return result; 1392 1393 for(i = 0; i < cert_list_size; i++) { 1394 const char *beg = (const char *) chainp[i].data; 1395 const char *end = beg + chainp[i].size; 1396 1397 result = Curl_extract_certinfo(data, (int)i, beg, end); 1398 if(result) 1399 return result; 1400 } 1401 } 1402 1403 if(config->verifypeer) { 1404 /* This function will try to verify the peer's certificate and return its 1405 status (trusted, invalid etc.). The value of status should be one or 1406 more of the gnutls_certificate_status_t enumerated elements bitwise 1407 or'd. To avoid denial of service attacks some default upper limits 1408 regarding the certificate key size and chain size are set. To override 1409 them use gnutls_certificate_set_verify_limits(). */ 1410 1411 rc = gnutls_certificate_verify_peers2(session, &verify_status); 1412 if(rc < 0) { 1413 failf(data, "server cert verify failed: %d", rc); 1414 *certverifyresult = rc; 1415 return CURLE_SSL_CONNECT_ERROR; 1416 } 1417 1418 *certverifyresult = verify_status; 1419 1420 /* verify_status is a bitmask of gnutls_certificate_status bits */ 1421 if(verify_status & GNUTLS_CERT_INVALID) { 1422 if(config->verifypeer) { 1423 const char *cause = "certificate error, no details available"; 1424 if(verify_status & GNUTLS_CERT_EXPIRED) 1425 cause = "certificate has expired"; 1426 else if(verify_status & GNUTLS_CERT_SIGNER_NOT_FOUND) 1427 cause = "certificate signer not trusted"; 1428 else if(verify_status & GNUTLS_CERT_INSECURE_ALGORITHM) 1429 cause = "certificate uses insecure algorithm"; 1430 else if(verify_status & GNUTLS_CERT_INVALID_OCSP_STATUS) 1431 cause = "attached OCSP status response is invalid"; 1432 failf(data, "server verification failed: %s. (CAfile: %s " 1433 "CRLfile: %s)", cause, 1434 config->CAfile ? config->CAfile : "none", 1435 ssl_config->primary.CRLfile ? 1436 ssl_config->primary.CRLfile : "none"); 1437 return CURLE_PEER_FAILED_VERIFICATION; 1438 } 1439 else 1440 infof(data, " server certificate verification FAILED"); 1441 } 1442 else 1443 infof(data, " server certificate verification OK"); 1444 } 1445 else 1446 infof(data, " server certificate verification SKIPPED"); 1447 1448 if(config->verifystatus) { 1449 gnutls_datum_t status_request; 1450 gnutls_ocsp_resp_t ocsp_resp; 1451 gnutls_ocsp_cert_status_t status; 1452 gnutls_x509_crl_reason_t reason; 1453 1454 rc = gnutls_ocsp_status_request_get(session, &status_request); 1455 1456 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { 1457 failf(data, "No OCSP response received"); 1458 return CURLE_SSL_INVALIDCERTSTATUS; 1459 } 1460 1461 if(rc < 0) { 1462 failf(data, "Invalid OCSP response received"); 1463 return CURLE_SSL_INVALIDCERTSTATUS; 1464 } 1465 1466 gnutls_ocsp_resp_init(&ocsp_resp); 1467 1468 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); 1469 if(rc < 0) { 1470 failf(data, "Invalid OCSP response received"); 1471 return CURLE_SSL_INVALIDCERTSTATUS; 1472 } 1473 1474 (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, 1475 &status, NULL, NULL, NULL, &reason); 1476 1477 switch(status) { 1478 case GNUTLS_OCSP_CERT_GOOD: 1479 break; 1480 1481 case GNUTLS_OCSP_CERT_REVOKED: { 1482 const char *crl_reason; 1483 1484 switch(reason) { 1485 default: 1486 case GNUTLS_X509_CRLREASON_UNSPECIFIED: 1487 crl_reason = "unspecified reason"; 1488 break; 1489 1490 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: 1491 crl_reason = "private key compromised"; 1492 break; 1493 1494 case GNUTLS_X509_CRLREASON_CACOMPROMISE: 1495 crl_reason = "CA compromised"; 1496 break; 1497 1498 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: 1499 crl_reason = "affiliation has changed"; 1500 break; 1501 1502 case GNUTLS_X509_CRLREASON_SUPERSEDED: 1503 crl_reason = "certificate superseded"; 1504 break; 1505 1506 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: 1507 crl_reason = "operation has ceased"; 1508 break; 1509 1510 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: 1511 crl_reason = "certificate is on hold"; 1512 break; 1513 1514 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: 1515 crl_reason = "will be removed from delta CRL"; 1516 break; 1517 1518 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: 1519 crl_reason = "privilege withdrawn"; 1520 break; 1521 1522 case GNUTLS_X509_CRLREASON_AACOMPROMISE: 1523 crl_reason = "AA compromised"; 1524 break; 1525 } 1526 1527 failf(data, "Server certificate was revoked: %s", crl_reason); 1528 break; 1529 } 1530 1531 default: 1532 case GNUTLS_OCSP_CERT_UNKNOWN: 1533 failf(data, "Server certificate status is unknown"); 1534 break; 1535 } 1536 1537 gnutls_ocsp_resp_deinit(ocsp_resp); 1538 if(status != GNUTLS_OCSP_CERT_GOOD) 1539 return CURLE_SSL_INVALIDCERTSTATUS; 1540 } 1541 else 1542 infof(data, " server certificate status verification SKIPPED"); 1543 1544 /* initialize an X.509 certificate structure. */ 1545 gnutls_x509_crt_init(&x509_cert); 1546 1547 if(chainp) 1548 /* convert the given DER or PEM encoded Certificate to the native 1549 gnutls_x509_crt_t format */ 1550 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); 1551 1552 if(config->issuercert) { 1553 gnutls_x509_crt_init(&x509_issuer); 1554 issuerp = load_file(config->issuercert); 1555 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); 1556 rc = (int)gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); 1557 gnutls_x509_crt_deinit(x509_issuer); 1558 unload_file(issuerp); 1559 if(rc <= 0) { 1560 failf(data, "server certificate issuer check failed (IssuerCert: %s)", 1561 config->issuercert ? config->issuercert : "none"); 1562 gnutls_x509_crt_deinit(x509_cert); 1563 return CURLE_SSL_ISSUER_ERROR; 1564 } 1565 infof(data, " server certificate issuer check OK (Issuer Cert: %s)", 1566 config->issuercert ? config->issuercert : "none"); 1567 } 1568 1569 size = sizeof(certname); 1570 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, 1571 0, /* the first and only one */ 1572 FALSE, 1573 certname, 1574 &size); 1575 if(rc) { 1576 infof(data, "error fetching CN from cert:%s", 1577 gnutls_strerror(rc)); 1578 } 1579 1580 /* This function will check if the given certificate's subject matches the 1581 given hostname. This is a basic implementation of the matching described 1582 in RFC2818 (HTTPS), which takes into account wildcards, and the subject 1583 alternative name PKIX extension. Returns non zero on success, and zero on 1584 failure. */ 1585 1586 /* This function does not handle trailing dots, so if we have an SNI name 1587 use that and fallback to the hostname only if there is no SNI (like for 1588 IP addresses) */ 1589 rc = (int)gnutls_x509_crt_check_hostname(x509_cert, 1590 peer->sni ? peer->sni : 1591 peer->hostname); 1592 #if GNUTLS_VERSION_NUMBER < 0x030306 1593 /* Before 3.3.6, gnutls_x509_crt_check_hostname() did not check IP 1594 addresses. */ 1595 if(!rc) { 1596 #ifdef USE_IPV6 1597 #define use_addr in6_addr 1598 #else 1599 #define use_addr in_addr 1600 #endif 1601 unsigned char addrbuf[sizeof(struct use_addr)]; 1602 size_t addrlen = 0; 1603 1604 if(curlx_inet_pton(AF_INET, peer->hostname, addrbuf) > 0) 1605 addrlen = 4; 1606 #ifdef USE_IPV6 1607 else if(curlx_inet_pton(AF_INET6, peer->hostname, addrbuf) > 0) 1608 addrlen = 16; 1609 #endif 1610 1611 if(addrlen) { 1612 unsigned char certaddr[sizeof(struct use_addr)]; 1613 int i; 1614 1615 for(i = 0; ; i++) { 1616 size_t certaddrlen = sizeof(certaddr); 1617 int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr, 1618 &certaddrlen, NULL); 1619 /* If this happens, it was not an IP address. */ 1620 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) 1621 continue; 1622 if(ret < 0) 1623 break; 1624 if(ret != GNUTLS_SAN_IPADDRESS) 1625 continue; 1626 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) { 1627 rc = 1; 1628 break; 1629 } 1630 } 1631 } 1632 } 1633 #endif 1634 if(!rc) { 1635 if(config->verifyhost) { 1636 failf(data, "SSL: certificate subject name (%s) does not match " 1637 "target hostname '%s'", certname, peer->dispname); 1638 gnutls_x509_crt_deinit(x509_cert); 1639 return CURLE_PEER_FAILED_VERIFICATION; 1640 } 1641 else 1642 infof(data, " common name: %s (does not match '%s')", 1643 certname, peer->dispname); 1644 } 1645 else 1646 infof(data, " common name: %s (matched)", certname); 1647 1648 /* Check for time-based validity */ 1649 certclock = gnutls_x509_crt_get_expiration_time(x509_cert); 1650 1651 if(certclock == (time_t)-1) { 1652 if(config->verifypeer) { 1653 failf(data, "server cert expiration date verify failed"); 1654 *certverifyresult = GNUTLS_CERT_EXPIRED; 1655 gnutls_x509_crt_deinit(x509_cert); 1656 return CURLE_SSL_CONNECT_ERROR; 1657 } 1658 else 1659 infof(data, " server certificate expiration date verify FAILED"); 1660 } 1661 else { 1662 if(certclock < time(NULL)) { 1663 if(config->verifypeer) { 1664 failf(data, "server certificate expiration date has passed."); 1665 *certverifyresult = GNUTLS_CERT_EXPIRED; 1666 gnutls_x509_crt_deinit(x509_cert); 1667 return CURLE_PEER_FAILED_VERIFICATION; 1668 } 1669 else 1670 infof(data, " server certificate expiration date FAILED"); 1671 } 1672 else 1673 infof(data, " server certificate expiration date OK"); 1674 } 1675 1676 certclock = gnutls_x509_crt_get_activation_time(x509_cert); 1677 1678 if(certclock == (time_t)-1) { 1679 if(config->verifypeer) { 1680 failf(data, "server cert activation date verify failed"); 1681 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; 1682 gnutls_x509_crt_deinit(x509_cert); 1683 return CURLE_SSL_CONNECT_ERROR; 1684 } 1685 else 1686 infof(data, " server certificate activation date verify FAILED"); 1687 } 1688 else { 1689 if(certclock > time(NULL)) { 1690 if(config->verifypeer) { 1691 failf(data, "server certificate not activated yet."); 1692 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; 1693 gnutls_x509_crt_deinit(x509_cert); 1694 return CURLE_PEER_FAILED_VERIFICATION; 1695 } 1696 else 1697 infof(data, " server certificate activation date FAILED"); 1698 } 1699 else 1700 infof(data, " server certificate activation date OK"); 1701 } 1702 1703 if(pinned_key) { 1704 result = pkp_pin_peer_pubkey(data, x509_cert, pinned_key); 1705 if(result != CURLE_OK) { 1706 failf(data, "SSL: public key does not match pinned public key"); 1707 gnutls_x509_crt_deinit(x509_cert); 1708 return result; 1709 } 1710 } 1711 1712 /* Show: 1713 1714 - subject 1715 - start date 1716 - expire date 1717 - common name 1718 - issuer 1719 1720 */ 1721 1722 #ifndef CURL_DISABLE_VERBOSE_STRINGS 1723 /* public key algorithm's parameters */ 1724 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); 1725 infof(data, " certificate public key: %s", 1726 gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo)); 1727 1728 /* version of the X.509 certificate. */ 1729 infof(data, " certificate version: #%d", 1730 gnutls_x509_crt_get_version(x509_cert)); 1731 1732 1733 rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); 1734 if(rc) 1735 infof(data, "Failed to get certificate name"); 1736 else { 1737 infof(data, " subject: %s", certfields.data); 1738 1739 certclock = gnutls_x509_crt_get_activation_time(x509_cert); 1740 showtime(data, "start date", certclock); 1741 1742 certclock = gnutls_x509_crt_get_expiration_time(x509_cert); 1743 showtime(data, "expire date", certclock); 1744 1745 gnutls_free(certfields.data); 1746 } 1747 1748 rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); 1749 if(rc) 1750 infof(data, "Failed to get certificate issuer"); 1751 else { 1752 infof(data, " issuer: %s", certfields.data); 1753 1754 gnutls_free(certfields.data); 1755 } 1756 #endif 1757 1758 gnutls_x509_crt_deinit(x509_cert); 1759 1760 return result; 1761 } 1762 1763 static CURLcode gtls_verifyserver(struct Curl_cfilter *cf, 1764 struct Curl_easy *data, 1765 gnutls_session_t session) 1766 { 1767 struct ssl_connect_data *connssl = cf->ctx; 1768 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 1769 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 1770 #ifndef CURL_DISABLE_PROXY 1771 const char *pinned_key = Curl_ssl_cf_is_proxy(cf) ? 1772 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : 1773 data->set.str[STRING_SSL_PINNEDPUBLICKEY]; 1774 #else 1775 const char *pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; 1776 #endif 1777 CURLcode result; 1778 1779 result = Curl_gtls_verifyserver(data, session, conn_config, ssl_config, 1780 &connssl->peer, pinned_key); 1781 if(result) 1782 goto out; 1783 1784 /* Only on TLSv1.2 or lower do we have the session id now. For 1785 * TLSv1.3 we get it via a SESSION_TICKET message that arrives later. */ 1786 if(gnutls_protocol_get_version(session) < GNUTLS_TLS1_3) 1787 result = cf_gtls_update_session_id(cf, data, session); 1788 1789 out: 1790 return result; 1791 } 1792 1793 static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf, 1794 struct Curl_easy *data) 1795 { 1796 struct ssl_connect_data *connssl = cf->ctx; 1797 struct gtls_ssl_backend_data *backend = 1798 (struct gtls_ssl_backend_data *)connssl->backend; 1799 CURLcode result = CURLE_OK; 1800 const unsigned char *buf; 1801 size_t blen; 1802 ssize_t n; 1803 1804 DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sending); 1805 backend->gtls.io_result = CURLE_OK; 1806 while(Curl_bufq_peek(&connssl->earlydata, &buf, &blen)) { 1807 n = gnutls_record_send_early_data(backend->gtls.session, buf, blen); 1808 CURL_TRC_CF(data, cf, "gtls_send_earlydata(len=%zu) -> %zd", 1809 blen, n); 1810 if(n < 0) { 1811 if(n == GNUTLS_E_AGAIN) 1812 result = CURLE_AGAIN; 1813 else 1814 result = backend->gtls.io_result ? 1815 backend->gtls.io_result : CURLE_SEND_ERROR; 1816 goto out; 1817 } 1818 else if(!n) { 1819 /* gnutls is buggy, it *SHOULD* return the amount of bytes it took in. 1820 * Instead it returns 0 if everything was written. */ 1821 n = (ssize_t)blen; 1822 } 1823 1824 Curl_bufq_skip(&connssl->earlydata, (size_t)n); 1825 } 1826 /* sent everything there was */ 1827 infof(data, "SSL sending %zu bytes of early data", connssl->earlydata_skip); 1828 out: 1829 return result; 1830 } 1831 1832 /* 1833 * This function is called after the TCP connect has completed. Setup the TLS 1834 * layer and do all necessary magic. 1835 */ 1836 /* We use connssl->connecting_state to keep track of the connection status; 1837 there are three states: 'ssl_connect_1' (not started yet or complete), 1838 'ssl_connect_2' (doing handshake with the server), and 1839 'ssl_connect_3' (verifying and getting stats). 1840 */ 1841 static CURLcode gtls_connect_common(struct Curl_cfilter *cf, 1842 struct Curl_easy *data, 1843 bool *done) { 1844 struct ssl_connect_data *connssl = cf->ctx; 1845 struct gtls_ssl_backend_data *backend = 1846 (struct gtls_ssl_backend_data *)connssl->backend; 1847 CURLcode result = CURLE_OK; 1848 1849 DEBUGASSERT(backend); 1850 /* check if the connection has already been established */ 1851 if(ssl_connection_complete == connssl->state) { 1852 *done = TRUE; 1853 return CURLE_OK; 1854 } 1855 1856 *done = FALSE; 1857 1858 /* Initiate the connection, if not already done */ 1859 if(connssl->connecting_state == ssl_connect_1) { 1860 result = gtls_connect_step1(cf, data); 1861 if(result) 1862 goto out; 1863 connssl->connecting_state = ssl_connect_2; 1864 } 1865 1866 if(connssl->connecting_state == ssl_connect_2) { 1867 if(connssl->earlydata_state == ssl_earlydata_await) { 1868 goto out; 1869 } 1870 else if(connssl->earlydata_state == ssl_earlydata_sending) { 1871 result = gtls_send_earlydata(cf, data); 1872 if(result) 1873 goto out; 1874 connssl->earlydata_state = ssl_earlydata_sent; 1875 } 1876 DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) || 1877 (connssl->earlydata_state == ssl_earlydata_sent)); 1878 1879 result = handshake(cf, data); 1880 if(result) 1881 goto out; 1882 connssl->connecting_state = ssl_connect_3; 1883 } 1884 1885 /* Finish connecting once the handshake is done */ 1886 if(connssl->connecting_state == ssl_connect_3) { 1887 gnutls_datum_t proto; 1888 int rc; 1889 1890 Curl_gtls_report_handshake(data, &backend->gtls); 1891 1892 result = gtls_verifyserver(cf, data, backend->gtls.session); 1893 if(result) 1894 goto out; 1895 1896 connssl->state = ssl_connection_complete; 1897 1898 rc = gnutls_alpn_get_selected_protocol(backend->gtls.session, &proto); 1899 if(rc) { /* No ALPN from server */ 1900 proto.data = NULL; 1901 proto.size = 0; 1902 } 1903 1904 result = Curl_alpn_set_negotiated(cf, data, connssl, 1905 proto.data, proto.size); 1906 if(result) 1907 goto out; 1908 1909 if(connssl->earlydata_state > ssl_earlydata_none) { 1910 /* We should be in this state by now */ 1911 DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent); 1912 connssl->earlydata_state = 1913 (gnutls_session_get_flags(backend->gtls.session) & 1914 GNUTLS_SFLAGS_EARLY_DATA) ? 1915 ssl_earlydata_accepted : ssl_earlydata_rejected; 1916 } 1917 connssl->connecting_state = ssl_connect_done; 1918 } 1919 1920 if(connssl->connecting_state == ssl_connect_done) 1921 DEBUGASSERT(connssl->state == ssl_connection_complete); 1922 1923 out: 1924 if(result == CURLE_AGAIN) { 1925 *done = FALSE; 1926 return CURLE_OK; 1927 } 1928 *done = ((connssl->state == ssl_connection_complete) || 1929 (connssl->state == ssl_connection_deferred)); 1930 CURL_TRC_CF(data, cf, "gtls_connect_common() -> %d, done=%d", result, *done); 1931 return result; 1932 } 1933 1934 static CURLcode gtls_connect(struct Curl_cfilter *cf, 1935 struct Curl_easy *data, 1936 bool *done) 1937 { 1938 struct ssl_connect_data *connssl = cf->ctx; 1939 if((connssl->state == ssl_connection_deferred) && 1940 (connssl->earlydata_state == ssl_earlydata_await)) { 1941 /* We refuse to be pushed, we are waiting for someone to send/recv. */ 1942 *done = TRUE; 1943 return CURLE_OK; 1944 } 1945 return gtls_connect_common(cf, data, done); 1946 } 1947 1948 static bool gtls_data_pending(struct Curl_cfilter *cf, 1949 const struct Curl_easy *data) 1950 { 1951 struct ssl_connect_data *ctx = cf->ctx; 1952 struct gtls_ssl_backend_data *backend; 1953 1954 (void)data; 1955 DEBUGASSERT(ctx && ctx->backend); 1956 backend = (struct gtls_ssl_backend_data *)ctx->backend; 1957 if(backend->gtls.session && 1958 0 != gnutls_record_check_pending(backend->gtls.session)) 1959 return TRUE; 1960 return FALSE; 1961 } 1962 1963 static CURLcode gtls_send(struct Curl_cfilter *cf, 1964 struct Curl_easy *data, 1965 const void *buf, 1966 size_t blen, 1967 size_t *pnwritten) 1968 { 1969 struct ssl_connect_data *connssl = cf->ctx; 1970 struct gtls_ssl_backend_data *backend = 1971 (struct gtls_ssl_backend_data *)connssl->backend; 1972 CURLcode result = CURLE_OK; 1973 ssize_t nwritten; 1974 size_t remain = blen; 1975 1976 (void)data; 1977 DEBUGASSERT(backend); 1978 *pnwritten = 0; 1979 1980 while(remain) { 1981 backend->gtls.io_result = CURLE_OK; 1982 nwritten = gnutls_record_send(backend->gtls.session, buf, remain); 1983 1984 if(nwritten >= 0) { 1985 *pnwritten += (size_t)nwritten; 1986 DEBUGASSERT((size_t)nwritten <= remain); 1987 buf = (char *)CURL_UNCONST(buf) + (size_t)nwritten; 1988 remain -= (size_t)nwritten; 1989 } 1990 else { 1991 if(*pnwritten && (nwritten == GNUTLS_E_AGAIN)) { 1992 result = CURLE_OK; 1993 goto out; 1994 } 1995 result = (nwritten == GNUTLS_E_AGAIN) ? 1996 CURLE_AGAIN : 1997 (backend->gtls.io_result ? backend->gtls.io_result : CURLE_SEND_ERROR); 1998 goto out; 1999 } 2000 } 2001 2002 out: 2003 CURL_TRC_CF(data, cf, "gtls_send(len=%zu) -> %d, %zu", 2004 blen, result, *pnwritten); 2005 return result; 2006 } 2007 2008 /* 2009 * This function is called to shut down the SSL layer but keep the 2010 * socket open (CCC - Clear Command Channel) 2011 */ 2012 static CURLcode gtls_shutdown(struct Curl_cfilter *cf, 2013 struct Curl_easy *data, 2014 bool send_shutdown, bool *done) 2015 { 2016 struct ssl_connect_data *connssl = cf->ctx; 2017 struct gtls_ssl_backend_data *backend = 2018 (struct gtls_ssl_backend_data *)connssl->backend; 2019 char buf[1024]; 2020 CURLcode result = CURLE_OK; 2021 ssize_t nread; 2022 size_t i; 2023 2024 DEBUGASSERT(backend); 2025 /* If we have no handshaked connection or already shut down */ 2026 if(!backend->gtls.session || cf->shutdown || 2027 connssl->state != ssl_connection_complete) { 2028 *done = TRUE; 2029 goto out; 2030 } 2031 2032 connssl->io_need = CURL_SSL_IO_NEED_NONE; 2033 *done = FALSE; 2034 2035 if(!backend->gtls.sent_shutdown) { 2036 /* do this only once */ 2037 backend->gtls.sent_shutdown = TRUE; 2038 if(send_shutdown) { 2039 int ret = gnutls_bye(backend->gtls.session, GNUTLS_SHUT_RDWR); 2040 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { 2041 CURL_TRC_CF(data, cf, "SSL shutdown, gnutls_bye EAGAIN"); 2042 connssl->io_need = gnutls_record_get_direction(backend->gtls.session) ? 2043 CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; 2044 backend->gtls.sent_shutdown = FALSE; 2045 result = CURLE_OK; 2046 goto out; 2047 } 2048 if(ret != GNUTLS_E_SUCCESS) { 2049 CURL_TRC_CF(data, cf, "SSL shutdown, gnutls_bye error: '%s'(%d)", 2050 gnutls_strerror((int)ret), (int)ret); 2051 result = CURLE_RECV_ERROR; 2052 goto out; 2053 } 2054 } 2055 } 2056 2057 /* SSL should now have started the shutdown from our side. Since it 2058 * was not complete, we are lacking the close notify from the server. */ 2059 for(i = 0; i < 10; ++i) { 2060 nread = gnutls_record_recv(backend->gtls.session, buf, sizeof(buf)); 2061 if(nread <= 0) 2062 break; 2063 } 2064 if(nread > 0) { 2065 /* still data coming in? */ 2066 } 2067 else if(nread == 0) { 2068 /* We got the close notify alert and are done. */ 2069 *done = TRUE; 2070 } 2071 else if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) { 2072 connssl->io_need = gnutls_record_get_direction(backend->gtls.session) ? 2073 CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; 2074 } 2075 else { 2076 CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)", 2077 gnutls_strerror((int)nread), (int)nread); 2078 result = CURLE_RECV_ERROR; 2079 } 2080 2081 out: 2082 cf->shutdown = (result || *done); 2083 return result; 2084 } 2085 2086 static void gtls_close(struct Curl_cfilter *cf, 2087 struct Curl_easy *data) 2088 { 2089 struct ssl_connect_data *connssl = cf->ctx; 2090 struct gtls_ssl_backend_data *backend = 2091 (struct gtls_ssl_backend_data *)connssl->backend; 2092 2093 (void) data; 2094 DEBUGASSERT(backend); 2095 CURL_TRC_CF(data, cf, "close"); 2096 if(backend->gtls.session) { 2097 gnutls_deinit(backend->gtls.session); 2098 backend->gtls.session = NULL; 2099 } 2100 if(backend->gtls.shared_creds) { 2101 Curl_gtls_shared_creds_free(&backend->gtls.shared_creds); 2102 } 2103 #ifdef USE_GNUTLS_SRP 2104 if(backend->gtls.srp_client_cred) { 2105 gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred); 2106 backend->gtls.srp_client_cred = NULL; 2107 } 2108 #endif 2109 } 2110 2111 static CURLcode gtls_recv(struct Curl_cfilter *cf, 2112 struct Curl_easy *data, 2113 char *buf, size_t blen, 2114 size_t *pnread) 2115 { 2116 struct ssl_connect_data *connssl = cf->ctx; 2117 struct gtls_ssl_backend_data *backend = 2118 (struct gtls_ssl_backend_data *)connssl->backend; 2119 CURLcode result = CURLE_OK; 2120 ssize_t nread; 2121 2122 (void)data; 2123 DEBUGASSERT(backend); 2124 2125 nread = gnutls_record_recv(backend->gtls.session, buf, blen); 2126 2127 if(nread >= 0) 2128 *pnread = (size_t)nread; 2129 else { 2130 if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) { 2131 result = CURLE_AGAIN; 2132 goto out; 2133 } 2134 else if(nread == GNUTLS_E_REHANDSHAKE) { 2135 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the 2136 proper way" takes a whole lot of work. */ 2137 result = handshake(cf, data); 2138 if(!result) 2139 result = CURLE_AGAIN; /* then return as if this was a wouldblock */ 2140 goto out; 2141 } 2142 else { 2143 failf(data, "GnuTLS recv error (%d): %s", 2144 (int)nread, gnutls_strerror((int)nread)); 2145 result = backend->gtls.io_result ? 2146 backend->gtls.io_result : CURLE_RECV_ERROR; 2147 goto out; 2148 } 2149 } 2150 2151 out: 2152 CURL_TRC_CF(data, cf, "gtls_recv(len=%zu) -> 0, %zu", blen, *pnread); 2153 return result; 2154 } 2155 2156 size_t Curl_gtls_version(char *buffer, size_t size) 2157 { 2158 return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); 2159 } 2160 2161 /* data might be NULL! */ 2162 static CURLcode gtls_random(struct Curl_easy *data, 2163 unsigned char *entropy, size_t length) 2164 { 2165 int rc; 2166 (void)data; 2167 rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); 2168 return rc ? CURLE_FAILED_INIT : CURLE_OK; 2169 } 2170 2171 static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */ 2172 size_t tmplen, 2173 unsigned char *sha256sum, /* output */ 2174 size_t sha256len) 2175 { 2176 struct sha256_ctx SHA256pw; 2177 sha256_init(&SHA256pw); 2178 sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); 2179 sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); 2180 return CURLE_OK; 2181 } 2182 2183 static bool gtls_cert_status_request(void) 2184 { 2185 return TRUE; 2186 } 2187 2188 static void *gtls_get_internals(struct ssl_connect_data *connssl, 2189 CURLINFO info UNUSED_PARAM) 2190 { 2191 struct gtls_ssl_backend_data *backend = 2192 (struct gtls_ssl_backend_data *)connssl->backend; 2193 (void)info; 2194 DEBUGASSERT(backend); 2195 return backend->gtls.session; 2196 } 2197 2198 const struct Curl_ssl Curl_ssl_gnutls = { 2199 { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */ 2200 2201 SSLSUPP_CA_PATH | 2202 SSLSUPP_CERTINFO | 2203 SSLSUPP_PINNEDPUBKEY | 2204 SSLSUPP_HTTPS_PROXY | 2205 SSLSUPP_CIPHER_LIST | 2206 SSLSUPP_CA_CACHE, 2207 2208 sizeof(struct gtls_ssl_backend_data), 2209 2210 gtls_init, /* init */ 2211 gtls_cleanup, /* cleanup */ 2212 Curl_gtls_version, /* version */ 2213 gtls_shutdown, /* shutdown */ 2214 gtls_data_pending, /* data_pending */ 2215 gtls_random, /* random */ 2216 gtls_cert_status_request, /* cert_status_request */ 2217 gtls_connect, /* connect */ 2218 Curl_ssl_adjust_pollset, /* adjust_pollset */ 2219 gtls_get_internals, /* get_internals */ 2220 gtls_close, /* close_one */ 2221 NULL, /* close_all */ 2222 NULL, /* set_engine */ 2223 NULL, /* set_engine_default */ 2224 NULL, /* engines_list */ 2225 gtls_sha256sum, /* sha256sum */ 2226 gtls_recv, /* recv decrypted data */ 2227 gtls_send, /* send data to encrypt */ 2228 NULL, /* get_channel_binding */ 2229 }; 2230 2231 #endif /* USE_GNUTLS */