]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
fixes in session resuming..
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 19 Jun 2001 08:52:01 +0000 (08:52 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 19 Jun 2001 08:52:01 +0000 (08:52 +0000)
15 files changed:
NEWS
doc/TODO
lib/auth_rsa.c
lib/debug.c
lib/debug.h
lib/gnutls.h.in
lib/gnutls_cipher.c
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_kx.h
lib/gnutls_record.c
lib/gnutls_session.c
lib/gnutls_v2_compat.c
src/serv.c

diff --git a/NEWS b/NEWS
index a8a899a4cbec5600df96b8e4b6137be6264ea19d..02de73833abbc32f1c32012161d8853d01d01422 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Version 0.1.4
 - Added RSA Ciphersuites (server side only).
 - Fixes in SSL 2.0 client hello parsing.
 - Added ASN.1 and DER parsers.
+- Bugfixes in session resuming
 
 Version 0.1.3 (01/06/2001)
 - Updated API (and the way it is documented - we use inline documentation)
index 07af4063cb14b8ecb96769a4b2e9d21d0d718624..b73be9d6eb0a1f078d928fe9284e2519ba020645 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -8,4 +8,3 @@
   only one parse of the der structures.
 * Create global variables that hold read/write and initialize
   the ASN.1 parser's structures.
-* Fix session resuming
index 04a4b4941c626a8418dd336b34710fa91fa943f3..52593599807002eb4e97c23c50af18e3a1346c39 100644 (file)
@@ -74,8 +74,8 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
-       gnutls_hash( td, key->client_random, 32);
-       gnutls_hash( td, key->server_random, 32);
+       gnutls_hash( td, key->client_random, TLS_RANDOM_SIZE);
+       gnutls_hash( td, key->server_random, TLS_RANDOM_SIZE);
        gnutls_hash( td, data, data_size);
        
        md5 = gnutls_hash_deinit(td);
@@ -92,8 +92,8 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
-       gnutls_hash( td, key->client_random, 32);
-       gnutls_hash( td, key->server_random, 32);
+       gnutls_hash( td, key->client_random, TLS_RANDOM_SIZE);
+       gnutls_hash( td, key->server_random, TLS_RANDOM_SIZE);
        gnutls_hash( td, data, data_size);
        
        sha = gnutls_hash_deinit(td);
@@ -388,7 +388,7 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
        return pdatasize;
 }
 
-#define RANDOMIZE_X(x) x.size=48; x.data=gnutls_malloc(x.size); \
+#define RANDOMIZE_X(x) x.size=TLS_MASTER_SIZE; x.data=gnutls_malloc(x.size); \
                if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
                if (_gnutls_get_random( key->key.data, key->key.size, GNUTLS_WEAK_RANDOM) < 0) { \
                        return GNUTLS_E_MEMORY_ERROR; \
@@ -419,7 +419,7 @@ int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
                RANDOMIZE_X(key->key);
        } else {
                ret = 0;
-               if (plaintext.size != 48) { /* WOW */
+               if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */
                        RANDOMIZE_X(key->key);
                } else {
                        if (key->version.major != plaintext.data[0]) ret = GNUTLS_E_DECRYPTION_FAILED;
index 2c61d408bdc8e3b0081a4089bdd603aaed94cab6..98b39f5feafc0b76859b41e9e94cabc1f34691f6 100644 (file)
@@ -77,46 +77,6 @@ void _gnutls_print_state(GNUTLS_STATE state)
 
 }
 
-void _gnutls_print_TLSCompressed(GNUTLSCompressed * compressed)
-{
-       fprintf(stderr, "TLSCompressed packet:\n");
-       fprintf(stderr, "type: %d\n", compressed->type);
-       fprintf(stderr, "version: %d,%d\n", compressed->version.major,
-               compressed->version.minor);
-       fprintf(stderr, "length: %d\n", compressed->length);
-       fprintf(stderr, "fragment: %s\n",
-               _gnutls_bin2hex(compressed->fragment, compressed->length));
-       fprintf(stderr, "\n");
-}
-
-
-void _gnutls_print_TLSPlaintext(GNUTLSPlaintext * plaintext)
-{
-       fprintf(stderr, "TLSPlaintext packet:\n");
-       fprintf(stderr, "type: %d\n", plaintext->type);
-       fprintf(stderr, "version: %d,%d\n", plaintext->version.major,
-               plaintext->version.minor);
-       fprintf(stderr, "length: %d\n", plaintext->length);
-       fprintf(stderr, "fragment: %s\n",
-               _gnutls_bin2hex(plaintext->fragment, plaintext->length));
-       fprintf(stderr, "\n");
-}
-
-
-void _gnutls_print_TLSCiphertext(GNUTLSCiphertext * ciphertext)
-{
-
-       fprintf(stderr, "TLSCiphertext packet:\n");
-       fprintf(stderr, "type: %d\n", ciphertext->type);
-       fprintf(stderr, "version: %d,%d\n", ciphertext->version.major,
-               ciphertext->version.minor);
-       fprintf(stderr, "length: %d\n", ciphertext->length);
-
-       fprintf(stderr, "fragment: %s\n",
-               _gnutls_bin2hex(ciphertext->fragment, ciphertext->length));
-       fprintf(stderr, "\n");
-}
-
 char* _gnutls_alert2str( int alert) {
 static char str[512];
 
index b793c1a106006072cb7f41d0cb9d67990d60248f..85ad14b261c594e933194cdc171d76e739059ad9 100644 (file)
@@ -20,9 +20,6 @@
 
 #ifdef DEBUG
 void _gnutls_print_state(GNUTLS_STATE state);
-void _gnutls_print_TLSCompressed(GNUTLSCompressed * compressed);
-void _gnutls_print_TLSPlaintext(GNUTLSPlaintext * plaintext);
-void _gnutls_print_TLSCiphertext( GNUTLSCiphertext *);
 char * _gnutls_bin2hex(const unsigned char *old, const size_t oldlen);
 void _gnutls_dump_mpi(char* prefix,MPI a);
 char* _gnutls_packet2str( int packet);
index 80a5e61748eb9a20ac9987e80e0ed8f7e288b4ab..9283d26f0f78abe0034f650c6f200963987df63a 100644 (file)
@@ -56,6 +56,8 @@ typedef struct {
 int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end);
 int gnutls_deinit(GNUTLS_STATE state);
 int gnutls_bye(SOCKET cd, GNUTLS_STATE state);
+int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state);
+
 int gnutls_handshake(SOCKET cd, GNUTLS_STATE state);
 int gnutls_check_pending(GNUTLS_STATE state);
 int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state);
index 942bff194aac973c4f961ed81a673e81d28b9cc5..41b451d2c073e80c67a45b5e6e298db8fb3c79d3 100644 (file)
@@ -30,6 +30,7 @@
 #include "gnutls_random.h"
 #include "gnutls_num.h"
 #include "gnutls_datum.h"
+#include "gnutls_kx.h"
 
 int _gnutls_encrypt(GNUTLS_STATE state, const char *data, size_t data_size,
                    uint8 ** ciphertext, ContentType type)
@@ -186,7 +187,7 @@ int _gnutls_set_mac(GNUTLS_STATE state, MACAlgorithm algo)
  */
 int _gnutls_connection_state_init(GNUTLS_STATE state)
 {
-       int rc, mac_size;
+       int rc, mac_size, ret;
 
        uint64zero(&state->connection_state.write_sequence_number);
        uint64zero(&state->connection_state.read_sequence_number);
@@ -225,19 +226,20 @@ int _gnutls_connection_state_init(GNUTLS_STATE state)
 
                /* clear the resumed security parameters */
                 memset( &state->gnutls_internals.resumed_security_parameters, 0, sizeof(SecurityParameters));
-#ifdef HARD_DEBUG
-                fprintf(stderr, "Master Secret: %s\n", _gnutls_bin2hex(state->security_parameters.master_secret, 48));
-#endif
        }
 /* Setup the keys since we have the master secret 
  */
-       _gnutls_set_keys(state);
+       if ( (ret=_gnutls_generate_master(state)) < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
+       _gnutls_set_keys(state);
 
 #ifdef DEBUG
        fprintf(stderr, "Cipher Suite: %s\n",
                _gnutls_cipher_suite_get_name(state->
-                                             security_parameters.current_suite));
+                                             security_parameters.current_cipher_suite));
 #endif
 
        if (state->connection_state.write_mac_secret!=NULL)
index 957bd009f13300a14296e63c0eded8e1b4fb386c..f2682709417e50ef83c3ebaf0dffde771efd9f5a 100644 (file)
 #define TRUE 1
 #define FALSE 0
 
-static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data, int datalen);
-int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, opaque * data, int datalen);
+static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
+                      int datalen);
+int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
+                            opaque * data, int datalen);
 
-void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random) {
-       memcpy( state->security_parameters.server_random, random, TLS_RANDOM_SIZE);
-       if (state->gnutls_key!=NULL)
-               memcpy( state->gnutls_key->server_random, random, TLS_RANDOM_SIZE);
+/* this will keep as less data to security_parameters.
+ */
+static void resume_copy_required_values(GNUTLS_STATE state) {
+       /* get the new random values */
+       memcpy(state->gnutls_internals.resumed_security_parameters.
+              server_random,
+              state->security_parameters.server_random,
+              TLS_RANDOM_SIZE);
+       memcpy(state->gnutls_internals.resumed_security_parameters.
+              client_random,
+              state->security_parameters.client_random,
+              TLS_RANDOM_SIZE);
+
+       /* keep the ciphersuite and compression 
+        * That is because the client must see these in our
+        * hello message.
+        */
+       memcpy(state->security_parameters.current_cipher_suite.
+              CipherSuite,
+              state->gnutls_internals.resumed_security_parameters.
+              current_cipher_suite.CipherSuite, 2);
+       state->gnutls_internals.compression_method =
+           state->gnutls_internals.resumed_security_parameters.
+           compression_algorithm;
+
+       memcpy(state->security_parameters.session_id,
+              state->gnutls_internals.resumed_security_parameters.
+              session_id, sizeof(state->security_parameters.session_id));
+       state->security_parameters.session_id_size =
+           state->gnutls_internals.resumed_security_parameters.
+           session_id_size;
+
+
+       return;
 }
-void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random) {
-       memcpy( state->security_parameters.client_random, random, TLS_RANDOM_SIZE);
-       if (state->gnutls_key!=NULL)
-               memcpy( state->gnutls_key->client_random, random, TLS_RANDOM_SIZE);
+
+void _gnutls_set_server_random(GNUTLS_STATE state, uint8 * random)
+{
+       memcpy(state->security_parameters.server_random, random,
+              TLS_RANDOM_SIZE);
+       if (state->gnutls_key != NULL)
+               memcpy(state->gnutls_key->server_random, random,
+                      TLS_RANDOM_SIZE);
+}
+
+void _gnutls_set_client_random(GNUTLS_STATE state, uint8 * random)
+{
+       memcpy(state->security_parameters.client_random, random,
+              TLS_RANDOM_SIZE);
+       if (state->gnutls_key != NULL)
+               memcpy(state->gnutls_key->client_random, random,
+                      TLS_RANDOM_SIZE);
 }
 
 /* Calculate The SSL3 Finished message */
@@ -157,19 +202,21 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
 /* this function will produce TLS_RANDOM_SIZE bytes of random data
  * and put it to dst.
  */
-int _gnutls_create_random( opaque* dst) {
-uint32 tim;
-opaque rand[TLS_RANDOM_SIZE-4];
+int _gnutls_create_random(opaque * dst)
+{
+       uint32 tim;
+       opaque rand[TLS_RANDOM_SIZE - 4];
 
        tim = time(NULL);
        /* generate server random value */
-       WRITEuint32( tim, dst);
+       WRITEuint32(tim, dst);
 
-       if (_gnutls_get_random(rand, TLS_RANDOM_SIZE-4, GNUTLS_STRONG_RANDOM) < 0) {
+       if (_gnutls_get_random
+           (rand, TLS_RANDOM_SIZE - 4, GNUTLS_STRONG_RANDOM) < 0) {
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
-       memcpy( &dst[4], rand, 28);
+       memcpy(&dst[4], rand, 28);
 
        return 0;
 }
@@ -194,7 +241,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        int err;
        opaque random[TLS_RANDOM_SIZE];
 
-       if (state->gnutls_internals.v2_hello!=0) {      /* version 2.0 */
+       if (state->gnutls_internals.v2_hello != 0) {    /* version 2.0 */
                return _gnutls_read_client_hello_v2(state, data, datalen);
        }
 
@@ -218,11 +265,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        pos += 2;
 
        DECR_LEN(len, TLS_RANDOM_SIZE);
-       _gnutls_set_client_random( state, &data[pos]);
+       _gnutls_set_client_random(state, &data[pos]);
        pos += TLS_RANDOM_SIZE;
 
-       _gnutls_create_random( random);
-       _gnutls_set_server_random( state, random);
+       _gnutls_create_random(random);
+       _gnutls_set_server_random(state, random);
 
        state->security_parameters.timestamp = time(NULL);
 
@@ -234,7 +281,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
-       
+
        DECR_LEN(len, session_id_len);
        ret =
            _gnutls_server_restore_session(state, &data[pos],
@@ -242,24 +289,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        pos += session_id_len;
 
        if (ret == 0) {         /* resumed! */
-               /* get the new random values */
-               memcpy(state->gnutls_internals.resumed_security_parameters.
-                      server_random,
-                      state->security_parameters.server_random, TLS_RANDOM_SIZE);
-               memcpy(state->gnutls_internals.resumed_security_parameters.
-                      client_random,
-                      state->security_parameters.client_random, TLS_RANDOM_SIZE);
-
-               /* keep the ciphersuite and compression 
-                * That is because the client must see these in our
-                * hello message.
-                */
-               memcpy( state->security_parameters.current_cipher_suite.CipherSuite,
-                       state->gnutls_internals.resumed_security_parameters.current_cipher_suite.CipherSuite,
-                       2);
-               state->gnutls_internals.compression_method =
-                       state->gnutls_internals.resumed_security_parameters.compression_algorithm;
-                       
+               resume_copy_required_values(state);
 
                state->gnutls_internals.resumed = RESUME_TRUE;
                return 0;
@@ -273,7 +303,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        }
        /* Select a ciphersuite */
        DECR_LEN(len, 2);
-       sizeOfSuites = READuint16( &data[pos]);
+       sizeOfSuites = READuint16(&data[pos]);
        pos += 2;
 
        DECR_LEN(len, sizeOfSuites);
@@ -321,10 +351,12 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
 
        DECR_LEN(len, z);
        ret = _gnutls_SelectCompMethod(state, &state->
-                              gnutls_internals.compression_method,
-                              &data[pos], z);
-#ifdef HARD_DEBUG
-       fprintf(stderr, "Selected Compression Method: %s\n", gnutls_compression_get_name(state->gnutls_internals.compression_method));
+                                      gnutls_internals.compression_method,
+                                      &data[pos], z);
+#ifdef HANDSHAKE_DEBUG
+       fprintf(stderr, "Selected Compression Method: %s\n",
+               gnutls_compression_get_name(state->gnutls_internals.
+                                           compression_method));
 #endif
        pos += z;
 
@@ -444,7 +476,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
        GNUTLS_CipherSuite *ciphers;
 
        x = _gnutls_supported_ciphersuites(state, &ciphers);
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
        fprintf(stderr, "Requested cipher suites: \n");
        for (j = 0; j < datalen; j += 2)
                fprintf(stderr, "\t%s\n",
@@ -462,7 +494,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
                for (i = 0; i < x; i++) {
                        if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
                            0) {
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
                                fprintf(stderr, "Selected cipher suite: ");
                                fprintf(stderr, "%s\n",
                                        _gnutls_cipher_suite_get_name(*
@@ -486,7 +518,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
 
 /* This selects the best supported compression method from the ones provided */
 int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
-                           opaque * data, int datalen)
+                            opaque * data, int datalen)
 {
        int x, i, j;
        uint8 *ciphers;
@@ -497,7 +529,8 @@ int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
        for (j = 0; j < datalen; j++) {
                for (i = 0; i < x; i++) {
                        if (ciphers[i] == data[j]) {
-                               *ret = _gnutls_compression_get_id(ciphers[i]);
+                               *ret =
+                                   _gnutls_compression_get_id(ciphers[i]);
                                gnutls_free(ciphers);
                                return 0;
                        }
@@ -527,8 +560,8 @@ int _gnutls_send_handshake(SOCKET cd, GNUTLS_STATE state, void *i_data,
        data = gnutls_malloc(i_datasize);
 
        memcpy(&data[pos++], &type, 1);
-       WRITEuint24( datasize, &data[pos]);
-       pos+=3;
+       WRITEuint24(datasize, &data[pos]);
+       pos += 3;
 
        if (i_datasize > 4)
                memcpy(&data[pos], i_data, i_datasize - 4);
@@ -563,41 +596,51 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
 {
        int ret;
        uint32 length32 = 0, sum = 0;
-       uint8 *dataptr=NULL; /* for realloc */
+       uint8 *dataptr = NULL;  /* for realloc */
        int handshake_headers = HANDSHAKE_HEADERS_SIZE;
        HandshakeType recv_type;
 
        if (type == GNUTLS_CERTIFICATE) {
                /* If the ciphersuite does not support certificate just quit */
                if (state->security_parameters.entity == GNUTLS_CLIENT) {
-                       if (_gnutls_kx_server_certificate( _gnutls_cipher_suite_get_kx_algo( state->security_parameters.current_cipher_suite) ) == 0)
+                       if (_gnutls_kx_server_certificate
+                           (_gnutls_cipher_suite_get_kx_algo
+                            (state->security_parameters.
+                             current_cipher_suite)) == 0)
                                return 0;
                } else {        /* server */
-                       if (_gnutls_kx_client_certificate( _gnutls_cipher_suite_get_kx_algo( state->security_parameters.current_cipher_suite) ) == 0)
+                       if (_gnutls_kx_client_certificate
+                           (_gnutls_cipher_suite_get_kx_algo
+                            (state->security_parameters.
+                             current_cipher_suite)) == 0)
                                return 0;
                }
        }
 
        dataptr = gnutls_malloc(HANDSHAKE_HEADERS_SIZE);
-       
+
        ret =
-           _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, dataptr, SSL2_HEADERS);
+           _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, dataptr,
+                            SSL2_HEADERS);
        if (ret < 0) {
                gnutls_assert();
                gnutls_free(dataptr);
                return ret;
        }
-       if (ret!=SSL2_HEADERS) {
+       if (ret != SSL2_HEADERS) {
                gnutls_assert();
                gnutls_free(dataptr);
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
 
-       if ( state->gnutls_internals.v2_hello == 0 || type != GNUTLS_CLIENT_HELLO) {
+       if (state->gnutls_internals.v2_hello == 0
+           || type != GNUTLS_CLIENT_HELLO) {
 
                ret =
-                   _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, &dataptr[SSL2_HEADERS],
-                            HANDSHAKE_HEADERS_SIZE-SSL2_HEADERS);
+                   _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE,
+                                    &dataptr[SSL2_HEADERS],
+                                    HANDSHAKE_HEADERS_SIZE -
+                                    SSL2_HEADERS);
                if (ret < 0) {
                        gnutls_assert();
                        gnutls_free(dataptr);
@@ -610,14 +653,14 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
                }
 
                recv_type = dataptr[0];
-               
+
                if (recv_type != type) {
                        gnutls_assert();
                        gnutls_free(dataptr);
                        return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
                }
-       
-               length32 = READuint24( &dataptr[1]);
+
+               length32 = READuint24(&dataptr[1]);
 
 #ifdef HANDSHAKE_DEBUG
                fprintf(stderr, "Handshake: %s was received [%ld bytes]\n",
@@ -626,31 +669,31 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
 #endif
 
 
-       } else { /* v2 hello */
-               length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
-               
-               handshake_headers = SSL2_HEADERS; /* we've already read one byte */
+       } else {                /* v2 hello */
+               length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS;     /* we've read the first byte */
+
+               handshake_headers = SSL2_HEADERS;       /* we've already read one byte */
 
                recv_type = dataptr[0];
 #ifdef HANDSHAKE_DEBUG
-               fprintf(stderr, "Handshake: %s(v2) was received [%ld bytes]\n",
+               fprintf(stderr,
+                       "Handshake: %s(v2) was received [%ld bytes]\n",
                        _gnutls_handshake2str(recv_type),
                        length32 + handshake_headers);
 #endif
 
-               if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
+               if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
                        gnutls_assert();
                        return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
                }
        }
 
-       dataptr =
-           gnutls_realloc(dataptr, length32 + handshake_headers);
+       dataptr = gnutls_realloc(dataptr, length32 + handshake_headers);
        if (length32 > 0 && data != NULL)
                *data = gnutls_malloc(length32);
 
        if (datalen != NULL)
-               *datalen = length32;            
+               *datalen = length32;
 
        sum = handshake_headers;
        do {
@@ -659,7 +702,7 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
                                     &dataptr[sum], length32);
                sum += ret;
        } while (((sum - handshake_headers) < length32) && (ret > 0));
-       
+
        if (ret < 0) {
                gnutls_assert();
                gnutls_free(dataptr);
@@ -671,9 +714,10 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
                memcpy(*data, &dataptr[handshake_headers], length32);
 
        /* here we buffer the handshake messages - needed at Finished message */
-       
-       if (recv_type!=GNUTLS_HELLO_REQUEST) 
-               gnutls_insertHashDataBuffer(state, dataptr, length32 + handshake_headers);
+
+       if (recv_type != GNUTLS_HELLO_REQUEST)
+               gnutls_insertHashDataBuffer(state, dataptr,
+                                           length32 + handshake_headers);
 
        switch (recv_type) {
        case GNUTLS_CLIENT_HELLO:
@@ -703,7 +747,7 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
                ret = length32;
                break;
        case GNUTLS_CERTIFICATE_REQUEST:
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
                fprintf(stderr, "Requested Client Certificate!\n");
 #endif
                /* FIXME: just ignore that message for the time being 
@@ -734,14 +778,14 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
   **/
 int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state)
 {
-int    ret;
+       int ret;
 
        /* only server sends that handshake packet */
        if (state->security_parameters.entity == GNUTLS_CLIENT)
                return GNUTLS_E_UNIMPLEMENTED_FEATURE;
 
        ret = _gnutls_send_handshake(cd, state, NULL, 0,
-                                     GNUTLS_HELLO_REQUEST);
+                                    GNUTLS_HELLO_REQUEST);
 
        if (ret < 0) {
                gnutls_assert();
@@ -764,7 +808,7 @@ int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state)
 
        /* we do not have that functionality yet */
        state->gnutls_internals.certificate_verify_needed = 0;
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
        fprintf(stderr, "Sending Client Certificate\n");
 #endif
 
@@ -778,7 +822,8 @@ int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state)
        return ret;
 }
 
-static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datalen)
+static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
+                                    int datalen)
 {
        uint8 session_id_len = 0, z;
        int pos = 0;
@@ -809,7 +854,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
        pos += 2;
 
        DECR_LEN(len, TLS_RANDOM_SIZE);
-       _gnutls_set_server_random( state, &data[pos]);
+       _gnutls_set_server_random(state, &data[pos]);
        pos += TLS_RANDOM_SIZE;
 
        DECR_LEN(len, 1);
@@ -822,7 +867,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
 
        DECR_LEN(len, session_id_len);
 
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
        fprintf(stderr, "SessionID length: %d\n", session_id_len);
        fprintf(stderr, "SessionID: %s\n",
                _gnutls_bin2hex(&data[pos], session_id_len));
@@ -852,9 +897,9 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
                    session_id_len;
                memcpy(state->security_parameters.session_id,
                       &data[pos], session_id_len);
-               }
-               pos += session_id_len;
-               DECR_LEN(len, 2);
+       }
+       pos += session_id_len;
+       DECR_LEN(len, 2);
        memcpy(cipher_suite.CipherSuite, &data[pos], 2);
        pos += 2;
 
@@ -873,15 +918,15 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
        }
 
        memcpy(state->security_parameters.
-               current_cipher_suite.CipherSuite,
-               cipher_suite.CipherSuite, 2);
+              current_cipher_suite.CipherSuite,
+              cipher_suite.CipherSuite, 2);
 
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
        fprintf(stderr, "Selected cipher suite: ");
        fprintf(stderr, "%s\n",
                _gnutls_cipher_suite_get_name(state->
-                             security_parameters.
-                             current_cipher_suite));
+                                             security_parameters.
+                                             current_cipher_suite));
 #endif
 
        /* check if the credentials (username, public key etc. are ok - actually check if they exist)
@@ -905,8 +950,8 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
                                   (cipher_suite));
        if (state->gnutls_internals.auth_struct == NULL) {
 #ifdef DEBUG
-       fprintf(stderr,
-               "Cannot find the appropriate handler for the KX algorithm\n");
+               fprintf(stderr,
+                       "Cannot find the appropriate handler for the KX algorithm\n");
 #endif
                gnutls_assert();
                return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
@@ -933,7 +978,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
                return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
        }
        state->gnutls_internals.compression_method =
-               _gnutls_compression_get_id( compression_method);
+           _gnutls_compression_get_id(compression_method);
 
        gnutls_free(cipher_suites);
        gnutls_free(compression_methods);
@@ -943,11 +988,12 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
                gnutls_assert();
                return ret;
        }
-       
+
        return ret;
 }
 
-int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
+
+static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
 {
        char *data = NULL;
        opaque *extdata;
@@ -960,140 +1006,168 @@ int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
        uint16 x;
        opaque random[TLS_RANDOM_SIZE];
 
-       if (state->security_parameters.entity == GNUTLS_CLIENT) {
-               opaque * SessionID = state->gnutls_internals.resumed_security_parameters.session_id;
-               uint8 session_id_len = state->gnutls_internals.resumed_security_parameters.session_id_size;
-
-               if (SessionID==NULL) session_id_len = 0;
-               
-               datalen = 2 + 4 + (session_id_len + 1) + 28 + 3;
-               /* 2 for version, 4 for unix time, 28 for random bytes 2 for cipher suite's
-                * size and 1 for compression method's size 
-                */
-               data = gnutls_malloc(datalen);
+       opaque *SessionID =
+           state->gnutls_internals.resumed_security_parameters.session_id;
+       uint8 session_id_len =
+           state->gnutls_internals.resumed_security_parameters.
+           session_id_size;
+
+       if (SessionID == NULL)
+               session_id_len = 0;
 
-               data[pos++] =
-                   _gnutls_version_get_major(state->connection_state.
-                                             version);
-               data[pos++] =
-                   _gnutls_version_get_minor(state->connection_state.
-                                             version);
+       datalen = 2 + 4 + (session_id_len + 1) + 28 + 3;
+       /* 2 for version, 4 for unix time, 28 for random bytes 2 for cipher suite's
+        * size and 1 for compression method's size 
+        */
+       data = gnutls_malloc(datalen);
 
-               _gnutls_create_random( random);
-               _gnutls_set_client_random( state, random);
-               
-               state->security_parameters.timestamp = time(0);
+       data[pos++] =
+           _gnutls_version_get_major(state->connection_state.version);
+       data[pos++] =
+           _gnutls_version_get_minor(state->connection_state.version);
 
-               memcpy(&data[pos],
-                       state->security_parameters.client_random, TLS_RANDOM_SIZE);
-               pos += TLS_RANDOM_SIZE;
+       _gnutls_create_random(random);
+       _gnutls_set_client_random(state, random);
 
-               memcpy(&data[pos++], &session_id_len, 1);
+       state->security_parameters.timestamp = time(0);
 
-               if (session_id_len > 0) {
-                       memcpy(&data[pos], SessionID, session_id_len);
-               }
-               pos += session_id_len;
+       memcpy(&data[pos],
+              state->security_parameters.client_random, TLS_RANDOM_SIZE);
+       pos += TLS_RANDOM_SIZE;
 
-               x = _gnutls_supported_ciphersuites_sorted(state,
-                                                         &cipher_suites);
-               x *= sizeof(uint16);    /* in order to get bytes */
+       memcpy(&data[pos++], &session_id_len, 1);
 
-               WRITEuint16( x, &data[pos]);
-               pos += sizeof(uint16);
+       if (session_id_len > 0) {
+               memcpy(&data[pos], SessionID, session_id_len);
+       }
+       pos += session_id_len;
 
-               datalen += x;
-               data = gnutls_realloc(data, datalen);
+       x = _gnutls_supported_ciphersuites_sorted(state, &cipher_suites);
+       x *= sizeof(uint16);    /* in order to get bytes */
 
-               for (i = 0; i < x / 2; i++) {
-                       memcpy(&data[pos], cipher_suites[i].CipherSuite,
-                               2);
-                       pos += 2;
-               }
-               gnutls_free(cipher_suites);
+       WRITEuint16(x, &data[pos]);
+       pos += sizeof(uint16);
+
+       datalen += x;
+       data = gnutls_realloc(data, datalen);
+
+       for (i = 0; i < x / 2; i++) {
+               memcpy(&data[pos], cipher_suites[i].CipherSuite, 2);
+               pos += 2;
+       }
+       gnutls_free(cipher_suites);
+
+       z = _gnutls_supported_compression_methods
+           (state, &compression_methods);
+
+       memcpy(&data[pos++], &z, 1);    /* put the number of compression methods */
 
-               z = _gnutls_supported_compression_methods
-                   (state, &compression_methods);
+       datalen += z;
+       data = gnutls_realloc(data, datalen);
+
+       for (i = 0; i < z; i++) {
+               memcpy(&data[pos++], &compression_methods[i], 1);
+       }
 
-               memcpy(&data[pos++], &z, 1);    /* put the number of compression methods */
+       gnutls_free(compression_methods);
 
-               datalen += z;
+       extdatalen = _gnutls_gen_extensions(state, &extdata);
+       if (extdatalen > 0) {
+               datalen += extdatalen;
                data = gnutls_realloc(data, datalen);
+               memcpy(&data[pos], extdata, extdatalen);
+               gnutls_free(extdata);
+       }
 
-               for (i = 0; i < z; i++) {
-                       memcpy(&data[pos++], &compression_methods[i], 1);
-               }
+       ret =
+           _gnutls_send_handshake(cd, state, data, datalen,
+                                  GNUTLS_CLIENT_HELLO);
+       gnutls_free(data);
 
-               gnutls_free(compression_methods);
 
-               extdatalen = _gnutls_gen_extensions(state, &extdata);
-               if (extdatalen > 0) {
-                       datalen += extdatalen;
-                       data = gnutls_realloc(data, datalen);
-                       memcpy(&data[pos], extdata, extdatalen);
-                       gnutls_free(extdata);
-               }
 
-               ret =
-                   _gnutls_send_handshake(cd, state, data, datalen,
-                                          GNUTLS_CLIENT_HELLO);
-               gnutls_free(data);
+       return ret;
+}
 
+static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
+{
+       char *data = NULL;
+       opaque *extdata;
+       int extdatalen;
+       int pos = 0;
+       int datalen, ret = 0;
+       uint8 comp;
+       opaque *SessionID = state->security_parameters.session_id;
+       uint8 session_id_len = state->security_parameters.session_id_size;
 
-       } else {                /* SERVER */
-               uint8 comp;
-               opaque * SessionID = state->security_parameters.session_id;
-               uint8 session_id_len = state->security_parameters.session_id_size;
-               
-               if (SessionID==NULL) session_id_len = 0;
-               
-               datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE;
-               data = gnutls_malloc(datalen);
-
-               data[pos++] =
-                   _gnutls_version_get_major(state->connection_state.
-                                             version);
-               data[pos++] =
-                   _gnutls_version_get_minor(state->connection_state.
-                                             version);
-
-               memcpy(&data[pos],
-                       state->security_parameters.server_random, TLS_RANDOM_SIZE);
-               pos += TLS_RANDOM_SIZE;
-
-               memcpy(&data[pos++], &session_id_len, sizeof(uint8));
-               if (session_id_len > 0) {
-                       memcpy(&data[pos], SessionID, session_id_len);
-               }
-               pos += session_id_len;
+       if (SessionID == NULL)
+               session_id_len = 0;
 
-               datalen += 2;
-               data = gnutls_realloc(data, datalen);
-               
-               memcpy(&data[pos],
-                       state->security_parameters.
-                       current_cipher_suite.CipherSuite, 2);
-               pos += 2;
+       datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE;
+       data = gnutls_malloc(datalen);
+
+       data[pos++] =
+           _gnutls_version_get_major(state->connection_state.version);
+       data[pos++] =
+           _gnutls_version_get_minor(state->connection_state.version);
+
+       memcpy(&data[pos],
+              state->security_parameters.server_random, TLS_RANDOM_SIZE);
+       pos += TLS_RANDOM_SIZE;
+
+       data[pos++] = session_id_len;
+       if (session_id_len > 0) {
+               memcpy(&data[pos], SessionID, session_id_len);
+       }
+       pos += session_id_len;
+
+#ifdef HANDSHAKE_DEBUG
+       fprintf(stderr, "Handshake: SessionID: %s\n",
+               _gnutls_bin2hex(SessionID, session_id_len));
+#endif
+
+       datalen += 2;
+       data = gnutls_realloc(data, datalen);
+
+       memcpy(&data[pos],
+              state->security_parameters.
+              current_cipher_suite.CipherSuite, 2);
+       pos += 2;
+
+       datalen += 1;
+       data = gnutls_realloc(data, datalen);
 
-               datalen += 1;
+       comp =
+           (uint8) _gnutls_compression_get_num(state->gnutls_internals.
+                                               compression_method);
+       memcpy(&data[pos++], &comp, 1);
+
+       extdatalen = _gnutls_gen_extensions(state, &extdata);
+       if (extdatalen > 0) {
+               datalen += extdatalen;
                data = gnutls_realloc(data, datalen);
-               
-               comp = (uint8) _gnutls_compression_get_num(state->gnutls_internals.compression_method);
-               memcpy(&data[pos++], &comp, 1);
-
-               extdatalen = _gnutls_gen_extensions(state, &extdata);
-               if (extdatalen > 0) {
-                       datalen += extdatalen;
-                       data = gnutls_realloc(data, datalen);
-                       memcpy(&data[pos], extdata, extdatalen);
-                       gnutls_free(extdata);
-               }
+               memcpy(&data[pos], extdata, extdatalen);
+               gnutls_free(extdata);
+       }
 
-               ret =
-                   _gnutls_send_handshake(cd, state, data, datalen,
-                                          GNUTLS_SERVER_HELLO);
-               gnutls_free(data);
+       ret =
+           _gnutls_send_handshake(cd, state, data, datalen,
+                                  GNUTLS_SERVER_HELLO);
+       gnutls_free(data);
+
+
+       return ret;
+}
+
+int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
+{
+       int ret;
+
+       if (state->security_parameters.entity == GNUTLS_CLIENT) {
+               ret = _gnutls_send_client_hello(cd, state);
 
+       } else {                /* SERVER */
+               ret = _gnutls_send_server_hello(cd, state);
        }
 
        return ret;
@@ -1103,14 +1177,15 @@ int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
  * hello message is expected. It uses the security_parameters.current_cipher_suite
  * and gnutls_internals.compression_method.
  */
-int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data, int datalen)
+int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
+                      int datalen)
 {
-int ret;
+       int ret;
 
        if (state->security_parameters.entity == GNUTLS_CLIENT) {
                ret = _gnutls_read_server_hello(state, data, datalen);
                if (ret < 0) {
-                       _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
+                       _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE);  /* send handshake failure */
                        gnutls_assert();
                        return ret;
                }
@@ -1118,7 +1193,7 @@ int ret;
 
                ret = _gnutls_read_client_hello(state, data, datalen);
                if (ret < 0) {
-                       _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
+                       _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE);  /* send handshake failure */
                        gnutls_assert();
                        return ret;
                }
@@ -1141,7 +1216,7 @@ int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state, char *data,
                        return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
                }
 
-               sizeOfCert = READuint24( &data[pos]);
+               sizeOfCert = READuint24(&data[pos]);
                pos += 3;
 
                if (sizeOfCert > MAX24) {
@@ -1217,7 +1292,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
        int ret;
 
        if (state->security_parameters.entity == GNUTLS_CLIENT) {
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
                if (state->gnutls_internals.resumed_security_parameters.
                    session_id_size > 0)
                        fprintf(stderr, "Ask to resume: %s\n",
@@ -1228,8 +1303,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
                                                resumed_security_parameters.
                                                session_id_size));
 #endif
-               ret =
-                   _gnutls_send_hello(cd, state);
+               ret = _gnutls_send_hello(cd, state);
                if (ret < 0) {
                        ERR("send hello", ret);
                        gnutls_clearHashDataBuffer(state);
@@ -1269,8 +1343,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
                        return ret;
                }
 
-               ret =
-                   _gnutls_send_hello(cd, state);
+               ret = _gnutls_send_hello(cd, state);
                if (ret < 0) {
                        ERR("send hello", ret);
                        gnutls_assert();
@@ -1339,7 +1412,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
        ret = _gnutls_send_change_cipher_spec(cd, state);
        if (ret < 0) {
                ERR("send ChangeCipherSpec", ret);
-               gnutls_clearHashDataBuffer(state);
                return ret;
        }
 
@@ -1348,7 +1420,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
                ret = _gnutls_connection_state_init(state);
                if (ret < 0) {
                        gnutls_assert();
-                       gnutls_clearHashDataBuffer(state);
                        return ret;
                }
        }
@@ -1357,7 +1428,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
        ret = _gnutls_send_finished(cd, state);
        if (ret < 0) {
                ERR("send Finished", ret);
-               gnutls_clearHashDataBuffer(state);
                return ret;
        }
        return ret;
@@ -1375,7 +1445,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
                            NULL, 0, 0);
        if (ret < 0) {
                ERR("recv ChangeCipherSpec", ret);
-               gnutls_clearHashDataBuffer(state);
                return ret;
        }
 
@@ -1384,7 +1453,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
                ret = _gnutls_connection_state_init(state);
                if (ret < 0) {
                        gnutls_assert();
-                       gnutls_clearHashDataBuffer(state);
                        return ret;
                }
        }
@@ -1392,7 +1460,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
        ret = _gnutls_recv_finished(cd, state);
        if (ret < 0) {
                ERR("recv finished", ret);
-               gnutls_clearHashDataBuffer(state);
                return ret;
        }
        return ret;
@@ -1534,7 +1601,9 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
                        gnutls_assert();
                        gnutls_clearHashDataBuffer(state);
                        /* for srp */
-                       if (state->security_parameters.kx_algorithm==GNUTLS_KX_SRP) return GNUTLS_E_AUTH_FAILED;
+                       if (state->security_parameters.kx_algorithm ==
+                           GNUTLS_KX_SRP)
+                               return GNUTLS_E_AUTH_FAILED;
                        return ret;
                }
 
@@ -1558,7 +1627,9 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
                        gnutls_assert();
                        gnutls_clearHashDataBuffer(state);
                        /* in srp failure here - means authentication error */
-                       if (state->security_parameters.kx_algorithm==GNUTLS_KX_SRP) return GNUTLS_E_AUTH_FAILED;
+                       if (state->security_parameters.kx_algorithm ==
+                           GNUTLS_KX_SRP)
+                               return GNUTLS_E_AUTH_FAILED;
                        return ret;
                }
        }
@@ -1577,7 +1648,8 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
 int _gnutls_generate_session_id(char *session_id, uint8 * len)
 {
        opaque rand[TLS_RANDOM_SIZE];
-       if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) < 0) {
+       if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) <
+           0) {
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
@@ -1585,45 +1657,50 @@ int _gnutls_generate_session_id(char *session_id, uint8 * len)
        memcpy(session_id, rand, TLS_RANDOM_SIZE);
        *len = TLS_RANDOM_SIZE;
 
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
        fprintf(stderr, "Generated SessionID: %s\n",
                _gnutls_bin2hex(session_id, TLS_RANDOM_SIZE));
 #endif
        return 0;
 }
+
 #define RENEGOTIATE
-int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void* data, uint32 data_size) {
+int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void *data,
+                              uint32 data_size)
+{
 #ifndef RENEGOTIATE
-int ret;
+       int ret;
 
        /* only client should receive that */
        if (state->security_parameters.entity == GNUTLS_SERVER)
                return GNUTLS_E_UNEXPECTED_PACKET;
 
        /* just return an alert that we don't like that */
-       ret = _gnutls_send_alert( cd, state, GNUTLS_WARNING, GNUTLS_NO_RENEGOTIATION);
+       ret =
+           _gnutls_send_alert(cd, state, GNUTLS_WARNING,
+                              GNUTLS_NO_RENEGOTIATION);
        if (ret < 0) {
                gnutls_assert();
                return ret;
        }
        return 0;
 
-#else /* this does not seem to work - yet */
-uint8 type;
+#else                          /* this does not seem to work - yet */
+       uint8 type;
 
        if (state->security_parameters.entity == GNUTLS_SERVER) {
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET;
        }
-       
+
        if (data_size < 1) {
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
-       
-       type = ((uint8*)data)[0];
-       if (type==GNUTLS_HELLO_REQUEST)
-               return gnutls_handshake( cd, state);
+
+       type = ((uint8 *) data)[0];
+       if (type == GNUTLS_HELLO_REQUEST)
+               return gnutls_handshake(cd, state);
        else {
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET;
index 487cd44ece9d1ebfd3efa8663bb959f374f36202..0b813528503281eae956f860afed97f6f3822ea1 100644 (file)
 #define READ_DEBUG
 #define WRITE_DEBUG
 #define BUFFERS_DEBUG
-#define HANDSHAKE_DEBUG
+*/#define HANDSHAKE_DEBUG
+/*#define RECORD_DEBUG
 #define HARD_DEBUG
-#define DEBUG
 */
+#define DEBUG
 
 #define SOCKET int
 #define LIST ...
@@ -41,6 +42,7 @@
 
 #define TLS_RANDOM_SIZE 32
 #define TLS_MAX_SESSION_ID_SIZE 32
+#define TLS_MASTER_SIZE 48
 
 /* the default for TCP */
 #define DEFAULT_LOWAT 1
@@ -207,7 +209,7 @@ typedef struct {
        uint8 key_size;
        uint8 key_material_length;
        uint8 hash_size;
-       opaque master_secret[48];
+       opaque master_secret[TLS_MASTER_SIZE];
        opaque client_random[TLS_RANDOM_SIZE];
        opaque server_random[TLS_RANDOM_SIZE];
        opaque session_id[TLS_MAX_SESSION_ID_SIZE];
index b31dfacfc6d4ce017385eea44112508809415463..261ece77d184562eebb4e758ff2ec2aaa0121fb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000 Nikos Mavroyanopoulos
+ * Copyright (C) 2000,2001 Nikos Mavroyanopoulos
  *
  * This file is part of GNUTLS.
  *
 #include "gnutls_gcry.h"
 
 #define MASTER_SECRET "master secret"
+static int generate_normal_master( GNUTLS_STATE state);
+static int generate_resumed_master( GNUTLS_STATE state);
 
+int _gnutls_generate_master( GNUTLS_STATE state) {
+       if (state->gnutls_internals.resumed==RESUME_FALSE)
+               return generate_normal_master(state);
+       return 0;
+}
 
-static int generate_master( GNUTLS_STATE state) {
+static int generate_normal_master( GNUTLS_STATE state) {
 int premaster_size;
 #ifdef HARD_DEBUG
 int i;
 #endif
 opaque* premaster, *master;
 int ret = 0;
-char random[64];
+char random[2*TLS_RANDOM_SIZE];
 
-       memmove(random, state->security_parameters.client_random, 32);
-       memmove(&random[32], state->security_parameters.server_random, 32);
+       memmove(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
+       memmove(&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
-       fprintf(stderr, "PREMASTER SECRET: ");
-       for (i=0;i<premaster_size;i++) fprintf(stderr, "%x",premaster[i]);
-       fprintf(stderr, "\n");
+       fprintf(stderr, "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
+       fprintf(stderr, "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
+       fprintf(stderr, "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
 #endif
 
        if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
                master =
                    gnutls_ssl3_generate_random( premaster, premaster_size,
-                              random, 64, 48);
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
 
        } else {
                master =
                    gnutls_PRF( premaster, premaster_size,
                               MASTER_SECRET, strlen(MASTER_SECRET),
-                              random, 64, 48); 
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE); 
        }
        secure_free(premaster);
        state->gnutls_key->key.size = 0;
        state->gnutls_key->key.data = NULL;
        
+       if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
+       
 #ifdef HARD_DEBUG
-       fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, 48));
+       fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
 #endif
-       memmove(state->security_parameters.master_secret, master, 48);
+       memmove(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
        secure_free(master);
        return ret;
+}
+
+static int generate_resumed_master( GNUTLS_STATE state) {
+int premaster_size;
+#ifdef HARD_DEBUG
+int i;
+#endif
+opaque* premaster, *master;
+int ret = 0;
+char random[2*TLS_RANDOM_SIZE];
+
+       memmove(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
+       memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
+
+       /* generate premaster */
+        premaster_size = sizeof(state->security_parameters.master_secret);
+       premaster = state->security_parameters.master_secret;
+
+#ifdef HARD_DEBUG
+       fprintf(stderr, "RESUME...\n");
+       fprintf(stderr, "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
+       fprintf(stderr, "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
+       fprintf(stderr, "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
+#endif
+
+       if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
+               master =
+                   gnutls_ssl3_generate_random( premaster, premaster_size,
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
+
+       } else {
+               master =
+                   gnutls_PRF( premaster, premaster_size,
+                              MASTER_SECRET, strlen(MASTER_SECRET),
+                              random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE); 
+       }
+       
+#ifdef HARD_DEBUG
+       fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
+#endif
+       if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
 
+       memmove(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
+       secure_free(master);
+       return ret;
 }
 
 /* This is called when we want to receive the key exchange message of the
@@ -142,11 +195,6 @@ int _gnutls_send_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
                        return ret;
                }
                
-               ret = generate_master( state);
-               if (ret<0) {
-                       gnutls_assert();
-                       return ret;
-               }
        }
        return data_size;
 }
@@ -187,12 +235,6 @@ int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state)
                return ret;
        }
 
-       ret = generate_master( state);
-       if (ret<0) {
-               gnutls_assert();
-               return ret;
-       }
-
        return ret;
 }
 
@@ -326,11 +368,6 @@ int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
                if (ret < 0)
                        return ret;
 
-               ret = generate_master( state);
-               if (ret<0) {
-                       gnutls_assert();
-                       return ret;
-               }
        }
        return ret;
 }
@@ -368,11 +405,6 @@ int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
                if (ret < 0)
                        return ret;
 
-               ret = generate_master( state);
-               if (ret<0) {
-                       gnutls_assert();
-                       return ret;
-               }
        }
 
        return ret;
index 6408832a352d8de933e5ef4cddd7eda9d0fec13f..68ab4a3b9e327af42e1b049daedf514974658b0a 100644 (file)
@@ -28,3 +28,4 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state);
 int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state);
 int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state);
 int _gnutls_send_certificate(int cd, GNUTLS_STATE state);
+int _gnutls_generate_master( GNUTLS_STATE state);
index cea9ce1e25fd9731a9280b0fc08eab11b952c002..91e0b02d89b1d72c83a3a53754caa247c590325d 100644 (file)
@@ -34,6 +34,7 @@
 #include "gnutls_auth_int.h"
 #include "gnutls_num.h"
 #include "gnutls_record.h"
+
 #ifdef HAVE_ERRNO_H
 # include <errno.h>
 #endif
@@ -189,6 +190,7 @@ int gnutls_deinit(GNUTLS_STATE state)
 
        GNUTLS_FREE(state->gnutls_internals.db_name);
 
+       memset( state, 0, sizeof(GNUTLS_STATE_INT));
        GNUTLS_FREE(state);
        return 0;
 }
@@ -356,25 +358,33 @@ int _gnutls_set_keys(GNUTLS_STATE state)
        int hash_size;
        int IV_size;
        int key_size;
-
+       int block_size;
+       
        hash_size = state->security_parameters.hash_size;
        IV_size = state->security_parameters.IV_size;
        key_size = state->security_parameters.key_material_length;
 
        memmove(random, state->security_parameters.server_random, TLS_RANDOM_SIZE);
-       memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, 32);
+       memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, TLS_RANDOM_SIZE);
+
+       block_size = 2 * hash_size + 2 * key_size + 2 * IV_size;
 
        if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3 */
-               key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, 48, random, 64,
-                       2 * hash_size + 2 * key_size + 2 * IV_size);
+               key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE,
+                       block_size);
        } else { /* TLS 1.0 */
                key_block =
-                   gnutls_PRF( state->security_parameters.master_secret, 48,
-                              keyexp, strlen(keyexp), random, 64, 2 * hash_size + 2 * key_size + 2 * IV_size);
+                   gnutls_PRF( state->security_parameters.master_secret, TLS_MASTER_SIZE,
+                              keyexp, strlen(keyexp), random, 2*TLS_RANDOM_SIZE, 
+                              block_size);
        }
        
        if (key_block==NULL) return GNUTLS_E_MEMORY_ERROR;
 
+#ifdef HARD_DEBUG
+       fprintf(stderr, "KEY BLOCK[%d]: %s\n",block_size, _gnutls_bin2hex(key_block, block_size));
+#endif
+
        if (hash_size>0) {
                state->cipher_specs.client_write_mac_secret = secure_malloc(hash_size);
                if (state->cipher_specs.client_write_mac_secret==NULL) 
@@ -451,6 +461,27 @@ int gnutls_bye(SOCKET cd, GNUTLS_STATE state)
        return ret;
 }
 
+/**
+  * gnutls_bye_nowait - This function terminates the current TLS/SSL connection.
+  * @cd: is a connection descriptor.
+  * @state: is a &GNUTLS_STATE structure.
+  *
+  * Terminates the current TLS/SSL connection. The connection should
+  * have been initiated using gnutls_handshake() or similar function.
+  * This function does not wait for the other peer to close the TLS
+  * connection.
+  **/
+int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state)
+{
+       int ret;
+
+       ret = _gnutls_send_alert(cd, state, GNUTLS_WARNING, GNUTLS_CLOSE_NOTIFY);
+
+       state->gnutls_internals.valid_connection = VALID_FALSE;
+
+       return ret;
+}
+
 int gnutls_close_nowait(SOCKET cd, GNUTLS_STATE state)
 {
        int ret;
@@ -496,7 +527,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
        headers[1]=_gnutls_version_get_major(state->connection_state.version);
        headers[2]=_gnutls_version_get_minor(state->connection_state.version);
 
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
        fprintf(stderr, "Record: Sending Packet[%d] %s(%d) with length: %d\n",
                (int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
 #endif
@@ -523,7 +554,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
                fprintf(stderr, "Record: Sended Packet[%d] %s(%d) with length: %d\n",
                (int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, cipher_size);
 #endif
@@ -592,7 +623,7 @@ ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state)
        headers[2] = _gnutls_version_get_minor(state->connection_state.version);
 
 #ifdef HANDSHAKE_DEBUG
-       fprintf(stderr, "ChangeCipherSpec was sent\n");
+       fprintf(stderr, "Record: ChangeCipherSpec was sent\n");
 #endif
 
        WRITEuint16( 1, &headers[3]);
@@ -722,7 +753,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
        }
 
 
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
        fprintf(stderr, "Record: Expected Packet[%d] %s(%d) with length: %d\n",
                (int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
        fprintf(stderr, "Record: Received Packet[%d] %s(%d) with length: %d\n",
@@ -795,7 +826,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
        }
        
        if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type == GNUTLS_CHANGE_CIPHER_SPEC) {
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
                fprintf(stderr, "Record: ChangeCipherSpec Packet was received\n");
 #endif
                gnutls_free(ciphertext);
@@ -826,7 +857,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
                return tmplen;
        }
 
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
        fprintf(stderr, "Record: Decrypted Packet[%d] %s(%d) with length: %d\n",
                (int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, tmplen);
 #endif
index 548e0dadc344b5548983857e316fac034c380fb0..58db0457283616121634abde63faf72b4d9683b0 100644 (file)
@@ -86,7 +86,7 @@ int gnutls_get_current_session_id( GNUTLS_STATE state, void* session, int *sessi
   *
   * Sets all session parameters - in order to support resuming
   * session must be the one returned by gnutls_get_current_session();
-  * This function should be called before gnutls_handshake_begin() or gnutls_handshake().
+  * This function should be called before gnutls_handshake().
   * Keep in mind that session resuming is advisory. The server may
   * choose not to resume the session, thus a full handshake will be
   * performed.
index 7192d3d60e81667dc46ab2f883695be1f6103a98..f441baee8c069e0dbf5375938565ab6c6dbff583 100644 (file)
@@ -207,9 +207,6 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
        DECR_LEN(len, challenge);
        memset( random, 0, TLS_RANDOM_SIZE);
        
-       /* Well, I think that this is not what TLS 1.0 defines,
-        * but with this, we are compatible with netscape browser!
-        */
        memcpy( &random[TLS_RANDOM_SIZE-challenge], &data[pos], challenge);
 
        _gnutls_set_client_random( state, random);
index 7225a31b3bfab3e8a3e574e2ffea522f016b48d1..24091ac960080bc5c0905777b44938e6aa54f4fb 100644 (file)
@@ -138,6 +138,15 @@ void print_info(GNUTLS_STATE state)
        const SRP_AUTH_INFO *srp_info;
        const ANON_AUTH_INFO *dh_info;
        char *tmp;
+       unsigned char sesid[32];
+       int sesid_size, i;
+       
+       /* print session_id specific data */
+       gnutls_get_current_session_id( state, sesid, &sesid_size);
+       printf("\n- Session ID: ");
+       for(i=0;i<sesid_size;i++)
+               printf("%.2X", sesid[i]);
+       printf("\n");
 
        /* print srp specific data */
        if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
@@ -177,13 +186,24 @@ void print_info(GNUTLS_STATE state)
 
 }
 
+/* Creates html with the current state information.
+ */
 #define tmp2 &http_buffer[strlen(http_buffer)]
 void peer_print_info(int cd, GNUTLS_STATE state)
 {
        const SRP_AUTH_INFO *srp_info;
        const ANON_AUTH_INFO *dh_info;
        char *tmp;
+       unsigned char sesid[32];
+       int sesid_size, i;
        
+       /* print session_id */
+       gnutls_get_current_session_id( state, sesid, &sesid_size);
+       sprintf(tmp2, "\n<p>Session ID: <i>");
+       for(i=0;i<sesid_size;i++)
+               sprintf(tmp2, "%.2X", sesid[i]);
+       sprintf(tmp2, "</i></p>\n");
+
        /* print srp specific data */
        if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
                srp_info = gnutls_get_auth_info(state);
@@ -231,23 +251,29 @@ void peer_print_info(int cd, GNUTLS_STATE state)
        return;
 }
 
+/* actually something like readline.
+ * if rnl!=1 then reads an http request in the form REQ\n\n
+ */
 int read_request(int cd, GNUTLS_STATE state, char *data, int data_size, int rnl)
 {
-       /* rnl is the requested new lines. Eg. return if 3 newlines
-        * were given 
-        */
        int n, rc, nl = 0;
-       char c, *ptr;
+       char c, *ptr, p1=0, p2=0;
 
        ptr = data;
        for (n = 1; n < data_size; n++) {
                if ((rc = gnutls_read(cd, state, &c, 1)) == 1) {
+
                        *ptr++ = c;
-                       if (c == '\n') {
+                       if (c == '\n' && rnl==1) break;
+
+                       if (c=='\n' && p1=='\r' && p2=='\n') {
                                nl++;
-                               if (nl == rnl)
+                               if (nl == 1)
                                        break;
                        }
+                       p2 = p1;
+                       p1 = c;
+
                } else if (rc == 0) {
                        if (n == 1)
                                return 0;
@@ -257,6 +283,7 @@ int read_request(int cd, GNUTLS_STATE state, char *data, int data_size, int rnl)
                        return rc;
                }
        }
+fprintf(stderr, "\n");
        *ptr = 0;
        return n;
 }
@@ -384,7 +411,7 @@ int main(int argc, char **argv)
                        }
                }
                printf("\n");
-               gnutls_bye(sd, state);
+               gnutls_bye_nowait(sd, state);
                close(sd);
                gnutls_deinit(state);
        }