2
0

ustream-mbedtls.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. * ustream-ssl - library for SSL over ustream
  3. *
  4. * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
  5. *
  6. * Permission to use, copy, modify, and/or distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include <sys/types.h>
  19. #include <sys/random.h>
  20. #include <fcntl.h>
  21. #include <unistd.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "ustream-ssl.h"
  25. #include "ustream-internal.h"
  26. #include <psa/crypto.h>
  27. #include <mbedtls/debug.h>
  28. static void debug_cb(void *ctx_p, int level,
  29. const char *file, int line,
  30. const char *str)
  31. {
  32. struct ustream_ssl_ctx *ctx = ctx_p;
  33. const char *fstr;
  34. char buf[512];
  35. int len;
  36. if (!ctx->debug_cb)
  37. return;
  38. while ((fstr = strstr(file + 1, "library/")) != NULL)
  39. file = fstr;
  40. len = snprintf(buf, sizeof(buf), "%s:%04d: %s", file, line, str);
  41. if (len >= (int)sizeof(buf))
  42. len = (int)sizeof(buf) - 1;
  43. if (buf[len - 1] == '\n')
  44. buf[len - 1] = 0;
  45. ctx->debug_cb(ctx->debug_cb_priv, level, buf);
  46. }
  47. static int s_ustream_read(void *ctx, unsigned char *buf, size_t len)
  48. {
  49. struct ustream *s = ctx;
  50. char *sbuf;
  51. int slen;
  52. if (s->eof)
  53. return 0;
  54. sbuf = ustream_get_read_buf(s, &slen);
  55. if ((size_t) slen > len)
  56. slen = len;
  57. if (!slen)
  58. return MBEDTLS_ERR_SSL_WANT_READ;
  59. memcpy(buf, sbuf, slen);
  60. ustream_consume(s, slen);
  61. return slen;
  62. }
  63. static int s_ustream_write(void *ctx, const unsigned char *buf, size_t len)
  64. {
  65. struct ustream *s = ctx;
  66. int ret;
  67. ret = ustream_write(s, (const char *) buf, len, false);
  68. if (ret < 0 || s->write_error)
  69. return MBEDTLS_ERR_NET_SEND_FAILED;
  70. return ret;
  71. }
  72. static int s_fd_read(void *ctx, unsigned char *buf, size_t len)
  73. {
  74. struct uloop_fd *ufd = ctx;
  75. mbedtls_net_context net = {
  76. .fd = ufd->fd
  77. };
  78. return mbedtls_net_recv(&net, buf, len);
  79. }
  80. static int s_fd_write(void *ctx, const unsigned char *buf, size_t len)
  81. {
  82. struct uloop_fd *ufd = ctx;
  83. mbedtls_net_context net = {
  84. .fd = ufd->fd
  85. };
  86. return mbedtls_net_send(&net, buf, len);
  87. }
  88. __hidden void ustream_set_io(struct ustream_ssl *us)
  89. {
  90. if (us->conn)
  91. mbedtls_ssl_set_bio(us->ssl, us->conn, s_ustream_write, s_ustream_read, NULL);
  92. else
  93. mbedtls_ssl_set_bio(us->ssl, &us->fd, s_fd_write, s_fd_read, NULL);
  94. }
  95. static int _random(void *ctx, unsigned char *out, size_t len)
  96. {
  97. #ifdef linux
  98. if (getrandom(out, len, 0) != (ssize_t) len)
  99. return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  100. #else
  101. static FILE *f;
  102. if (!f)
  103. f = fopen("/dev/urandom", "r");
  104. if (fread(out, len, 1, f) != 1)
  105. return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  106. #endif
  107. return 0;
  108. }
  109. #define AES_GCM_CIPHERS(v) \
  110. MBEDTLS_TLS_##v##_WITH_AES_128_GCM_SHA256, \
  111. MBEDTLS_TLS_##v##_WITH_AES_256_GCM_SHA384
  112. #define AES_CBC_CIPHERS(v) \
  113. MBEDTLS_TLS_##v##_WITH_AES_128_CBC_SHA, \
  114. MBEDTLS_TLS_##v##_WITH_AES_256_CBC_SHA
  115. #define AES_CIPHERS(v) \
  116. AES_GCM_CIPHERS(v), \
  117. AES_CBC_CIPHERS(v)
  118. static const int default_ciphersuites_server[] =
  119. {
  120. #ifdef MBEDTLS_SSL_PROTO_TLS1_3
  121. MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
  122. MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
  123. MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
  124. MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
  125. MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
  126. #endif
  127. MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
  128. AES_GCM_CIPHERS(ECDHE_ECDSA),
  129. MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
  130. AES_GCM_CIPHERS(ECDHE_RSA),
  131. AES_CBC_CIPHERS(ECDHE_RSA),
  132. AES_CIPHERS(RSA),
  133. 0
  134. };
  135. static const int default_ciphersuites_client[] =
  136. {
  137. #ifdef MBEDTLS_SSL_PROTO_TLS1_3
  138. MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
  139. MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
  140. MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
  141. MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
  142. MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
  143. #endif
  144. MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
  145. AES_GCM_CIPHERS(ECDHE_ECDSA),
  146. MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
  147. AES_GCM_CIPHERS(ECDHE_RSA),
  148. MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
  149. AES_GCM_CIPHERS(DHE_RSA),
  150. AES_CBC_CIPHERS(ECDHE_ECDSA),
  151. AES_CBC_CIPHERS(ECDHE_RSA),
  152. AES_CBC_CIPHERS(DHE_RSA),
  153. /* Removed in Mbed TLS 3.0.0 */
  154. #ifdef MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
  155. MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
  156. #endif
  157. AES_CIPHERS(RSA),
  158. /* Removed in Mbed TLS 3.0.0 */
  159. #ifdef MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
  160. MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
  161. #endif
  162. 0
  163. };
  164. __hidden struct ustream_ssl_ctx *
  165. __ustream_ssl_context_new(bool server)
  166. {
  167. struct ustream_ssl_ctx *ctx;
  168. mbedtls_ssl_config *conf;
  169. int ep;
  170. #ifdef MBEDTLS_PSA_CRYPTO_C
  171. static bool psa_init;
  172. if (!psa_init && !psa_crypto_init())
  173. psa_init = true;
  174. #endif
  175. ctx = calloc(1, sizeof(*ctx));
  176. if (!ctx)
  177. return NULL;
  178. ctx->server = server;
  179. mbedtls_pk_init(&ctx->key);
  180. mbedtls_x509_crt_init(&ctx->cert);
  181. mbedtls_x509_crt_init(&ctx->ca_cert);
  182. #if defined(MBEDTLS_SSL_CACHE_C)
  183. mbedtls_ssl_cache_init(&ctx->cache);
  184. mbedtls_ssl_cache_set_timeout(&ctx->cache, 30 * 60);
  185. mbedtls_ssl_cache_set_max_entries(&ctx->cache, 5);
  186. #endif
  187. conf = &ctx->conf;
  188. mbedtls_ssl_config_init(conf);
  189. ep = server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT;
  190. mbedtls_ssl_config_defaults(conf, ep, MBEDTLS_SSL_TRANSPORT_STREAM,
  191. MBEDTLS_SSL_PRESET_DEFAULT);
  192. mbedtls_ssl_conf_rng(conf, _random, NULL);
  193. if (server) {
  194. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
  195. mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_server);
  196. mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3,
  197. MBEDTLS_SSL_MINOR_VERSION_3);
  198. } else {
  199. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
  200. mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_client);
  201. }
  202. #if defined(MBEDTLS_SSL_CACHE_C)
  203. mbedtls_ssl_conf_session_cache(conf, &ctx->cache,
  204. mbedtls_ssl_cache_get,
  205. mbedtls_ssl_cache_set);
  206. #endif
  207. return ctx;
  208. }
  209. static void ustream_ssl_update_own_cert(struct ustream_ssl_ctx *ctx)
  210. {
  211. if (!ctx->cert.version)
  212. return;
  213. if (mbedtls_pk_get_type(&ctx->key) == MBEDTLS_PK_NONE)
  214. return;
  215. mbedtls_ssl_conf_own_cert(&ctx->conf, &ctx->cert, &ctx->key);
  216. }
  217. __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
  218. {
  219. int ret;
  220. ret = mbedtls_x509_crt_parse_file(&ctx->ca_cert, file);
  221. if (ret)
  222. return -1;
  223. mbedtls_ssl_conf_ca_chain(&ctx->conf, &ctx->ca_cert, NULL);
  224. mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
  225. return 0;
  226. }
  227. __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
  228. {
  229. int ret;
  230. ret = mbedtls_x509_crt_parse_file(&ctx->cert, file);
  231. if (ret)
  232. return -1;
  233. ustream_ssl_update_own_cert(ctx);
  234. return 0;
  235. }
  236. __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file)
  237. {
  238. int ret;
  239. #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
  240. ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL, _random, NULL);
  241. #else
  242. ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL);
  243. #endif
  244. if (ret)
  245. return -1;
  246. ustream_ssl_update_own_cert(ctx);
  247. return 0;
  248. }
  249. __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers)
  250. {
  251. int *ciphersuites = NULL, *tmp, id;
  252. char *cipherstr, *p, *last, c;
  253. size_t len = 0;
  254. if (ciphers == NULL)
  255. return -1;
  256. cipherstr = strdup(ciphers);
  257. if (cipherstr == NULL)
  258. return -1;
  259. for (p = cipherstr, last = p;; p++) {
  260. if (*p == ':' || *p == 0) {
  261. c = *p;
  262. *p = 0;
  263. id = mbedtls_ssl_get_ciphersuite_id(last);
  264. if (id != 0) {
  265. tmp = realloc(ciphersuites, (len + 2) * sizeof(int));
  266. if (tmp == NULL) {
  267. free(ciphersuites);
  268. free(cipherstr);
  269. return -1;
  270. }
  271. ciphersuites = tmp;
  272. ciphersuites[len++] = id;
  273. ciphersuites[len] = 0;
  274. }
  275. if (c == 0)
  276. break;
  277. last = p + 1;
  278. }
  279. /*
  280. * mbedTLS expects cipher names with dashes while many sources elsewhere
  281. * like the Firefox wiki or Wireshark specify ciphers with underscores,
  282. * so simply convert all underscores to dashes to accept both notations.
  283. */
  284. else if (*p == '_') {
  285. *p = '-';
  286. }
  287. }
  288. free(cipherstr);
  289. if (len == 0)
  290. return -1;
  291. mbedtls_ssl_conf_ciphersuites(&ctx->conf, ciphersuites);
  292. free(ctx->ciphersuites);
  293. ctx->ciphersuites = ciphersuites;
  294. return 0;
  295. }
  296. __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require)
  297. {
  298. int mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
  299. if (!require)
  300. mode = MBEDTLS_SSL_VERIFY_NONE;
  301. /* force TLS 1.2 when not requiring validation for now */
  302. if (!require && !ctx->server)
  303. mbedtls_ssl_conf_max_version(&ctx->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
  304. MBEDTLS_SSL_MINOR_VERSION_3);
  305. mbedtls_ssl_conf_authmode(&ctx->conf, mode);
  306. return 0;
  307. }
  308. __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx)
  309. {
  310. free(ctx->session_data);
  311. #if defined(MBEDTLS_SSL_CACHE_C)
  312. mbedtls_ssl_cache_free(&ctx->cache);
  313. #endif
  314. mbedtls_pk_free(&ctx->key);
  315. mbedtls_x509_crt_free(&ctx->ca_cert);
  316. mbedtls_x509_crt_free(&ctx->cert);
  317. mbedtls_ssl_config_free(&ctx->conf);
  318. free(ctx->ciphersuites);
  319. free(ctx);
  320. }
  321. static void ustream_ssl_error(struct ustream_ssl *us, int ret)
  322. {
  323. us->error = ret;
  324. uloop_timeout_set(&us->error_timer, 0);
  325. }
  326. #ifdef MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET
  327. static void
  328. __ustream_ssl_save_session(struct ustream_ssl *us)
  329. {
  330. struct ustream_ssl_ctx *ctx = us->ctx;
  331. mbedtls_ssl_session sess;
  332. if (ctx->server)
  333. return;
  334. free(ctx->session_data);
  335. ctx->session_data = NULL;
  336. mbedtls_ssl_session_init(&sess);
  337. if (mbedtls_ssl_get_session(us->ssl, &sess) != 0)
  338. return;
  339. mbedtls_ssl_session_save(&sess, NULL, 0, &ctx->session_data_len);
  340. ctx->session_data = malloc(ctx->session_data_len);
  341. if (mbedtls_ssl_session_save(&sess, ctx->session_data, ctx->session_data_len,
  342. &ctx->session_data_len))
  343. ctx->session_data_len = 0;
  344. mbedtls_ssl_session_free(&sess);
  345. }
  346. #endif
  347. static int ssl_check_return(struct ustream_ssl *us, int ret)
  348. {
  349. switch(ret) {
  350. case MBEDTLS_ERR_SSL_WANT_READ:
  351. case MBEDTLS_ERR_SSL_WANT_WRITE:
  352. return U_SSL_PENDING;
  353. #ifdef MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET
  354. case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
  355. __ustream_ssl_save_session(us);
  356. return U_SSL_RETRY;
  357. #endif
  358. #ifdef MBEDTLS_ECP_RESTARTABLE
  359. case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
  360. return U_SSL_RETRY;
  361. #endif
  362. case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
  363. case MBEDTLS_ERR_NET_CONN_RESET:
  364. return 0;
  365. default:
  366. ustream_ssl_error(us, ret);
  367. return U_SSL_ERROR;
  368. }
  369. }
  370. static void ustream_ssl_verify_cert(struct ustream_ssl *us)
  371. {
  372. void *ssl = us->ssl;
  373. const char *msg = NULL;
  374. bool cn_mismatch;
  375. int r;
  376. r = mbedtls_ssl_get_verify_result(ssl);
  377. cn_mismatch = r & MBEDTLS_X509_BADCERT_CN_MISMATCH;
  378. r &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
  379. if (r & MBEDTLS_X509_BADCERT_EXPIRED)
  380. msg = "certificate has expired";
  381. else if (r & MBEDTLS_X509_BADCERT_REVOKED)
  382. msg = "certificate has been revoked";
  383. else if (r & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
  384. msg = "certificate is self-signed or not signed by a trusted CA";
  385. else
  386. msg = "unknown error";
  387. if (r) {
  388. if (us->notify_verify_error)
  389. us->notify_verify_error(us, r, msg);
  390. return;
  391. }
  392. if (!cn_mismatch)
  393. us->valid_cn = true;
  394. }
  395. __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
  396. {
  397. void *ssl = us->ssl;
  398. int r;
  399. do {
  400. r = mbedtls_ssl_handshake(ssl);
  401. if (r == 0) {
  402. ustream_ssl_verify_cert(us);
  403. return U_SSL_OK;
  404. }
  405. r = ssl_check_return(us, r);
  406. } while (r == U_SSL_RETRY);
  407. return r;
  408. }
  409. __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len)
  410. {
  411. void *ssl = us->ssl;
  412. int done = 0, ret = 0;
  413. while (done != len) {
  414. ret = mbedtls_ssl_write(ssl, (const unsigned char *) buf + done, len - done);
  415. if (ret < 0) {
  416. ret = ssl_check_return(us, ret);
  417. if (ret == U_SSL_RETRY)
  418. continue;
  419. if (ret == U_SSL_PENDING)
  420. return done;
  421. return -1;
  422. }
  423. done += ret;
  424. }
  425. return done;
  426. }
  427. __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len)
  428. {
  429. int ret;
  430. do {
  431. ret = mbedtls_ssl_read(us->ssl, (unsigned char *) buf, len);
  432. if (ret >= 0)
  433. return ret;
  434. ret = ssl_check_return(us, ret);
  435. } while (ret == U_SSL_RETRY);
  436. return ret;
  437. }
  438. __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level,
  439. ustream_ssl_debug_cb cb, void *cb_priv)
  440. {
  441. ctx->debug_cb = cb;
  442. ctx->debug_cb_priv = cb_priv;
  443. mbedtls_ssl_conf_dbg(&ctx->conf, debug_cb, ctx);
  444. #ifdef MBEDTLS_DEBUG_C
  445. mbedtls_debug_set_threshold(level);
  446. #endif
  447. }
  448. __hidden void *__ustream_ssl_session_new(struct ustream_ssl_ctx *ctx)
  449. {
  450. mbedtls_ssl_context *ssl;
  451. mbedtls_ssl_session sess;
  452. ssl = calloc(1, sizeof(*ssl));
  453. if (!ssl)
  454. return NULL;
  455. mbedtls_ssl_init(ssl);
  456. if (mbedtls_ssl_setup(ssl, &ctx->conf)) {
  457. free(ssl);
  458. return NULL;
  459. }
  460. if (!ctx->session_data_len)
  461. return ssl;
  462. mbedtls_ssl_session_init(&sess);
  463. if (mbedtls_ssl_session_load(&sess, ctx->session_data, ctx->session_data_len) == 0)
  464. mbedtls_ssl_set_session(ssl, &sess);
  465. return ssl;
  466. }
  467. __hidden void __ustream_ssl_session_free(struct ustream_ssl *us)
  468. {
  469. mbedtls_ssl_free(us->ssl);
  470. free(us->ssl);
  471. }