1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan (at) gmail.com> 9 * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel (at) haxx.se>, et al. 10 * 11 * This software is licensed as described in the file COPYING, which 12 * you should have received as part of this distribution. The terms 13 * are also available at https://curl.haxx.se/docs/copyright.html. 14 * 15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 16 * copies of the Software, and permit persons to whom the Software is 17 * furnished to do so, under the terms of the COPYING file. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 ***************************************************************************/ 23 24 /* 25 * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code 26 * but vtls.c should ever call or use these functions. 27 * 28 */ 29 30 #include "curl_setup.h" 31 32 #ifdef USE_MBEDTLS 33 34 #include <mbedtls/version.h> 35 #if MBEDTLS_VERSION_NUMBER >= 0x02040000 36 #include <mbedtls/net_sockets.h> 37 #else 38 #include <mbedtls/net.h> 39 #endif 40 #include <mbedtls/ssl.h> 41 #include <mbedtls/certs.h> 42 #include <mbedtls/x509.h> 43 44 #include <mbedtls/error.h> 45 #include <mbedtls/entropy.h> 46 #include <mbedtls/ctr_drbg.h> 47 #include <mbedtls/sha256.h> 48 49 #include "urldata.h" 50 #include "sendf.h" 51 #include "inet_pton.h" 52 #include "mbedtls.h" 53 #include "vtls.h" 54 #include "parsedate.h" 55 #include "connect.h" /* for the connect timeout */ 56 #include "select.h" 57 #include "polarssl_threadlock.h" 58 59 /* The last 3 #include files should be in this order */ 60 #include "curl_printf.h" 61 #include "curl_memory.h" 62 #include "memdebug.h" 63 64 /* apply threading? */ 65 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) 66 #define THREADING_SUPPORT 67 #endif 68 69 #if defined(THREADING_SUPPORT) 70 static mbedtls_entropy_context entropy; 71 72 static int entropy_init_initialized = 0; 73 74 /* start of entropy_init_mutex() */ 75 static void entropy_init_mutex(mbedtls_entropy_context *ctx) 76 { 77 /* lock 0 = entropy_init_mutex() */ 78 Curl_polarsslthreadlock_lock_function(0); 79 if(entropy_init_initialized == 0) { 80 mbedtls_entropy_init(ctx); 81 entropy_init_initialized = 1; 82 } 83 Curl_polarsslthreadlock_unlock_function(0); 84 } 85 /* end of entropy_init_mutex() */ 86 87 /* start of entropy_func_mutex() */ 88 static int entropy_func_mutex(void *data, unsigned char *output, size_t len) 89 { 90 int ret; 91 /* lock 1 = entropy_func_mutex() */ 92 Curl_polarsslthreadlock_lock_function(1); 93 ret = mbedtls_entropy_func(data, output, len); 94 Curl_polarsslthreadlock_unlock_function(1); 95 96 return ret; 97 } 98 /* end of entropy_func_mutex() */ 99 100 #endif /* THREADING_SUPPORT */ 101 102 /* Define this to enable lots of debugging for mbedTLS */ 103 #undef MBEDTLS_DEBUG 104 105 #ifdef MBEDTLS_DEBUG 106 static void mbed_debug(void *context, int level, const char *f_name, 107 int line_nb, const char *line) 108 { 109 struct Curl_easy *data = NULL; 110 111 if(!context) 112 return; 113 114 data = (struct Curl_easy *)context; 115 116 infof(data, "%s", line); 117 (void) level; 118 } 119 #else 120 #endif 121 122 /* ALPN for http2? */ 123 #ifdef USE_NGHTTP2 124 # undef HAS_ALPN 125 # ifdef MBEDTLS_SSL_ALPN 126 # define HAS_ALPN 127 # endif 128 #endif 129 130 131 /* 132 * profile 133 */ 134 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = 135 { 136 /* Hashes from SHA-1 and above */ 137 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | 138 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) | 139 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | 140 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | 141 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | 142 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), 143 0xFFFFFFF, /* Any PK alg */ 144 0xFFFFFFF, /* Any curve */ 145 1024, /* RSA min key len */ 146 }; 147 148 /* See https://tls.mbed.org/discussions/generic/ 149 howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der 150 */ 151 #define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE) 152 #define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) 153 154 #define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 155 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) 156 157 static Curl_recv mbed_recv; 158 static Curl_send mbed_send; 159 160 static CURLcode 161 mbed_connect_step1(struct connectdata *conn, 162 int sockindex) 163 { 164 struct Curl_easy *data = conn->data; 165 struct ssl_connect_data* connssl = &conn->ssl[sockindex]; 166 const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); 167 const bool verifypeer = SSL_CONN_CONFIG(verifypeer); 168 const char * const ssl_capath = SSL_CONN_CONFIG(CApath); 169 char * const ssl_cert = SSL_SET_OPTION(cert); 170 const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); 171 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : 172 conn->host.name; 173 const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; 174 175 int ret = -1; 176 char errorbuf[128]; 177 errorbuf[0]=0; 178 179 /* mbedTLS only supports SSLv3 and TLSv1 */ 180 if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { 181 failf(data, "mbedTLS does not support SSLv2"); 182 return CURLE_SSL_CONNECT_ERROR; 183 } 184 185 #ifdef THREADING_SUPPORT 186 entropy_init_mutex(&entropy); 187 mbedtls_ctr_drbg_init(&connssl->ctr_drbg); 188 189 ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex, 190 &entropy, NULL, 0); 191 if(ret) { 192 #ifdef MBEDTLS_ERROR_C 193 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 194 #endif /* MBEDTLS_ERROR_C */ 195 failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", 196 -ret, errorbuf); 197 } 198 #else 199 mbedtls_entropy_init(&connssl->entropy); 200 mbedtls_ctr_drbg_init(&connssl->ctr_drbg); 201 202 ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func, 203 &connssl->entropy, NULL, 0); 204 if(ret) { 205 #ifdef MBEDTLS_ERROR_C 206 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 207 #endif /* MBEDTLS_ERROR_C */ 208 failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", 209 -ret, errorbuf); 210 } 211 #endif /* THREADING_SUPPORT */ 212 213 /* Load the trusted CA */ 214 mbedtls_x509_crt_init(&connssl->cacert); 215 216 if(ssl_cafile) { 217 ret = mbedtls_x509_crt_parse_file(&connssl->cacert, ssl_cafile); 218 219 if(ret<0) { 220 #ifdef MBEDTLS_ERROR_C 221 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 222 #endif /* MBEDTLS_ERROR_C */ 223 failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", 224 ssl_cafile, -ret, errorbuf); 225 226 if(verifypeer) 227 return CURLE_SSL_CACERT_BADFILE; 228 } 229 } 230 231 if(ssl_capath) { 232 ret = mbedtls_x509_crt_parse_path(&connssl->cacert, ssl_capath); 233 234 if(ret<0) { 235 #ifdef MBEDTLS_ERROR_C 236 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 237 #endif /* MBEDTLS_ERROR_C */ 238 failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", 239 ssl_capath, -ret, errorbuf); 240 241 if(verifypeer) 242 return CURLE_SSL_CACERT_BADFILE; 243 } 244 } 245 246 /* Load the client certificate */ 247 mbedtls_x509_crt_init(&connssl->clicert); 248 249 if(ssl_cert) { 250 ret = mbedtls_x509_crt_parse_file(&connssl->clicert, ssl_cert); 251 252 if(ret) { 253 #ifdef MBEDTLS_ERROR_C 254 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 255 #endif /* MBEDTLS_ERROR_C */ 256 failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", 257 ssl_cert, -ret, errorbuf); 258 259 return CURLE_SSL_CERTPROBLEM; 260 } 261 } 262 263 /* Load the client private key */ 264 mbedtls_pk_init(&connssl->pk); 265 266 if(SSL_SET_OPTION(key)) { 267 ret = mbedtls_pk_parse_keyfile(&connssl->pk, SSL_SET_OPTION(key), 268 SSL_SET_OPTION(key_passwd)); 269 if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA)) 270 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; 271 272 if(ret) { 273 #ifdef MBEDTLS_ERROR_C 274 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 275 #endif /* MBEDTLS_ERROR_C */ 276 failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", 277 SSL_SET_OPTION(key), -ret, errorbuf); 278 279 return CURLE_SSL_CERTPROBLEM; 280 } 281 } 282 283 /* Load the CRL */ 284 mbedtls_x509_crl_init(&connssl->crl); 285 286 if(ssl_crlfile) { 287 ret = mbedtls_x509_crl_parse_file(&connssl->crl, ssl_crlfile); 288 289 if(ret) { 290 #ifdef MBEDTLS_ERROR_C 291 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 292 #endif /* MBEDTLS_ERROR_C */ 293 failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", 294 ssl_crlfile, -ret, errorbuf); 295 296 return CURLE_SSL_CRL_BADFILE; 297 } 298 } 299 300 infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port); 301 302 mbedtls_ssl_config_init(&connssl->config); 303 304 mbedtls_ssl_init(&connssl->ssl); 305 if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) { 306 failf(data, "mbedTLS: ssl_init failed"); 307 return CURLE_SSL_CONNECT_ERROR; 308 } 309 ret = mbedtls_ssl_config_defaults(&connssl->config, 310 MBEDTLS_SSL_IS_CLIENT, 311 MBEDTLS_SSL_TRANSPORT_STREAM, 312 MBEDTLS_SSL_PRESET_DEFAULT); 313 if(ret) { 314 failf(data, "mbedTLS: ssl_config failed"); 315 return CURLE_SSL_CONNECT_ERROR; 316 } 317 318 /* new profile with RSA min key len = 1024 ... */ 319 mbedtls_ssl_conf_cert_profile(&connssl->config, 320 &mbedtls_x509_crt_profile_fr); 321 322 switch(SSL_CONN_CONFIG(version)) { 323 case CURL_SSLVERSION_DEFAULT: 324 case CURL_SSLVERSION_TLSv1: 325 mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 326 MBEDTLS_SSL_MINOR_VERSION_1); 327 infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); 328 break; 329 case CURL_SSLVERSION_SSLv3: 330 mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 331 MBEDTLS_SSL_MINOR_VERSION_0); 332 mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 333 MBEDTLS_SSL_MINOR_VERSION_0); 334 infof(data, "mbedTLS: Set SSL version to SSLv3\n"); 335 break; 336 case CURL_SSLVERSION_TLSv1_0: 337 mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 338 MBEDTLS_SSL_MINOR_VERSION_1); 339 mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 340 MBEDTLS_SSL_MINOR_VERSION_1); 341 infof(data, "mbedTLS: Set SSL version to TLS 1.0\n"); 342 break; 343 case CURL_SSLVERSION_TLSv1_1: 344 mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 345 MBEDTLS_SSL_MINOR_VERSION_2); 346 mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 347 MBEDTLS_SSL_MINOR_VERSION_2); 348 infof(data, "mbedTLS: Set SSL version to TLS 1.1\n"); 349 break; 350 case CURL_SSLVERSION_TLSv1_2: 351 mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 352 MBEDTLS_SSL_MINOR_VERSION_3); 353 mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, 354 MBEDTLS_SSL_MINOR_VERSION_3); 355 infof(data, "mbedTLS: Set SSL version to TLS 1.2\n"); 356 break; 357 case CURL_SSLVERSION_TLSv1_3: 358 failf(data, "mbedTLS: TLS 1.3 is not yet supported"); 359 return CURLE_SSL_CONNECT_ERROR; 360 default: 361 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); 362 return CURLE_SSL_CONNECT_ERROR; 363 } 364 365 mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL); 366 367 mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random, 368 &connssl->ctr_drbg); 369 mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex], 370 mbedtls_net_send, 371 mbedtls_net_recv, 372 NULL /* rev_timeout() */); 373 374 mbedtls_ssl_conf_ciphersuites(&connssl->config, 375 mbedtls_ssl_list_ciphersuites()); 376 377 /* Check if there's a cached ID we can/should use here! */ 378 if(data->set.general_ssl.sessionid) { 379 void *old_session = NULL; 380 381 Curl_ssl_sessionid_lock(conn); 382 if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { 383 ret = mbedtls_ssl_set_session(&connssl->ssl, old_session); 384 if(ret) { 385 Curl_ssl_sessionid_unlock(conn); 386 failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); 387 return CURLE_SSL_CONNECT_ERROR; 388 } 389 infof(data, "mbedTLS re-using session\n"); 390 } 391 Curl_ssl_sessionid_unlock(conn); 392 } 393 394 mbedtls_ssl_conf_ca_chain(&connssl->config, 395 &connssl->cacert, 396 &connssl->crl); 397 398 if(SSL_SET_OPTION(key)) { 399 mbedtls_ssl_conf_own_cert(&connssl->config, 400 &connssl->clicert, &connssl->pk); 401 } 402 if(mbedtls_ssl_set_hostname(&connssl->ssl, hostname)) { 403 /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* 404 the name to set in the SNI extension. So even if curl connects to a 405 host specified as an IP address, this function must be used. */ 406 failf(data, "couldn't set hostname in mbedTLS"); 407 return CURLE_SSL_CONNECT_ERROR; 408 } 409 410 #ifdef HAS_ALPN 411 if(conn->bits.tls_enable_alpn) { 412 const char **p = &connssl->protocols[0]; 413 #ifdef USE_NGHTTP2 414 if(data->set.httpversion >= CURL_HTTP_VERSION_2) 415 *p++ = NGHTTP2_PROTO_VERSION_ID; 416 #endif 417 *p++ = ALPN_HTTP_1_1; 418 *p = NULL; 419 /* this function doesn't clone the protocols array, which is why we need 420 to keep it around */ 421 if(mbedtls_ssl_conf_alpn_protocols(&connssl->config, 422 &connssl->protocols[0])) { 423 failf(data, "Failed setting ALPN protocols"); 424 return CURLE_SSL_CONNECT_ERROR; 425 } 426 for(p = &connssl->protocols[0]; *p; ++p) 427 infof(data, "ALPN, offering %s\n", *p); 428 } 429 #endif 430 431 #ifdef MBEDTLS_DEBUG 432 /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ 433 mbedtls_ssl_conf_dbg(&connssl->config, mbed_debug, data); 434 /* - 0 No debug 435 * - 1 Error 436 * - 2 State change 437 * - 3 Informational 438 * - 4 Verbose 439 */ 440 mbedtls_debug_set_threshold(4); 441 #endif 442 443 connssl->connecting_state = ssl_connect_2; 444 445 return CURLE_OK; 446 } 447 448 static CURLcode 449 mbed_connect_step2(struct connectdata *conn, 450 int sockindex) 451 { 452 int ret; 453 struct Curl_easy *data = conn->data; 454 struct ssl_connect_data* connssl = &conn->ssl[sockindex]; 455 const mbedtls_x509_crt *peercert; 456 457 #ifdef HAS_ALPN 458 const char *next_protocol; 459 #endif 460 461 char errorbuf[128]; 462 errorbuf[0] = 0; 463 464 conn->recv[sockindex] = mbed_recv; 465 conn->send[sockindex] = mbed_send; 466 467 ret = mbedtls_ssl_handshake(&connssl->ssl); 468 469 if(ret == MBEDTLS_ERR_SSL_WANT_READ) { 470 connssl->connecting_state = ssl_connect_2_reading; 471 return CURLE_OK; 472 } 473 else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { 474 connssl->connecting_state = ssl_connect_2_writing; 475 return CURLE_OK; 476 } 477 else if(ret) { 478 #ifdef MBEDTLS_ERROR_C 479 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 480 #endif /* MBEDTLS_ERROR_C */ 481 failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", 482 -ret, errorbuf); 483 return CURLE_SSL_CONNECT_ERROR; 484 } 485 486 infof(data, "mbedTLS: Handshake complete, cipher is %s\n", 487 mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) 488 ); 489 490 ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl); 491 492 if(ret && SSL_CONN_CONFIG(verifypeer)) { 493 if(ret & MBEDTLS_X509_BADCERT_EXPIRED) 494 failf(data, "Cert verify failed: BADCERT_EXPIRED"); 495 496 if(ret & MBEDTLS_X509_BADCERT_REVOKED) { 497 failf(data, "Cert verify failed: BADCERT_REVOKED"); 498 return CURLE_SSL_CACERT; 499 } 500 501 if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) 502 failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); 503 504 if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) 505 failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); 506 507 return CURLE_PEER_FAILED_VERIFICATION; 508 } 509 510 peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl); 511 512 if(peercert && data->set.verbose) { 513 const size_t bufsize = 16384; 514 char *buffer = malloc(bufsize); 515 516 if(!buffer) 517 return CURLE_OUT_OF_MEMORY; 518 519 if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) 520 infof(data, "Dumping cert info:\n%s\n", buffer); 521 else 522 infof(data, "Unable to dump certificate information.\n"); 523 524 free(buffer); 525 } 526 527 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { 528 int size; 529 CURLcode result; 530 mbedtls_x509_crt *p; 531 unsigned char pubkey[PUB_DER_MAX_BYTES]; 532 533 if(!peercert || !peercert->raw.p || !peercert->raw.len) { 534 failf(data, "Failed due to missing peer certificate"); 535 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 536 } 537 538 p = calloc(1, sizeof(*p)); 539 540 if(!p) 541 return CURLE_OUT_OF_MEMORY; 542 543 mbedtls_x509_crt_init(p); 544 545 /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der 546 needs a non-const key, for now. 547 https://github.com/ARMmbed/mbedtls/issues/396 */ 548 if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { 549 failf(data, "Failed copying peer certificate"); 550 mbedtls_x509_crt_free(p); 551 free(p); 552 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 553 } 554 555 size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); 556 557 if(size <= 0) { 558 failf(data, "Failed copying public key from peer certificate"); 559 mbedtls_x509_crt_free(p); 560 free(p); 561 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 562 } 563 564 /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ 565 result = Curl_pin_peer_pubkey(data, 566 data->set.str[STRING_SSL_PINNEDPUBLICKEY], 567 &pubkey[PUB_DER_MAX_BYTES - size], size); 568 if(result) { 569 mbedtls_x509_crt_free(p); 570 free(p); 571 return result; 572 } 573 574 mbedtls_x509_crt_free(p); 575 free(p); 576 } 577 578 #ifdef HAS_ALPN 579 if(conn->bits.tls_enable_alpn) { 580 next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl); 581 582 if(next_protocol) { 583 infof(data, "ALPN, server accepted to use %s\n", next_protocol); 584 #ifdef USE_NGHTTP2 585 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, 586 NGHTTP2_PROTO_VERSION_ID_LEN) && 587 !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) { 588 conn->negnpn = CURL_HTTP_VERSION_2; 589 } 590 else 591 #endif 592 if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) && 593 !next_protocol[ALPN_HTTP_1_1_LENGTH]) { 594 conn->negnpn = CURL_HTTP_VERSION_1_1; 595 } 596 } 597 else { 598 infof(data, "ALPN, server did not agree to a protocol\n"); 599 } 600 } 601 #endif 602 603 connssl->connecting_state = ssl_connect_3; 604 infof(data, "SSL connected\n"); 605 606 return CURLE_OK; 607 } 608 609 static CURLcode 610 mbed_connect_step3(struct connectdata *conn, 611 int sockindex) 612 { 613 CURLcode retcode = CURLE_OK; 614 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 615 struct Curl_easy *data = conn->data; 616 617 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); 618 619 if(data->set.general_ssl.sessionid) { 620 int ret; 621 mbedtls_ssl_session *our_ssl_sessionid; 622 void *old_ssl_sessionid = NULL; 623 624 our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); 625 if(!our_ssl_sessionid) 626 return CURLE_OUT_OF_MEMORY; 627 628 mbedtls_ssl_session_init(our_ssl_sessionid); 629 630 ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid); 631 if(ret) { 632 failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); 633 return CURLE_SSL_CONNECT_ERROR; 634 } 635 636 /* If there's already a matching session in the cache, delete it */ 637 Curl_ssl_sessionid_lock(conn); 638 if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)) 639 Curl_ssl_delsessionid(conn, old_ssl_sessionid); 640 641 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); 642 Curl_ssl_sessionid_unlock(conn); 643 if(retcode) { 644 free(our_ssl_sessionid); 645 failf(data, "failed to store ssl session"); 646 return retcode; 647 } 648 } 649 650 connssl->connecting_state = ssl_connect_done; 651 652 return CURLE_OK; 653 } 654 655 static ssize_t mbed_send(struct connectdata *conn, int sockindex, 656 const void *mem, size_t len, 657 CURLcode *curlcode) 658 { 659 int ret = -1; 660 661 ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl, 662 (unsigned char *)mem, len); 663 664 if(ret < 0) { 665 *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ? 666 CURLE_AGAIN : CURLE_SEND_ERROR; 667 ret = -1; 668 } 669 670 return ret; 671 } 672 673 void Curl_mbedtls_close_all(struct Curl_easy *data) 674 { 675 (void)data; 676 } 677 678 void Curl_mbedtls_close(struct connectdata *conn, int sockindex) 679 { 680 mbedtls_pk_free(&conn->ssl[sockindex].pk); 681 mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert); 682 mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert); 683 mbedtls_x509_crl_free(&conn->ssl[sockindex].crl); 684 mbedtls_ssl_config_free(&conn->ssl[sockindex].config); 685 mbedtls_ssl_free(&conn->ssl[sockindex].ssl); 686 mbedtls_ctr_drbg_free(&conn->ssl[sockindex].ctr_drbg); 687 #ifndef THREADING_SUPPORT 688 mbedtls_entropy_free(&conn->ssl[sockindex].entropy); 689 #endif /* THREADING_SUPPORT */ 690 } 691 692 static ssize_t mbed_recv(struct connectdata *conn, int num, 693 char *buf, size_t buffersize, 694 CURLcode *curlcode) 695 { 696 int ret = -1; 697 ssize_t len = -1; 698 699 memset(buf, 0, buffersize); 700 ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, 701 buffersize); 702 703 if(ret <= 0) { 704 if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) 705 return 0; 706 707 *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ? 708 CURLE_AGAIN : CURLE_RECV_ERROR; 709 return -1; 710 } 711 712 len = ret; 713 714 return len; 715 } 716 717 void Curl_mbedtls_session_free(void *ptr) 718 { 719 mbedtls_ssl_session_free(ptr); 720 free(ptr); 721 } 722 723 size_t Curl_mbedtls_version(char *buffer, size_t size) 724 { 725 unsigned int version = mbedtls_version_get_number(); 726 return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24, 727 (version>>16)&0xff, (version>>8)&0xff); 728 } 729 730 static CURLcode 731 mbed_connect_common(struct connectdata *conn, 732 int sockindex, 733 bool nonblocking, 734 bool *done) 735 { 736 CURLcode retcode; 737 struct Curl_easy *data = conn->data; 738 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 739 curl_socket_t sockfd = conn->sock[sockindex]; 740 long timeout_ms; 741 int what; 742 743 /* check if the connection has already been established */ 744 if(ssl_connection_complete == connssl->state) { 745 *done = TRUE; 746 return CURLE_OK; 747 } 748 749 if(ssl_connect_1==connssl->connecting_state) { 750 /* Find out how much more time we're allowed */ 751 timeout_ms = Curl_timeleft(data, NULL, TRUE); 752 753 if(timeout_ms < 0) { 754 /* no need to continue if time already is up */ 755 failf(data, "SSL connection timeout"); 756 return CURLE_OPERATION_TIMEDOUT; 757 } 758 retcode = mbed_connect_step1(conn, sockindex); 759 if(retcode) 760 return retcode; 761 } 762 763 while(ssl_connect_2 == connssl->connecting_state || 764 ssl_connect_2_reading == connssl->connecting_state || 765 ssl_connect_2_writing == connssl->connecting_state) { 766 767 /* check allowed time left */ 768 timeout_ms = Curl_timeleft(data, NULL, TRUE); 769 770 if(timeout_ms < 0) { 771 /* no need to continue if time already is up */ 772 failf(data, "SSL connection timeout"); 773 return CURLE_OPERATION_TIMEDOUT; 774 } 775 776 /* if ssl is expecting something, check if it's available. */ 777 if(connssl->connecting_state == ssl_connect_2_reading 778 || connssl->connecting_state == ssl_connect_2_writing) { 779 780 curl_socket_t writefd = ssl_connect_2_writing== 781 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 782 curl_socket_t readfd = ssl_connect_2_reading== 783 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 784 785 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, 786 nonblocking ? 0 : timeout_ms); 787 if(what < 0) { 788 /* fatal error */ 789 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); 790 return CURLE_SSL_CONNECT_ERROR; 791 } 792 else if(0 == what) { 793 if(nonblocking) { 794 *done = FALSE; 795 return CURLE_OK; 796 } 797 else { 798 /* timeout */ 799 failf(data, "SSL connection timeout"); 800 return CURLE_OPERATION_TIMEDOUT; 801 } 802 } 803 /* socket is readable or writable */ 804 } 805 806 /* Run transaction, and return to the caller if it failed or if 807 * this connection is part of a multi handle and this loop would 808 * execute again. This permits the owner of a multi handle to 809 * abort a connection attempt before step2 has completed while 810 * ensuring that a client using select() or epoll() will always 811 * have a valid fdset to wait on. 812 */ 813 retcode = mbed_connect_step2(conn, sockindex); 814 if(retcode || (nonblocking && 815 (ssl_connect_2 == connssl->connecting_state || 816 ssl_connect_2_reading == connssl->connecting_state || 817 ssl_connect_2_writing == connssl->connecting_state))) 818 return retcode; 819 820 } /* repeat step2 until all transactions are done. */ 821 822 if(ssl_connect_3==connssl->connecting_state) { 823 retcode = mbed_connect_step3(conn, sockindex); 824 if(retcode) 825 return retcode; 826 } 827 828 if(ssl_connect_done==connssl->connecting_state) { 829 connssl->state = ssl_connection_complete; 830 conn->recv[sockindex] = mbed_recv; 831 conn->send[sockindex] = mbed_send; 832 *done = TRUE; 833 } 834 else 835 *done = FALSE; 836 837 /* Reset our connect state machine */ 838 connssl->connecting_state = ssl_connect_1; 839 840 return CURLE_OK; 841 } 842 843 CURLcode 844 Curl_mbedtls_connect_nonblocking(struct connectdata *conn, 845 int sockindex, 846 bool *done) 847 { 848 return mbed_connect_common(conn, sockindex, TRUE, done); 849 } 850 851 852 CURLcode 853 Curl_mbedtls_connect(struct connectdata *conn, 854 int sockindex) 855 { 856 CURLcode retcode; 857 bool done = FALSE; 858 859 retcode = mbed_connect_common(conn, sockindex, FALSE, &done); 860 if(retcode) 861 return retcode; 862 863 DEBUGASSERT(done); 864 865 return CURLE_OK; 866 } 867 868 /* 869 * return 0 error initializing SSL 870 * return 1 SSL initialized successfully 871 */ 872 int Curl_mbedtls_init(void) 873 { 874 return Curl_polarsslthreadlock_thread_setup(); 875 } 876 877 void Curl_mbedtls_cleanup(void) 878 { 879 (void)Curl_polarsslthreadlock_thread_cleanup(); 880 } 881 882 int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex) 883 { 884 mbedtls_ssl_context *ssl = 885 (mbedtls_ssl_context *)&conn->ssl[sockindex].ssl; 886 return ssl->in_msglen != 0; 887 } 888 889 #endif /* USE_MBEDTLS */ 890