From c2b5e4f3b89a0ecacece533aea0b8706d729e538 Mon Sep 17 00:00:00 2001 From: "Deomid \"rojer\" Ryabkov" Date: Tue, 21 Jan 2020 23:39:29 +0000 Subject: [PATCH] Fix a leak when CA certificate file is invalid Also free up some RAM by not allocating ca_cert when `MBEDTLS_X509_CA_CHAIN_ON_DISK` is enabled. PUBLISHED_FROM=5e5f4103707de98c929973d2aed0aaedf0bb60da --- mongoose.c | 28 +++++++++++++++++----------- src/mg_ssl_if_mbedtls.c | 28 +++++++++++++++++----------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/mongoose.c b/mongoose.c index a61a04dc..4c185ad2 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4900,7 +4900,11 @@ struct mg_ssl_if_ctx { mbedtls_ssl_context *ssl; mbedtls_x509_crt *cert; mbedtls_pk_context *key; +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + char *ca_chain_file; +#else mbedtls_x509_crt *ca_cert; +#endif struct mbuf cipher_suites; size_t saved_len; }; @@ -5076,18 +5080,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) { MG_FREE(ctx->key); ctx->key = NULL; } +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + MG_FREE(ctx->ca_chain_file); + ctx->ca_chain_file = NULL; +#else if (ctx->ca_cert != NULL) { mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, NULL); -#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK - if (ctx->conf->ca_chain_file != NULL) { - MG_FREE((void *) ctx->conf->ca_chain_file); - ctx->conf->ca_chain_file = NULL; - } -#endif mbedtls_x509_crt_free(ctx->ca_cert); MG_FREE(ctx->ca_cert); ctx->ca_cert = NULL; } +#endif } enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) { @@ -5168,11 +5171,11 @@ void mg_ssl_if_conn_free(struct mg_connection *nc) { mbedtls_ssl_free(ctx->ssl); MG_FREE(ctx->ssl); } - mg_ssl_if_mbed_free_certs_and_keys(ctx); if (ctx->conf != NULL) { mbedtls_ssl_config_free(ctx->conf); MG_FREE(ctx->conf); } + mg_ssl_if_mbed_free_certs_and_keys(ctx); mbuf_free(&ctx->cipher_suites); memset(ctx, 0, sizeof(*ctx)); MG_FREE(ctx); @@ -5184,12 +5187,15 @@ static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx, mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_NONE); return MG_SSL_OK; } +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + ctx->ca_chain_file = strdup(ca_cert); + if (ctx->ca_chain_file == NULL) return MG_SSL_ERROR; + if (mbedtls_ssl_conf_ca_chain_file(ctx->conf, ctx->ca_chain_file, NULL) != 0) { + return MG_SSL_ERROR; + } +#else ctx->ca_cert = (mbedtls_x509_crt *) MG_CALLOC(1, sizeof(*ctx->ca_cert)); mbedtls_x509_crt_init(ctx->ca_cert); -#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK - ca_cert = strdup(ca_cert); - mbedtls_ssl_conf_ca_chain_file(ctx->conf, ca_cert, NULL); -#else if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) { return MG_SSL_ERROR; } diff --git a/src/mg_ssl_if_mbedtls.c b/src/mg_ssl_if_mbedtls.c index a4508ace..d837481a 100644 --- a/src/mg_ssl_if_mbedtls.c +++ b/src/mg_ssl_if_mbedtls.c @@ -44,7 +44,11 @@ struct mg_ssl_if_ctx { mbedtls_ssl_context *ssl; mbedtls_x509_crt *cert; mbedtls_pk_context *key; +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + char *ca_chain_file; +#else mbedtls_x509_crt *ca_cert; +#endif struct mbuf cipher_suites; size_t saved_len; }; @@ -220,18 +224,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) { MG_FREE(ctx->key); ctx->key = NULL; } +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + MG_FREE(ctx->ca_chain_file); + ctx->ca_chain_file = NULL; +#else if (ctx->ca_cert != NULL) { mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, NULL); -#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK - if (ctx->conf->ca_chain_file != NULL) { - MG_FREE((void *) ctx->conf->ca_chain_file); - ctx->conf->ca_chain_file = NULL; - } -#endif mbedtls_x509_crt_free(ctx->ca_cert); MG_FREE(ctx->ca_cert); ctx->ca_cert = NULL; } +#endif } enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) { @@ -312,11 +315,11 @@ void mg_ssl_if_conn_free(struct mg_connection *nc) { mbedtls_ssl_free(ctx->ssl); MG_FREE(ctx->ssl); } - mg_ssl_if_mbed_free_certs_and_keys(ctx); if (ctx->conf != NULL) { mbedtls_ssl_config_free(ctx->conf); MG_FREE(ctx->conf); } + mg_ssl_if_mbed_free_certs_and_keys(ctx); mbuf_free(&ctx->cipher_suites); memset(ctx, 0, sizeof(*ctx)); MG_FREE(ctx); @@ -328,12 +331,15 @@ static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx, mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_NONE); return MG_SSL_OK; } +#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK + ctx->ca_chain_file = strdup(ca_cert); + if (ctx->ca_chain_file == NULL) return MG_SSL_ERROR; + if (mbedtls_ssl_conf_ca_chain_file(ctx->conf, ctx->ca_chain_file, NULL) != 0) { + return MG_SSL_ERROR; + } +#else ctx->ca_cert = (mbedtls_x509_crt *) MG_CALLOC(1, sizeof(*ctx->ca_cert)); mbedtls_x509_crt_init(ctx->ca_cert); -#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK - ca_cert = strdup(ca_cert); - mbedtls_ssl_conf_ca_chain_file(ctx->conf, ca_cert, NULL); -#else if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) { return MG_SSL_ERROR; }