File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / vtls / mbedtls.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>