1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan (at) gmail.com> 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 PolarSSL-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_POLARSSL 33 34 #include <polarssl/net.h> 35 #include <polarssl/ssl.h> 36 #include <polarssl/certs.h> 37 #include <polarssl/x509.h> 38 #include <polarssl/version.h> 39 #include <polarssl/sha256.h> 40 41 #if POLARSSL_VERSION_NUMBER < 0x01030000 42 #error too old PolarSSL 43 #endif 44 45 #include <polarssl/error.h> 46 #include <polarssl/entropy.h> 47 #include <polarssl/ctr_drbg.h> 48 49 #include "urldata.h" 50 #include "sendf.h" 51 #include "inet_pton.h" 52 #include "polarssl.h" 53 #include "vtls.h" 54 #include "parsedate.h" 55 #include "connect.h" /* for the connect timeout */ 56 #include "select.h" 57 #include "strcase.h" 58 #include "polarssl_threadlock.h" 59 #include "curl_printf.h" 60 #include "curl_memory.h" 61 /* The last #include file should be: */ 62 #include "memdebug.h" 63 64 /* See https://tls.mbed.org/discussions/generic/ 65 howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der 66 */ 67 #define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE) 68 #define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES) 69 70 #define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 71 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) 72 73 /* apply threading? */ 74 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) 75 #define THREADING_SUPPORT 76 #endif 77 78 #ifndef POLARSSL_ERROR_C 79 #define error_strerror(x,y,z) 80 #endif /* POLARSSL_ERROR_C */ 81 82 83 #if defined(THREADING_SUPPORT) 84 static entropy_context entropy; 85 86 static int entropy_init_initialized = 0; 87 88 /* start of entropy_init_mutex() */ 89 static void entropy_init_mutex(entropy_context *ctx) 90 { 91 /* lock 0 = entropy_init_mutex() */ 92 Curl_polarsslthreadlock_lock_function(0); 93 if(entropy_init_initialized == 0) { 94 entropy_init(ctx); 95 entropy_init_initialized = 1; 96 } 97 Curl_polarsslthreadlock_unlock_function(0); 98 } 99 /* end of entropy_init_mutex() */ 100 101 /* start of entropy_func_mutex() */ 102 static int entropy_func_mutex(void *data, unsigned char *output, size_t len) 103 { 104 int ret; 105 /* lock 1 = entropy_func_mutex() */ 106 Curl_polarsslthreadlock_lock_function(1); 107 ret = entropy_func(data, output, len); 108 Curl_polarsslthreadlock_unlock_function(1); 109 110 return ret; 111 } 112 /* end of entropy_func_mutex() */ 113 114 #endif /* THREADING_SUPPORT */ 115 116 /* Define this to enable lots of debugging for PolarSSL */ 117 #undef POLARSSL_DEBUG 118 119 #ifdef POLARSSL_DEBUG 120 static void polarssl_debug(void *context, int level, const char *line) 121 { 122 struct Curl_easy *data = NULL; 123 124 if(!context) 125 return; 126 127 data = (struct Curl_easy *)context; 128 129 infof(data, "%s", line); 130 (void) level; 131 } 132 #else 133 #endif 134 135 /* ALPN for http2? */ 136 #ifdef POLARSSL_SSL_ALPN 137 # define HAS_ALPN 138 #endif 139 140 static Curl_recv polarssl_recv; 141 static Curl_send polarssl_send; 142 143 144 static CURLcode 145 polarssl_connect_step1(struct connectdata *conn, 146 int sockindex) 147 { 148 struct Curl_easy *data = conn->data; 149 struct ssl_connect_data* connssl = &conn->ssl[sockindex]; 150 const char *capath = SSL_CONN_CONFIG(CApath); 151 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : 152 conn->host.name; 153 const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; 154 int ret = -1; 155 char errorbuf[128]; 156 errorbuf[0]=0; 157 158 /* PolarSSL only supports SSLv3 and TLSv1 */ 159 if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { 160 failf(data, "PolarSSL does not support SSLv2"); 161 return CURLE_SSL_CONNECT_ERROR; 162 } 163 164 #ifdef THREADING_SUPPORT 165 entropy_init_mutex(&entropy); 166 167 if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy, 168 NULL, 0)) != 0) { 169 error_strerror(ret, errorbuf, sizeof(errorbuf)); 170 failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", 171 -ret, errorbuf); 172 } 173 #else 174 entropy_init(&connssl->entropy); 175 176 if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy, 177 NULL, 0)) != 0) { 178 error_strerror(ret, errorbuf, sizeof(errorbuf)); 179 failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", 180 -ret, errorbuf); 181 } 182 #endif /* THREADING_SUPPORT */ 183 184 /* Load the trusted CA */ 185 memset(&connssl->cacert, 0, sizeof(x509_crt)); 186 187 if(SSL_CONN_CONFIG(CAfile)) { 188 ret = x509_crt_parse_file(&connssl->cacert, 189 SSL_CONN_CONFIG(CAfile)); 190 191 if(ret<0) { 192 error_strerror(ret, errorbuf, sizeof(errorbuf)); 193 failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", 194 SSL_CONN_CONFIG(CAfile), -ret, errorbuf); 195 196 if(SSL_CONN_CONFIG(verifypeer)) 197 return CURLE_SSL_CACERT_BADFILE; 198 } 199 } 200 201 if(capath) { 202 ret = x509_crt_parse_path(&connssl->cacert, capath); 203 204 if(ret<0) { 205 error_strerror(ret, errorbuf, sizeof(errorbuf)); 206 failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s", 207 capath, -ret, errorbuf); 208 209 if(SSL_CONN_CONFIG(verifypeer)) 210 return CURLE_SSL_CACERT_BADFILE; 211 } 212 } 213 214 /* Load the client certificate */ 215 memset(&connssl->clicert, 0, sizeof(x509_crt)); 216 217 if(SSL_SET_OPTION(cert)) { 218 ret = x509_crt_parse_file(&connssl->clicert, 219 SSL_SET_OPTION(cert)); 220 221 if(ret) { 222 error_strerror(ret, errorbuf, sizeof(errorbuf)); 223 failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s", 224 SSL_SET_OPTION(cert), -ret, errorbuf); 225 226 return CURLE_SSL_CERTPROBLEM; 227 } 228 } 229 230 /* Load the client private key */ 231 if(SSL_SET_OPTION(key)) { 232 pk_context pk; 233 pk_init(&pk); 234 ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key), 235 SSL_SET_OPTION(key_passwd)); 236 if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) 237 ret = POLARSSL_ERR_PK_TYPE_MISMATCH; 238 if(ret == 0) 239 rsa_copy(&connssl->rsa, pk_rsa(pk)); 240 else 241 rsa_free(&connssl->rsa); 242 pk_free(&pk); 243 244 if(ret) { 245 error_strerror(ret, errorbuf, sizeof(errorbuf)); 246 failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", 247 SSL_SET_OPTION(key), -ret, errorbuf); 248 249 return CURLE_SSL_CERTPROBLEM; 250 } 251 } 252 253 /* Load the CRL */ 254 memset(&connssl->crl, 0, sizeof(x509_crl)); 255 256 if(SSL_SET_OPTION(CRLfile)) { 257 ret = x509_crl_parse_file(&connssl->crl, 258 SSL_SET_OPTION(CRLfile)); 259 260 if(ret) { 261 error_strerror(ret, errorbuf, sizeof(errorbuf)); 262 failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", 263 SSL_SET_OPTION(CRLfile), -ret, errorbuf); 264 265 return CURLE_SSL_CRL_BADFILE; 266 } 267 } 268 269 infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port); 270 271 if(ssl_init(&connssl->ssl)) { 272 failf(data, "PolarSSL: ssl_init failed"); 273 return CURLE_SSL_CONNECT_ERROR; 274 } 275 276 switch(SSL_CONN_CONFIG(version)) { 277 case CURL_SSLVERSION_DEFAULT: 278 case CURL_SSLVERSION_TLSv1: 279 ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 280 SSL_MINOR_VERSION_1); 281 break; 282 case CURL_SSLVERSION_SSLv3: 283 ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 284 SSL_MINOR_VERSION_0); 285 ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 286 SSL_MINOR_VERSION_0); 287 infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n"); 288 break; 289 case CURL_SSLVERSION_TLSv1_0: 290 ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 291 SSL_MINOR_VERSION_1); 292 ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 293 SSL_MINOR_VERSION_1); 294 infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n"); 295 break; 296 case CURL_SSLVERSION_TLSv1_1: 297 ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 298 SSL_MINOR_VERSION_2); 299 ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 300 SSL_MINOR_VERSION_2); 301 infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n"); 302 break; 303 case CURL_SSLVERSION_TLSv1_2: 304 ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 305 SSL_MINOR_VERSION_3); 306 ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, 307 SSL_MINOR_VERSION_3); 308 infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n"); 309 break; 310 case CURL_SSLVERSION_TLSv1_3: 311 failf(data, "PolarSSL: TLS 1.3 is not yet supported"); 312 return CURLE_SSL_CONNECT_ERROR; 313 default: 314 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); 315 return CURLE_SSL_CONNECT_ERROR; 316 } 317 318 ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT); 319 ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL); 320 321 ssl_set_rng(&connssl->ssl, ctr_drbg_random, 322 &connssl->ctr_drbg); 323 ssl_set_bio(&connssl->ssl, 324 net_recv, &conn->sock[sockindex], 325 net_send, &conn->sock[sockindex]); 326 327 ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites()); 328 329 /* Check if there's a cached ID we can/should use here! */ 330 if(data->set.general_ssl.sessionid) { 331 void *old_session = NULL; 332 333 Curl_ssl_sessionid_lock(conn); 334 if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { 335 ret = ssl_set_session(&connssl->ssl, old_session); 336 if(ret) { 337 Curl_ssl_sessionid_unlock(conn); 338 failf(data, "ssl_set_session returned -0x%x", -ret); 339 return CURLE_SSL_CONNECT_ERROR; 340 } 341 infof(data, "PolarSSL re-using session\n"); 342 } 343 Curl_ssl_sessionid_unlock(conn); 344 } 345 346 ssl_set_ca_chain(&connssl->ssl, 347 &connssl->cacert, 348 &connssl->crl, 349 hostname); 350 351 ssl_set_own_cert_rsa(&connssl->ssl, 352 &connssl->clicert, &connssl->rsa); 353 354 if(ssl_set_hostname(&connssl->ssl, hostname)) { 355 /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name 356 to set in the SNI extension. So even if curl connects to a host 357 specified as an IP address, this function must be used. */ 358 failf(data, "couldn't set hostname in PolarSSL"); 359 return CURLE_SSL_CONNECT_ERROR; 360 } 361 362 #ifdef HAS_ALPN 363 if(conn->bits.tls_enable_alpn) { 364 static const char *protocols[3]; 365 int cur = 0; 366 367 #ifdef USE_NGHTTP2 368 if(data->set.httpversion >= CURL_HTTP_VERSION_2) { 369 protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; 370 infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); 371 } 372 #endif 373 374 protocols[cur++] = ALPN_HTTP_1_1; 375 infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); 376 377 protocols[cur] = NULL; 378 379 ssl_set_alpn_protocols(&connssl->ssl, protocols); 380 } 381 #endif 382 383 #ifdef POLARSSL_DEBUG 384 ssl_set_dbg(&connssl->ssl, polarssl_debug, data); 385 #endif 386 387 connssl->connecting_state = ssl_connect_2; 388 389 return CURLE_OK; 390 } 391 392 static CURLcode 393 polarssl_connect_step2(struct connectdata *conn, 394 int sockindex) 395 { 396 int ret; 397 struct Curl_easy *data = conn->data; 398 struct ssl_connect_data* connssl = &conn->ssl[sockindex]; 399 char buffer[1024]; 400 401 char errorbuf[128]; 402 errorbuf[0] = 0; 403 404 conn->recv[sockindex] = polarssl_recv; 405 conn->send[sockindex] = polarssl_send; 406 407 ret = ssl_handshake(&connssl->ssl); 408 409 switch(ret) { 410 case 0: 411 break; 412 413 case POLARSSL_ERR_NET_WANT_READ: 414 connssl->connecting_state = ssl_connect_2_reading; 415 return CURLE_OK; 416 417 case POLARSSL_ERR_NET_WANT_WRITE: 418 connssl->connecting_state = ssl_connect_2_writing; 419 return CURLE_OK; 420 421 default: 422 error_strerror(ret, errorbuf, sizeof(errorbuf)); 423 failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", 424 -ret, errorbuf); 425 return CURLE_SSL_CONNECT_ERROR; 426 } 427 428 infof(data, "PolarSSL: Handshake complete, cipher is %s\n", 429 ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) ); 430 431 ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl); 432 433 if(ret && SSL_CONN_CONFIG(verifypeer)) { 434 if(ret & BADCERT_EXPIRED) 435 failf(data, "Cert verify failed: BADCERT_EXPIRED"); 436 437 if(ret & BADCERT_REVOKED) { 438 failf(data, "Cert verify failed: BADCERT_REVOKED"); 439 return CURLE_SSL_CACERT; 440 } 441 442 if(ret & BADCERT_CN_MISMATCH) 443 failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); 444 445 if(ret & BADCERT_NOT_TRUSTED) 446 failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); 447 448 return CURLE_PEER_FAILED_VERIFICATION; 449 } 450 451 if(ssl_get_peer_cert(&(connssl->ssl))) { 452 /* If the session was resumed, there will be no peer certs */ 453 memset(buffer, 0, sizeof(buffer)); 454 455 if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", 456 ssl_get_peer_cert(&(connssl->ssl))) != -1) 457 infof(data, "Dumping cert info:\n%s\n", buffer); 458 } 459 460 /* adapted from mbedtls.c */ 461 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { 462 int size; 463 CURLcode result; 464 x509_crt *p; 465 unsigned char pubkey[PUB_DER_MAX_BYTES]; 466 const x509_crt *peercert; 467 468 peercert = ssl_get_peer_cert(&connssl->ssl); 469 470 if(!peercert || !peercert->raw.p || !peercert->raw.len) { 471 failf(data, "Failed due to missing peer certificate"); 472 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 473 } 474 475 p = calloc(1, sizeof(*p)); 476 477 if(!p) 478 return CURLE_OUT_OF_MEMORY; 479 480 x509_crt_init(p); 481 482 /* Make a copy of our const peercert because pk_write_pubkey_der 483 needs a non-const key, for now. 484 https://github.com/ARMmbed/mbedtls/issues/396 */ 485 if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { 486 failf(data, "Failed copying peer certificate"); 487 x509_crt_free(p); 488 free(p); 489 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 490 } 491 492 size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); 493 494 if(size <= 0) { 495 failf(data, "Failed copying public key from peer certificate"); 496 x509_crt_free(p); 497 free(p); 498 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 499 } 500 501 /* pk_write_pubkey_der writes data at the end of the buffer. */ 502 result = Curl_pin_peer_pubkey(data, 503 data->set.str[STRING_SSL_PINNEDPUBLICKEY], 504 &pubkey[PUB_DER_MAX_BYTES - size], size); 505 if(result) { 506 x509_crt_free(p); 507 free(p); 508 return result; 509 } 510 511 x509_crt_free(p); 512 free(p); 513 } 514 515 #ifdef HAS_ALPN 516 if(conn->bits.tls_enable_alpn) { 517 const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl); 518 519 if(next_protocol != NULL) { 520 infof(data, "ALPN, server accepted to use %s\n", next_protocol); 521 522 #ifdef USE_NGHTTP2 523 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, 524 NGHTTP2_PROTO_VERSION_ID_LEN)) { 525 conn->negnpn = CURL_HTTP_VERSION_2; 526 } 527 else 528 #endif 529 if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { 530 conn->negnpn = CURL_HTTP_VERSION_1_1; 531 } 532 } 533 else 534 infof(data, "ALPN, server did not agree to a protocol\n"); 535 } 536 #endif 537 538 connssl->connecting_state = ssl_connect_3; 539 infof(data, "SSL connected\n"); 540 541 return CURLE_OK; 542 } 543 544 static CURLcode 545 polarssl_connect_step3(struct connectdata *conn, 546 int sockindex) 547 { 548 CURLcode retcode = CURLE_OK; 549 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 550 struct Curl_easy *data = conn->data; 551 552 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); 553 554 if(data->set.general_ssl.sessionid) { 555 int ret; 556 ssl_session *our_ssl_sessionid; 557 void *old_ssl_sessionid = NULL; 558 559 our_ssl_sessionid = malloc(sizeof(ssl_session)); 560 if(!our_ssl_sessionid) 561 return CURLE_OUT_OF_MEMORY; 562 563 ssl_session_init(our_ssl_sessionid); 564 565 ret = ssl_get_session(&connssl->ssl, our_ssl_sessionid); 566 if(ret) { 567 failf(data, "ssl_get_session returned -0x%x", -ret); 568 return CURLE_SSL_CONNECT_ERROR; 569 } 570 571 /* If there's already a matching session in the cache, delete it */ 572 Curl_ssl_sessionid_lock(conn); 573 if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)) 574 Curl_ssl_delsessionid(conn, old_ssl_sessionid); 575 576 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); 577 Curl_ssl_sessionid_unlock(conn); 578 if(retcode) { 579 free(our_ssl_sessionid); 580 failf(data, "failed to store ssl session"); 581 return retcode; 582 } 583 } 584 585 connssl->connecting_state = ssl_connect_done; 586 587 return CURLE_OK; 588 } 589 590 static ssize_t polarssl_send(struct connectdata *conn, 591 int sockindex, 592 const void *mem, 593 size_t len, 594 CURLcode *curlcode) 595 { 596 int ret = -1; 597 598 ret = ssl_write(&conn->ssl[sockindex].ssl, 599 (unsigned char *)mem, len); 600 601 if(ret < 0) { 602 *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ? 603 CURLE_AGAIN : CURLE_SEND_ERROR; 604 ret = -1; 605 } 606 607 return ret; 608 } 609 610 void Curl_polarssl_close(struct connectdata *conn, int sockindex) 611 { 612 rsa_free(&conn->ssl[sockindex].rsa); 613 x509_crt_free(&conn->ssl[sockindex].clicert); 614 x509_crt_free(&conn->ssl[sockindex].cacert); 615 x509_crl_free(&conn->ssl[sockindex].crl); 616 ssl_free(&conn->ssl[sockindex].ssl); 617 } 618 619 static ssize_t polarssl_recv(struct connectdata *conn, 620 int num, 621 char *buf, 622 size_t buffersize, 623 CURLcode *curlcode) 624 { 625 int ret = -1; 626 ssize_t len = -1; 627 628 memset(buf, 0, buffersize); 629 ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize); 630 631 if(ret <= 0) { 632 if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) 633 return 0; 634 635 *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ? 636 CURLE_AGAIN : CURLE_RECV_ERROR; 637 return -1; 638 } 639 640 len = ret; 641 642 return len; 643 } 644 645 void Curl_polarssl_session_free(void *ptr) 646 { 647 ssl_session_free(ptr); 648 free(ptr); 649 } 650 651 /* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and 652 higher) will be mbed TLS branded.. */ 653 654 size_t Curl_polarssl_version(char *buffer, size_t size) 655 { 656 unsigned int version = version_get_number(); 657 return snprintf(buffer, size, "%s/%d.%d.%d", 658 version >= 0x01030A00?"mbedTLS":"PolarSSL", 659 version>>24, (version>>16)&0xff, (version>>8)&0xff); 660 } 661 662 static CURLcode 663 polarssl_connect_common(struct connectdata *conn, 664 int sockindex, 665 bool nonblocking, 666 bool *done) 667 { 668 CURLcode result; 669 struct Curl_easy *data = conn->data; 670 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 671 curl_socket_t sockfd = conn->sock[sockindex]; 672 long timeout_ms; 673 int what; 674 675 /* check if the connection has already been established */ 676 if(ssl_connection_complete == connssl->state) { 677 *done = TRUE; 678 return CURLE_OK; 679 } 680 681 if(ssl_connect_1 == connssl->connecting_state) { 682 /* Find out how much more time we're allowed */ 683 timeout_ms = Curl_timeleft(data, NULL, TRUE); 684 685 if(timeout_ms < 0) { 686 /* no need to continue if time already is up */ 687 failf(data, "SSL connection timeout"); 688 return CURLE_OPERATION_TIMEDOUT; 689 } 690 691 result = polarssl_connect_step1(conn, sockindex); 692 if(result) 693 return result; 694 } 695 696 while(ssl_connect_2 == connssl->connecting_state || 697 ssl_connect_2_reading == connssl->connecting_state || 698 ssl_connect_2_writing == connssl->connecting_state) { 699 700 /* check allowed time left */ 701 timeout_ms = Curl_timeleft(data, NULL, TRUE); 702 703 if(timeout_ms < 0) { 704 /* no need to continue if time already is up */ 705 failf(data, "SSL connection timeout"); 706 return CURLE_OPERATION_TIMEDOUT; 707 } 708 709 /* if ssl is expecting something, check if it's available. */ 710 if(connssl->connecting_state == ssl_connect_2_reading || 711 connssl->connecting_state == ssl_connect_2_writing) { 712 713 curl_socket_t writefd = ssl_connect_2_writing== 714 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 715 curl_socket_t readfd = ssl_connect_2_reading== 716 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 717 718 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, 719 nonblocking?0:timeout_ms); 720 if(what < 0) { 721 /* fatal error */ 722 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); 723 return CURLE_SSL_CONNECT_ERROR; 724 } 725 else if(0 == what) { 726 if(nonblocking) { 727 *done = FALSE; 728 return CURLE_OK; 729 } 730 else { 731 /* timeout */ 732 failf(data, "SSL connection timeout"); 733 return CURLE_OPERATION_TIMEDOUT; 734 } 735 } 736 /* socket is readable or writable */ 737 } 738 739 /* Run transaction, and return to the caller if it failed or if 740 * this connection is part of a multi handle and this loop would 741 * execute again. This permits the owner of a multi handle to 742 * abort a connection attempt before step2 has completed while 743 * ensuring that a client using select() or epoll() will always 744 * have a valid fdset to wait on. 745 */ 746 result = polarssl_connect_step2(conn, sockindex); 747 if(result || (nonblocking && 748 (ssl_connect_2 == connssl->connecting_state || 749 ssl_connect_2_reading == connssl->connecting_state || 750 ssl_connect_2_writing == connssl->connecting_state))) 751 return result; 752 753 } /* repeat step2 until all transactions are done. */ 754 755 if(ssl_connect_3 == connssl->connecting_state) { 756 result = polarssl_connect_step3(conn, sockindex); 757 if(result) 758 return result; 759 } 760 761 if(ssl_connect_done == connssl->connecting_state) { 762 connssl->state = ssl_connection_complete; 763 conn->recv[sockindex] = polarssl_recv; 764 conn->send[sockindex] = polarssl_send; 765 *done = TRUE; 766 } 767 else 768 *done = FALSE; 769 770 /* Reset our connect state machine */ 771 connssl->connecting_state = ssl_connect_1; 772 773 return CURLE_OK; 774 } 775 776 CURLcode 777 Curl_polarssl_connect_nonblocking(struct connectdata *conn, 778 int sockindex, 779 bool *done) 780 { 781 return polarssl_connect_common(conn, sockindex, TRUE, done); 782 } 783 784 785 CURLcode 786 Curl_polarssl_connect(struct connectdata *conn, 787 int sockindex) 788 { 789 CURLcode result; 790 bool done = FALSE; 791 792 result = polarssl_connect_common(conn, sockindex, FALSE, &done); 793 if(result) 794 return result; 795 796 DEBUGASSERT(done); 797 798 return CURLE_OK; 799 } 800 801 /* 802 * return 0 error initializing SSL 803 * return 1 SSL initialized successfully 804 */ 805 int Curl_polarssl_init(void) 806 { 807 return Curl_polarsslthreadlock_thread_setup(); 808 } 809 810 void Curl_polarssl_cleanup(void) 811 { 812 (void)Curl_polarsslthreadlock_thread_cleanup(); 813 } 814 815 #endif /* USE_POLARSSL */ 816