diff --git a/mongoose.c b/mongoose.c index 6c060435..31ea1ff9 100644 --- a/mongoose.c +++ b/mongoose.c @@ -12523,7 +12523,7 @@ static void read_conn(struct mg_connection *c) { // there can still be > 16K from last iteration, always mg_tls_recv() m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031 - if (c->rtls.len == 0 || m < 0) { + if (c->rtls.len == 0 || (m < 0 && m != MG_IO_WAIT)) { // Close only when we have fully drained both rtls and TLS buffers c->is_closing = 1; // or there's nothing we can do about it. if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104 @@ -18642,11 +18642,6 @@ 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_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \ - defined(MBEDTLS_PSA_CRYPTO_C) - psa_crypto_init(); // https://github.com/Mbed-TLS/mbedtls/issues/9072#issuecomment-2084845711 - // this initializes global resources and then just returns when called again -#endif mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); mbedtls_x509_crt_init(&tls->ca); @@ -18698,9 +18693,11 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { } #ifdef MBEDTLS_SSL_SESSION_TICKETS - mbedtls_ssl_conf_session_tickets_cb( - &tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse, - &((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets); + if (!c->is_client && c->mgr->tls_ctx != NULL) { + mbedtls_ssl_conf_session_tickets_cb( + &tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse, + &((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets); + } #endif if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) { @@ -18744,6 +18741,12 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { tls->throttled_len) /* flush old data */ : mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len); // encrypt current data +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) { + c->is_tls_throttled = was_throttled; + return MG_IO_WAIT; + } +#endif c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE); if (was_throttled) return MG_IO_WAIT; // flushed throttled data instead @@ -18762,32 +18765,46 @@ void mg_tls_flush(struct mg_connection *c) { if (c->is_tls_throttled) { long n = mbedtls_ssl_write(&tls->ssl, tls->throttled_buf, tls->throttled_len); +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) return; +#endif c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE); } } void mg_tls_ctx_init(struct mg_mgr *mgr) { - struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - MG_ERROR(("TLS context init OOM")); - } else { +#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \ + defined(MBEDTLS_PSA_CRYPTO_C) + psa_crypto_init(); // Initializes global PSA resources, no-op if already done +#endif #ifdef MBEDTLS_SSL_SESSION_TICKETS - int rc; - mbedtls_ssl_ticket_init(&ctx->tickets); + { + struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + MG_ERROR(("TLS context init OOM")); + } else { + int rc; + mbedtls_ssl_ticket_init(&ctx->tickets); #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000 - if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM, - PSA_KEY_TYPE_AES, 128, 86400)) + rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM, + PSA_KEY_TYPE_AES, 128, 86400); #else - if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL, - MBEDTLS_CIPHER_AES_128_GCM, 86400)) + rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL, + MBEDTLS_CIPHER_AES_128_GCM, 86400); #endif - != 0) { - MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc)); + if (rc != 0) { + MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc)); + mbedtls_ssl_ticket_free(&ctx->tickets); + mg_free(ctx); + } else { + mgr->tls_ctx = ctx; + } } -#endif - mgr->tls_ctx = ctx; } +#else + (void) mgr; +#endif } void mg_tls_ctx_free(struct mg_mgr *mgr) { diff --git a/src/sock.c b/src/sock.c index 77fca2f9..228226cd 100644 --- a/src/sock.c +++ b/src/sock.c @@ -341,7 +341,7 @@ static void read_conn(struct mg_connection *c) { // there can still be > 16K from last iteration, always mg_tls_recv() m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031 - if (c->rtls.len == 0 || m < 0) { + if (c->rtls.len == 0 || (m < 0 && m != MG_IO_WAIT)) { // Close only when we have fully drained both rtls and TLS buffers c->is_closing = 1; // or there's nothing we can do about it. if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104 diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 0a3acca6..b7a49281 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -122,11 +122,6 @@ 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_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \ - defined(MBEDTLS_PSA_CRYPTO_C) - psa_crypto_init(); // https://github.com/Mbed-TLS/mbedtls/issues/9072#issuecomment-2084845711 - // this initializes global resources and then just returns when called again -#endif mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); mbedtls_x509_crt_init(&tls->ca); @@ -178,9 +173,11 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { } #ifdef MBEDTLS_SSL_SESSION_TICKETS - mbedtls_ssl_conf_session_tickets_cb( - &tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse, - &((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets); + if (!c->is_client && c->mgr->tls_ctx != NULL) { + mbedtls_ssl_conf_session_tickets_cb( + &tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse, + &((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets); + } #endif if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) { @@ -224,6 +221,12 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { tls->throttled_len) /* flush old data */ : mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len); // encrypt current data +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) { + c->is_tls_throttled = was_throttled; + return MG_IO_WAIT; + } +#endif c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE); if (was_throttled) return MG_IO_WAIT; // flushed throttled data instead @@ -242,32 +245,46 @@ void mg_tls_flush(struct mg_connection *c) { if (c->is_tls_throttled) { long n = mbedtls_ssl_write(&tls->ssl, tls->throttled_buf, tls->throttled_len); +#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) return; +#endif c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE); } } void mg_tls_ctx_init(struct mg_mgr *mgr) { - struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - MG_ERROR(("TLS context init OOM")); - } else { +#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \ + defined(MBEDTLS_PSA_CRYPTO_C) + psa_crypto_init(); // Initializes global PSA resources, no-op if already done +#endif #ifdef MBEDTLS_SSL_SESSION_TICKETS - int rc; - mbedtls_ssl_ticket_init(&ctx->tickets); + { + struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + MG_ERROR(("TLS context init OOM")); + } else { + int rc; + mbedtls_ssl_ticket_init(&ctx->tickets); #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000 - if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM, - PSA_KEY_TYPE_AES, 128, 86400)) + rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM, + PSA_KEY_TYPE_AES, 128, 86400); #else - if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL, - MBEDTLS_CIPHER_AES_128_GCM, 86400)) + rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL, + MBEDTLS_CIPHER_AES_128_GCM, 86400); #endif - != 0) { - MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc)); + if (rc != 0) { + MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc)); + mbedtls_ssl_ticket_free(&ctx->tickets); + mg_free(ctx); + } else { + mgr->tls_ctx = ctx; + } } -#endif - mgr->tls_ctx = ctx; } +#else + (void) mgr; +#endif } void mg_tls_ctx_free(struct mg_mgr *mgr) {