mbedtls.c 40 KB

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