]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Optimized memory handling in the record protocol.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 21 Apr 2002 11:22:56 +0000 (11:22 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 21 Apr 2002 11:22:56 +0000 (11:22 +0000)
lib/gnutls_buffers.c
lib/gnutls_cipher.c
lib/gnutls_cipher.h
lib/gnutls_compress.c
lib/gnutls_compress.h
lib/gnutls_compress_int.c
lib/gnutls_int.h
lib/gnutls_record.c
lib/gnutls_srp.c
lib/gnutls_state.h

index 72cb9d7a64670943fc6f56e41aea7b8277b8e5a6..001946d210b791b57798c532dcc21b2001ed7808 100644 (file)
@@ -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)
index 2069562bb4d1b34a4f45ac281485c99d4929e71d..d5898870dc6a5cf01e997c8a8221a58e61f1fca4 100644 (file)
@@ -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;
 }
 
index bb3b22479ef8a455001460c2e553260c722c4f1c..dd83394b9d50372edb92726af01453af99ad6de2 100644 (file)
  * 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);
index 019a6c35b32dcbcb34c344d5b3c7768ad666a203..13891324246be31a3787e504d4953a4685e02e89 100644 (file)
@@ -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)
index e526a2a481465f35c5103ab1d6f3c17401374881..4d87d48d4406289a29e93552d0da45b10f044b66 100644 (file)
@@ -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);
index 38e1dce3e1d196eb3f6ebd5e6e580852cb8e2de6..9970e8c11ec7147be799994fc006fcb53cab4911 100644 (file)
@@ -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;
        }
index 18d923b83fbea5d4eae801ef8291927b8dab7fd9..bbaf3013daf2bb8ce9e0e7b7f36724089e0ba70f 100644 (file)
@@ -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
 
index 8066d39d336a0961633e963c1e06911ea9d7b773..0e46a1408e69ee1645e3d67c4c03d3313dc3f107 100644 (file)
@@ -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)) {
index 70e2e7662422910ad71a6fb935271f2753ef3997..2fd21dedc96b76d39b3f5f27c2081efd5036cf26 100644 (file)
@@ -21,6 +21,7 @@
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
 #include <auth_srp.h>
+#include <gnutls_state.h>
 
 #ifdef ENABLE_SRP
 
index 02c476cffe35fcc2eea8b2672d985789363e3aa3..1303e3cd0d464a783ad78d67f94a40887bd41eac 100644 (file)
@@ -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; \