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