mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
altcp_tls: ensure no memory leaks and entropy counter is protected
This commit is contained in:
parent
dc7ba26e69
commit
2be031e238
@ -50,6 +50,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
|
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
@ -714,6 +715,55 @@ altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static err_t
|
||||||
|
altcp_mbedtls_ref_entropy()
|
||||||
|
{
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
if (!altcp_tls_entropy_rng) {
|
||||||
|
altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng));
|
||||||
|
if (altcp_tls_entropy_rng) {
|
||||||
|
int ret;
|
||||||
|
altcp_tls_entropy_rng->ref = 1;
|
||||||
|
mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg);
|
||||||
|
/* Seed the RNG, only once */
|
||||||
|
ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg,
|
||||||
|
ALTCP_MBEDTLS_RNG_FN, &altcp_tls_entropy_rng->entropy,
|
||||||
|
ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
|
||||||
|
if (ret != 0) {
|
||||||
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
|
||||||
|
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
||||||
|
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
||||||
|
altcp_tls_entropy_rng = NULL;
|
||||||
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
altcp_tls_entropy_rng->ref++;
|
||||||
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
altcp_mbedtls_unref_entropy()
|
||||||
|
{
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref)
|
||||||
|
altcp_tls_entropy_rng->ref--;
|
||||||
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
}
|
||||||
|
|
||||||
/** Create new TLS configuration
|
/** Create new TLS configuration
|
||||||
* ATTENTION: Server certificate and private key have to be added outside this function!
|
* ATTENTION: Server certificate and private key have to be added outside this function!
|
||||||
*/
|
*/
|
||||||
@ -764,31 +814,9 @@ altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int hav
|
|||||||
|
|
||||||
mbedtls_ssl_config_init(&conf->conf);
|
mbedtls_ssl_config_init(&conf->conf);
|
||||||
|
|
||||||
if (!altcp_tls_entropy_rng) {
|
if (altcp_mbedtls_ref_entropy() != ERR_OK) {
|
||||||
altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng));
|
altcp_mbedtls_free_config(conf);
|
||||||
if (altcp_tls_entropy_rng) {
|
return NULL;
|
||||||
altcp_tls_entropy_rng->ref = 1;
|
|
||||||
mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy);
|
|
||||||
mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg);
|
|
||||||
/* Seed the RNG, only once */
|
|
||||||
ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg,
|
|
||||||
mbedtls_entropy_func, &altcp_tls_entropy_rng->entropy,
|
|
||||||
ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
|
|
||||||
if (ret != 0) {
|
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
|
|
||||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
|
||||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
|
||||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
|
||||||
altcp_tls_entropy_rng = NULL;
|
|
||||||
altcp_mbedtls_free_config(conf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
altcp_mbedtls_free_config(conf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
altcp_tls_entropy_rng->ref++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
|
/* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
|
||||||
@ -796,12 +824,7 @@ altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int hav
|
|||||||
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
|
||||||
if (altcp_tls_entropy_rng->ref == 1) {
|
altcp_mbedtls_unref_entropy();
|
||||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
|
||||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
|
||||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
|
||||||
altcp_tls_entropy_rng = NULL;
|
|
||||||
}
|
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_mbedtls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -824,6 +847,7 @@ altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int hav
|
|||||||
ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS);
|
ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret));
|
||||||
|
altcp_mbedtls_unref_entropy();
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_mbedtls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -911,7 +935,7 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
|||||||
|
|
||||||
if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len,
|
if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len,
|
||||||
privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) {
|
privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) {
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_tls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +959,7 @@ altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2way
|
|||||||
ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
|
ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_tls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,7 +997,7 @@ altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_
|
|||||||
ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
|
ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x", ret, -1*ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x", ret, -1*ret));
|
||||||
altcp_mbedtls_free_config(conf->cert);
|
altcp_tls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,14 +1005,14 @@ altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_
|
|||||||
ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
|
ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x", ret, -1*ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x", ret, -1*ret));
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_tls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
|
ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x", ret, -1*ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x", ret, -1*ret));
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_tls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,19 +1049,21 @@ altcp_tls_free_config(struct altcp_tls_config *conf)
|
|||||||
mbedtls_entropy_free(&conf->entropy);
|
mbedtls_entropy_free(&conf->entropy);
|
||||||
mbedtls_ctr_drbg_free(&conf->ctr_drbg);
|
mbedtls_ctr_drbg_free(&conf->ctr_drbg);
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_mbedtls_free_config(conf);
|
||||||
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref)
|
altcp_mbedtls_unref_entropy();
|
||||||
altcp_tls_entropy_rng->ref--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
altcp_tls_free_entropy(void)
|
altcp_tls_free_entropy(void)
|
||||||
{
|
{
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
|
SYS_ARCH_PROTECT(old_level);
|
||||||
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) {
|
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) {
|
||||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
||||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
||||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
||||||
altcp_tls_entropy_rng = NULL;
|
altcp_tls_entropy_rng = NULL;
|
||||||
}
|
}
|
||||||
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "virtual" functions */
|
/* "virtual" functions */
|
||||||
|
Loading…
Reference in New Issue
Block a user