Commit c2b5e4f3 authored by Deomid "rojer" Ryabkov's avatar Deomid "rojer" Ryabkov Committed by Cesanta Bot

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
parent bc15e9ce
...@@ -4900,7 +4900,11 @@ struct mg_ssl_if_ctx { ...@@ -4900,7 +4900,11 @@ struct mg_ssl_if_ctx {
mbedtls_ssl_context *ssl; mbedtls_ssl_context *ssl;
mbedtls_x509_crt *cert; mbedtls_x509_crt *cert;
mbedtls_pk_context *key; mbedtls_pk_context *key;
#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK
char *ca_chain_file;
#else
mbedtls_x509_crt *ca_cert; mbedtls_x509_crt *ca_cert;
#endif
struct mbuf cipher_suites; struct mbuf cipher_suites;
size_t saved_len; size_t saved_len;
}; };
...@@ -5076,18 +5080,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) { ...@@ -5076,18 +5080,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) {
MG_FREE(ctx->key); MG_FREE(ctx->key);
ctx->key = NULL; 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) { if (ctx->ca_cert != NULL) {
mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, 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); mbedtls_x509_crt_free(ctx->ca_cert);
MG_FREE(ctx->ca_cert); MG_FREE(ctx->ca_cert);
ctx->ca_cert = NULL; ctx->ca_cert = NULL;
} }
#endif
} }
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) { 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) { ...@@ -5168,11 +5171,11 @@ void mg_ssl_if_conn_free(struct mg_connection *nc) {
mbedtls_ssl_free(ctx->ssl); mbedtls_ssl_free(ctx->ssl);
MG_FREE(ctx->ssl); MG_FREE(ctx->ssl);
} }
mg_ssl_if_mbed_free_certs_and_keys(ctx);
if (ctx->conf != NULL) { if (ctx->conf != NULL) {
mbedtls_ssl_config_free(ctx->conf); mbedtls_ssl_config_free(ctx->conf);
MG_FREE(ctx->conf); MG_FREE(ctx->conf);
} }
mg_ssl_if_mbed_free_certs_and_keys(ctx);
mbuf_free(&ctx->cipher_suites); mbuf_free(&ctx->cipher_suites);
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
MG_FREE(ctx); MG_FREE(ctx);
...@@ -5184,12 +5187,15 @@ static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *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); mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_NONE);
return MG_SSL_OK; return MG_SSL_OK;
} }
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 #ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK
ca_cert = strdup(ca_cert); ctx->ca_chain_file = strdup(ca_cert);
mbedtls_ssl_conf_ca_chain_file(ctx->conf, ca_cert, NULL); 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 #else
ctx->ca_cert = (mbedtls_x509_crt *) MG_CALLOC(1, sizeof(*ctx->ca_cert));
mbedtls_x509_crt_init(ctx->ca_cert);
if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) { if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) {
return MG_SSL_ERROR; return MG_SSL_ERROR;
} }
......
...@@ -44,7 +44,11 @@ struct mg_ssl_if_ctx { ...@@ -44,7 +44,11 @@ struct mg_ssl_if_ctx {
mbedtls_ssl_context *ssl; mbedtls_ssl_context *ssl;
mbedtls_x509_crt *cert; mbedtls_x509_crt *cert;
mbedtls_pk_context *key; mbedtls_pk_context *key;
#ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK
char *ca_chain_file;
#else
mbedtls_x509_crt *ca_cert; mbedtls_x509_crt *ca_cert;
#endif
struct mbuf cipher_suites; struct mbuf cipher_suites;
size_t saved_len; size_t saved_len;
}; };
...@@ -220,18 +224,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) { ...@@ -220,18 +224,17 @@ static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) {
MG_FREE(ctx->key); MG_FREE(ctx->key);
ctx->key = NULL; 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) { if (ctx->ca_cert != NULL) {
mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, 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); mbedtls_x509_crt_free(ctx->ca_cert);
MG_FREE(ctx->ca_cert); MG_FREE(ctx->ca_cert);
ctx->ca_cert = NULL; ctx->ca_cert = NULL;
} }
#endif
} }
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) { 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) { ...@@ -312,11 +315,11 @@ void mg_ssl_if_conn_free(struct mg_connection *nc) {
mbedtls_ssl_free(ctx->ssl); mbedtls_ssl_free(ctx->ssl);
MG_FREE(ctx->ssl); MG_FREE(ctx->ssl);
} }
mg_ssl_if_mbed_free_certs_and_keys(ctx);
if (ctx->conf != NULL) { if (ctx->conf != NULL) {
mbedtls_ssl_config_free(ctx->conf); mbedtls_ssl_config_free(ctx->conf);
MG_FREE(ctx->conf); MG_FREE(ctx->conf);
} }
mg_ssl_if_mbed_free_certs_and_keys(ctx);
mbuf_free(&ctx->cipher_suites); mbuf_free(&ctx->cipher_suites);
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
MG_FREE(ctx); MG_FREE(ctx);
...@@ -328,12 +331,15 @@ static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *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); mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_NONE);
return MG_SSL_OK; return MG_SSL_OK;
} }
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 #ifdef MBEDTLS_X509_CA_CHAIN_ON_DISK
ca_cert = strdup(ca_cert); ctx->ca_chain_file = strdup(ca_cert);
mbedtls_ssl_conf_ca_chain_file(ctx->conf, ca_cert, NULL); 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 #else
ctx->ca_cert = (mbedtls_x509_crt *) MG_CALLOC(1, sizeof(*ctx->ca_cert));
mbedtls_x509_crt_init(ctx->ca_cert);
if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) { if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) {
return MG_SSL_ERROR; return MG_SSL_ERROR;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment