]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
optimizations and fixes in the TLS PRF calculation (and the SSL3 equivalent)
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 10 Dec 2001 08:25:38 +0000 (08:25 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 10 Dec 2001 08:25:38 +0000 (08:25 +0000)
17 files changed:
doc/TODO
lib/auth_anon.c
lib/auth_rsa.c
lib/gnutls_constate.c
lib/gnutls_datum.c
lib/gnutls_datum.h
lib/gnutls_errors.c
lib/gnutls_errors_int.h
lib/gnutls_global.c
lib/gnutls_handshake.c
lib/gnutls_hash_int.c
lib/gnutls_hash_int.h
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_mem.c
lib/gnutls_mem.h
lib/gnutls_record.c

index 85f06464ea42fc3ad58658549e9e81a502d88171..aabefcbe8e0087547392cd85be3700226251b151 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -5,12 +5,12 @@ in order to avoid having people working on the same thing.
 Current list:
 + Trace memory leaks in libgcrypt
 + Audit the code
+* Add support for certificates with DSS parameters
+* OpenPGP certificate support
 * Add callbacks to get SRP parameters (instead of a reading password file)
 * Minimize footprint.
-* Add support for certificates with DSS parameters
 * Add more TLS extensions
 * Add support for PKCS8 encrypted private keys
-* OpenPGP certificate support
 - Add Kerberos support
 
 (+) Means high priority 
index aece0378a24ab9f876d6ef21c94b3acd80464480..712da0fbffb3ef9b6ed5c88daa9245ff8fca3fb0 100644 (file)
@@ -57,7 +57,7 @@ MOD_AUTH_STRUCT anon_auth_struct = {
  */
 int _gnutls_generate_key(GNUTLS_KEY key) {
         _gnutls_mpi_print( NULL, &key->key.size, key->KEY);
-       key->key.data = secure_malloc( key->key.size);
+       key->key.data = gnutls_secure_malloc( key->key.size);
        if ( key->key.data==NULL) {
                return GNUTLS_E_MEMORY_ERROR;
        }
index f34b96a4fa6f458a3e22dedc7573db8415ab5d0b..57ca961672ae9720bb5ed88a301e97460781c9b1 100644 (file)
@@ -109,11 +109,11 @@ return ret;
 #ifdef DEBUG
                _gnutls_log( "Possible PKCS-1 format attack\n");
 #endif
-               RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
+               RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
        } else {
                ret = 0;
                if (plaintext.size != TLS_MASTER_SIZE) {        /* WOW */
-                       RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
+                       RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
                } else {
                        if (_gnutls_get_adv_version_major( state) != plaintext.data[0] 
                                || _gnutls_get_adv_version_minor( state) != plaintext.data[1]) {
@@ -157,7 +157,7 @@ int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
                gnutls_assert();
                return GNUTLS_E_INSUFICIENT_CRED;
        }
-       RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
+       RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
 
        ver = _gnutls_version_max(state);
 
index e118420e086e8b41a3e4fed7da602595ef49f30f..d09d6da863cceec39f5dd5f9d8a41a7575212c49 100644 (file)
@@ -36,7 +36,7 @@ int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_siz
        opaque *key_block;
        char keyexp[] = "key expansion";
        char random[2*TLS_RANDOM_SIZE];
-       int pos;
+       int pos, ret;
        int block_size;
        
        if (state->cipher_specs.generated_keys!=0) {
@@ -49,57 +49,78 @@ int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_siz
        
 
        block_size = 2 * hash_size + 2 * key_size + 2 * IV_size;
-
+       key_block = gnutls_secure_malloc( block_size);
+       if (key_block==NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       
        memcpy(random, state->security_parameters.server_random, TLS_RANDOM_SIZE);
        memcpy(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, TLS_RANDOM_SIZE);
 
        if ( state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */
-               key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE,
-                       block_size);
+               ret = gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE,
+                       block_size, key_block);
        } else { /* TLS 1.0 */
-               key_block =
+               ret =
                    gnutls_PRF( state->security_parameters.master_secret, TLS_MASTER_SIZE,
                               keyexp, strlen(keyexp), random, 2*TLS_RANDOM_SIZE, 
-                              block_size);
+                              block_size, key_block);
+       }
+       
+       if (ret<0) {
+               gnutls_assert();
+               gnutls_secure_free(key_block);
+               return ret;
        }
        
-       if (key_block==NULL) return GNUTLS_E_MEMORY_ERROR;
-
 #ifdef HARD_DEBUG
        _gnutls_log( "KEY BLOCK[%d]: %s\n",block_size, _gnutls_bin2hex(key_block, block_size));
 #endif
 
        pos = 0;
        if (hash_size > 0) {
-               if (gnutls_sset_datum( &state->cipher_specs.client_write_mac_secret, &key_block[pos], hash_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.client_write_mac_secret, &key_block[pos], hash_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=hash_size;
 
-               if (gnutls_sset_datum( &state->cipher_specs.server_write_mac_secret, &key_block[pos], hash_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.server_write_mac_secret, &key_block[pos], hash_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=hash_size;
        }
        
        if (key_size > 0) {
-               if (gnutls_sset_datum( &state->cipher_specs.client_write_key, &key_block[pos], key_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.client_write_key, &key_block[pos], key_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=key_size;
 
-               if (gnutls_sset_datum( &state->cipher_specs.server_write_key, &key_block[pos], key_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.server_write_key, &key_block[pos], key_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=key_size;
        }
        if (IV_size > 0) {
-               if (gnutls_sset_datum( &state->cipher_specs.client_write_IV, &key_block[pos], IV_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.client_write_IV, &key_block[pos], IV_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=IV_size;
        
-               if (gnutls_sset_datum( &state->cipher_specs.server_write_IV, &key_block[pos], IV_size) < 0 )
+               if (gnutls_sset_datum( &state->cipher_specs.server_write_IV, &key_block[pos], IV_size) < 0 ) {
+                       gnutls_secure_free(key_block);
                        return GNUTLS_E_MEMORY_ERROR;
+               }
                pos+=IV_size;
        }
        
-       secure_free(key_block);
+       gnutls_secure_free(key_block);
 
        state->cipher_specs.generated_keys = 1;
 
@@ -236,8 +257,10 @@ int rc;
        }
 
 
-       _gnutls_set_read_keys(state);
-        
+       rc = _gnutls_set_read_keys(state);
+       if (rc < 0)
+               return rc;
+               
 #ifdef HANDSHAKE_DEBUG
        _gnutls_log( "Cipher Suite: %s\n",
                _gnutls_cipher_suite_get_name(state->
@@ -381,7 +404,9 @@ int rc;
                _gnutls_cpy_write_security_parameters( &state->security_parameters, &state->gnutls_internals.resumed_security_parameters);
        }
        
-       _gnutls_set_write_keys(state);
+       rc = _gnutls_set_write_keys(state);
+       if (rc < 0)
+               return rc;
 
 #ifdef HANDSHAKE_DEBUG
        _gnutls_log( "Cipher Suite: %s\n",
index c94144bc96aa904565027564588dfcbede3f459b..d39ef33fd1f5c558ffc26d87ef314dde657db962 100644 (file)
@@ -56,7 +56,7 @@ int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size) {
 }
 
 int gnutls_sset_datum( gnutls_datum* dat, const void* data, int data_size) {
-       dat->data = secure_malloc(data_size);
+       dat->data = gnutls_secure_malloc(data_size);
        if (dat->data==NULL) return GNUTLS_E_MEMORY_ERROR;
        
        dat->size = data_size;
@@ -75,7 +75,7 @@ void gnutls_free_datum( gnutls_datum* dat) {
 
 void gnutls_sfree_datum( gnutls_datum* dat) {
        if (dat->data!=NULL && dat->size!=0)
-               secure_free( dat->data);
+               gnutls_secure_free( dat->data);
 
        dat->data = NULL;
        dat->size = 0;
index 4280b191e53d868a40771c0c0c8dfe68710380ca..15aa73ba63e98dfc3cf52450884338916a4ca73f 100644 (file)
@@ -3,8 +3,6 @@ void WRITEdatum24( opaque* dest, gnutls_datum dat);
 void WRITEdatum32( opaque* dest, gnutls_datum dat);
 void WRITEdatum8( opaque* dest, gnutls_datum dat);
 
-typedef gnutls_datum gnutls_sdatum;
-
 int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size);
 /* uses secure_malloc */
 int gnutls_sset_datum( gnutls_sdatum* dat, const void* data, int data_size);
index 2da20177c90c65491ca322fe6be35c2059e1fec8..1eae48c2c9a07ecc51662b7009fde0b2b7a4dea2 100644 (file)
@@ -47,6 +47,7 @@ static gnutls_error_entry error_algorithms[] = {
        GNUTLS_ERROR_ENTRY( GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_SESSION, 1),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_INTERNAL, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_UNABLE_SEND_DATA, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_FATAL_ALERT_RECEIVED ,1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_BAD_MESSAGE, 1),
index 4f3c73bf2bb5377c2231c7822715ee880203e72e..fa6d9f9b7442b745a7ec4ddd1e768306336cbb67 100644 (file)
@@ -58,5 +58,6 @@
 #define GNUTLS_E_ILLEGAL_PARAMETER -55  /* GNUTLS_A_ILLEGAL_PARAMETER */
 #define GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE -56
 #define GNUTLS_E_PKCS1_WRONG_PAD -57
+#define GNUTLS_E_INTERNAL -58
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250
index 5273faac5d4c2b8a39b934f99eebb4cd02ed9d0f..491e4c1bbed81056b15d61704a5f90109bf28d3b 100644 (file)
@@ -83,7 +83,7 @@ int gnutls_global_init()
        int result;
 
        /* for gcrypt in order to be able to allocate memory */
-       gcry_set_allocation_handler(gnutls_malloc, secure_malloc, _gnutls_is_secure_memory, gnutls_realloc, gnutls_free);
+       gcry_set_allocation_handler(gnutls_malloc, gnutls_secure_malloc, _gnutls_is_secure_memory, gnutls_realloc, gnutls_free);
 
        /* set default recv/send functions
         */
index b812d2d50c69778dc5a6111955f807d39b9c3342..64e66398d246d7082d090cd1720c6076ccb5006d 100644 (file)
@@ -113,34 +113,39 @@ void _gnutls_set_client_random(GNUTLS_STATE state, uint8 * random)
 /* Calculate The SSL3 Finished message */
 #define SSL3_CLIENT_MSG "CLNT"
 #define SSL3_SERVER_MSG "SRVR"
-void *_gnutls_ssl3_finished(GNUTLS_STATE state, int type, int skip)
+static int _gnutls_ssl3_finished(GNUTLS_STATE state, int type, int skip, opaque* ret)
 {
        int siz;
        GNUTLS_MAC_HANDLE td;
        GNUTLS_MAC_HANDLE td2;
        char tmp[MAX_HASH_SIZE];
-       char *concat;
        char *mesg, *data;
 
-       concat = gnutls_malloc(36);
-       if (concat==NULL) {
-               gnutls_assert();
-               return NULL;
-       }
-       
        td = gnutls_mac_init_ssl3_handshake(GNUTLS_MAC_MD5,
                                            state->security_parameters.
                                            master_secret, 48);
+       if (td==NULL) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+
        td2 =
            gnutls_mac_init_ssl3_handshake(GNUTLS_MAC_SHA,
                                           state->security_parameters.
                                           master_secret, 48);
+       if (td2==NULL) {
+               gnutls_assert();
+               gnutls_mac_deinit_ssl3_handshake(td, tmp);
+               return GNUTLS_E_HASH_FAILED;
+       }
 
        siz = gnutls_get_handshake_buffer_size(state) - skip;
        data = gnutls_malloc(siz);
        if (data==NULL) {
                gnutls_assert();
-               return NULL;
+               gnutls_mac_deinit_ssl3_handshake(td2, tmp);
+               gnutls_mac_deinit_ssl3_handshake(td, tmp);
+               return GNUTLS_E_MEMORY_ERROR;
        }
 
        gnutls_read_handshake_buffer(state, data, siz);
@@ -159,35 +164,47 @@ void *_gnutls_ssl3_finished(GNUTLS_STATE state, int type, int skip)
        gnutls_mac_ssl3(td2, mesg, siz);
 
        gnutls_mac_deinit_ssl3_handshake(td, tmp);
-       memcpy(concat, tmp, 16);
+       memcpy(ret, tmp, 16);
 
        gnutls_mac_deinit_ssl3_handshake(td2, tmp);
 
-       memcpy(&concat[16], tmp, 20);
-       return concat;
+       memcpy(&ret[16], tmp, 20);
+       return 0;
 }
 
 /* Hash the handshake messages as required by TLS 1.0 */
 #define SERVER_MSG "server finished"
 #define CLIENT_MSG "client finished"
-void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
+int _gnutls_finished(GNUTLS_STATE state, int type, int skip, void* ret)
 {
        int siz;
        GNUTLS_MAC_HANDLE td;
        GNUTLS_MAC_HANDLE td2;
        char tmp[MAX_HASH_SIZE];
-       char concat[36];
-       char *mesg;
-       char *data;
+       opaque concat[36];
+       opaque *mesg, *data;
 
        td = gnutls_hash_init(GNUTLS_MAC_MD5);
+       if (td==GNUTLS_HASH_FAILED) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+       
        td2 = gnutls_hash_init(GNUTLS_MAC_SHA);
+       if (td2==GNUTLS_HASH_FAILED) {
+               gnutls_assert();
+               gnutls_hash_deinit( td2, tmp);
+               return GNUTLS_E_HASH_FAILED;
+       }
 
        siz = gnutls_get_handshake_buffer_size(state) - skip;
-       data = gnutls_malloc(siz);
+
+       data = gnutls_malloc( siz);
        if (data==NULL) {
                gnutls_assert();
-               return NULL;
+               gnutls_hash_deinit( td2, tmp);
+               gnutls_hash_deinit( td, tmp);
+               return GNUTLS_E_MEMORY_ERROR;
        }
 
        gnutls_read_handshake_buffer(state, data, siz);
@@ -209,10 +226,8 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
        } else {
                mesg = CLIENT_MSG;
        }
-       data =
-           gnutls_PRF(state->security_parameters.master_secret,
-                      48, mesg, strlen(mesg), concat, 36, 12);
-       return data;
+       return gnutls_PRF(state->security_parameters.master_secret,
+                      48, mesg, strlen(mesg), concat, 36, 12, ret);
 }
 
 /* this function will produce TLS_RANDOM_SIZE bytes of random data
@@ -401,28 +416,33 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
  */
 int _gnutls_send_finished( GNUTLS_STATE state, int again)
 {
-       uint8 *data=NULL;
+       uint8 data[36];
        int ret;
        int data_size=0;
 
        if (again==0) {
                if (state->security_parameters.version == GNUTLS_SSL3) {
-                       data =
+                       ret =
                            _gnutls_ssl3_finished(state,
                                                  state->security_parameters.
-                                                 entity, 0);
+                                                 entity, 0, data);
                        data_size = 36;
                } else {                /* TLS 1.0 */
-                       data =
+                       ret =
                            _gnutls_finished(state,
-                                            state->security_parameters.entity, 0);
+                                            state->security_parameters.entity, 0, data);
                        data_size = 12;
                }
        }
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+       
        ret =
            _gnutls_send_handshake( state, data, data_size,
                                   GNUTLS_FINISHED);
-       gnutls_free(data);
 
        return ret;
 }
@@ -432,7 +452,7 @@ int _gnutls_send_finished( GNUTLS_STATE state, int again)
  */
 int _gnutls_recv_finished( GNUTLS_STATE state)
 {
-       uint8 *data, *vrfy;
+       uint8 data[36], *vrfy;
        int data_size;
        int ret;
        int vrfysize;
@@ -457,27 +477,32 @@ int _gnutls_recv_finished( GNUTLS_STATE state)
                gnutls_assert();
                return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
        }
+       
        if (state->security_parameters.version == GNUTLS_SSL3) {
                /* skip the bytes from the last message */
-               data =
+               ret =
                    _gnutls_ssl3_finished(state,
                                          (state->security_parameters.
                                           entity + 1) % 2,
                                          vrfysize +
-                                         HANDSHAKE_HEADER_SIZE);
+                                         HANDSHAKE_HEADER_SIZE, data);
        } else {                /* TLS 1.0 */
-               data =
+               ret =
                    _gnutls_finished(state,
                                     (state->security_parameters.entity +
                                      1) % 2,
-                                    vrfysize + HANDSHAKE_HEADER_SIZE);
+                                    vrfysize + HANDSHAKE_HEADER_SIZE, data);
+       }
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
        }
 
        if (memcmp(vrfy, data, data_size) != 0) {
                gnutls_assert();
                ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
        }
-       gnutls_free(data);
        gnutls_free(vrfy);
 
        return ret;
index 097fc9c46933ebe1b377605c746aa786852f3df1..aabb2b1ac8dd9baf452cf0f18d27c6f4a2775e1b 100644 (file)
@@ -19,8 +19,8 @@
  */
 
 #include <gnutls_int.h>
-
 #include <gnutls_hash_int.h>
+#include <gnutls_errors.h>
 
 /* This file handles all the internal functions that cope with hashes
  * and hmacs. Currently it uses the functions provided by
@@ -367,7 +367,7 @@ void gnutls_mac_deinit_ssl3_handshake(GNUTLS_MAC_HANDLE handle, void* digest)
        return;
 }
 
-static void ssl3_sha(int i, char *secret, int secret_len, char *random,
+static int ssl3_sha(int i, char *secret, int secret_len, char *random,
               int random_len, void* digest)
 {
        int j;
@@ -380,42 +380,63 @@ static void ssl3_sha(int i, char *secret, int secret_len, char *random,
        }
 
        td = gnutls_hash_init(GNUTLS_MAC_SHA);
+       if (td == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+
        gnutls_hash(td, text1, i + 1);
        gnutls_hash(td, secret, secret_len);
        gnutls_hash(td, random, random_len);
        
        gnutls_hash_deinit(td, digest);
+       return 0;
 }
 
-static void ssl3_md5(int i, char *secret, int secret_len, char *random,
+static int ssl3_md5(int i, char *secret, int secret_len, char *random,
               int random_len, void* digest)
 {
        opaque tmp[MAX_HASH_SIZE];
        GNUTLS_MAC_HANDLE td;
-
+       int ret;
+       
        td = gnutls_hash_init(GNUTLS_MAC_MD5);
+       if (td == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+
        gnutls_hash(td, secret, secret_len);
 
-       ssl3_sha(i, secret, secret_len, random, random_len, tmp);
+       ret = ssl3_sha(i, secret, secret_len, random, random_len, tmp);
+       if (ret < 0) {
+               gnutls_assert();
+               gnutls_hash_deinit(td, digest);
+               return ret;
+       }
 
        gnutls_hash(td, tmp, gnutls_hash_get_algo_len(GNUTLS_MAC_SHA));
 
        gnutls_hash_deinit(td, digest);
-
+       return 0;
 }
 
-svoid *gnutls_ssl3_generate_random(void *secret, int secret_len, void *random,
-                          int random_len, int bytes)
+int gnutls_ssl3_generate_random(void *secret, int secret_len, void *random,
+                          int random_len, int bytes, opaque* ret)
 {
        int size = 0, i = 0;
        char digest[MAX_HASH_SIZE];
-       char *ret = secure_malloc(bytes);
        int block = gnutls_hash_get_algo_len(GNUTLS_MAC_MD5);
+       int result;
 
        while (size < bytes) {
 
-               ssl3_md5(i, secret, secret_len, random, random_len, digest);
-
+               result = ssl3_md5(i, secret, secret_len, random, random_len, digest);
+               if (result < 0) {
+                       gnutls_assert();
+                       return result;
+               }
+               
                size += block;
                        
                memcpy(&ret[size - block], digest,
@@ -423,5 +444,5 @@ svoid *gnutls_ssl3_generate_random(void *secret, int secret_len, void *random,
                i++;
        }
 
-       return ret;
+       return 0;
 }
index be1066c4d40fa7176852662bec3b770bd10eced2..03f34dbc9a5c357329ae763479f03440ac22bb54 100644 (file)
@@ -60,7 +60,7 @@ int gnutls_hash_get_algo_len(MACAlgorithm algorithm);
 int gnutls_hash(GNUTLS_HASH_HANDLE handle, const void* text, int textlen);
 void gnutls_hash_deinit(GNUTLS_HASH_HANDLE handle, void* digest);
 
-svoid *gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, int random_len, int bytes);
+int gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, int random_len, int bytes, opaque* ret);
 
 GNUTLS_MAC_HANDLE gnutls_mac_init_ssl3_handshake(MACAlgorithm algorithm, void *key, int keylen);
 void gnutls_mac_deinit_ssl3_handshake(GNUTLS_MAC_HANDLE handle, void* digest);
index 01dff2a60fe5c56ff3d4dbf88a1a593f5535ad91..32a119d39e62748cc1b34a0c3cc5528308c5428d 100644 (file)
 #define HARD_DEBUG
 #define WRITE_DEBUG
 #define READ_DEBUG
-#define RECORD_DEBUG
 #define HANDSHAKE_DEBUG // Prints some information on handshake 
-#define DEBUG
+#define RECORD_DEBUG
 */
+#define DEBUG
+
 
 /* It might be a good idea to replace int with void*
  * here.
@@ -131,6 +132,7 @@ typedef struct {
        opaque * data;
        int size;
 } gnutls_datum;
+typedef gnutls_datum gnutls_sdatum;
 
 typedef struct {
        AlertLevel level;
@@ -182,7 +184,7 @@ typedef struct {
 
 struct GNUTLS_KEY_INT {
        /* For DH KX */
-       gnutls_datum                    key;
+       gnutls_sdatum                   key;
        MPI                             KEY;
        MPI                             client_Y;
        MPI                             client_g;
@@ -245,17 +247,10 @@ typedef enum GNUTLS_Version { GNUTLS_SSL3=1, GNUTLS_TLS1, GNUTLS_VERSION_UNKNOWN
 
 /* This structure holds parameters got from TLS extension
  * mechanism. (some extensions may hold parameters in AUTH_INFO
- * structures instead - see SRP).
+ * structures also - see SRP).
  */
-typedef enum GNUTLS_NAME_IND { GNUTLS_DNSNAME=1 } GNUTLS_NAME_IND; 
-
-typedef struct {
-       opaque dnsname[MAX_DNSNAME_SIZE];
-       GNUTLS_NAME_IND type;
-} name_ind;
 
 typedef struct {
-       name_ind        name;
        opaque          srp_username[MAX_SRP_USERNAME];
 } TLSExtensions;
 
@@ -502,9 +497,9 @@ typedef struct GNUTLS_STATE_INT *GNUTLS_STATE;
 
 /* functions */
 int gnutls_send_alert( GNUTLS_STATE state, AlertLevel level, AlertDescription desc);
-svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label,
+int gnutls_PRF( opaque * secret, int secret_size, uint8 * label,
                  int label_size, opaque * seed, int seed_size,
-                 int total_bytes);
+                 int total_bytes, void* ret);
 void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version);
 GNUTLS_Version gnutls_protocol_get_version(GNUTLS_STATE state);
 void _gnutls_free_auth_info( GNUTLS_STATE state);
index f52e3cf1b7ff43c01c346a4fdc0fffdba886d964..7b695b6e5904c314d9690b9ffebccc76ff0d3674 100644 (file)
@@ -27,6 +27,7 @@
 #include "debug.h"
 #include "gnutls_gcry.h"
 #include <gnutls_record.h>
+#include <gnutls_datum.h>
 
 /* This file contains important thing for the TLS handshake procedure.
  */
@@ -40,47 +41,40 @@ int _gnutls_generate_master( GNUTLS_STATE state) {
        return 0;
 }
 
+#define PREMASTER state->gnutls_key->key
 static int generate_normal_master( GNUTLS_STATE state) {
-int premaster_size;
-opaque* premaster, *master;
 int ret = 0;
 char random[2*TLS_RANDOM_SIZE];
 
        memcpy(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
        memcpy(&random[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
 
-       /* generate premaster */
-        premaster_size = state->gnutls_key->key.size;
-       premaster = state->gnutls_key->key.data;
-
 #ifdef HARD_DEBUG
-       _gnutls_log( "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
+       _gnutls_log( "PREMASTER SECRET[%d]: %s\n", PREMASTER.size, _gnutls_bin2hex(PREMASTER.data, PREMASTER.size));
        _gnutls_log( "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
        _gnutls_log( "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
 #endif
 
        if ( state->security_parameters.version == GNUTLS_SSL3) {
-               master =
-                   gnutls_ssl3_generate_random( premaster, premaster_size,
-                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
+               ret =
+                   gnutls_ssl3_generate_random( PREMASTER.data, PREMASTER.size,
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE,
+                              state->security_parameters.master_secret);
 
        } else {
-               master =
-                   gnutls_PRF( premaster, premaster_size,
+               ret =
+                   gnutls_PRF( PREMASTER.data, PREMASTER.size,
                               MASTER_SECRET, strlen(MASTER_SECRET),
-                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE); 
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE, 
+                              state->security_parameters.master_secret); 
        }
-       secure_free(premaster);
-       state->gnutls_key->key.size = 0;
-       state->gnutls_key->key.data = NULL;
+       gnutls_sfree_datum(&PREMASTER);
        
-       if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
+       if (ret<0) return ret;
        
 #ifdef HARD_DEBUG
-       _gnutls_log( "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
+       _gnutls_log( "MASTER SECRET: %s\n", _gnutls_bin2hex(state->security_parameters.master_secret, TLS_MASTER_SIZE));
 #endif
-       memcpy(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
-       secure_free(master);
        return ret;
 }
 
index 6ed871a93f3ad634b2bdb5fc1c60e656f3e56129..25476482e4b8bcfc0c845e2ed8b8ebecdd3ee28f 100644 (file)
@@ -36,6 +36,7 @@ int _gnutls_is_secure_memory(const void *ign)
 
 int _gnutls_is_secure_memory(const svoid * mem)
 {
+       if (mem==NULL) return 0;
        return *((opaque *) mem - 1);
 }
 
@@ -122,21 +123,26 @@ void *gnutls_realloc_fast(void *ptr, size_t size)
 
 void gnutls_free(void *_ptr)
 {
-       opaque *ptr = _ptr;
-
        if (_ptr == NULL)
                return;
 
-       ptr -= EXTRA_SIZE;
+       if ( _gnutls_is_secure_memory( _ptr) != 0) {
+               return gnutls_secure_free( _ptr);
+       } else {
+               opaque *ptr = _ptr;
+
+
+               ptr -= EXTRA_SIZE;
 
 #ifdef MALLOC_DEBUG
-       _gnutls_log("Freed: %x with %d bytes\n", _ptr,
+               _gnutls_log("Freed: %x with %d bytes\n", _ptr,
                    _gnutls_malloc_ptr_size(_ptr));
 #endif
-       free(ptr);
+               free(ptr);
+       }
 }
 
-svoid *secure_malloc(size_t size)
+svoid *gnutls_secure_malloc(size_t size)
 {
        opaque *ret;
        ret = gnutls_malloc(size);
@@ -149,10 +155,10 @@ svoid *secure_malloc(size_t size)
 
 }
 
-svoid *secure_calloc(size_t nmemb, size_t size)
+svoid *gnutls_secure_calloc(size_t nmemb, size_t size)
 {
        svoid *ret;
-       ret = secure_malloc(size);
+       ret = gnutls_secure_malloc(size);
        if (ret == NULL)
                return ret;
 
@@ -161,35 +167,39 @@ svoid *secure_calloc(size_t nmemb, size_t size)
        return ret;
 }
 
-size_t _secure_ptr_size(svoid * ptr)
+size_t _gnutls_secure_ptr_size(svoid * ptr)
 {
        return _gnutls_malloc_ptr_size(ptr);
 }
 
-svoid *secure_realloc(svoid * ptr, size_t size)
+svoid *gnutls_secure_realloc(svoid * ptr, size_t size)
 {
        svoid *ret;
-       if (ptr != NULL && size <= _secure_ptr_size(ptr)) {
+       if (ptr != NULL && size <= _gnutls_secure_ptr_size(ptr)) {
                /* do not do realloc.
                 * return the previous pointer.
                 */
                return ptr;
        }
-       ret = secure_malloc(size);
+       ret = gnutls_secure_malloc(size);
        if (ret == NULL)
                return ret;
 
        if (ptr != NULL) {
-               memcpy(ret, ptr, GMIN(_secure_ptr_size(ptr), size));
-               secure_free(ptr);
+               memcpy(ret, ptr, GMIN(_gnutls_secure_ptr_size(ptr), size));
+               gnutls_secure_free(ptr);
        }
 
        return ret;
 }
 
-void secure_free(svoid * ptr)
+void gnutls_secure_free(svoid * ptr)
 {
-       memset(ptr, 0, _secure_ptr_size(ptr));
+opaque* _ptr = ptr;
+
+       memset(ptr, 0, _gnutls_secure_ptr_size(ptr));
+       *((opaque *) _ptr - 1) = 0;     /* not secure mem */
+
        gnutls_free(ptr);
 }
 
index fbe0375cc61bd5d82e9ed482814c5f2352d98a19..84f9d32610c6203f793da84075d4d67c2d904844 100644 (file)
@@ -2,7 +2,7 @@
 # include <dmalloc.h>
 #endif
 
-typedef void svoid; /* for functions that allocate using secure_free */
+typedef void svoid; /* for functions that allocate using gnutls_secure_free */
 
 #ifdef USE_DMALLOC
 # define gnutls_malloc malloc
@@ -10,20 +10,20 @@ typedef void svoid; /* for functions that allocate using secure_free */
 # define gnutls_realloc_fast realloc
 # define gnutls_free free
 # define gnutls_calloc calloc
-# define secure_malloc malloc
-# define secure_realloc realloc
-# define secure_free free
-# define secure_calloc calloc
+# define gnutls_secure_malloc malloc
+# define gnutls_secure_realloc realloc
+# define gnutls_secure_free free
+# define gnutls_secure_calloc calloc
 # define gnutls_strdup strdup
 int _gnutls_is_secure_memory(const void*);
 
 #else
 
-svoid* secure_malloc( size_t size);
-svoid* secure_calloc( size_t nmemb, size_t size);
-size_t _secure_ptr_size( svoid* ptr);
-svoid* secure_realloc( svoid* ptr, size_t size);
-void secure_free( svoid* ptr);
+svoid* gnutls_secure_malloc( size_t size);
+svoid* gnutls_secure_calloc( size_t nmemb, size_t size);
+size_t _gnutls_secure_ptr_size( svoid* ptr);
+svoid* gnutls_secure_realloc( svoid* ptr, size_t size);
+void gnutls_secure_free( svoid* ptr);
 int _gnutls_is_secure_memory(const svoid* mem);
 
 void* gnutls_malloc( size_t size);
index 4fb47990b54b2182629980403c56dfbc97b6eeea..14703b8807f0b7b9a7d169d83308dbae8438f448 100644 (file)
@@ -255,30 +255,23 @@ static void _gnutls_cal_PRF_A( MACAlgorithm algorithm, void *secret, int secret_
        return;
 }
 
-#define MAX_SEED_SIZE 140
+#define MAX_SEED_SIZE 200
 
 /* Produces "total_bytes" bytes using the hash algorithm specified.
  * (used in the PRF function)
  */
-static svoid *gnutls_P_hash( MACAlgorithm algorithm, opaque * secret, int secret_size, opaque * seed, int seed_size, int total_bytes)
+static int gnutls_P_hash( MACAlgorithm algorithm, opaque * secret, int secret_size, opaque * seed, int seed_size, int total_bytes, opaque* ret)
 {
 
        GNUTLS_MAC_HANDLE td2;
-       opaque *ret;
        int i = 0, times, how, blocksize, A_size;
        opaque final[20], Atmp[MAX_SEED_SIZE];
 
        if (seed_size > MAX_SEED_SIZE || total_bytes<=0) {
                gnutls_assert();
-               return NULL;
+               return GNUTLS_E_INTERNAL;
        }
        
-       ret = secure_calloc(1, total_bytes);
-       if (ret==NULL) {
-               gnutls_assert();
-               return ret;
-       }
-
        blocksize = gnutls_hmac_get_algo_len(algorithm);
        do {
                i += blocksize;
@@ -312,7 +305,8 @@ static svoid *gnutls_P_hash( MACAlgorithm algorithm, opaque * secret, int secret
                        memcpy(&ret[i * blocksize], final, how);
                }
        }
-       return ret;
+       
+       return 0;
 }
 
 /* Function that xor's buffers using the maximum word size supported
@@ -335,22 +329,30 @@ int modlen = _length%sizeof(unsigned long int);
        return ;
 }
 
+#define MAX_PRF_BYTES 200
+
 /* The PRF function expands a given secret 
- * needed by the TLS specification
+ * needed by the TLS specification. ret must have a least total_bytes
+ * available.
  */
-svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label, int label_size, opaque * seed, int seed_size, int total_bytes)
+int gnutls_PRF( opaque * secret, int secret_size, uint8 * label, int label_size, opaque * seed, int seed_size, int total_bytes, void* ret)
 {
        int l_s, s_seed_size;
-       char *o1, *o2;
        char *s1, *s2;
-       char *s_seed;
+       opaque s_seed[MAX_SEED_SIZE];
+       opaque o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES];
+       int result;
 
+       if (total_bytes > MAX_PRF_BYTES) {
+               gnutls_assert();
+               return GNUTLS_E_INTERNAL;
+       }
        /* label+seed = s_seed */
        s_seed_size = seed_size + label_size;
-       s_seed = gnutls_malloc(s_seed_size);
-       if (s_seed==NULL) {
+
+       if (s_seed_size > MAX_SEED_SIZE) {
                gnutls_assert();
-               return NULL;
+               return GNUTLS_E_INTERNAL;
        }
 
        memcpy(s_seed, label, label_size);
@@ -364,26 +366,23 @@ svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label, int label_si
                l_s++;
        }
 
-       o1 = gnutls_P_hash( GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size, total_bytes);
-       if (o1==NULL) {
+       result = gnutls_P_hash( GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size, total_bytes, o1);
+       if (result<0) {
                gnutls_assert();
-               return NULL;
+               return result;
        }
 
-       o2 = gnutls_P_hash( GNUTLS_MAC_SHA, s2, l_s, s_seed, s_seed_size, total_bytes);
-       if (o2==NULL) {
+       result = gnutls_P_hash( GNUTLS_MAC_SHA, s2, l_s, s_seed, s_seed_size, total_bytes, o2);
+       if (result<0) {
                gnutls_assert();
-               return NULL;
+               return result;
        }
 
-
-       gnutls_free(s_seed);
-
        _gnutls_xor(o1, o2, total_bytes);
 
-       secure_free(o2);
+       memcpy( ret, o1, total_bytes);
 
-       return o1;
+       return 0; /* ok */
 
 }