diff --git a/mongoose.c b/mongoose.c index 4d90a81e..0e6fb901 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7485,8 +7485,7 @@ static void read_conn(struct mg_connection *c) { } else { if (n > 0) c->rtls.len += (size_t) n; if (c->is_tls_hs) mg_tls_handshake(c); - if (c->is_tls_hs) return; - n = mg_tls_recv(c, buf, len); + n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); } } else { n = recv_raw(c, buf, len); @@ -10854,6 +10853,9 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { if (c->is_listening) goto fail; MG_DEBUG(("%lu Setting TLS", c->id)); MG_PROF_ADD(c, "mbedtls_init_start"); +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_crypto_init(); +#endif mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); mbedtls_x509_crt_init(&tls->ca); @@ -10873,6 +10875,8 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { mbedtls_ssl_conf_rng(&tls->conf, mg_mbed_rng, c); if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) { + // NOTE: MBEDTLS_SSL_VERIFY_NONE is not supported for TLS1.3 on client side + // See https://github.com/Mbed-TLS/mbedtls/issues/7075 mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE); } else { if (mg_load_cert(opts->ca, &tls->ca) == false) goto fail; @@ -10925,6 +10929,11 @@ long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len); if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_IO_WAIT; +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) { + return MG_IO_WAIT; + } +#endif if (n <= 0) return MG_IO_ERR; return n; } diff --git a/mongoose.h b/mongoose.h index d12d2cc5..600d1e44 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2920,49 +2920,6 @@ struct mg_tcpip_driver_tm4c_data { #endif -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500 - -#undef MG_ENABLE_TCPIP_DRIVER_INIT -#define MG_ENABLE_TCPIP_DRIVER_INIT 0 - -#endif - - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 - -struct mg_tcpip_driver_xmc7_data { - int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 - uint8_t phy_addr; -}; - -#ifndef MG_TCPIP_PHY_ADDR -#define MG_TCPIP_PHY_ADDR 0 -#endif - -#ifndef MG_DRIVER_MDC_CR -#define MG_DRIVER_MDC_CR 3 -#endif - -#define MG_TCPIP_DRIVER_INIT(mgr) \ - do { \ - static struct mg_tcpip_driver_xmc7_data driver_data_; \ - static struct mg_tcpip_if mif_; \ - driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ - driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ - mif_.ip = MG_TCPIP_IP; \ - mif_.mask = MG_TCPIP_MASK; \ - mif_.gw = MG_TCPIP_GW; \ - mif_.driver = &mg_tcpip_driver_xmc7; \ - mif_.driver_data = &driver_data_; \ - MG_SET_MAC_ADDRESS(mif_.mac); \ - mg_tcpip_init(mgr, &mif_); \ - MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ - } while (0) - -#endif - - - #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { @@ -3009,6 +2966,41 @@ struct mg_tcpip_driver_xmc_data { #endif + +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 + +struct mg_tcpip_driver_xmc7_data { + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 + uint8_t phy_addr; +}; + +#ifndef MG_TCPIP_PHY_ADDR +#define MG_TCPIP_PHY_ADDR 0 +#endif + +#ifndef MG_DRIVER_MDC_CR +#define MG_DRIVER_MDC_CR 3 +#endif + +#define MG_TCPIP_DRIVER_INIT(mgr) \ + do { \ + static struct mg_tcpip_driver_xmc7_data driver_data_; \ + static struct mg_tcpip_if mif_; \ + driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ + driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ + mif_.ip = MG_TCPIP_IP; \ + mif_.mask = MG_TCPIP_MASK; \ + mif_.gw = MG_TCPIP_GW; \ + mif_.driver = &mg_tcpip_driver_xmc7; \ + mif_.driver_data = &driver_data_; \ + MG_SET_MAC_ADDRESS(mif_.mac); \ + mg_tcpip_init(mgr, &mif_); \ + MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ + } while (0) + +#endif + + #ifdef __cplusplus } #endif diff --git a/src/sock.c b/src/sock.c index ce53b750..66a23482 100644 --- a/src/sock.c +++ b/src/sock.c @@ -285,8 +285,7 @@ static void read_conn(struct mg_connection *c) { } else { if (n > 0) c->rtls.len += (size_t) n; if (c->is_tls_hs) mg_tls_handshake(c); - if (c->is_tls_hs) return; - n = mg_tls_recv(c, buf, len); + n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); } } else { n = recv_raw(c, buf, len); diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 61396aa6..2b729e20 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -105,6 +105,9 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { if (c->is_listening) goto fail; MG_DEBUG(("%lu Setting TLS", c->id)); MG_PROF_ADD(c, "mbedtls_init_start"); +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_crypto_init(); +#endif mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); mbedtls_x509_crt_init(&tls->ca); @@ -124,6 +127,8 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { mbedtls_ssl_conf_rng(&tls->conf, mg_mbed_rng, c); if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) { + // NOTE: MBEDTLS_SSL_VERIFY_NONE is not supported for TLS1.3 on client side + // See https://github.com/Mbed-TLS/mbedtls/issues/7075 mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE); } else { if (mg_load_cert(opts->ca, &tls->ca) == false) goto fail; @@ -176,6 +181,11 @@ long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len); if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_IO_WAIT; +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) { + return MG_IO_WAIT; + } +#endif if (n <= 0) return MG_IO_ERR; return n; } diff --git a/test/unit_test.c b/test/unit_test.c index 20ef1d0d..b99f57df 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -37,9 +37,12 @@ static void test_match(void) { ASSERT(mg_match(mg_str_n("/x/2/foo", 8), mg_str_n("/x/*/*", 6), NULL) == 1); ASSERT(mg_match(mg_str_n("///", 3), mg_str_n("#", 1), NULL) == 1); ASSERT(mg_match(mg_str_n("/api/foo", 8), mg_str_n("/api/*", 6), NULL) == 1); - ASSERT(mg_match(mg_str_n("/api/log/static", 15), mg_str_n("/api/*", 6), NULL) == 0); - ASSERT(mg_match(mg_str_n("/api/log/static", 15), mg_str_n("/api/#", 6), NULL) == 1); - ASSERT(mg_match(mg_str_n("/ssi/index.shtml", 16), mg_str_n("#.shtml", 7), NULL) == 1); + ASSERT(mg_match(mg_str_n("/api/log/static", 15), mg_str_n("/api/*", 6), + NULL) == 0); + ASSERT(mg_match(mg_str_n("/api/log/static", 15), mg_str_n("/api/#", 6), + NULL) == 1); + ASSERT(mg_match(mg_str_n("/ssi/index.shtml", 16), mg_str_n("#.shtml", 7), + NULL) == 1); ASSERT(mg_match(mg_str_n(".c", 2), mg_str_n("#.c", 3), NULL) == 1); ASSERT(mg_match(mg_str_n("ab", 2), mg_str_n("abc", 3), NULL) == 0); ASSERT(mg_match(mg_str_n("a.c", 3), mg_str_n("#.c", 3), NULL) == 1); @@ -48,7 +51,8 @@ static void test_match(void) { ASSERT(mg_match(mg_str_n("//a.c", 5), mg_str_n("#.c", 3), NULL) == 1); ASSERT(mg_match(mg_str_n("x/a.c", 5), mg_str_n("#.c", 3), NULL) == 1); ASSERT(mg_match(mg_str_n("./a.c", 5), mg_str_n("#.c", 3), NULL) == 1); - ASSERT(mg_match(mg_str_n("./ssi/index.shtml", 17), mg_str_n("#.shtml", 7), NULL) == 1); + ASSERT(mg_match(mg_str_n("./ssi/index.shtml", 17), mg_str_n("#.shtml", 7), + NULL) == 1); ASSERT(mg_match(mg_str_n("caabba", 6), mg_str_n("#aa#bb#", 7), NULL) == 1); ASSERT(mg_match(mg_str_n("caabxa", 6), mg_str_n("#aa#bb#", 7), NULL) == 0); ASSERT(mg_match(mg_str_n("a__b_c", 6), mg_str_n("a*b*c", 5), NULL) == 1); @@ -139,7 +143,7 @@ static struct mg_str strstrip(struct mg_str s) { return s; } static const char *mgstrstr(const struct mg_str haystack, - const struct mg_str needle) { + const struct mg_str needle) { size_t i; if (needle.len > haystack.len) return NULL; if (needle.len == 0) return haystack.buf; @@ -151,8 +155,6 @@ static const char *mgstrstr(const struct mg_str haystack, return NULL; } - - static void test_url(void) { // Host ASSERT(vcmp(mg_url_host("foo"), "foo")); @@ -524,7 +526,8 @@ static void test_mqtt_basic(void) { // Publish with QoS1 to subscribed topic and check reception // keep former opts.topic - opts.message = mg_str("hi1"), opts.qos = 1, opts.retain = false, opts.retransmit_id = 0; + opts.message = mg_str("hi1"), opts.qos = 1, opts.retain = false, + opts.retransmit_id = 0; retries = 0; // don't do retries for test speed do { // retry on failure after an expected timeout opts.retransmit_id = mg_mqtt_pub(c, &opts); // save id for possible resend @@ -617,7 +620,7 @@ static void test_mqtt_ver(uint8_t mqtt_version) { ASSERT(test_data.flags & flags_received); test_data.flags &= ~flags_received; opts.retransmit_id = 0; -// Mongoose sent PUBREL, wait for PUBCOMP + // Mongoose sent PUBREL, wait for PUBCOMP for (i = 0; i < 500 && !(test_data.flags & flags_completed); i++) mg_mgr_poll(&mgr, 10); // TODO(): retry sending PUBREL on failure after an expected timeout @@ -1232,6 +1235,7 @@ static void f3(struct mg_connection *c, int ev, void *ev_data) { // MG_INFO(("%d", ev)); if (ev == MG_EV_CONNECT) { // c->is_hexdumping = 1; + ASSERT((c->loc.ip[0] != 0)); // Make sure that c->loc address is populated mg_printf(c, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", c->rem.is_ip6 ? "" : "/robots.txt", c->rem.is_ip6 ? "ipv6.google.com" : "cesanta.com"); @@ -1241,6 +1245,7 @@ static void f3(struct mg_connection *c, int ev, void *ev_data) { // ASSERT(vcmp(hm->method, "HTTP/1.1")); // ASSERT(vcmp(hm->uri, "301")); *ok = mg_http_status(hm); + c->is_closing = 1; } else if (ev == MG_EV_CLOSE) { if (*ok == 0) *ok = 888; } else if (ev == MG_EV_ERROR) { @@ -1265,8 +1270,6 @@ static void test_http_client(void) { for (i = 0; i < 500 && ok <= 0; i++) mg_mgr_poll(&mgr, 1); MG_INFO(("%d", ok)); ASSERT(ok == 301); - c->is_closing = 1; - ASSERT((c->loc.ip[0] != 0)); // Make sure that c->loc address is populated mg_mgr_poll(&mgr, 0); ok = 0; #if MG_TLS @@ -1275,7 +1278,6 @@ static void test_http_client(void) { mg_tls_init(c, &opts); for (i = 0; i < 1500 && ok <= 0; i++) mg_mgr_poll(&mgr, 1); ASSERT(ok == 200); - c->is_closing = 1; mg_mgr_poll(&mgr, 1); // Test failed host validation @@ -1289,6 +1291,9 @@ static void test_http_client(void) { ASSERT(ok == 777); mg_mgr_poll(&mgr, 1); + // Test empty CA + // Disable mbedTLS: https://github.com/Mbed-TLS/mbedtls/issues/7075 +#if MG_TLS != MG_TLS_MBED opts.name = mg_str("cesanta.com"); opts.ca = mg_str(""); c = mg_http_connect(&mgr, "https://cesanta.com", f3, &ok); @@ -1299,6 +1304,7 @@ static void test_http_client(void) { ASSERT(ok == 200); mg_mgr_poll(&mgr, 1); #endif +#endif #if MG_ENABLE_IPV6 ok = 0; @@ -1313,33 +1319,6 @@ static void test_http_client(void) { ASSERT(mgr.conns == NULL); } -// Test host validation only (no CA, no cert) -static void test_host_validation(void) { -#if MG_TLS - const char *url = "https://cesanta.com"; - struct mg_tls_opts opts; - struct mg_mgr mgr; - struct mg_connection *c = NULL; - int i, ok = 0; - memset(&opts, 0, sizeof(opts)); - mg_mgr_init(&mgr); - - ok = 0; - c = mg_http_connect(&mgr, url, f3, &ok); - ASSERT(c != NULL); - opts.ca = mg_unpacked("/data/ca.pem"); - opts.name = mg_url_host(url); - mg_tls_init(c, &opts); - for (i = 0; i < 1500 && ok <= 0; i++) mg_mgr_poll(&mgr, 10); - ASSERT(ok == 200); - c->is_closing = 1; - mg_mgr_poll(&mgr, 1); - - mg_mgr_free(&mgr); - ASSERT(mgr.conns == NULL); -#endif -} - static void f4(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; @@ -3396,7 +3375,6 @@ int main(void) { test_tls(); test_ws(); test_ws_fragmentation(); - test_host_validation(); test_http_server(); test_http_404(); test_http_no_content_length();