Annotation of embedaddon/curl/lib/vtls/mbedtls.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
                      9:  * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@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 "multiif.h"
                     58: #include "mbedtls_threadlock.h"
                     59: 
                     60: /* The last 3 #include files should be in this order */
                     61: #include "curl_printf.h"
                     62: #include "curl_memory.h"
                     63: #include "memdebug.h"
                     64: 
                     65: struct ssl_backend_data {
                     66:   mbedtls_ctr_drbg_context ctr_drbg;
                     67:   mbedtls_entropy_context entropy;
                     68:   mbedtls_ssl_context ssl;
                     69:   int server_fd;
                     70:   mbedtls_x509_crt cacert;
                     71:   mbedtls_x509_crt clicert;
                     72:   mbedtls_x509_crl crl;
                     73:   mbedtls_pk_context pk;
                     74:   mbedtls_ssl_config config;
                     75:   const char *protocols[3];
                     76: };
                     77: 
                     78: /* apply threading? */
                     79: #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
                     80: #define THREADING_SUPPORT
                     81: #endif
                     82: 
                     83: #if defined(THREADING_SUPPORT)
                     84: static mbedtls_entropy_context ts_entropy;
                     85: 
                     86: static int entropy_init_initialized = 0;
                     87: 
                     88: /* start of entropy_init_mutex() */
                     89: static void entropy_init_mutex(mbedtls_entropy_context *ctx)
                     90: {
                     91:   /* lock 0 = entropy_init_mutex() */
                     92:   Curl_mbedtlsthreadlock_lock_function(0);
                     93:   if(entropy_init_initialized == 0) {
                     94:     mbedtls_entropy_init(ctx);
                     95:     entropy_init_initialized = 1;
                     96:   }
                     97:   Curl_mbedtlsthreadlock_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_mbedtlsthreadlock_lock_function(1);
                    107:   ret = mbedtls_entropy_func(data, output, len);
                    108:   Curl_mbedtlsthreadlock_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 mbedTLS */
                    117: #undef MBEDTLS_DEBUG
                    118: 
                    119: #ifdef MBEDTLS_DEBUG
                    120: static void mbed_debug(void *context, int level, const char *f_name,
                    121:                        int line_nb, const char *line)
                    122: {
                    123:   struct Curl_easy *data = NULL;
                    124: 
                    125:   if(!context)
                    126:     return;
                    127: 
                    128:   data = (struct Curl_easy *)context;
                    129: 
                    130:   infof(data, "%s", line);
                    131:   (void) level;
                    132: }
                    133: #else
                    134: #endif
                    135: 
                    136: /* ALPN for http2? */
                    137: #ifdef USE_NGHTTP2
                    138: #  undef HAS_ALPN
                    139: #  ifdef MBEDTLS_SSL_ALPN
                    140: #    define HAS_ALPN
                    141: #  endif
                    142: #endif
                    143: 
                    144: 
                    145: /*
                    146:  *  profile
                    147:  */
                    148: static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
                    149: {
                    150:   /* Hashes from SHA-1 and above */
                    151:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) |
                    152:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) |
                    153:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) |
                    154:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
                    155:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
                    156:   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
                    157:   0xFFFFFFF, /* Any PK alg    */
                    158:   0xFFFFFFF, /* Any curve     */
                    159:   1024,      /* RSA min key len */
                    160: };
                    161: 
                    162: /* See https://tls.mbed.org/discussions/generic/
                    163:    howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
                    164: */
                    165: #define RSA_PUB_DER_MAX_BYTES   (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
                    166: #define ECP_PUB_DER_MAX_BYTES   (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
                    167: 
                    168: #define PUB_DER_MAX_BYTES   (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
                    169:                              RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
                    170: 
                    171: static Curl_recv mbed_recv;
                    172: static Curl_send mbed_send;
                    173: 
                    174: static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
                    175: {
                    176:   switch(version) {
                    177:     case CURL_SSLVERSION_TLSv1_0:
                    178:       *mbedver = MBEDTLS_SSL_MINOR_VERSION_1;
                    179:       return CURLE_OK;
                    180:     case CURL_SSLVERSION_TLSv1_1:
                    181:       *mbedver = MBEDTLS_SSL_MINOR_VERSION_2;
                    182:       return CURLE_OK;
                    183:     case CURL_SSLVERSION_TLSv1_2:
                    184:       *mbedver = MBEDTLS_SSL_MINOR_VERSION_3;
                    185:       return CURLE_OK;
                    186:     case CURL_SSLVERSION_TLSv1_3:
                    187:       break;
                    188:   }
                    189:   return CURLE_SSL_CONNECT_ERROR;
                    190: }
                    191: 
                    192: static CURLcode
                    193: set_ssl_version_min_max(struct connectdata *conn, int sockindex)
                    194: {
                    195:   struct Curl_easy *data = conn->data;
                    196:   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                    197:   struct ssl_backend_data *backend = connssl->backend;
                    198:   int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
                    199:   int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
                    200:   long ssl_version = SSL_CONN_CONFIG(version);
                    201:   long ssl_version_max = SSL_CONN_CONFIG(version_max);
                    202:   CURLcode result = CURLE_OK;
                    203: 
                    204:   switch(ssl_version) {
                    205:     case CURL_SSLVERSION_DEFAULT:
                    206:     case CURL_SSLVERSION_TLSv1:
                    207:       ssl_version = CURL_SSLVERSION_TLSv1_0;
                    208:       break;
                    209:   }
                    210: 
                    211:   switch(ssl_version_max) {
                    212:     case CURL_SSLVERSION_MAX_NONE:
                    213:     case CURL_SSLVERSION_MAX_DEFAULT:
                    214:       ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
                    215:       break;
                    216:   }
                    217: 
                    218:   result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version);
                    219:   if(result) {
                    220:     failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
                    221:     return result;
                    222:   }
                    223:   result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16);
                    224:   if(result) {
                    225:     failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
                    226:     return result;
                    227:   }
                    228: 
                    229:   mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                    230:                                mbedtls_ver_min);
                    231:   mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                    232:                                mbedtls_ver_max);
                    233: 
                    234:   return result;
                    235: }
                    236: 
                    237: static CURLcode
                    238: mbed_connect_step1(struct connectdata *conn,
                    239:                    int sockindex)
                    240: {
                    241:   struct Curl_easy *data = conn->data;
                    242:   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
                    243:   struct ssl_backend_data *backend = connssl->backend;
                    244:   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
                    245:   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
                    246:   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
                    247:   char * const ssl_cert = SSL_SET_OPTION(cert);
                    248:   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
                    249:   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
                    250:     conn->host.name;
                    251:   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
                    252:   int ret = -1;
                    253:   char errorbuf[128];
                    254:   errorbuf[0] = 0;
                    255: 
                    256:   /* mbedTLS only supports SSLv3 and TLSv1 */
                    257:   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
                    258:     failf(data, "mbedTLS does not support SSLv2");
                    259:     return CURLE_SSL_CONNECT_ERROR;
                    260:   }
                    261: 
                    262: #ifdef THREADING_SUPPORT
                    263:   entropy_init_mutex(&ts_entropy);
                    264:   mbedtls_ctr_drbg_init(&backend->ctr_drbg);
                    265: 
                    266:   ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
                    267:                               &ts_entropy, NULL, 0);
                    268:   if(ret) {
                    269: #ifdef MBEDTLS_ERROR_C
                    270:     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    271: #endif /* MBEDTLS_ERROR_C */
                    272:     failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
                    273:           -ret, errorbuf);
                    274:   }
                    275: #else
                    276:   mbedtls_entropy_init(&backend->entropy);
                    277:   mbedtls_ctr_drbg_init(&backend->ctr_drbg);
                    278: 
                    279:   ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
                    280:                               &backend->entropy, NULL, 0);
                    281:   if(ret) {
                    282: #ifdef MBEDTLS_ERROR_C
                    283:     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    284: #endif /* MBEDTLS_ERROR_C */
                    285:     failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
                    286:           -ret, errorbuf);
                    287:   }
                    288: #endif /* THREADING_SUPPORT */
                    289: 
                    290:   /* Load the trusted CA */
                    291:   mbedtls_x509_crt_init(&backend->cacert);
                    292: 
                    293:   if(ssl_cafile) {
                    294:     ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
                    295: 
                    296:     if(ret<0) {
                    297: #ifdef MBEDTLS_ERROR_C
                    298:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    299: #endif /* MBEDTLS_ERROR_C */
                    300:       failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
                    301:             ssl_cafile, -ret, errorbuf);
                    302: 
                    303:       if(verifypeer)
                    304:         return CURLE_SSL_CACERT_BADFILE;
                    305:     }
                    306:   }
                    307: 
                    308:   if(ssl_capath) {
                    309:     ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
                    310: 
                    311:     if(ret<0) {
                    312: #ifdef MBEDTLS_ERROR_C
                    313:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    314: #endif /* MBEDTLS_ERROR_C */
                    315:       failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
                    316:             ssl_capath, -ret, errorbuf);
                    317: 
                    318:       if(verifypeer)
                    319:         return CURLE_SSL_CACERT_BADFILE;
                    320:     }
                    321:   }
                    322: 
                    323:   /* Load the client certificate */
                    324:   mbedtls_x509_crt_init(&backend->clicert);
                    325: 
                    326:   if(ssl_cert) {
                    327:     ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
                    328: 
                    329:     if(ret) {
                    330: #ifdef MBEDTLS_ERROR_C
                    331:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    332: #endif /* MBEDTLS_ERROR_C */
                    333:       failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
                    334:             ssl_cert, -ret, errorbuf);
                    335: 
                    336:       return CURLE_SSL_CERTPROBLEM;
                    337:     }
                    338:   }
                    339: 
                    340:   /* Load the client private key */
                    341:   mbedtls_pk_init(&backend->pk);
                    342: 
                    343:   if(SSL_SET_OPTION(key)) {
                    344:     ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key),
                    345:                                    SSL_SET_OPTION(key_passwd));
                    346:     if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
                    347:                      mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
                    348:       ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
                    349: 
                    350:     if(ret) {
                    351: #ifdef MBEDTLS_ERROR_C
                    352:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    353: #endif /* MBEDTLS_ERROR_C */
                    354:       failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
                    355:             SSL_SET_OPTION(key), -ret, errorbuf);
                    356: 
                    357:       return CURLE_SSL_CERTPROBLEM;
                    358:     }
                    359:   }
                    360: 
                    361:   /* Load the CRL */
                    362:   mbedtls_x509_crl_init(&backend->crl);
                    363: 
                    364:   if(ssl_crlfile) {
                    365:     ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile);
                    366: 
                    367:     if(ret) {
                    368: #ifdef MBEDTLS_ERROR_C
                    369:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    370: #endif /* MBEDTLS_ERROR_C */
                    371:       failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
                    372:             ssl_crlfile, -ret, errorbuf);
                    373: 
                    374:       return CURLE_SSL_CRL_BADFILE;
                    375:     }
                    376:   }
                    377: 
                    378:   infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port);
                    379: 
                    380:   mbedtls_ssl_config_init(&backend->config);
                    381: 
                    382:   mbedtls_ssl_init(&backend->ssl);
                    383:   if(mbedtls_ssl_setup(&backend->ssl, &backend->config)) {
                    384:     failf(data, "mbedTLS: ssl_init failed");
                    385:     return CURLE_SSL_CONNECT_ERROR;
                    386:   }
                    387:   ret = mbedtls_ssl_config_defaults(&backend->config,
                    388:                                     MBEDTLS_SSL_IS_CLIENT,
                    389:                                     MBEDTLS_SSL_TRANSPORT_STREAM,
                    390:                                     MBEDTLS_SSL_PRESET_DEFAULT);
                    391:   if(ret) {
                    392:     failf(data, "mbedTLS: ssl_config failed");
                    393:     return CURLE_SSL_CONNECT_ERROR;
                    394:   }
                    395: 
                    396:   /* new profile with RSA min key len = 1024 ... */
                    397:   mbedtls_ssl_conf_cert_profile(&backend->config,
                    398:                                 &mbedtls_x509_crt_profile_fr);
                    399: 
                    400:   switch(SSL_CONN_CONFIG(version)) {
                    401:   case CURL_SSLVERSION_DEFAULT:
                    402:   case CURL_SSLVERSION_TLSv1:
                    403:     mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                    404:                                  MBEDTLS_SSL_MINOR_VERSION_1);
                    405:     infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
                    406:     break;
                    407:   case CURL_SSLVERSION_SSLv3:
                    408:     mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                    409:                                  MBEDTLS_SSL_MINOR_VERSION_0);
                    410:     mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                    411:                                  MBEDTLS_SSL_MINOR_VERSION_0);
                    412:     infof(data, "mbedTLS: Set SSL version to SSLv3\n");
                    413:     break;
                    414:   case CURL_SSLVERSION_TLSv1_0:
                    415:   case CURL_SSLVERSION_TLSv1_1:
                    416:   case CURL_SSLVERSION_TLSv1_2:
                    417:   case CURL_SSLVERSION_TLSv1_3:
                    418:     {
                    419:       CURLcode result = set_ssl_version_min_max(conn, sockindex);
                    420:       if(result != CURLE_OK)
                    421:         return result;
                    422:       break;
                    423:     }
                    424:   default:
                    425:     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
                    426:     return CURLE_SSL_CONNECT_ERROR;
                    427:   }
                    428: 
                    429:   mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
                    430: 
                    431:   mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
                    432:                        &backend->ctr_drbg);
                    433:   mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex],
                    434:                       mbedtls_net_send,
                    435:                       mbedtls_net_recv,
                    436:                       NULL /*  rev_timeout() */);
                    437: 
                    438:   mbedtls_ssl_conf_ciphersuites(&backend->config,
                    439:                                 mbedtls_ssl_list_ciphersuites());
                    440: 
                    441: #if defined(MBEDTLS_SSL_RENEGOTIATION)
                    442:   mbedtls_ssl_conf_renegotiation(&backend->config,
                    443:                                  MBEDTLS_SSL_RENEGOTIATION_ENABLED);
                    444: #endif
                    445: 
                    446: #if defined(MBEDTLS_SSL_SESSION_TICKETS)
                    447:   mbedtls_ssl_conf_session_tickets(&backend->config,
                    448:                                    MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
                    449: #endif
                    450: 
                    451:   /* Check if there's a cached ID we can/should use here! */
                    452:   if(SSL_SET_OPTION(primary.sessionid)) {
                    453:     void *old_session = NULL;
                    454: 
                    455:     Curl_ssl_sessionid_lock(conn);
                    456:     if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
                    457:       ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
                    458:       if(ret) {
                    459:         Curl_ssl_sessionid_unlock(conn);
                    460:         failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
                    461:         return CURLE_SSL_CONNECT_ERROR;
                    462:       }
                    463:       infof(data, "mbedTLS re-using session\n");
                    464:     }
                    465:     Curl_ssl_sessionid_unlock(conn);
                    466:   }
                    467: 
                    468:   mbedtls_ssl_conf_ca_chain(&backend->config,
                    469:                             &backend->cacert,
                    470:                             &backend->crl);
                    471: 
                    472:   if(SSL_SET_OPTION(key)) {
                    473:     mbedtls_ssl_conf_own_cert(&backend->config,
                    474:                               &backend->clicert, &backend->pk);
                    475:   }
                    476:   if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) {
                    477:     /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
                    478:        the name to set in the SNI extension. So even if curl connects to a
                    479:        host specified as an IP address, this function must be used. */
                    480:     failf(data, "couldn't set hostname in mbedTLS");
                    481:     return CURLE_SSL_CONNECT_ERROR;
                    482:   }
                    483: 
                    484: #ifdef HAS_ALPN
                    485:   if(conn->bits.tls_enable_alpn) {
                    486:     const char **p = &backend->protocols[0];
                    487: #ifdef USE_NGHTTP2
                    488:     if(data->set.httpversion >= CURL_HTTP_VERSION_2)
                    489:       *p++ = NGHTTP2_PROTO_VERSION_ID;
                    490: #endif
                    491:     *p++ = ALPN_HTTP_1_1;
                    492:     *p = NULL;
                    493:     /* this function doesn't clone the protocols array, which is why we need
                    494:        to keep it around */
                    495:     if(mbedtls_ssl_conf_alpn_protocols(&backend->config,
                    496:                                        &backend->protocols[0])) {
                    497:       failf(data, "Failed setting ALPN protocols");
                    498:       return CURLE_SSL_CONNECT_ERROR;
                    499:     }
                    500:     for(p = &backend->protocols[0]; *p; ++p)
                    501:       infof(data, "ALPN, offering %s\n", *p);
                    502:   }
                    503: #endif
                    504: 
                    505: #ifdef MBEDTLS_DEBUG
                    506:   /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
                    507:   mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
                    508:   /* - 0 No debug
                    509:    * - 1 Error
                    510:    * - 2 State change
                    511:    * - 3 Informational
                    512:    * - 4 Verbose
                    513:    */
                    514:   mbedtls_debug_set_threshold(4);
                    515: #endif
                    516: 
                    517:   /* give application a chance to interfere with mbedTLS set up. */
                    518:   if(data->set.ssl.fsslctx) {
                    519:     ret = (*data->set.ssl.fsslctx)(data, &backend->config,
                    520:                                    data->set.ssl.fsslctxp);
                    521:     if(ret) {
                    522:       failf(data, "error signaled by ssl ctx callback");
                    523:       return ret;
                    524:     }
                    525:   }
                    526: 
                    527:   connssl->connecting_state = ssl_connect_2;
                    528: 
                    529:   return CURLE_OK;
                    530: }
                    531: 
                    532: static CURLcode
                    533: mbed_connect_step2(struct connectdata *conn,
                    534:                    int sockindex)
                    535: {
                    536:   int ret;
                    537:   struct Curl_easy *data = conn->data;
                    538:   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
                    539:   struct ssl_backend_data *backend = connssl->backend;
                    540:   const mbedtls_x509_crt *peercert;
                    541:   const char * const pinnedpubkey = SSL_IS_PROXY() ?
                    542:     data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
                    543:     data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
                    544: 
                    545:   conn->recv[sockindex] = mbed_recv;
                    546:   conn->send[sockindex] = mbed_send;
                    547: 
                    548:   ret = mbedtls_ssl_handshake(&backend->ssl);
                    549: 
                    550:   if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
                    551:     connssl->connecting_state = ssl_connect_2_reading;
                    552:     return CURLE_OK;
                    553:   }
                    554:   else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
                    555:     connssl->connecting_state = ssl_connect_2_writing;
                    556:     return CURLE_OK;
                    557:   }
                    558:   else if(ret) {
                    559:     char errorbuf[128];
                    560:     errorbuf[0] = 0;
                    561: #ifdef MBEDTLS_ERROR_C
                    562:     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    563: #endif /* MBEDTLS_ERROR_C */
                    564:     failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
                    565:           -ret, errorbuf);
                    566:     return CURLE_SSL_CONNECT_ERROR;
                    567:   }
                    568: 
                    569:   infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
                    570:         mbedtls_ssl_get_ciphersuite(&backend->ssl)
                    571:     );
                    572: 
                    573:   ret = mbedtls_ssl_get_verify_result(&backend->ssl);
                    574: 
                    575:   if(!SSL_CONN_CONFIG(verifyhost))
                    576:     /* Ignore hostname errors if verifyhost is disabled */
                    577:     ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
                    578: 
                    579:   if(ret && SSL_CONN_CONFIG(verifypeer)) {
                    580:     if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
                    581:       failf(data, "Cert verify failed: BADCERT_EXPIRED");
                    582: 
                    583:     else if(ret & MBEDTLS_X509_BADCERT_REVOKED)
                    584:       failf(data, "Cert verify failed: BADCERT_REVOKED");
                    585: 
                    586:     else if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
                    587:       failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
                    588: 
                    589:     else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
                    590:       failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
                    591: 
                    592:     else if(ret & MBEDTLS_X509_BADCERT_FUTURE)
                    593:       failf(data, "Cert verify failed: BADCERT_FUTURE");
                    594: 
                    595:     return CURLE_PEER_FAILED_VERIFICATION;
                    596:   }
                    597: 
                    598:   peercert = mbedtls_ssl_get_peer_cert(&backend->ssl);
                    599: 
                    600:   if(peercert && data->set.verbose) {
                    601:     const size_t bufsize = 16384;
                    602:     char *buffer = malloc(bufsize);
                    603: 
                    604:     if(!buffer)
                    605:       return CURLE_OUT_OF_MEMORY;
                    606: 
                    607:     if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0)
                    608:       infof(data, "Dumping cert info:\n%s\n", buffer);
                    609:     else
                    610:       infof(data, "Unable to dump certificate information.\n");
                    611: 
                    612:     free(buffer);
                    613:   }
                    614: 
                    615:   if(pinnedpubkey) {
                    616:     int size;
                    617:     CURLcode result;
                    618:     mbedtls_x509_crt *p;
                    619:     unsigned char pubkey[PUB_DER_MAX_BYTES];
                    620: 
                    621:     if(!peercert || !peercert->raw.p || !peercert->raw.len) {
                    622:       failf(data, "Failed due to missing peer certificate");
                    623:       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
                    624:     }
                    625: 
                    626:     p = calloc(1, sizeof(*p));
                    627: 
                    628:     if(!p)
                    629:       return CURLE_OUT_OF_MEMORY;
                    630: 
                    631:     mbedtls_x509_crt_init(p);
                    632: 
                    633:     /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
                    634:        needs a non-const key, for now.
                    635:        https://github.com/ARMmbed/mbedtls/issues/396 */
                    636:     if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
                    637:       failf(data, "Failed copying peer certificate");
                    638:       mbedtls_x509_crt_free(p);
                    639:       free(p);
                    640:       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
                    641:     }
                    642: 
                    643:     size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
                    644: 
                    645:     if(size <= 0) {
                    646:       failf(data, "Failed copying public key from peer certificate");
                    647:       mbedtls_x509_crt_free(p);
                    648:       free(p);
                    649:       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
                    650:     }
                    651: 
                    652:     /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
                    653:     result = Curl_pin_peer_pubkey(data,
                    654:                                   pinnedpubkey,
                    655:                                   &pubkey[PUB_DER_MAX_BYTES - size], size);
                    656:     if(result) {
                    657:       mbedtls_x509_crt_free(p);
                    658:       free(p);
                    659:       return result;
                    660:     }
                    661: 
                    662:     mbedtls_x509_crt_free(p);
                    663:     free(p);
                    664:   }
                    665: 
                    666: #ifdef HAS_ALPN
                    667:   if(conn->bits.tls_enable_alpn) {
                    668:     const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
                    669: 
                    670:     if(next_protocol) {
                    671:       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
                    672: #ifdef USE_NGHTTP2
                    673:       if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
                    674:                   NGHTTP2_PROTO_VERSION_ID_LEN) &&
                    675:          !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) {
                    676:         conn->negnpn = CURL_HTTP_VERSION_2;
                    677:       }
                    678:       else
                    679: #endif
                    680:         if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
                    681:            !next_protocol[ALPN_HTTP_1_1_LENGTH]) {
                    682:           conn->negnpn = CURL_HTTP_VERSION_1_1;
                    683:         }
                    684:     }
                    685:     else {
                    686:       infof(data, "ALPN, server did not agree to a protocol\n");
                    687:     }
                    688:     Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
                    689:                         BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
                    690:   }
                    691: #endif
                    692: 
                    693:   connssl->connecting_state = ssl_connect_3;
                    694:   infof(data, "SSL connected\n");
                    695: 
                    696:   return CURLE_OK;
                    697: }
                    698: 
                    699: static CURLcode
                    700: mbed_connect_step3(struct connectdata *conn,
                    701:                    int sockindex)
                    702: {
                    703:   CURLcode retcode = CURLE_OK;
                    704:   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                    705:   struct ssl_backend_data *backend = connssl->backend;
                    706:   struct Curl_easy *data = conn->data;
                    707: 
                    708:   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
                    709: 
                    710:   if(SSL_SET_OPTION(primary.sessionid)) {
                    711:     int ret;
                    712:     mbedtls_ssl_session *our_ssl_sessionid;
                    713:     void *old_ssl_sessionid = NULL;
                    714: 
                    715:     our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
                    716:     if(!our_ssl_sessionid)
                    717:       return CURLE_OUT_OF_MEMORY;
                    718: 
                    719:     mbedtls_ssl_session_init(our_ssl_sessionid);
                    720: 
                    721:     ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid);
                    722:     if(ret) {
                    723:       if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
                    724:         mbedtls_ssl_session_free(our_ssl_sessionid);
                    725:       free(our_ssl_sessionid);
                    726:       failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
                    727:       return CURLE_SSL_CONNECT_ERROR;
                    728:     }
                    729: 
                    730:     /* If there's already a matching session in the cache, delete it */
                    731:     Curl_ssl_sessionid_lock(conn);
                    732:     if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
                    733:       Curl_ssl_delsessionid(conn, old_ssl_sessionid);
                    734: 
                    735:     retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
                    736:     Curl_ssl_sessionid_unlock(conn);
                    737:     if(retcode) {
                    738:       mbedtls_ssl_session_free(our_ssl_sessionid);
                    739:       free(our_ssl_sessionid);
                    740:       failf(data, "failed to store ssl session");
                    741:       return retcode;
                    742:     }
                    743:   }
                    744: 
                    745:   connssl->connecting_state = ssl_connect_done;
                    746: 
                    747:   return CURLE_OK;
                    748: }
                    749: 
                    750: static ssize_t mbed_send(struct connectdata *conn, int sockindex,
                    751:                          const void *mem, size_t len,
                    752:                          CURLcode *curlcode)
                    753: {
                    754:   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                    755:   struct ssl_backend_data *backend = connssl->backend;
                    756:   int ret = -1;
                    757: 
                    758:   ret = mbedtls_ssl_write(&backend->ssl,
                    759:                           (unsigned char *)mem, len);
                    760: 
                    761:   if(ret < 0) {
                    762:     *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
                    763:       CURLE_AGAIN : CURLE_SEND_ERROR;
                    764:     ret = -1;
                    765:   }
                    766: 
                    767:   return ret;
                    768: }
                    769: 
                    770: static void Curl_mbedtls_close_all(struct Curl_easy *data)
                    771: {
                    772:   (void)data;
                    773: }
                    774: 
                    775: static void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
                    776: {
                    777:   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                    778:   struct ssl_backend_data *backend = connssl->backend;
                    779:   mbedtls_pk_free(&backend->pk);
                    780:   mbedtls_x509_crt_free(&backend->clicert);
                    781:   mbedtls_x509_crt_free(&backend->cacert);
                    782:   mbedtls_x509_crl_free(&backend->crl);
                    783:   mbedtls_ssl_config_free(&backend->config);
                    784:   mbedtls_ssl_free(&backend->ssl);
                    785:   mbedtls_ctr_drbg_free(&backend->ctr_drbg);
                    786: #ifndef THREADING_SUPPORT
                    787:   mbedtls_entropy_free(&backend->entropy);
                    788: #endif /* THREADING_SUPPORT */
                    789: }
                    790: 
                    791: static ssize_t mbed_recv(struct connectdata *conn, int num,
                    792:                          char *buf, size_t buffersize,
                    793:                          CURLcode *curlcode)
                    794: {
                    795:   struct ssl_connect_data *connssl = &conn->ssl[num];
                    796:   struct ssl_backend_data *backend = connssl->backend;
                    797:   int ret = -1;
                    798:   ssize_t len = -1;
                    799: 
                    800:   memset(buf, 0, buffersize);
                    801:   ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
                    802:                          buffersize);
                    803: 
                    804:   if(ret <= 0) {
                    805:     if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
                    806:       return 0;
                    807: 
                    808:     *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ?
                    809:       CURLE_AGAIN : CURLE_RECV_ERROR;
                    810:     return -1;
                    811:   }
                    812: 
                    813:   len = ret;
                    814: 
                    815:   return len;
                    816: }
                    817: 
                    818: static void Curl_mbedtls_session_free(void *ptr)
                    819: {
                    820:   mbedtls_ssl_session_free(ptr);
                    821:   free(ptr);
                    822: }
                    823: 
                    824: static size_t Curl_mbedtls_version(char *buffer, size_t size)
                    825: {
                    826: #ifdef MBEDTLS_VERSION_C
                    827:   /* if mbedtls_version_get_number() is available it is better */
                    828:   unsigned int version = mbedtls_version_get_number();
                    829:   return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
                    830:                    (version>>16)&0xff, (version>>8)&0xff);
                    831: #else
                    832:   return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING);
                    833: #endif
                    834: }
                    835: 
                    836: static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
                    837:                                     unsigned char *entropy, size_t length)
                    838: {
                    839: #if defined(MBEDTLS_CTR_DRBG_C)
                    840:   int ret = -1;
                    841:   char errorbuf[128];
                    842:   mbedtls_entropy_context ctr_entropy;
                    843:   mbedtls_ctr_drbg_context ctr_drbg;
                    844:   mbedtls_entropy_init(&ctr_entropy);
                    845:   mbedtls_ctr_drbg_init(&ctr_drbg);
                    846:   errorbuf[0] = 0;
                    847: 
                    848:   ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
                    849:                               &ctr_entropy, NULL, 0);
                    850: 
                    851:   if(ret) {
                    852: #ifdef MBEDTLS_ERROR_C
                    853:     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    854: #endif /* MBEDTLS_ERROR_C */
                    855:     failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
                    856:           -ret, errorbuf);
                    857:   }
                    858:   else {
                    859:     ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
                    860: 
                    861:     if(ret) {
                    862: #ifdef MBEDTLS_ERROR_C
                    863:       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
                    864: #endif /* MBEDTLS_ERROR_C */
                    865:       failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
                    866:             -ret, errorbuf);
                    867:     }
                    868:   }
                    869: 
                    870:   mbedtls_ctr_drbg_free(&ctr_drbg);
                    871:   mbedtls_entropy_free(&ctr_entropy);
                    872: 
                    873:   return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
                    874: #elif defined(MBEDTLS_HAVEGE_C)
                    875:   mbedtls_havege_state hs;
                    876:   mbedtls_havege_init(&hs);
                    877:   mbedtls_havege_random(&hs, entropy, length);
                    878:   mbedtls_havege_free(&hs);
                    879:   return CURLE_OK;
                    880: #else
                    881:   return CURLE_NOT_BUILT_IN;
                    882: #endif
                    883: }
                    884: 
                    885: static CURLcode
                    886: mbed_connect_common(struct connectdata *conn,
                    887:                     int sockindex,
                    888:                     bool nonblocking,
                    889:                     bool *done)
                    890: {
                    891:   CURLcode retcode;
                    892:   struct Curl_easy *data = conn->data;
                    893:   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                    894:   curl_socket_t sockfd = conn->sock[sockindex];
                    895:   timediff_t timeout_ms;
                    896:   int what;
                    897: 
                    898:   /* check if the connection has already been established */
                    899:   if(ssl_connection_complete == connssl->state) {
                    900:     *done = TRUE;
                    901:     return CURLE_OK;
                    902:   }
                    903: 
                    904:   if(ssl_connect_1 == connssl->connecting_state) {
                    905:     /* Find out how much more time we're allowed */
                    906:     timeout_ms = Curl_timeleft(data, NULL, TRUE);
                    907: 
                    908:     if(timeout_ms < 0) {
                    909:       /* no need to continue if time already is up */
                    910:       failf(data, "SSL connection timeout");
                    911:       return CURLE_OPERATION_TIMEDOUT;
                    912:     }
                    913:     retcode = mbed_connect_step1(conn, sockindex);
                    914:     if(retcode)
                    915:       return retcode;
                    916:   }
                    917: 
                    918:   while(ssl_connect_2 == connssl->connecting_state ||
                    919:         ssl_connect_2_reading == connssl->connecting_state ||
                    920:         ssl_connect_2_writing == connssl->connecting_state) {
                    921: 
                    922:     /* check allowed time left */
                    923:     timeout_ms = Curl_timeleft(data, NULL, TRUE);
                    924: 
                    925:     if(timeout_ms < 0) {
                    926:       /* no need to continue if time already is up */
                    927:       failf(data, "SSL connection timeout");
                    928:       return CURLE_OPERATION_TIMEDOUT;
                    929:     }
                    930: 
                    931:     /* if ssl is expecting something, check if it's available. */
                    932:     if(connssl->connecting_state == ssl_connect_2_reading
                    933:        || connssl->connecting_state == ssl_connect_2_writing) {
                    934: 
                    935:       curl_socket_t writefd = ssl_connect_2_writing ==
                    936:         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
                    937:       curl_socket_t readfd = ssl_connect_2_reading ==
                    938:         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
                    939: 
                    940:       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
                    941:                                nonblocking ? 0 : (time_t)timeout_ms);
                    942:       if(what < 0) {
                    943:         /* fatal error */
                    944:         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
                    945:         return CURLE_SSL_CONNECT_ERROR;
                    946:       }
                    947:       else if(0 == what) {
                    948:         if(nonblocking) {
                    949:           *done = FALSE;
                    950:           return CURLE_OK;
                    951:         }
                    952:         else {
                    953:           /* timeout */
                    954:           failf(data, "SSL connection timeout");
                    955:           return CURLE_OPERATION_TIMEDOUT;
                    956:         }
                    957:       }
                    958:       /* socket is readable or writable */
                    959:     }
                    960: 
                    961:     /* Run transaction, and return to the caller if it failed or if
                    962:      * this connection is part of a multi handle and this loop would
                    963:      * execute again. This permits the owner of a multi handle to
                    964:      * abort a connection attempt before step2 has completed while
                    965:      * ensuring that a client using select() or epoll() will always
                    966:      * have a valid fdset to wait on.
                    967:      */
                    968:     retcode = mbed_connect_step2(conn, sockindex);
                    969:     if(retcode || (nonblocking &&
                    970:                    (ssl_connect_2 == connssl->connecting_state ||
                    971:                     ssl_connect_2_reading == connssl->connecting_state ||
                    972:                     ssl_connect_2_writing == connssl->connecting_state)))
                    973:       return retcode;
                    974: 
                    975:   } /* repeat step2 until all transactions are done. */
                    976: 
                    977:   if(ssl_connect_3 == connssl->connecting_state) {
                    978:     retcode = mbed_connect_step3(conn, sockindex);
                    979:     if(retcode)
                    980:       return retcode;
                    981:   }
                    982: 
                    983:   if(ssl_connect_done == connssl->connecting_state) {
                    984:     connssl->state = ssl_connection_complete;
                    985:     conn->recv[sockindex] = mbed_recv;
                    986:     conn->send[sockindex] = mbed_send;
                    987:     *done = TRUE;
                    988:   }
                    989:   else
                    990:     *done = FALSE;
                    991: 
                    992:   /* Reset our connect state machine */
                    993:   connssl->connecting_state = ssl_connect_1;
                    994: 
                    995:   return CURLE_OK;
                    996: }
                    997: 
                    998: static CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
                    999:                                                  int sockindex, bool *done)
                   1000: {
                   1001:   return mbed_connect_common(conn, sockindex, TRUE, done);
                   1002: }
                   1003: 
                   1004: 
                   1005: static CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex)
                   1006: {
                   1007:   CURLcode retcode;
                   1008:   bool done = FALSE;
                   1009: 
                   1010:   retcode = mbed_connect_common(conn, sockindex, FALSE, &done);
                   1011:   if(retcode)
                   1012:     return retcode;
                   1013: 
                   1014:   DEBUGASSERT(done);
                   1015: 
                   1016:   return CURLE_OK;
                   1017: }
                   1018: 
                   1019: /*
                   1020:  * return 0 error initializing SSL
                   1021:  * return 1 SSL initialized successfully
                   1022:  */
                   1023: static int Curl_mbedtls_init(void)
                   1024: {
                   1025:   return Curl_mbedtlsthreadlock_thread_setup();
                   1026: }
                   1027: 
                   1028: static void Curl_mbedtls_cleanup(void)
                   1029: {
                   1030:   (void)Curl_mbedtlsthreadlock_thread_cleanup();
                   1031: }
                   1032: 
                   1033: static bool Curl_mbedtls_data_pending(const struct connectdata *conn,
                   1034:                                       int sockindex)
                   1035: {
                   1036:   const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
                   1037:   struct ssl_backend_data *backend = connssl->backend;
                   1038:   return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
                   1039: }
                   1040: 
                   1041: static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input,
                   1042:                                     size_t inputlen,
                   1043:                                     unsigned char *sha256sum,
                   1044:                                     size_t sha256len UNUSED_PARAM)
                   1045: {
                   1046:   (void)sha256len;
                   1047: #if MBEDTLS_VERSION_NUMBER < 0x02070000
                   1048:   mbedtls_sha256(input, inputlen, sha256sum, 0);
                   1049: #else
                   1050:   /* returns 0 on success, otherwise failure */
                   1051:   if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0)
                   1052:     return CURLE_BAD_FUNCTION_ARGUMENT;
                   1053: #endif
                   1054:   return CURLE_OK;
                   1055: }
                   1056: 
                   1057: static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl,
                   1058:                                         CURLINFO info UNUSED_PARAM)
                   1059: {
                   1060:   struct ssl_backend_data *backend = connssl->backend;
                   1061:   (void)info;
                   1062:   return &backend->ssl;
                   1063: }
                   1064: 
                   1065: const struct Curl_ssl Curl_ssl_mbedtls = {
                   1066:   { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
                   1067: 
                   1068:   SSLSUPP_CA_PATH |
                   1069:   SSLSUPP_PINNEDPUBKEY |
                   1070:   SSLSUPP_SSL_CTX,
                   1071: 
                   1072:   sizeof(struct ssl_backend_data),
                   1073: 
                   1074:   Curl_mbedtls_init,                /* init */
                   1075:   Curl_mbedtls_cleanup,             /* cleanup */
                   1076:   Curl_mbedtls_version,             /* version */
                   1077:   Curl_none_check_cxn,              /* check_cxn */
                   1078:   Curl_none_shutdown,               /* shutdown */
                   1079:   Curl_mbedtls_data_pending,        /* data_pending */
                   1080:   Curl_mbedtls_random,              /* random */
                   1081:   Curl_none_cert_status_request,    /* cert_status_request */
                   1082:   Curl_mbedtls_connect,             /* connect */
                   1083:   Curl_mbedtls_connect_nonblocking, /* connect_nonblocking */
                   1084:   Curl_mbedtls_get_internals,       /* get_internals */
                   1085:   Curl_mbedtls_close,               /* close_one */
                   1086:   Curl_mbedtls_close_all,           /* close_all */
                   1087:   Curl_mbedtls_session_free,        /* session_free */
                   1088:   Curl_none_set_engine,             /* set_engine */
                   1089:   Curl_none_set_engine_default,     /* set_engine_default */
                   1090:   Curl_none_engines_list,           /* engines_list */
                   1091:   Curl_none_false_start,            /* false_start */
                   1092:   Curl_none_md5sum,                 /* md5sum */
                   1093:   Curl_mbedtls_sha256sum            /* sha256sum */
                   1094: };
                   1095: 
                   1096: #endif /* USE_MBEDTLS */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>