]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
corrected some obscure bugs in the handshake and record send buffering code.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 15 Nov 2001 12:37:08 +0000 (12:37 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 15 Nov 2001 12:37:08 +0000 (12:37 +0000)
configure.in
lib/auth_dhe_rsa.c
lib/auth_srp.c
lib/auth_x509.c
lib/gnutls_buffers.c
lib/gnutls_buffers.h
lib/gnutls_errors.c
lib/gnutls_errors_int.h
lib/gnutls_record.c
src/serv.c

index ca975efa4fb105a1338e13a9b493d13a1726c455..19cc3ef489c7261508bc6fc6836966fb900c731c 100644 (file)
@@ -176,6 +176,7 @@ dnl **** CROSS COMPILING
 AC_MSG_RESULT(none)
 )
 
+
 AC_MSG_CHECKING([whether to check for external libraries])
 
 dnl if used --with-ext-libraries then we will not check
index 519a80cdf9e8897911355022d6605d519b5b1b04..bec7454fcc347cbabf99044143df6ab35569c1fd 100644 (file)
@@ -309,7 +309,7 @@ static int proc_dhe_rsa_server_kx(GNUTLS_STATE state, opaque * data,
        
        sigsize = READuint16( &data[vparams.size]);
        signature.data = &data[vparams.size+2];
-       signature.size = GMIN(data_size-vparams.size-2, sigsize);       
+       signature.size = GMIN(data_size-vparams.size-2, sigsize);
 
        ret = _gnutls_verify_sig_params( state, &state->gnutls_internals.peer_cert, &vparams, &signature);
        if (ret<0) {
index dad9eb68bc80062b5d6081d137f4ad4b4cf9031e..7d36b4344d6d19bfc438805124c414b507ae2877 100644 (file)
@@ -88,7 +88,6 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data)
        username = ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username;
        strcpy( username, state->security_parameters.extensions.srp_username);
 
-#warning GET_PWD_ENTRY_USERNAME
        pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, username, &err);
 
        if (pwd_entry == NULL) {
@@ -249,7 +248,6 @@ int gen_srp_client_kx0(GNUTLS_STATE state, opaque ** data)
                return GNUTLS_E_INSUFICIENT_CRED;
        }
        
-#warning GET_USERNAME_PASSWORD
        username = cred->username;
        password = cred->password;
 
@@ -310,7 +308,6 @@ int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size
                return GNUTLS_E_INSUFICIENT_CRED;
        }
        
-#warning GET_USERNAME_PASSWORD
        username = cred->username;
        password = cred->password;
 
index 668466872d66e8bfb1dcfa90fa7942090405404b..41b739531a07d5693c199e82bba04c8b07539979 100644 (file)
@@ -414,7 +414,6 @@ int _gnutls_gen_x509_client_certificate(GNUTLS_STATE state, opaque ** data)
        gnutls_private_key *apr_pkey;
        int apr_cert_list_length;
 
-#warning GET_CLIENT_CERTIFICATE
        /* find the appropriate certificate */
        if ((ret=_gnutls_find_apr_cert( state, &apr_cert_list, &apr_cert_list_length, &apr_pkey))<0) {
                gnutls_assert();
@@ -475,7 +474,6 @@ int _gnutls_gen_x509_server_certificate(GNUTLS_STATE state, opaque ** data)
        gnutls_private_key *apr_pkey;
        int apr_cert_list_length;
 
-#warning GET_SERVER_CERTIFICATE
        if ((ret=_gnutls_find_apr_cert( state, &apr_cert_list, &apr_cert_list_length, &apr_pkey))<0) {
                gnutls_assert();
                return ret;
@@ -533,7 +531,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
        gnutls_datum tmp;
        CertificateStatus verify;
 
-#warning PUT_SERVER_CERTIFICATE
        cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL);
        if (cred == NULL) {
                gnutls_assert();
@@ -626,7 +623,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
                j++;
        }
 
-#warning GET_SERVER_CERTIFICATE_PARAMS
        /* store the required parameters for the handshake
         */
        if ((ret =
@@ -759,7 +755,6 @@ int _gnutls_gen_x509_client_cert_vrfy(GNUTLS_STATE state, opaque ** data)
 
        *data = NULL;
        
-#warning GENERATE_SIGNATURE_FROM_DATA
        /* find the appropriate certificate */
        if ((ret=_gnutls_find_apr_cert( state, &apr_cert_list, &apr_cert_list_length, &apr_pkey))<0) {
                gnutls_assert();
@@ -802,7 +797,6 @@ gnutls_datum sig;
        size = READuint16( pdata);
        pdata += 2;
 
-#warning VERIFY_SIGNATURE_FROM_DATA
        if ( size < data_size - 2) {
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
@@ -861,7 +855,6 @@ int _gnutls_gen_x509_server_cert_req(GNUTLS_STATE state, opaque ** data)
        pdata += 2;
        size += 2;
 
-#warning GET_TRUSTED_CAS_DN
        for (i = 0; i < cred->ncas; i++) {
                if ( (ret=_gnutls_find_dn( &dn, &cred->ca_list[i])) < 0) {
                        gnutls_free( (*data));
index 64a9ee9775ee7caa30a53658277716180e7fe023..e5c712a8efbd92a9dfedcaa9de3ca34bbc2d22fd 100644 (file)
@@ -1,4 +1,3 @@
-#define IO_DEBUG 5
 /*
  *      Copyright (C) 2000,2001 Nikos Mavroyanopoulos
  *
 # define EAGAIN EWOULDBLOCK
 #endif
 
+inline 
+static int RET( int err) {
+       if (err==EAGAIN) return GNUTLS_E_AGAIN;
+       return GNUTLS_E_INTERRUPTED;
+}
+
 #ifdef IO_DEBUG
 # include <io_debug.h>
 #endif
@@ -206,8 +211,8 @@ static ssize_t _gnutls_read( SOCKET fd, GNUTLS_STATE state, void *iptr, size_t s
                                        goto finish;
                                }
                                gnutls_assert();
-                               if (errno==EAGAIN) return GNUTLS_E_AGAIN;
-                               else return GNUTLS_E_INTERRUPTED;
+
+                               return RET(errno);
                        } else {
                                gnutls_assert();
                                return GNUTLS_E_PULL_ERROR;
@@ -440,6 +445,58 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t
        }
 }
 
+
+/* These two functions are used to insert data to the send buffer of the handshake or
+ * record protocol. The send buffer is kept if a send is interrupted and we need to keep
+ * the data left to sent, in order to send them later.
+ */
+#define MEMSUB(x,y) (x-y)
+
+inline
+static int _gnutls_buffer_insert( gnutls_datum * buffer, const opaque* _data, int data_size) {
+
+       if ( ( MEMSUB(_data, buffer->data) >= 0) && (MEMSUB(_data, buffer->data) < buffer->size) ) {
+               /* the given _data is part of the buffer.
+                */
+               if (data_size > buffer->size) {
+                       gnutls_assert();
+                       /* this shouldn't have happened */
+                       return GNUTLS_E_UNKNOWN_ERROR;
+               }
+               
+               if (_data==buffer->data) { /* then don't even memmove */
+                       buffer->size = data_size;
+                       return 0;
+               }
+               
+               memmove( buffer->data, _data, data_size);
+               buffer->size = data_size;
+
+               return 0;               
+       }
+       
+       buffer->data = gnutls_realloc_fast( buffer->data, data_size);
+       buffer->size = data_size;
+       
+       if (buffer->data == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       memcpy( buffer->data, _data, data_size);
+
+       return 0;
+}
+
+inline
+static int _gnutls_buffer_get( gnutls_datum * buffer, const opaque ** ptr, size_t *ptr_size) {
+       *ptr_size = buffer->size;
+       *ptr = buffer->data;
+       
+       return 0;
+}
+
 /* This function is like write. But it does not return -1 on error.
  * It does return gnutls_errno instead.
  *
@@ -459,8 +516,8 @@ ssize_t _gnutls_write_buffered(SOCKET fd, GNUTLS_STATE state, const void *iptr,
 #endif
        ssize_t retval, i;
        const opaque * ptr;
-       int ptrcopy; /* indicates whether to copy from the ptr */
-
+       int ret;
+       
        ptr = iptr;
        
        /* In case the previous write was interrupted, check if the
@@ -474,12 +531,13 @@ ssize_t _gnutls_write_buffered(SOCKET fd, GNUTLS_STATE state, const void *iptr,
 
        /* If data in the buffer exist
         */
-       ptrcopy = 1;
        if (iptr == NULL) {
                /* checking is handled above */
-               ptr = state->gnutls_internals.send_buffer.data;
-               n = state->gnutls_internals.send_buffer.size;
-               ptrcopy = 0;
+               ret = _gnutls_buffer_get( &state->gnutls_internals.send_buffer, &ptr, &n);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return retval;
+               }
 #ifdef WRITE_DEBUG
                _gnutls_log( "WRITE: Restoring old write. (%d bytes to send)\n", n);
 #endif
@@ -502,25 +560,16 @@ ssize_t _gnutls_write_buffered(SOCKET fd, GNUTLS_STATE state, const void *iptr,
                        if (errno == EAGAIN || errno == EINTR) {
                                state->gnutls_internals.send_buffer_prev_size += n - left;
 
-                               state->gnutls_internals.send_buffer.data = gnutls_realloc_fast( 
-                                       state->gnutls_internals.send_buffer.data, left);
-       
-                               if (state->gnutls_internals.send_buffer.data == NULL) {
+                               retval = _gnutls_buffer_insert( &state->gnutls_internals.send_buffer, &ptr[n-left], left);
+                               if (retval < 0) {
                                        gnutls_assert();
-                                       return GNUTLS_E_MEMORY_ERROR;
+                                       return retval;
                                }
-                               state->gnutls_internals.send_buffer.size = left;
-
-                               if (ptrcopy != 0)
-                                       memcpy( state->gnutls_internals.send_buffer.data, &ptr[n-left], left);
-                               else 
-                                       memmove( state->gnutls_internals.send_buffer.data, &state->gnutls_internals.send_buffer.data[n-left], left);
-
+                               
 #ifdef WRITE_DEBUG
                                _gnutls_log( "WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n", left, n-left);
 #endif
-                               if (errno==EAGAIN) retval = GNUTLS_E_AGAIN;
-                               else retval = GNUTLS_E_INTERRUPTED;
+                               retval = RET(errno);
 
                                return retval;
                        } else {
@@ -584,7 +633,6 @@ ssize_t _gnutls_write_flush(SOCKET fd, GNUTLS_STATE state)
 ssize_t _gnutls_handshake_write_flush(SOCKET fd, GNUTLS_STATE state)
 {
     ssize_t ret;
-
     ret = _gnutls_handshake_send_int(fd, state, 0, 0, NULL, 0);
     if (ret < 0) {
        gnutls_assert();
@@ -609,41 +657,63 @@ ssize_t _gnutls_handshake_write_flush(SOCKET fd, GNUTLS_STATE state)
 /* This is a send function for the gnutls handshake 
  * protocol. Just makes sure that all data have been sent.
  */
-ssize_t _gnutls_handshake_send_int( SOCKET fd, GNUTLS_STATE state, ContentType type, HandshakeType htype, void *iptr, size_t n)
+ssize_t _gnutls_handshake_send_int( SOCKET fd, GNUTLS_STATE state, ContentType type, HandshakeType htype, const void *iptr, size_t n)
 {
        size_t left;
        ssize_t i = 0, ret=0;
-       opaque *ptr;
-        int ptrcopy;
+       const opaque *ptr;
         ssize_t retval = 0;
+
+       ptr = iptr;
        
-        ptrcopy = 1; 
-       if (state->gnutls_internals.handshake_send_buffer.size > 0 && iptr==NULL && n == 0) {
+       if (state->gnutls_internals.handshake_send_buffer.size > 0 && ptr==NULL && n == 0) {
                /* resuming previously interrupted write
                 */
                gnutls_assert(); 
-               n = state->gnutls_internals.handshake_send_buffer.size;
-               iptr = state->gnutls_internals.handshake_send_buffer.data;
+               ret = _gnutls_buffer_get( &state->gnutls_internals.handshake_send_buffer, &ptr, &n);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return retval;
+               }
 
                type = state->gnutls_internals.handshake_send_buffer_type;
                htype = state->gnutls_internals.handshake_send_buffer_htype;
-               ptrcopy = 0;
 
        } else if (state->gnutls_internals.handshake_send_buffer.size > 0) {
                gnutls_assert();
                return GNUTLS_E_UNKNOWN_ERROR;
+       } else {
+#ifdef WRITE_DEBUG
+               size_t sum=0, x, j;
+               
+               _gnutls_log( "HWRITE: will write %d bytes to %d.\n", n, fd);
+               for (x=0;x<((n)/16)+1;x++) {
+                       if (sum>n)
+                               break;
+
+                       _gnutls_log( "%.4x - ",x);
+                       for (j=0;j<16;j++) {
+                               if (sum<n) {
+                                       _gnutls_log( "%.2x ", ((unsigned char*)ptr)[sum++]);
+                               } else break;
+                       }
+                       _gnutls_log( "\n");
+               }
+               _gnutls_log( "\n");
+#endif
+
+       
        }
 
        if (n==0) { /* if we have no data to send */
                gnutls_assert();
                return 0;
-       } else if (iptr==NULL) {
+       } else if (ptr==NULL) {
                gnutls_assert();
                return GNUTLS_E_UNKNOWN_ERROR;
        }
        
 
-       ptr = iptr;
        left = n;
        while (left > 0) {
                ret = gnutls_send_int(fd, state, type, htype, &ptr[n-left], left);
@@ -657,22 +727,12 @@ ssize_t _gnutls_handshake_send_int( SOCKET fd, GNUTLS_STATE state, ContentType t
                        if ( left > 0 && (ret==GNUTLS_E_INTERRUPTED || ret==GNUTLS_E_AGAIN)) { 
                                gnutls_assert();
 
-                               state->gnutls_internals.handshake_send_buffer.data = gnutls_realloc_fast(
-                                               state->gnutls_internals.handshake_send_buffer.data, left);
-
-                               if (state->gnutls_internals.handshake_send_buffer.data==NULL) {
+                               retval = _gnutls_buffer_insert( &state->gnutls_internals.handshake_send_buffer, &ptr[n-left], left);
+                               if (retval < 0) {
                                        gnutls_assert();
-                                       return GNUTLS_E_MEMORY_ERROR;
+                                       return retval;
                                }
-                               
-                               if (ptrcopy!=0) 
-                                       memcpy( state->gnutls_internals.handshake_send_buffer.data, &ptr[n-left], left);
-                               else
-                                       if (n-left > 0)
-                                               memmove( state->gnutls_internals.handshake_send_buffer.data, 
-                                                       &state->gnutls_internals.handshake_send_buffer.data[n-left], left);
-
-                               state->gnutls_internals.handshake_send_buffer.size = left;
+
                                state->gnutls_internals.handshake_send_buffer_prev_size += n-left;
 
                                state->gnutls_internals.handshake_send_buffer_type = type;
index 63b17e0ef5ac38f735b740cc73e362966384f6f4..28f54a595d8f31736ab4d3d28b99cb9d428d8de1 100644 (file)
@@ -35,6 +35,6 @@ int gnutls_insert_to_handshake_buffer( GNUTLS_STATE state, char *data, int lengt
 int gnutls_clear_handshake_buffer( GNUTLS_STATE state);
 
 ssize_t _gnutls_handshake_recv_int(SOCKET fd, GNUTLS_STATE, ContentType, HandshakeType, void *, size_t);
-ssize_t _gnutls_handshake_send_int(SOCKET fd, GNUTLS_STATE, ContentType, HandshakeType, void *, size_t);
+ssize_t _gnutls_handshake_send_int(SOCKET fd, GNUTLS_STATE, ContentType, HandshakeType, const void *, size_t);
 ssize_t _gnutls_write_flush(SOCKET fd, GNUTLS_STATE state);
 ssize_t _gnutls_handshake_write_flush(SOCKET fd, GNUTLS_STATE state);
index f8c80e266b480d9b28fa2011276b08241d6ef88c..499d0c5033c850e311ab7c7991cef59ea78a3b10 100644 (file)
@@ -84,6 +84,7 @@ static gnutls_error_entry error_algorithms[] = {
        GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_KEY_USAGE_VIOLATION, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_INTERRUPTED, 0),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_TIMEOUT, 0),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_REHANDSHAKE, 0),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_APPLICATION_DATA, 0),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1),
index 4426100b5c4d771d978074334c2235b0a32ad0a5..ea2ff4ca6aec0f3b5be2489481dbe4120cf975ad 100644 (file)
@@ -56,5 +56,6 @@
 #define GNUTLS_E_PUSH_ERROR -53
 #define GNUTLS_E_PULL_ERROR -54
 #define GNUTLS_E_ILLEGAL_PARAMETER -55
+#define GNUTLS_E_TIMEOUT -56
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250
index 6c316635af0eb084dced686dc4530616b0660105..9628c6489225c9924c87bb656da9208fae7029e9 100644 (file)
@@ -543,6 +543,8 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha
        if (state->gnutls_internals.send_buffer.size > 0) {
                ret = _gnutls_write_flush(cd, state);
                if (ret > 0) cipher_size = ret;
+               else cipher_size = 0;
+               
                cipher = NULL;
 
                retval = state->gnutls_internals.send_buffer_user_size;
index 7aa3da7868f182053d089d16fbd5f78565e381a4..c6efeb4c594e1392be789c6b5f8ba33cfdb55073 100644 (file)
@@ -63,7 +63,7 @@ static char http_buffer[16*1024];
 
 #define HTTP_END  "</BODY></HTML>\n\n"
 
-//#define RENEGOTIATE
+#define RENEGOTIATE
 
 /* These are global */
 SRP_SERVER_CREDENTIALS srp_cred;