Home | History | Annotate | Download | only in vtls
      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