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/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