mbedtls.c 33 KB

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