From 3d9e793ed193c7722f31b177f0bfb4629662c663 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 26 Mar 2004 22:52:09 +0000 Subject: some improvements that lead to fewer calls to malloc(). --- lib/gnutls_extensions.c | 41 +++++++++++++++++++++++--------------- lib/gnutls_extensions.h | 2 +- lib/gnutls_handshake.c | 52 +++++++++++++++++++++---------------------------- lib/gnutls_x509.c | 4 ++++ 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c index d13e89cd86..515ecb7032 100644 --- a/lib/gnutls_extensions.c +++ b/lib/gnutls_extensions.c @@ -174,20 +174,29 @@ static void _gnutls_extension_list_add( gnutls_session session, uint16 type) { } } -int _gnutls_gen_extensions( gnutls_session session, opaque** data) { +int _gnutls_gen_extensions( gnutls_session session, opaque* data, size_t data_size) +{ int next, size; uint16 pos=0; -opaque sdata[1024]; -int sdata_size = sizeof(sdata); +opaque *sdata; +int sdata_size; ext_send_func ext_send; - (*data) = gnutls_malloc(2); /* allocate size for size */ - if ((*data)==NULL) { + if (data_size < 2) { gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_INTERNAL_ERROR; } + /* allocate enough data for each extension. + */ + sdata_size = data_size; + sdata = gnutls_malloc( sdata_size); + if (sdata == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + pos+=2; next = MAX_EXT_TYPES; /* maximum supported extensions */ do { @@ -196,21 +205,21 @@ ext_send_func ext_send; if (ext_send == NULL) continue; size = ext_send( session, sdata, sdata_size); if (size > 0) { - (*data) = gnutls_realloc_fast( (*data), pos+size+4); - if ((*data)==NULL) { + if (data_size < pos+(size_t)size+4) { gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; + gnutls_free(sdata); + return GNUTLS_E_INTERNAL_ERROR; } /* write extension type */ - _gnutls_write_uint16( next, &(*data)[pos]); + _gnutls_write_uint16( next, &data[pos]); pos+=2; /* write size */ - _gnutls_write_uint16( size, &(*data)[pos]); + _gnutls_write_uint16( size, &data[pos]); pos+=2; - memcpy( &(*data)[pos], sdata, size); + memcpy( &data[pos], sdata, size); pos+=size; /* add this extension to the extension list @@ -221,7 +230,7 @@ ext_send_func ext_send; _gnutls_extension_get_name(next)); } else if (size < 0) { gnutls_assert(); - gnutls_free(*data); *data = NULL; + gnutls_free(sdata); return size; } @@ -230,13 +239,13 @@ ext_send_func ext_send; size = pos; pos-=2; /* remove the size of the size header! */ - _gnutls_write_uint16( pos, (*data)); + _gnutls_write_uint16( pos, data); if (size==2) { /* empty */ size = 0; - gnutls_free(*data); - (*data) = NULL; } + + gnutls_free( sdata); return size; } diff --git a/lib/gnutls_extensions.h b/lib/gnutls_extensions.h index 3ea42a7739..f87bc80cbd 100644 --- a/lib/gnutls_extensions.h +++ b/lib/gnutls_extensions.h @@ -22,7 +22,7 @@ const char *_gnutls_extension_get_name(uint16 type); int _gnutls_parse_extensions( gnutls_session, const opaque*, int); -int _gnutls_gen_extensions( gnutls_session session, opaque** data); +int _gnutls_gen_extensions( gnutls_session session, opaque* data, size_t data_size); typedef int (*ext_recv_func)( gnutls_session, const opaque*, size_t); /* recv data */ typedef int (*ext_send_func)( gnutls_session, opaque*, size_t); /* send data */ diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 2d4019cde5..efdc9a09b3 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1339,7 +1339,7 @@ static int _gnutls_read_server_hello(gnutls_session session, opaque *data, * Needed in client hello messages. Returns the new data length. */ static int _gnutls_copy_ciphersuites(gnutls_session session, - opaque ** ret_data) + opaque * ret_data, size_t ret_data_size) { int ret, i; GNUTLS_CipherSuite *cipher_suites; @@ -1381,21 +1381,18 @@ static int _gnutls_copy_ciphersuites(gnutls_session session, datalen += sizeof(uint16) + cipher_num; - *ret_data = gnutls_malloc(datalen); - if (*ret_data == NULL) { + if (datalen > ret_data_size) { gnutls_assert(); - gnutls_free(cipher_suites); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_INTERNAL_ERROR; } - - _gnutls_write_uint16(cipher_num, *ret_data); + + _gnutls_write_uint16(cipher_num, ret_data); pos += 2; for (i = 0; i < (cipher_num / 2); i++) { - memcpy( &(*ret_data)[pos], cipher_suites[i].CipherSuite, 2); + memcpy( &ret_data[pos], cipher_suites[i].CipherSuite, 2); pos += 2; } - gnutls_free(cipher_suites); return datalen; @@ -1406,7 +1403,7 @@ static int _gnutls_copy_ciphersuites(gnutls_session session, * Needed in hello messages. Returns the new data length. */ static int _gnutls_copy_comp_methods(gnutls_session session, - opaque ** ret_data) + opaque * ret_data, size_t ret_data_size) { int ret, i; uint8 *compression_methods, comp_num; @@ -1425,17 +1422,15 @@ static int _gnutls_copy_comp_methods(gnutls_session session, datalen = pos = 0; datalen += comp_num + 1; - *ret_data = gnutls_malloc(datalen); - if (*ret_data == NULL) { + if (datalen > ret_data_size) { gnutls_assert(); - gnutls_free(compression_methods); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_INTERNAL_ERROR; } - (*ret_data)[pos++] = comp_num; /* put the number of compression methods */ + ret_data[pos++] = comp_num; /* put the number of compression methods */ for (i = 0; i < comp_num; i++) { - (*ret_data)[pos++] = compression_methods[i]; + ret_data[pos++] = compression_methods[i]; } gnutls_free(compression_methods); @@ -1443,17 +1438,22 @@ static int _gnutls_copy_comp_methods(gnutls_session session, return datalen; } +/* This should be sufficient by now. It should hold all the extensions + * plus the headers in a hello message. + */ +#define MAX_EXT_DATA_LENGTH 1024 + /* This function sends the client hello handshake message. */ static int _gnutls_send_client_hello(gnutls_session session, int again) { opaque *data = NULL; - opaque *extdata = NULL; int extdatalen; int pos = 0; int datalen = 0, ret = 0; opaque random[TLS_RANDOM_SIZE]; gnutls_protocol_version hver; + opaque extdata[MAX_EXT_DATA_LENGTH]; opaque *SessionID = session->internals.resumed_security_parameters.session_id; @@ -1535,18 +1535,16 @@ static int _gnutls_send_client_hello(gnutls_session session, int again) /* Copy the ciphersuites. */ - extdatalen = _gnutls_copy_ciphersuites(session, &extdata); + extdatalen = _gnutls_copy_ciphersuites(session, extdata, sizeof(extdata)); if (extdatalen > 0) { datalen += extdatalen; data = gnutls_realloc_fast(data, datalen); if (data == NULL) { gnutls_assert(); - gnutls_free(extdata); return GNUTLS_E_MEMORY_ERROR; } memcpy(&data[pos], extdata, extdatalen); - gnutls_free(extdata); pos += extdatalen; } else { @@ -1560,18 +1558,16 @@ static int _gnutls_send_client_hello(gnutls_session session, int again) /* Copy the compression methods. */ - extdatalen = _gnutls_copy_comp_methods(session, &extdata); + extdatalen = _gnutls_copy_comp_methods(session, extdata, sizeof(extdata)); if (extdatalen > 0) { datalen += extdatalen; data = gnutls_realloc_fast(data, datalen); if (data == NULL) { gnutls_assert(); - gnutls_free(extdata); return GNUTLS_E_MEMORY_ERROR; } memcpy(&data[pos], extdata, extdatalen); - gnutls_free(extdata); pos += extdatalen; } else { @@ -1585,19 +1581,17 @@ static int _gnutls_send_client_hello(gnutls_session session, int again) /* Generate and copy TLS extensions. */ if (hver >= GNUTLS_TLS1) { - extdatalen = _gnutls_gen_extensions(session, &extdata); + extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata)); if (extdatalen > 0) { datalen += extdatalen; data = gnutls_realloc_fast(data, datalen); if (data == NULL) { gnutls_assert(); - gnutls_free(extdata); return GNUTLS_E_MEMORY_ERROR; } memcpy(&data[pos], extdata, extdatalen); - gnutls_free(extdata); } else if (extdatalen < 0) { gnutls_assert(); gnutls_free(data); @@ -1617,7 +1611,7 @@ static int _gnutls_send_client_hello(gnutls_session session, int again) static int _gnutls_send_server_hello(gnutls_session session, int again) { opaque *data = NULL; - opaque *extdata = NULL; + opaque extdata[MAX_EXT_DATA_LENGTH]; int extdatalen; int pos = 0; int datalen, ret = 0; @@ -1654,7 +1648,7 @@ static int _gnutls_send_server_hello(gnutls_session session, int again) if (again == 0) { datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3; - extdatalen = _gnutls_gen_extensions(session, &extdata); + extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata)); if (extdatalen < 0) { gnutls_assert(); @@ -1664,7 +1658,6 @@ static int _gnutls_send_server_hello(gnutls_session session, int again) data = gnutls_alloca(datalen + extdatalen); if (data == NULL) { gnutls_assert(); - gnutls_free(extdata); return GNUTLS_E_MEMORY_ERROR; } @@ -1705,7 +1698,6 @@ static int _gnutls_send_server_hello(gnutls_session session, int again) datalen += extdatalen; memcpy(&data[pos], extdata, extdatalen); - gnutls_free(extdata); } } diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index ff2603333d..e7d358f8e1 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -670,6 +670,10 @@ strfile _gnutls_file_to_str( const char * file) } tot_size = stat_st.st_size; + if (tot_size == 0) { + gnutls_assert(); + goto error; + } #ifdef HAVE_MMAP if ((tmp=mmap( NULL, tot_size, PROT_READ, MAP_SHARED, fd1, 0)) != MAP_FAILED) { -- cgit v1.2.1