diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-11-15 12:37:08 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-11-15 12:37:08 +0000 |
commit | 80bc85066bd8406464f2d2d36574dfe1b6bfdc6b (patch) | |
tree | 8c5446d81cc1c283e8ed1edd610d9c55473e0ef9 | |
parent | abc3977c66a2b00c5e76a5a8a03d5d3a74215c28 (diff) | |
download | gnutls-80bc85066bd8406464f2d2d36574dfe1b6bfdc6b.tar.gz |
corrected some obscure bugs in the handshake and record send buffering code.
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | lib/auth_dhe_rsa.c | 2 | ||||
-rw-r--r-- | lib/auth_srp.c | 3 | ||||
-rw-r--r-- | lib/auth_x509.c | 7 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 156 | ||||
-rw-r--r-- | lib/gnutls_buffers.h | 2 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_record.c | 2 | ||||
-rw-r--r-- | src/serv.c | 2 |
10 files changed, 116 insertions, 61 deletions
diff --git a/configure.in b/configure.in index ca975efa4f..19cc3ef489 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/lib/auth_dhe_rsa.c b/lib/auth_dhe_rsa.c index 519a80cdf9..bec7454fcc 100644 --- a/lib/auth_dhe_rsa.c +++ b/lib/auth_dhe_rsa.c @@ -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) { diff --git a/lib/auth_srp.c b/lib/auth_srp.c index dad9eb68bc..7d36b4344d 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -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; diff --git a/lib/auth_x509.c b/lib/auth_x509.c index 668466872d..41b739531a 100644 --- a/lib/auth_x509.c +++ b/lib/auth_x509.c @@ -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)); diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 64a9ee9775..e5c712a8ef 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -1,4 +1,3 @@ -#define IO_DEBUG 5 /* * Copyright (C) 2000,2001 Nikos Mavroyanopoulos * @@ -38,6 +37,12 @@ # 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; diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index 63b17e0ef5..28f54a595d 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -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); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index f8c80e266b..499d0c5033 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -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), diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 4426100b5c..ea2ff4ca6a 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -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 diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 6c316635af..9628c64892 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -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; diff --git a/src/serv.c b/src/serv.c index 7aa3da7868..c6efeb4c59 100644 --- a/src/serv.c +++ b/src/serv.c @@ -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; |