1
0

mbedtls.c 37 KB

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