diff options
Diffstat (limited to 'thirdparty/libwebsockets/tls/tls.c')
-rw-r--r-- | thirdparty/libwebsockets/tls/tls.c | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/thirdparty/libwebsockets/tls/tls.c b/thirdparty/libwebsockets/tls/tls.c deleted file mode 100644 index 92b7c5593c..0000000000 --- a/thirdparty/libwebsockets/tls/tls.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -/* - * fakes POLLIN on all tls guys with buffered rx - * - * returns nonzero if any tls guys had POLLIN faked - */ - -int -lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt) -{ - struct lws *wsi, *wsi_next; - int ret = 0; - - wsi = pt->tls.pending_read_list; - while (wsi && wsi->position_in_fds_table != LWS_NO_FDS_POS) { - wsi_next = wsi->tls.pending_read_list_next; - pt->fds[wsi->position_in_fds_table].revents |= - pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN; - ret |= pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN; - - wsi = wsi_next; - } - - return !!ret; -} - -void -__lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - if (!wsi->tls.pending_read_list_prev && - !wsi->tls.pending_read_list_next && - pt->tls.pending_read_list != wsi) - /* we are not on the list */ - return; - - /* point previous guy's next to our next */ - if (!wsi->tls.pending_read_list_prev) - pt->tls.pending_read_list = wsi->tls.pending_read_list_next; - else - wsi->tls.pending_read_list_prev->tls.pending_read_list_next = - wsi->tls.pending_read_list_next; - - /* point next guy's previous to our previous */ - if (wsi->tls.pending_read_list_next) - wsi->tls.pending_read_list_next->tls.pending_read_list_prev = - wsi->tls.pending_read_list_prev; - - wsi->tls.pending_read_list_prev = NULL; - wsi->tls.pending_read_list_next = NULL; -} - -void -lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - __lws_ssl_remove_wsi_from_buffered_list(wsi); - lws_pt_unlock(pt); -} - -#if defined(LWS_WITH_ESP32) -int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf, - lws_filepos_t *amount) -{ - nvs_handle nvh; - size_t s; - int n = 0; - - ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); - if (nvs_get_blob(nvh, filename, NULL, &s) != ESP_OK) { - n = 1; - goto bail; - } - *buf = lws_malloc(s + 1, "alloc_file"); - if (!*buf) { - n = 2; - goto bail; - } - if (nvs_get_blob(nvh, filename, (char *)*buf, &s) != ESP_OK) { - lws_free(*buf); - n = 1; - goto bail; - } - - *amount = s; - (*buf)[s] = '\0'; - - lwsl_notice("%s: nvs: read %s, %d bytes\n", __func__, filename, (int)s); - -bail: - nvs_close(nvh); - - return n; -} -#else -int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf, - lws_filepos_t *amount) -{ - FILE *f; - size_t s; - int n = 0; - - f = fopen(filename, "rb"); - if (f == NULL) { - n = 1; - goto bail; - } - - if (fseek(f, 0, SEEK_END) != 0) { - n = 1; - goto bail; - } - - s = ftell(f); - if (s == (size_t)-1) { - n = 1; - goto bail; - } - - if (fseek(f, 0, SEEK_SET) != 0) { - n = 1; - goto bail; - } - - *buf = lws_malloc(s, "alloc_file"); - if (!*buf) { - n = 2; - goto bail; - } - - if (fread(*buf, s, 1, f) != 1) { - lws_free(*buf); - n = 1; - goto bail; - } - - *amount = s; - -bail: - if (f) - fclose(f); - - return n; - -} -#endif - -int -lws_tls_alloc_pem_to_der_file(struct lws_context *context, const char *filename, - const char *inbuf, lws_filepos_t inlen, - uint8_t **buf, lws_filepos_t *amount) -{ - const uint8_t *pem, *p, *end; - uint8_t *q; - lws_filepos_t len; - int n; - - if (filename) { - n = alloc_file(context, filename, (uint8_t **)&pem, &len); - if (n) - return n; - } else { - pem = (const uint8_t *)inbuf; - len = inlen; - } - - /* trim the first line */ - - p = pem; - end = p + len; - if (strncmp((char *)p, "-----", 5)) - goto bail; - p += 5; - while (p < end && *p != '\n' && *p != '-') - p++; - - if (*p != '-') - goto bail; - - while (p < end && *p != '\n') - p++; - - if (p >= end) - goto bail; - - p++; - - /* trim the last line */ - - q = (uint8_t *)end - 2; - - while (q > pem && *q != '\n') - q--; - - if (*q != '\n') - goto bail; - - *q = '\0'; - - *amount = lws_b64_decode_string((char *)p, (char *)pem, - (int)(long long)len); - *buf = (uint8_t *)pem; - - return 0; - -bail: - lws_free((uint8_t *)pem); - - return 4; -} - -int -lws_tls_check_cert_lifetime(struct lws_vhost *v) -{ - union lws_tls_cert_info_results ir; - time_t now = (time_t)lws_now_secs(), life = 0; - struct lws_acme_cert_aging_args caa; - int n; - - if (v->tls.ssl_ctx && !v->tls.skipped_certs) { - - if (now < 1464083026) /* May 2016 */ - /* our clock is wrong and we can't judge the certs */ - return -1; - - n = lws_tls_vhost_cert_info(v, LWS_TLS_CERT_INFO_VALIDITY_TO, &ir, 0); - if (n) - return 1; - - life = (ir.time - now) / (24 * 3600); - lwsl_notice(" vhost %s: cert expiry: %dd\n", v->name, (int)life); - } else - lwsl_notice(" vhost %s: no cert\n", v->name); - - memset(&caa, 0, sizeof(caa)); - caa.vh = v; - lws_broadcast(v->context, LWS_CALLBACK_VHOST_CERT_AGING, (void *)&caa, - (size_t)(ssize_t)life); - - return 0; -} - -int -lws_tls_check_all_cert_lifetimes(struct lws_context *context) -{ - struct lws_vhost *v = context->vhost_list; - - while (v) { - if (lws_tls_check_cert_lifetime(v) < 0) - return -1; - v = v->vhost_next; - } - - return 0; -} -#if !defined(LWS_WITH_ESP32) && !defined(LWS_PLAT_OPTEE) -static int -lws_tls_extant(const char *name) -{ - /* it exists if we can open it... */ - int fd = open(name, O_RDONLY), n; - char buf[1]; - - if (fd < 0) - return 1; - - /* and we can read at least one byte out of it */ - n = read(fd, buf, 1); - close(fd); - - return n != 1; -} -#endif -/* - * Returns 0 if the filepath "name" exists and can be read from. - * - * In addition, if "name".upd exists, backup "name" to "name.old.1" - * and rename "name".upd to "name" before reporting its existence. - * - * There are four situations and three results possible: - * - * 1) LWS_TLS_EXTANT_NO: There are no certs at all (we are waiting for them to - * be provisioned). We also feel like this if we need privs we don't have - * any more to look in the directory. - * - * 2) There are provisioned certs written (xxx.upd) and we still have root - * privs... in this case we rename any existing cert to have a backup name - * and move the upd cert into place with the correct name. This then becomes - * situation 4 for the caller. - * - * 3) LWS_TLS_EXTANT_ALTERNATIVE: There are provisioned certs written (xxx.upd) - * but we no longer have the privs needed to read or rename them. In this - * case, indicate that the caller should use temp copies if any we do have - * rights to access. This is normal after we have updated the cert. - * - * But if we dropped privs, we can't detect the provisioned xxx.upd cert + - * key, because we can't see in the dir. So we have to upgrade NO to - * ALTERNATIVE when we actually have the in-memory alternative. - * - * 4) LWS_TLS_EXTANT_YES: The certs are present with the correct name and we - * have the rights to read them. - */ -enum lws_tls_extant -lws_tls_use_any_upgrade_check_extant(const char *name) -{ -#if !defined(LWS_PLAT_OPTEE) - - int n; - -#if !defined(LWS_WITH_ESP32) - char buf[256]; - - lws_snprintf(buf, sizeof(buf) - 1, "%s.upd", name); - if (!lws_tls_extant(buf)) { - /* ah there is an updated file... how about the desired file? */ - if (!lws_tls_extant(name)) { - /* rename the desired file */ - for (n = 0; n < 50; n++) { - lws_snprintf(buf, sizeof(buf) - 1, - "%s.old.%d", name, n); - if (!rename(name, buf)) - break; - } - if (n == 50) { - lwsl_notice("unable to rename %s\n", name); - - return LWS_TLS_EXTANT_ALTERNATIVE; - } - lws_snprintf(buf, sizeof(buf) - 1, "%s.upd", name); - } - /* desired file is out of the way, rename the updated file */ - if (rename(buf, name)) { - lwsl_notice("unable to rename %s to %s\n", buf, name); - - return LWS_TLS_EXTANT_ALTERNATIVE; - } - } - - if (lws_tls_extant(name)) - return LWS_TLS_EXTANT_NO; -#else - nvs_handle nvh; - size_t s = 8192; - - if (nvs_open("lws-station", NVS_READWRITE, &nvh)) { - lwsl_notice("%s: can't open nvs\n", __func__); - return LWS_TLS_EXTANT_NO; - } - - n = nvs_get_blob(nvh, name, NULL, &s); - nvs_close(nvh); - - if (n) - return LWS_TLS_EXTANT_NO; -#endif -#endif - return LWS_TLS_EXTANT_YES; -} - -/* - * LWS_TLS_EXTANT_NO : skip adding the cert - * LWS_TLS_EXTANT_YES : use the cert and private key paths normally - * LWS_TLS_EXTANT_ALTERNATIVE: normal paths not usable, try alternate if poss - */ -enum lws_tls_extant -lws_tls_generic_cert_checks(struct lws_vhost *vhost, const char *cert, - const char *private_key) -{ - int n, m; - - /* - * The user code can choose to either pass the cert and - * key filepaths using the info members like this, or it can - * leave them NULL; force the vhost SSL_CTX init using the info - * options flag LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX; and - * set up the cert himself using the user callback - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, which - * happened just above and has the vhost SSL_CTX * in the user - * parameter. - */ - - if (!cert || !private_key) - return LWS_TLS_EXTANT_NO; - - n = lws_tls_use_any_upgrade_check_extant(cert); - if (n == LWS_TLS_EXTANT_ALTERNATIVE) - return LWS_TLS_EXTANT_ALTERNATIVE; - m = lws_tls_use_any_upgrade_check_extant(private_key); - if (m == LWS_TLS_EXTANT_ALTERNATIVE) - return LWS_TLS_EXTANT_ALTERNATIVE; - - if ((n == LWS_TLS_EXTANT_NO || m == LWS_TLS_EXTANT_NO) && - (vhost->options & LWS_SERVER_OPTION_IGNORE_MISSING_CERT)) { - lwsl_notice("Ignoring missing %s or %s\n", cert, private_key); - vhost->tls.skipped_certs = 1; - - return LWS_TLS_EXTANT_NO; - } - - /* - * the cert + key exist - */ - - return LWS_TLS_EXTANT_YES; -} - -#if !defined(LWS_NO_SERVER) -/* - * update the cert for every vhost using the given path - */ - -LWS_VISIBLE int -lws_tls_cert_updated(struct lws_context *context, const char *certpath, - const char *keypath, - const char *mem_cert, size_t len_mem_cert, - const char *mem_privkey, size_t len_mem_privkey) -{ - struct lws wsi; - - wsi.context = context; - - lws_start_foreach_ll(struct lws_vhost *, v, context->vhost_list) { - wsi.vhost = v; - if (v->tls.alloc_cert_path && v->tls.key_path && - !strcmp(v->tls.alloc_cert_path, certpath) && - !strcmp(v->tls.key_path, keypath)) { - lws_tls_server_certs_load(v, &wsi, certpath, keypath, - mem_cert, len_mem_cert, - mem_privkey, len_mem_privkey); - - if (v->tls.skipped_certs) - lwsl_notice("%s: vhost %s: cert unset\n", - __func__, v->name); - } - } lws_end_foreach_ll(v, vhost_next); - - return 0; -} -#endif - -int -lws_gate_accepts(struct lws_context *context, int on) -{ - struct lws_vhost *v = context->vhost_list; - - lwsl_notice("%s: on = %d\n", __func__, on); - -#if defined(LWS_WITH_STATS) - context->updated = 1; -#endif - - while (v) { - if (v->tls.use_ssl && v->lserv_wsi && - lws_change_pollfd(v->lserv_wsi, (LWS_POLLIN) * !on, - (LWS_POLLIN) * on)) - lwsl_notice("Unable to set accept POLLIN %d\n", on); - - v = v->vhost_next; - } - - return 0; -} - -/* comma-separated alpn list, like "h2,http/1.1" to openssl alpn format */ - -int -lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len) -{ - uint8_t *oos = os, *plen = NULL; - - while (*comma && len > 1) { - if (!plen && *comma == ' ') { - comma++; - continue; - } - if (!plen) { - plen = os++; - len--; - } - - if (*comma == ',') { - *plen = lws_ptr_diff(os, plen + 1); - plen = NULL; - comma++; - } else { - *os++ = *comma++; - len--; - } - } - - if (plen) - *plen = lws_ptr_diff(os, plen + 1); - - return lws_ptr_diff(os, oos); -} - |