mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
esp32-selfsigned
This commit is contained in:
parent
946bfa2f18
commit
516001db8a
11 changed files with 215 additions and 47 deletions
1
Makefile.projbuild
Normal file
1
Makefile.projbuild
Normal file
|
@ -0,0 +1 @@
|
|||
CPPFLAGS += -I$(BUILD_DIR_BASE)/libwebsockets/include
|
|
@ -275,10 +275,10 @@ lws_protocol_init(struct lws_context *context)
|
|||
if (vh->protocols[n].callback(&wsi,
|
||||
LWS_CALLBACK_PROTOCOL_INIT, NULL,
|
||||
(void *)pvo, 0)) {
|
||||
lwsl_err("%s: vhost %s failed init\n", __func__,
|
||||
lws_free(vh->protocol_vh_privs[n]);
|
||||
vh->protocol_vh_privs[n] = NULL;
|
||||
lwsl_err("%s: protocol %s failed init\n", __func__,
|
||||
vh->protocols[n].name);
|
||||
context->doing_protocol_init = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,8 @@ lws_create_vhost(struct lws_context *context,
|
|||
/* for the case we are adding a vhost much later, after server init */
|
||||
|
||||
if (context->protocol_init_done)
|
||||
lws_protocol_init(context);
|
||||
if (lws_protocol_init(context))
|
||||
goto bail;
|
||||
|
||||
return vh;
|
||||
|
||||
|
|
|
@ -4306,6 +4306,10 @@ lws_sql_purify(char *escaped, const char *string, int len);
|
|||
*/
|
||||
LWS_VISIBLE LWS_EXTERN const char *
|
||||
lws_json_purify(char *escaped, const char *string, int len);
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len);
|
||||
///@}
|
||||
|
||||
/*! \defgroup ev libev helpers
|
||||
|
|
|
@ -1601,8 +1601,9 @@ lws_esp32_set_creation_defaults(struct lws_context_creation_info *info)
|
|||
part = lws_esp_ota_get_boot_partition();
|
||||
(void)part;
|
||||
|
||||
info->vhost_name = "default";
|
||||
info->port = 443;
|
||||
info->fd_limit_per_thread = 10;
|
||||
info->fd_limit_per_thread = 30;
|
||||
info->max_http_header_pool = 16;
|
||||
info->max_http_header_data = 512;
|
||||
info->pt_serv_buf_size = 2048;
|
||||
|
@ -1612,8 +1613,8 @@ lws_esp32_set_creation_defaults(struct lws_context_creation_info *info)
|
|||
info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
|
||||
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
|
||||
info->ssl_cert_filepath = "ssl-pub.pem";
|
||||
info->ssl_private_key_filepath = "ssl-pri.pem";
|
||||
// info->ssl_cert_filepath = "default-cert.pem";
|
||||
// info->ssl_private_key_filepath = "default-key.pem";
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1655,6 +1656,138 @@ lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_rngf(void *context, unsigned char *buf, size_t len)
|
||||
{
|
||||
if ((size_t)lws_get_random(context, buf, len) == len)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
lws_esp32_selfsigned(struct lws_vhost *vhost)
|
||||
{
|
||||
mbedtls_x509write_cert crt;
|
||||
char subject[200];
|
||||
mbedtls_pk_context mpk;
|
||||
int buf_size = 4096, n;
|
||||
uint8_t *buf = malloc(buf_size); /* malloc because given to user code */
|
||||
mbedtls_mpi mpi;
|
||||
nvs_handle nvh;
|
||||
size_t s;
|
||||
|
||||
lwsl_notice("%s: %s\n", __func__, vhost->name);
|
||||
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
if (nvs_open("lws-station", NVS_READWRITE, &nvh)) {
|
||||
lwsl_notice("%s: can't open nvs\n", __func__);
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
if (!nvs_get_blob(nvh, vhost->alloc_cert_path, NULL, &s))
|
||||
n |= 1;
|
||||
if (!nvs_get_blob(nvh, vhost->key_path, NULL, &s))
|
||||
n |= 2;
|
||||
|
||||
nvs_close(nvh);
|
||||
if (n == 3) {
|
||||
lwsl_notice("%s: certs exist\n", __func__);
|
||||
return 0; /* certs already exist */
|
||||
}
|
||||
|
||||
lwsl_notice("%s: creating selfsigned initial certs\n", __func__);
|
||||
|
||||
mbedtls_x509write_crt_init(&crt);
|
||||
|
||||
mbedtls_pk_init(&mpk);
|
||||
if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) {
|
||||
lwsl_notice("%s: pk_setup failed\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
lwsl_notice("%s: generating 2048-bit RSA keypair... "
|
||||
"this may take a minute or so...\n", __func__);
|
||||
n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, vhost->context,
|
||||
2048, 65537);
|
||||
if (n) {
|
||||
lwsl_notice("%s: failed to generate keys\n", __func__);
|
||||
goto fail1;
|
||||
}
|
||||
lwsl_notice("%s: keys done\n", __func__);
|
||||
|
||||
/* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */
|
||||
|
||||
lws_snprintf(subject, sizeof(subject) - 1,
|
||||
"C=TW,ST=New Taipei City,L=Taipei,O=warmcat,CN=%s",
|
||||
lws_esp32.hostname);
|
||||
|
||||
if (mbedtls_x509write_crt_set_subject_name(&crt, subject)) {
|
||||
lwsl_notice("set SN failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
mbedtls_x509write_crt_set_subject_key(&crt, &mpk);
|
||||
if (mbedtls_x509write_crt_set_issuer_name(&crt, subject)) {
|
||||
lwsl_notice("set IN failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
mbedtls_x509write_crt_set_issuer_key(&crt, &mpk);
|
||||
|
||||
lws_get_random(vhost->context, &n, sizeof(n));
|
||||
lws_snprintf(subject, sizeof(subject), "%d", n);
|
||||
|
||||
mbedtls_mpi_init(&mpi);
|
||||
mbedtls_mpi_read_string(&mpi, 10, subject);
|
||||
mbedtls_x509write_crt_set_serial(&crt, &mpi);
|
||||
mbedtls_mpi_free(&mpi);
|
||||
|
||||
mbedtls_x509write_crt_set_validity(&crt, "20171105235959",
|
||||
"20491231235959");
|
||||
|
||||
mbedtls_x509write_crt_set_key_usage(&crt,
|
||||
MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
|
||||
MBEDTLS_X509_KU_KEY_ENCIPHERMENT);
|
||||
|
||||
|
||||
mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
|
||||
|
||||
n = mbedtls_x509write_crt_pem(&crt, buf, buf_size, _rngf,
|
||||
vhost->context);
|
||||
if (n < 0) {
|
||||
lwsl_notice("%s: write crt der failed\n", __func__);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
lws_plat_write_cert(vhost, 0, 0, buf, strlen((const char *)buf));
|
||||
|
||||
if (mbedtls_pk_write_key_pem(&mpk, buf, buf_size)) {
|
||||
lwsl_notice("write key pem failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
lws_plat_write_cert(vhost, 1, 0, buf, strlen((const char *)buf));
|
||||
|
||||
mbedtls_pk_free(&mpk);
|
||||
mbedtls_x509write_crt_free(&crt);
|
||||
|
||||
lwsl_notice("%s: cert creation complete\n", __func__);
|
||||
|
||||
return n;
|
||||
|
||||
fail1:
|
||||
mbedtls_pk_free(&mpk);
|
||||
fail:
|
||||
mbedtls_x509write_crt_free(&crt);
|
||||
free(buf);
|
||||
|
||||
nvs_close(nvh);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct lws_context *
|
||||
lws_esp32_init(struct lws_context_creation_info *info, struct lws_vhost **pvh)
|
||||
{
|
||||
|
@ -1662,27 +1795,8 @@ lws_esp32_init(struct lws_context_creation_info *info, struct lws_vhost **pvh)
|
|||
struct lws_context *context;
|
||||
struct lws_esp32_image i;
|
||||
struct lws_vhost *vhost;
|
||||
nvs_handle nvh;
|
||||
struct lws wsi;
|
||||
char buf[512];
|
||||
size_t s;
|
||||
int n;
|
||||
|
||||
ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
|
||||
n = 0;
|
||||
s = 1;
|
||||
if (nvs_get_blob(nvh, "ssl-pub.pem", NULL, &s) == ESP_OK)
|
||||
n = 1;
|
||||
s = 1;
|
||||
if (nvs_get_blob(nvh, "ssl-pri.pem", NULL, &s) == ESP_OK)
|
||||
n |= 2;
|
||||
nvs_close(nvh);
|
||||
|
||||
if (n != 3) {
|
||||
/* we are not configured for SSL yet... fall back to port 80 / http */
|
||||
info->port = 80;
|
||||
info->options &= ~LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
lwsl_notice("No SSL certs... using port 80\n");
|
||||
}
|
||||
|
||||
context = lws_create_context(info);
|
||||
if (context == NULL) {
|
||||
|
@ -1706,16 +1820,29 @@ lws_esp32_init(struct lws_context_creation_info *info, struct lws_vhost **pvh)
|
|||
|
||||
lws_set_fops(context, &fops);
|
||||
|
||||
info->options |= LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX |
|
||||
LWS_SERVER_OPTION_IGNORE_MISSING_CERT;
|
||||
|
||||
vhost = lws_create_vhost(context, info);
|
||||
if (!vhost)
|
||||
if (!vhost) {
|
||||
lwsl_err("Failed to create vhost\n");
|
||||
else
|
||||
lws_init_vhost_client_ssl(info, vhost);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lws_esp32_selfsigned(vhost);
|
||||
wsi.context = vhost->context;
|
||||
wsi.vhost = vhost;
|
||||
|
||||
lws_tls_server_certs_load(vhost, &wsi, info->ssl_cert_filepath,
|
||||
info->ssl_private_key_filepath, NULL, 0, NULL, 0);
|
||||
|
||||
lws_init_vhost_client_ssl(info, vhost);
|
||||
|
||||
if (pvh)
|
||||
*pvh = vhost;
|
||||
|
||||
lws_protocol_init(context);
|
||||
if (lws_protocol_init(context))
|
||||
return NULL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -1763,24 +1890,31 @@ uint16_t lws_esp32_sine_interp(int n)
|
|||
|
||||
/* we write vhostname.cert.pem and vhostname.key.pem, 0 return means OK */
|
||||
|
||||
int
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len)
|
||||
{
|
||||
char name[64];
|
||||
const char *name = vhost->alloc_cert_path;
|
||||
nvs_handle nvh;
|
||||
int n;
|
||||
|
||||
lws_snprintf(name, sizeof(name) - 1, "%s-%s.pem", vhost->name,
|
||||
is_key ? "key" : "cert");
|
||||
if (is_key)
|
||||
name = vhost->key_path;
|
||||
|
||||
if (nvs_open("lws-station", NVS_READWRITE, &nvh))
|
||||
if (nvs_open("lws-station", NVS_READWRITE, &nvh)) {
|
||||
lwsl_notice("%s: failed to open nvs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = nvs_set_blob(nvh, ssl_names[n], pss->buffer, pss->file_length);
|
||||
n = nvs_set_blob(nvh, name, buf, len);
|
||||
if (n)
|
||||
nvs_commit(nvh);
|
||||
|
||||
nvs_close(nvh);
|
||||
|
||||
lwsl_notice("%s: wrote %s\n", __func__, name);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -713,7 +713,7 @@ lws_plat_init(struct lws_context *context,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len)
|
||||
{
|
||||
|
|
|
@ -326,7 +326,7 @@ lws_plat_init(struct lws_context *context,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len)
|
||||
{
|
||||
|
|
|
@ -870,7 +870,7 @@ lws_plat_init(struct lws_context *context,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len)
|
||||
{
|
||||
|
|
|
@ -755,7 +755,7 @@ int fork(void)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
LWS_VISIBLE int
|
||||
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
|
||||
int len)
|
||||
{
|
||||
|
|
|
@ -983,7 +983,8 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
|
|||
int more;
|
||||
|
||||
if (!context->protocol_init_done)
|
||||
lws_protocol_init(context);
|
||||
if (lws_protocol_init(context))
|
||||
return -1;
|
||||
|
||||
time(&now);
|
||||
|
||||
|
|
|
@ -104,13 +104,20 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
|
|||
const char *mem_cert, size_t len_mem_cert,
|
||||
const char *mem_privkey, size_t mem_privkey_len)
|
||||
{
|
||||
int n = lws_tls_generic_cert_checks(vhost, cert, private_key), f = 0;
|
||||
int n, f = 0;
|
||||
const char *filepath = private_key;
|
||||
uint8_t *mem = NULL, *p = NULL;
|
||||
size_t mem_len = 0;
|
||||
lws_filepos_t flen;
|
||||
long err;
|
||||
|
||||
if (!cert || !private_key) {
|
||||
lwsl_notice("%s: no paths\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = lws_tls_generic_cert_checks(vhost, cert, private_key);
|
||||
|
||||
if (n == LWS_TLS_EXTANT_NO && (!mem_cert || !mem_privkey))
|
||||
return 0;
|
||||
|
||||
|
@ -613,3 +620,4 @@ fail:
|
|||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
|
|||
n = 1;
|
||||
goto bail;
|
||||
}
|
||||
*buf = lws_malloc(s, "alloc_file");
|
||||
*buf = lws_malloc(s + 1, "alloc_file");
|
||||
if (!*buf) {
|
||||
n = 2;
|
||||
goto bail;
|
||||
|
@ -123,6 +123,9 @@ int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
|
|||
}
|
||||
|
||||
*amount = s;
|
||||
(*buf)[s] = '\0';
|
||||
|
||||
lwsl_notice("%s: nvs: read %s, %d bytes\n", __func__, filename, (int)s);
|
||||
|
||||
bail:
|
||||
nvs_close(nvh);
|
||||
|
@ -286,7 +289,7 @@ lws_tls_check_all_cert_lifetimes(struct lws_context *context)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(LWS_WITH_ESP32)
|
||||
static int
|
||||
lws_tls_extant(const char *name)
|
||||
{
|
||||
|
@ -303,7 +306,7 @@ lws_tls_extant(const char *name)
|
|||
|
||||
return n != 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Returns 0 if the filepath "name" exists and can be read from.
|
||||
*
|
||||
|
@ -337,8 +340,9 @@ lws_tls_extant(const char *name)
|
|||
enum lws_tls_extant
|
||||
lws_tls_use_any_upgrade_check_extant(const char *name)
|
||||
{
|
||||
char buf[256];
|
||||
int n;
|
||||
#if !defined(LWS_WITH_ESP32)
|
||||
char buf[256];
|
||||
|
||||
lws_snprintf(buf, sizeof(buf) - 1, "%s.upd", name);
|
||||
if (!lws_tls_extant(buf)) {
|
||||
|
@ -368,6 +372,21 @@ lws_tls_use_any_upgrade_check_extant(const char *name)
|
|||
|
||||
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
|
||||
|
||||
return LWS_TLS_EXTANT_YES;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue