summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-04-21 11:22:56 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-04-21 11:22:56 +0000
commitec66696a8d45e009cae3d4c58eafec86cc971785 (patch)
treeb9009fea57613d6776fd53922ed8c2be9a1c53cc
parent7d1ab188e980d9e6524b7bdf4e0f277bc345fb79 (diff)
downloadgnutls-ec66696a8d45e009cae3d4c58eafec86cc971785.tar.gz
Optimized memory handling in the record protocol.
-rw-r--r--lib/gnutls_buffers.c3
-rw-r--r--lib/gnutls_cipher.c255
-rw-r--r--lib/gnutls_cipher.h12
-rw-r--r--lib/gnutls_compress.c6
-rw-r--r--lib/gnutls_compress.h4
-rw-r--r--lib/gnutls_compress_int.c2
-rw-r--r--lib/gnutls_int.h5
-rw-r--r--lib/gnutls_record.c66
-rw-r--r--lib/gnutls_srp.c1
-rw-r--r--lib/gnutls_state.h2
10 files changed, 208 insertions, 148 deletions
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 72cb9d7a64..001946d210 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -316,7 +316,8 @@ void _gnutls_io_clear_read_buffer( GNUTLS_STATE state) {
*
* sizeOfPtr should be unsigned.
*
- * This is not a general purpose function. It returns EXACTLY the data requested.
+ * This is not a general purpose function. It returns EXACTLY the data requested,
+ * which are stored in a local (in the state) buffer. A pointer (iptr) to this buffer is returned.
*
*/
ssize_t _gnutls_io_read_buffered( GNUTLS_STATE state, opaque **iptr, size_t sizeOfPtr, ContentType recv_type)
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index 2069562bb4..d5898870dc 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -57,81 +57,91 @@ is_read_comp_null( GNUTLS_STATE state) {
*/
int _gnutls_encrypt(GNUTLS_STATE state, const char* headers, int headers_size,
const char *data, size_t data_size,
- uint8 ** ciphertext, ContentType type, int random_pad)
+ opaque * ciphertext, int ciphertext_size, ContentType type, int random_pad)
{
gnutls_datum plain = { (char*)data, data_size };
- gnutls_datum comp, ciph;
- int err;
+ gnutls_datum comp;
+ int ret;
int free_comp = 1;
if (plain.size == 0 || is_write_comp_null( state)==0) {
comp = plain;
free_comp = 0;
} else {
- err = _gnutls_plaintext2TLSCompressed(state, &comp, plain);
- if (err < 0) {
+ ret = _gnutls_m_plaintext2compressed(state, &comp, plain);
+ if (ret < 0) {
gnutls_assert();
- return err;
+ return ret;
}
}
- err = _gnutls_compressed2TLSCiphertext(state, &ciph, comp, type, headers_size, random_pad);
- if (err < 0) {
- gnutls_assert();
- return err;
- }
+ ret = _gnutls_compressed2ciphertext(state, &ciphertext[headers_size],
+ ciphertext_size - headers_size, comp, type, random_pad);
if (free_comp)
gnutls_free_datum(&comp);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+
/* copy the headers */
- memcpy( ciph.data, headers, headers_size);
- WRITEuint16( ciph.size - headers_size, &ciph.data[3]);
-
- *ciphertext = ciph.data;
+ memcpy( ciphertext, headers, headers_size);
+ WRITEuint16( ret, &ciphertext[3]);
- return ciph.size;
+ return ret+headers_size;
}
int _gnutls_decrypt(GNUTLS_STATE state, char *ciphertext,
- size_t ciphertext_size, uint8 ** data,
+ size_t ciphertext_size, uint8 * data, int data_size,
ContentType type)
{
gnutls_datum gtxt;
- gnutls_datum gcomp;
gnutls_datum gcipher;
int ret;
- *data = NULL;
-
if (ciphertext_size == 0)
return 0;
gcipher.size = ciphertext_size;
gcipher.data = ciphertext;
- ret = _gnutls_ciphertext2TLSCompressed(state, &gcomp, gcipher, type);
+ ret = _gnutls_ciphertext2compressed(state, data, data_size, gcipher, type);
if (ret < 0) {
return ret;
}
- if (gcomp.size==0 || is_read_comp_null( state)==0) {
- gtxt = gcomp;
+ if (ret==0 || is_read_comp_null( state)==0) {
+ /* ret == ret */
+
} else {
- ret = _gnutls_TLSCompressed2plaintext(state, &gtxt, gcomp);
+ gnutls_datum gcomp;
+
+ /* compression has this malloc overhead.
+ */
+
+ gcomp.data = data;
+ gcomp.size = ret;
+ ret = _gnutls_m_compressed2plaintext(state, &gtxt, gcomp);
if (ret < 0) {
- gnutls_free_datum(&gcomp);
return ret;
}
+
+ if (gtxt.size > data_size) {
+ gnutls_assert();
+ gnutls_free_datum( &gtxt);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ memcpy( data, gtxt.data, gtxt.size);
+ ret = gtxt.size;
- gnutls_free_datum(&gcomp);
+ gnutls_free_datum( &gtxt);
}
- ret = gtxt.size;
-
- *data = gtxt.data;
-
return ret;
}
@@ -160,22 +170,69 @@ static void mac_deinit( GNUTLS_MAC_HANDLE td, opaque* res, int ver) {
}
}
+inline
+static int calc_enc_length( GNUTLS_STATE state, int data_size, int hash_size, uint8* pad, int random_pad,
+ CipherType block_algo, int blocksize)
+{
+uint8 rand;
+int length;
+
+ *pad = 0;
+
+ switch ( block_algo) {
+ case CIPHER_STREAM:
+ length =
+ data_size + hash_size;
+
+ break;
+ case CIPHER_BLOCK:
+ if (_gnutls_get_random(&rand, 1, GNUTLS_WEAK_RANDOM) < 0) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* make rand a multiple of blocksize */
+ if ( state->security_parameters.version == GNUTLS_SSL3 ||
+ random_pad==0) {
+ rand = 0;
+ } else {
+ rand = (rand / blocksize) * blocksize;
+ /* added to avoid the case of pad calculated 0
+ * seen below for pad calculation.
+ */
+ if (rand > blocksize) rand-=blocksize;
+ }
+
+ length =
+ data_size +
+ hash_size;
+
+ *pad = (uint8) (blocksize - (length % blocksize)) + rand;
+
+ length += *pad;
+
+ break;
+ default:
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
+ }
+
+ return length;
+}
+
/* This is the actual encryption
- * (and also keeps some space for headers (RECORD_HEADER_SIZE) in the
- * encrypted data)
+ * Encrypts the given compressed datum, and puts the result to cipher_data,
+ * which has cipher_size size.
+ * return the actual encrypted data length.
*/
-int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state,
- gnutls_datum*
- cipher,
+int _gnutls_compressed2ciphertext(GNUTLS_STATE state,
+ opaque* cipher_data, int cipher_size,
gnutls_datum compressed, ContentType _type,
- int headers_size,
int random_pad)
{
uint8 MAC[MAX_HASH_SIZE];
uint16 c_length;
- uint8 *data;
uint8 pad;
- uint8 rand;
uint64 seq_num;
int length,ret;
GNUTLS_MAC_HANDLE td;
@@ -186,6 +243,8 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state,
int blocksize =
_gnutls_cipher_get_block_size(state->security_parameters.
write_bulk_cipher_algorithm);
+ CipherType block_algo = _gnutls_cipher_is_block(state->security_parameters.write_bulk_cipher_algorithm);
+
ver = gnutls_protocol_get_version( state);
minor = _gnutls_version_get_minor( ver);
@@ -219,82 +278,51 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state,
_gnutls_hmac(td, compressed.data, compressed.size);
mac_deinit( td, MAC, ver);
}
- switch (_gnutls_cipher_is_block(state->security_parameters.write_bulk_cipher_algorithm)) {
- case CIPHER_STREAM:
- length =
- compressed.size + hash_size;
-
- data = gnutls_malloc(length+headers_size);
- if (data==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- break;
- case CIPHER_BLOCK:
- if (_gnutls_get_random(&rand, 1, GNUTLS_WEAK_RANDOM) < 0) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- /* make rand a multiple of blocksize */
- if ( state->security_parameters.version == GNUTLS_SSL3 ||
- random_pad==0) {
- rand = 0;
- } else {
- rand = (rand / blocksize) * blocksize;
- /* added to avoid the case of pad calculated 0
- * seen below for pad calculation.
- */
- if (rand > blocksize) rand-=blocksize;
- }
-
- length =
- compressed.size +
- hash_size;
-
- pad = (uint8) (blocksize - (length % blocksize)) + rand;
- length += pad;
- data = gnutls_malloc(length+headers_size);
- if (data==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- memset(&data[headers_size + length - pad], pad - 1, pad);
+ /* Calculate the encrypted length (padding etc.)
+ */
+ length = calc_enc_length( state, compressed.size, hash_size, &pad, random_pad, block_algo,
+ blocksize);
+ if (length < 0) {
+ gnutls_assert();
+ return length;
+ }
- break;
- default:
+ /* copy the encrypted data to cipher_data.
+ */
+ if (cipher_size < length) {
gnutls_assert();
- return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
+ return GNUTLS_E_MEMORY_ERROR;
}
- memcpy(&data[headers_size], compressed.data, compressed.size);
- memcpy(&data[compressed.size+headers_size], MAC, hash_size);
+ memcpy(cipher_data, compressed.data, compressed.size);
+ if (hash_size > 0)
+ memcpy(&cipher_data[compressed.size], MAC, hash_size);
+ if (block_algo==CIPHER_BLOCK && pad > 0)
+ memset(&cipher_data[ length - pad], pad - 1, pad);
+
+ /* Actual encryption (inplace).
+ */
if ( (ret = _gnutls_cipher_encrypt(state->connection_state.
- write_cipher_state, &data[headers_size],
+ write_cipher_state, cipher_data,
length)) < 0) {
- gnutls_free( data);
return ret;
}
- cipher->data = data;
- cipher->size = length + headers_size;
- return 0;
-
+ return length;
}
-int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state,
- gnutls_datum *
- compress,
+/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
+ * Returns the actual compressed packet size.
+ */
+int _gnutls_ciphertext2compressed(GNUTLS_STATE state,
+ opaque* compress_data, int compress_size,
gnutls_datum ciphertext, uint8 type)
{
uint8 MAC[MAX_HASH_SIZE];
uint16 c_length;
- uint8 *data;
uint8 pad;
uint64 seq_num;
uint16 length;
@@ -323,7 +351,8 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state,
return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
}
- /* actual encryption
+
+ /* actual decryption (inplace)
*/
switch (_gnutls_cipher_is_block(state->security_parameters.read_bulk_cipher_algorithm)) {
case CIPHER_STREAM:
@@ -379,23 +408,22 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state,
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
}
- if (length > 0) {
- data = gnutls_malloc(length);
- if (data==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- } else data = NULL;
- if (data!=NULL) {
- memcpy(data, ciphertext.data, length);
+ /* copy the decrypted stuff to compress_data.
+ */
+ if (compress_size < length) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
}
- compress->data = data;
- compress->size = length;
+ memcpy( compress_data, ciphertext.data, length);
+
- c_length = CONVuint16((uint16) compress->size);
+ c_length = CONVuint16((uint16) length);
seq_num = CONVuint64( &state->connection_state.read_sequence_number);
+ /* Pass the type, version, length and compressed through
+ * MAC.
+ */
if (td != GNUTLS_MAC_FAILED) {
_gnutls_hmac(td, UINT64DATA(seq_num), 8);
@@ -406,8 +434,8 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state,
}
_gnutls_hmac(td, &c_length, 2);
- if (data!=NULL)
- _gnutls_hmac(td, data, compress->size);
+ if (length!=0)
+ _gnutls_hmac(td, compress_data, length);
mac_deinit( td, MAC, ver);
}
@@ -415,12 +443,11 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state,
/* HMAC was not the same.
*/
if (memcmp
- (MAC, &ciphertext.data[compress->size], hash_size) != 0) {
- gnutls_free( data);
+ (MAC, &ciphertext.data[length], hash_size) != 0) {
gnutls_assert();
return GNUTLS_E_DECRYPTION_FAILED;
}
- return 0;
+ return length;
}
diff --git a/lib/gnutls_cipher.h b/lib/gnutls_cipher.h
index bb3b22479e..dd83394b9d 100644
--- a/lib/gnutls_cipher.h
+++ b/lib/gnutls_cipher.h
@@ -18,9 +18,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-int _gnutls_encrypt( GNUTLS_STATE state, const char* headers, int headers_size, const char* data, size_t data_size, uint8** ciphertext, ContentType type, int random_pad);
+int _gnutls_encrypt( GNUTLS_STATE state, const char* headers, int headers_size, const char* data, size_t data_size,
+ uint8* ciphertext, int ciphertext_size, ContentType type, int random_pad);
+
int _gnutls_decrypt(GNUTLS_STATE state, char *ciphertext,
- size_t ciphertext_size, uint8 ** data,
+ size_t ciphertext_size, uint8 * data, int data_size,
ContentType type);
-int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, gnutls_datum* cipher, gnutls_datum compressed, ContentType _type, int headers_size, int random_pad);
-int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state, gnutls_datum * compress, gnutls_datum ciphertext, uint8 type);
+int _gnutls_compressed2ciphertext(GNUTLS_STATE state, opaque* cipher_data, int cipher_size, gnutls_datum compressed,
+ ContentType _type, int random_pad);
+int _gnutls_ciphertext2compressed(GNUTLS_STATE state, opaque * compress_data, int compress_size,
+ gnutls_datum ciphertext, uint8 type);
diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c
index 019a6c35b3..1389132424 100644
--- a/lib/gnutls_compress.c
+++ b/lib/gnutls_compress.c
@@ -23,7 +23,9 @@
#include "gnutls_errors.h"
#include "gnutls_compress_int.h"
-int _gnutls_plaintext2TLSCompressed(GNUTLS_STATE state,
+/* These functions allocate the return value internally
+ */
+int _gnutls_m_plaintext2compressed(GNUTLS_STATE state,
gnutls_datum*
compress,
gnutls_datum plaintext)
@@ -45,7 +47,7 @@ int _gnutls_plaintext2TLSCompressed(GNUTLS_STATE state,
return 0;
}
-int _gnutls_TLSCompressed2plaintext(GNUTLS_STATE state,
+int _gnutls_m_compressed2plaintext(GNUTLS_STATE state,
gnutls_datum* plain,
gnutls_datum
compressed)
diff --git a/lib/gnutls_compress.h b/lib/gnutls_compress.h
index e526a2a481..4d87d48d44 100644
--- a/lib/gnutls_compress.h
+++ b/lib/gnutls_compress.h
@@ -18,5 +18,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-int _gnutls_plaintext2TLSCompressed(GNUTLS_STATE state, gnutls_datum* compress, gnutls_datum plaintext);
-int _gnutls_TLSCompressed2plaintext(GNUTLS_STATE state, gnutls_datum* plain, gnutls_datum compressed);
+int _gnutls_m_plaintext2compressed(GNUTLS_STATE state, gnutls_datum* compress, gnutls_datum plaintext);
+int _gnutls_m_compressed2plaintext(GNUTLS_STATE state, gnutls_datum* plain, gnutls_datum compressed);
diff --git a/lib/gnutls_compress_int.c b/lib/gnutls_compress_int.c
index 38e1dce3e1..9970e8c11e 100644
--- a/lib/gnutls_compress_int.c
+++ b/lib/gnutls_compress_int.c
@@ -157,7 +157,7 @@ uLongf size;
z_stream* zhandle;
#endif
- if (compressed_size > max_record_size+1024) {
+ if (compressed_size > max_record_size+EXTRA_COMP_SIZE) {
gnutls_assert();
return GNUTLS_E_DECOMPRESSION_FAILED;
}
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 18d923b83f..bbaf3013da 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -49,7 +49,7 @@ typedef const int* GNUTLS_LIST;
#define MAX24 16777215
#define MAX16 65535
-/* The sequence of handshake messages should not
+/* The size of a handshake message should not
* be larger than this value.
*/
#define MAX_HANDSHAKE_PACKET_SIZE 16*1024
@@ -83,7 +83,8 @@ typedef const int* GNUTLS_LIST;
#define MAX_RECORD_SIZE state->security_parameters.max_record_size
#define MAX_PAD_SIZE 255
#define EXTRA_COMP_SIZE 2048
-#define MAX_RECV_SIZE EXTRA_COMP_SIZE+MAX_PAD_SIZE+MAX_RECORD_SIZE+RECORD_HEADER_SIZE
+#define MAX_RECORD_OVERHEAD MAX_PAD_SIZE+EXTRA_COMP_SIZE
+#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_SIZE+RECORD_HEADER_SIZE
#define HANDSHAKE_HEADER_SIZE 4
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 8066d39d33..0e46a1408e 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -177,7 +177,7 @@ static int _gnutls_session_is_valid( GNUTLS_STATE state) {
static
ssize_t _gnutls_create_empty_record( GNUTLS_STATE state, ContentType type,
- opaque** erecord)
+ opaque* erecord, int erecord_size)
{
int cipher_size;
int retval;
@@ -185,9 +185,6 @@ ssize_t _gnutls_create_empty_record( GNUTLS_STATE state, ContentType type,
uint8 headers[5];
GNUTLS_Version lver;
- *erecord = NULL;
-
-
if (type!=GNUTLS_APPLICATION_DATA ||
_gnutls_cipher_is_block( gnutls_cipher_get(state))!=CIPHER_BLOCK)
/* alert messages and stream ciphers
@@ -208,7 +205,7 @@ ssize_t _gnutls_create_empty_record( GNUTLS_STATE state, ContentType type,
data2send = 0;
- cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, NULL, 0, erecord, type, 0);
+ cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, NULL, 0, erecord, erecord_size, type, 0);
if (cipher_size <= 0) {
gnutls_assert();
if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
@@ -244,7 +241,7 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
uint8 *cipher;
int cipher_size;
int retval, ret;
- int data2send;
+ int data2send_size;
uint8 headers[5];
const uint8 *data=_data;
GNUTLS_Version lver;
@@ -278,9 +275,9 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
(int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
if ( sizeofdata > MAX_RECORD_SIZE)
- data2send = MAX_RECORD_SIZE;
+ data2send_size = MAX_RECORD_SIZE;
else
- data2send = sizeofdata;
+ data2send_size = sizeofdata;
/* Only encrypt if we don't have data to send
* from the previous run. - probably interrupted.
@@ -301,8 +298,15 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
/* if this protection has been disabled
*/
if (state->gnutls_internals.cbc_protection_hack!=0) {
+ erecord_size = MAX_RECORD_OVERHEAD;
+ erecord = gnutls_alloca( erecord_size);
+ if (erecord==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
erecord_size =
- _gnutls_create_empty_record( state, type, &erecord);
+ _gnutls_create_empty_record( state, type, erecord, erecord_size);
if (erecord_size < 0) {
gnutls_assert();
return erecord_size;
@@ -311,29 +315,39 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
/* now proceed to packet encryption
*/
- cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, data, data2send, &cipher, type, 1);
+ cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
+ cipher = gnutls_alloca( cipher_size);
+ if (cipher==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, data, data2send_size, cipher,
+ cipher_size, type, 1);
if (cipher_size <= 0) {
gnutls_assert();
if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
- gnutls_free( erecord);
+ gnutls_afree( erecord);
+ gnutls_afree( cipher);
return cipher_size; /* error */
}
- retval = data2send;
- state->gnutls_internals.record_send_buffer_user_size = data2send;
+ retval = data2send_size;
+ state->gnutls_internals.record_send_buffer_user_size = data2send_size;
/* increase sequence number
*/
if (uint64pp( &state->connection_state.write_sequence_number) != 0) {
_gnutls_session_invalidate( state);
gnutls_assert();
- gnutls_free( erecord);
+ gnutls_afree( erecord);
+ gnutls_afree( cipher);
return GNUTLS_E_RECORD_LIMIT_REACHED;
}
ret = _gnutls_io_write_buffered2( state, erecord, erecord_size, cipher, cipher_size);
- gnutls_free( erecord);
- gnutls_free( cipher);
+ gnutls_afree( erecord);
+ gnutls_afree( cipher);
}
if ( ret != cipher_size + erecord_size) {
@@ -701,10 +715,18 @@ ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
/* decrypt the data we got
*/
- tmplen = _gnutls_decrypt( state, ciphertext, length, &tmpdata, recv_type);
+ tmplen = length + MAX_RECORD_OVERHEAD;
+ tmpdata = gnutls_alloca( tmplen);
+ if (tmpdata==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ tmplen = _gnutls_decrypt( state, ciphertext, length, tmpdata, tmplen, recv_type);
if (tmplen < 0) {
_gnutls_session_unresumable( state);
_gnutls_session_invalidate( state);
+ gnutls_afree(tmpdata);
gnutls_assert();
return tmplen;
}
@@ -717,11 +739,11 @@ ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */
gnutls_assert();
- gnutls_free(tmpdata);
+ gnutls_afree(tmpdata);
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
memcpy( data, tmpdata, sizeofdata);
- gnutls_free(tmpdata);
+ gnutls_afree(tmpdata);
return tmplen;
}
@@ -732,20 +754,20 @@ ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
/* increase sequence number */
if (uint64pp( &state->connection_state.read_sequence_number)!=0) {
_gnutls_session_invalidate( state);
- gnutls_free(tmpdata);
+ gnutls_afree(tmpdata);
gnutls_assert();
return GNUTLS_E_RECORD_LIMIT_REACHED;
}
if ( (ret=_gnutls_record_check_type( state, recv_type, type, htype, tmpdata, tmplen)) < 0) {
- gnutls_free( tmpdata);
+ gnutls_afree(tmpdata);
if (ret==GNUTLS_E_INT_RET_0) return 0;
gnutls_assert();
return ret;
}
- gnutls_free( tmpdata);
+ gnutls_afree(tmpdata);
/* Get Application data from buffer */
if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) {
diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c
index 70e2e76624..2fd21dedc9 100644
--- a/lib/gnutls_srp.c
+++ b/lib/gnutls_srp.c
@@ -21,6 +21,7 @@
#include <gnutls_int.h>
#include <gnutls_errors.h>
#include <auth_srp.h>
+#include <gnutls_state.h>
#ifdef ENABLE_SRP
diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h
index 02c476cffe..1303e3cd0d 100644
--- a/lib/gnutls_state.h
+++ b/lib/gnutls_state.h
@@ -10,6 +10,8 @@ KXAlgorithm gnutls_kx_get( GNUTLS_STATE state);
GNUTLS_BulkCipherAlgorithm gnutls_cipher_get( GNUTLS_STATE state);
CertificateType gnutls_cert_type_get( GNUTLS_STATE state);
+#include <gnutls_auth_int.h>
+
#define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(state) != auth) { \
gnutls_assert(); \
return ret; \