diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-11-10 21:37:13 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-11-10 21:37:13 +0000 |
commit | 7d28c069875e58a0a6640684a379fe6d2aaf69b6 (patch) | |
tree | a2a01fdffbf4495fccd17a16f442d128e0bfe0cf /lib | |
parent | d4b8f2c7eea4246a6e2d1dee4118f0bd8ebd20e6 (diff) | |
download | gnutls-7d28c069875e58a0a6640684a379fe6d2aaf69b6.tar.gz |
several fixes.
Including:
- max_record_header extension.
- resume handshake sending wrong ssl version
- Non blocking IO (not ready yet)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ext_max_record.c | 23 | ||||
-rw-r--r-- | lib/gnutls.h.in | 1 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 256 | ||||
-rw-r--r-- | lib/gnutls_buffers.h | 1 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 44 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 5 | ||||
-rw-r--r-- | lib/gnutls_compress_int.c | 2 | ||||
-rw-r--r-- | lib/gnutls_global.c | 68 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 44 | ||||
-rw-r--r-- | lib/gnutls_int.h | 51 | ||||
-rw-r--r-- | lib/gnutls_mem.c | 5 | ||||
-rw-r--r-- | lib/gnutls_mem.h | 1 | ||||
-rw-r--r-- | lib/gnutls_privkey.c | 12 | ||||
-rw-r--r-- | lib/gnutls_record.c | 73 | ||||
-rw-r--r-- | lib/io_debug.h | 10 |
15 files changed, 382 insertions, 214 deletions
diff --git a/lib/ext_max_record.c b/lib/ext_max_record.c index 09f269df5d..b33adf809e 100644 --- a/lib/ext_max_record.c +++ b/lib/ext_max_record.c @@ -38,6 +38,7 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int if (state->security_parameters.entity == GNUTLS_SERVER) { if (data_size > 0) { + gnutls_assert(); if ( data_size != 1) { gnutls_assert(); @@ -61,15 +62,14 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - - new_size = _gnutls_mre_num2record(data[0]); -fprintf(stderr, "RECEIVING IT %d\n", new_size); + new_size = _gnutls_mre_num2record(data[0]); - if (new_size < 0 || new_size != state->security_parameters.max_record_size) { + if (new_size < 0 || new_size != state->gnutls_internals.proposed_record_size) { gnutls_assert(); return GNUTLS_E_ILLEGAL_PARAMETER; - } + } else + state->security_parameters.max_record_size = state->gnutls_internals.proposed_record_size; } @@ -87,12 +87,14 @@ int _gnutls_max_record_send_params( GNUTLS_STATE state, opaque** data) { /* this function sends the client extension data (dnsname) */ if (state->security_parameters.entity == GNUTLS_CLIENT) { - if (state->security_parameters.max_record_size != DEFAULT_MAX_RECORD_SIZE) { + if (state->gnutls_internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE) { + gnutls_assert(); + len = 1; (*data) = gnutls_malloc(len); /* hold the size and the type also */ if (*data==NULL) return GNUTLS_E_MEMORY_ERROR; - (*data)[0] = _gnutls_mre_record2num( state->security_parameters.max_record_size); + (*data)[0] = _gnutls_mre_record2num( state->gnutls_internals.proposed_record_size); return len; } @@ -100,7 +102,7 @@ int _gnutls_max_record_send_params( GNUTLS_STATE state, opaque** data) { if (state->security_parameters.max_record_size != DEFAULT_MAX_RECORD_SIZE) { len = 1; - (*data) = gnutls_malloc(len+2); /* hold the size and the type also */ + (*data) = gnutls_malloc(len); if (*data==NULL) return GNUTLS_E_MEMORY_ERROR; (*data)[0] = _gnutls_mre_record2num( state->security_parameters.max_record_size); @@ -114,7 +116,7 @@ int _gnutls_max_record_send_params( GNUTLS_STATE state, opaque** data) { return 0; } -/* Maps record size to numbers according to the +/* Maps numbers to record sizes according to the * extensions draft. */ int _gnutls_mre_num2record( int num) { @@ -132,6 +134,9 @@ int _gnutls_mre_num2record( int num) { } } +/* Maps record size to numbers according to the + * extensions draft. + */ int _gnutls_mre_record2num( int record_size) { switch(record_size) { case 512: diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index f7a9d9464e..87b6cf684b 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -94,6 +94,7 @@ int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state); AlertDescription gnutls_get_last_alert( GNUTLS_STATE state); int gnutls_send_alert(SOCKET, GNUTLS_STATE, AlertLevel, AlertDescription); +int gnutls_send_appropriate_alert( SOCKET cd, GNUTLS_STATE state, int err); /* get information on the current state */ BulkCipherAlgorithm gnutls_get_current_cipher( GNUTLS_STATE state); diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 364cbfb832..e1ae16bce2 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -1,3 +1,4 @@ +#define READ_DEBUG /* * Copyright (C) 2000,2001 Nikos Mavroyanopoulos * @@ -17,13 +18,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ - +#define IO_DEBUG 5 #include <gnutls_int.h> #include <gnutls_errors.h> #include <gnutls_num.h> #include <gnutls_record.h> +#include <gnutls_buffers.h> /* This is the only file that uses the berkeley sockets API. + * + * Also holds all the buffering code used in gnutls. */ #ifdef HAVE_ERRNO_H @@ -113,6 +117,11 @@ int gnutls_check_pending(GNUTLS_STATE state) { int gnutls_get_data_buffer(ContentType type, GNUTLS_STATE state, char *data, int length) { + if (length < 0 || data==NULL) { + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; + } + switch(type) { case GNUTLS_APPLICATION_DATA: @@ -304,7 +313,7 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t int recvlowat = RCVLOWAT; int recvdata; - *iptr = NULL; + *iptr = state->gnutls_internals.recv_buffer.data; if ( sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0 || (state->gnutls_internals.recv_buffer.size+sizeOfPtr) > MAX_RECV_SIZE) { @@ -431,13 +440,11 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t } } - - /* This function is like write. But it does not return -1 on error. * It does return gnutls_errno instead. * - * This function may not cope right with interrupted system calls - * and EAGAIN error. Ideas? + * In case of E_AGAIN and E_INTERRUPTED errors, you must call gnutls_write_flush(), + * until it returns ok (0). * * We need to push exactly the data in n, since we cannot send less * data. In TLS the peer must receive the whole packet in order @@ -452,6 +459,7 @@ 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 */ ptr = iptr; @@ -466,12 +474,14 @@ 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; #ifdef WRITE_DEBUG - _gnutls_log( "WRITE: Restoring old write. (%d data to send)\n", n); + _gnutls_log( "WRITE: Restoring old write. (%d bytes to send)\n", n); #endif } @@ -492,19 +502,23 @@ 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); + state->gnutls_internals.send_buffer.data = gnutls_realloc_fast( + state->gnutls_internals.send_buffer.data, left); + if (state->gnutls_internals.send_buffer.data == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } state->gnutls_internals.send_buffer.size = left; - /* use memmove since they may overlap - */ - memmove( state->gnutls_internals.send_buffer.data, &ptr[n-left], 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.\n"); + _gnutls_log( "WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n", left, n-left); #endif - gnutls_assert(); if (errno==EAGAIN) retval = GNUTLS_E_AGAIN; else retval = GNUTLS_E_INTERRUPTED; @@ -517,16 +531,20 @@ ssize_t _gnutls_write_buffered(SOCKET fd, GNUTLS_STATE state, const void *iptr, left -= i; #ifdef WRITE_DEBUG - _gnutls_log( "WRITE: wrote %d bytes to %d. Left %d bytes\n", i, fd, left); - for (x=0;x<((n-left)/16)+1;x++) { + _gnutls_log( "WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n", i, fd, left, n); + for (x=0;x<((i)/16)+1;x++) { + if (sum>n-left) + break; + _gnutls_log( "%.4x - ",x); for (j=0;j<16;j++) { if (sum<n-left) { _gnutls_log( "%.2x ", ((unsigned char*)ptr)[sum++]); - } + } else break; } _gnutls_log( "\n"); } + _gnutls_log( "\n"); #endif } @@ -553,8 +571,37 @@ ssize_t _gnutls_write_flush(SOCKET fd, GNUTLS_STATE state) ret = _gnutls_write_buffered(fd, state, NULL, 0); #ifdef WRITE_DEBUG - _gnutls_log("WRITE FLUSH: %d\n", ret); + _gnutls_log("WRITE FLUSH: %d [buffer: %d]\n", ret, state->gnutls_internals.send_buffer.size); +#endif + + return ret; +} + +/* This function writes the data that are left in the + * Handshake write buffer (ie. because the previous write was + * interrupted. + */ +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(); + return ret; + } +#ifdef WRITE_DEBUG + _gnutls_log("HANDSHAKE_FLUSH: written[1] %d bytes\n", ret); #endif + + if (state->gnutls_internals.handshake_send_buffer.size == 0) { + ret = state->gnutls_internals.handshake_send_buffer_prev_size; /* done */ + state->gnutls_internals.handshake_send_buffer_prev_size = 0; + state->gnutls_internals.handshake_send_buffer.size = 0; + + return ret; + } + return ret; } @@ -565,35 +612,90 @@ ssize_t _gnutls_write_flush(SOCKET fd, GNUTLS_STATE state) ssize_t _gnutls_handshake_send_int( SOCKET fd, GNUTLS_STATE state, ContentType type, HandshakeType htype, void *iptr, size_t n) { size_t left; - ssize_t i = 0; - char *ptr = iptr; - - if (iptr==NULL && n == 0) { - /* resuming interrupted write. + ssize_t i = 0, ret=0; + opaque *ptr; + int ptrcopy; + ssize_t retval = 0; + + ptrcopy = 1; + if (state->gnutls_internals.handshake_send_buffer.size > 0 && iptr==NULL && n == 0) { + /* resuming previously interrupted write */ - return _gnutls_write_flush( fd, state); + gnutls_assert(); + n = state->gnutls_internals.handshake_send_buffer.size; + iptr = state->gnutls_internals.handshake_send_buffer.data; + + 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; } - /* FIXME: Potential problem here. If ie one message has been - * sent, and the next send_int() gets an interrupt (or e_again). - * This might be more dangerous, since a non blocking server may - * block here. Should a buffer be used here? - */ + if (n==0) { /* if we have no data to send */ + gnutls_assert(); + return 0; + } else if (iptr==NULL) { + gnutls_assert(); + return GNUTLS_E_UNKNOWN_ERROR; + } + + + ptr = iptr; left = n; while (left > 0) { - i = gnutls_send_int(fd, state, type, htype, &ptr[i], left); - if (i <= 0) { - gnutls_assert(); - if (n-left > 0) { + ret = gnutls_send_int(fd, state, type, htype, &ptr[n-left], left); + + if (ret <= 0) { + if (ret==0) { gnutls_assert(); - return n-left; + ret = GNUTLS_E_UNKNOWN_ERROR; } - return i; + + 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) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + 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; + state->gnutls_internals.handshake_send_buffer_htype = htype; + + } else { + state->gnutls_internals.handshake_send_buffer_prev_size = 0; + state->gnutls_internals.handshake_send_buffer.size = 0; + } + + gnutls_assert(); + return ret; } + i = ret; left -= i; } - return n; + retval = n + state->gnutls_internals.handshake_send_buffer_prev_size; + + state->gnutls_internals.handshake_send_buffer.size = 0; + state->gnutls_internals.handshake_send_buffer_prev_size = 0; + + return retval; } @@ -603,18 +705,69 @@ ssize_t _gnutls_handshake_send_int( SOCKET fd, GNUTLS_STATE state, ContentType t ssize_t _gnutls_handshake_recv_int(int fd, GNUTLS_STATE state, ContentType type, HandshakeType htype, void *iptr, size_t sizeOfPtr) { size_t left; - ssize_t i=0; - char *ptr = iptr; - + ssize_t i; + char *ptr; + size_t dsize; + + ptr = iptr; left = sizeOfPtr; + + if (state->gnutls_internals.handshake_recv_buffer.size > 0) { + /* if we have already received some data */ + fprintf(stderr, "C1: BUFFER_SIZE: %d\n", state->gnutls_internals.handshake_recv_buffer.size); + if (sizeOfPtr <= state->gnutls_internals.handshake_recv_buffer.size) { + /* if requested less data then return it. + */ + gnutls_assert(); + memcpy( iptr, state->gnutls_internals.handshake_recv_buffer.data, sizeOfPtr); + + state->gnutls_internals.handshake_recv_buffer.size -= sizeOfPtr; + + memmove( state->gnutls_internals.handshake_recv_buffer.data, + &state->gnutls_internals.handshake_recv_buffer.data[sizeOfPtr], + state->gnutls_internals.handshake_recv_buffer.size); + fprintf(stderr, "C2: BUFFER_SIZE: %d\n", state->gnutls_internals.handshake_recv_buffer.size); + + return sizeOfPtr; + } + gnutls_assert(); + memcpy( iptr, state->gnutls_internals.handshake_recv_buffer.data, state->gnutls_internals.handshake_recv_buffer.size); + + htype = state->gnutls_internals.handshake_recv_buffer_htype; + type = state->gnutls_internals.handshake_recv_buffer_type; + + left -= state->gnutls_internals.handshake_recv_buffer.size; + + state->gnutls_internals.handshake_recv_buffer.size = 0; + } + while (left > 0) { - i = gnutls_recv_int(fd, state, type, htype, &ptr[i], left); + dsize = sizeOfPtr - left; + i = gnutls_recv_int(fd, state, type, htype, &ptr[dsize], left); if (i < 0) { - if (sizeOfPtr - left > 0) { + + if (dsize > 0 && (i==GNUTLS_E_INTERRUPTED || i==GNUTLS_E_AGAIN)) { gnutls_assert(); - goto finish; - } + + state->gnutls_internals.handshake_recv_buffer.data = gnutls_realloc_fast( + state->gnutls_internals.handshake_recv_buffer.data, dsize); + if (state->gnutls_internals.handshake_recv_buffer.data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + memcpy( state->gnutls_internals.handshake_recv_buffer.data, iptr, dsize); + + state->gnutls_internals.handshake_recv_buffer_htype = htype; + state->gnutls_internals.handshake_recv_buffer_type = type; + + state->gnutls_internals.handshake_recv_buffer.size = dsize; + } else + state->gnutls_internals.handshake_recv_buffer.size = 0; + gnutls_assert(); + fprintf(stderr, "C3: BUFFER_SIZE: %d\n", state->gnutls_internals.handshake_recv_buffer.size); + return i; } else { if (i == 0) @@ -625,12 +778,27 @@ ssize_t _gnutls_handshake_recv_int(int fd, GNUTLS_STATE state, ContentType type, } - finish: + state->gnutls_internals.handshake_recv_buffer.size = 0; + +{int x,j,sum=0; + fprintf(stderr, "HREAD: read %d bytes from %d\n", (sizeOfPtr-left), fd); + for (x=0;x<((sizeOfPtr-left)/16)+1;x++) { + fprintf(stderr, "%.4x - ",x); + for (j=0;j<16;j++) { + if (sum<(sizeOfPtr-left)) { + fprintf(stderr, "%.2x ", ((unsigned char*)ptr)[sum++]); + } + } + fprintf(stderr, "\n"); + + } +} return (sizeOfPtr - left); } /* Buffer for handshake packets. Keeps the packets in order - * for finished messages to use them. + * for finished messages to use them. Used in HMAC calculation + * and finished messages. */ int gnutls_insert_to_handshake_buffer( GNUTLS_STATE state, char *data, int length) { diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index 430282a2ae..63b17e0ef5 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -37,3 +37,4 @@ 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_write_flush(SOCKET fd, GNUTLS_STATE state); +ssize_t _gnutls_handshake_write_flush(SOCKET fd, GNUTLS_STATE state); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 0830152bd8..c5156bdab0 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -34,6 +34,10 @@ #include <gnutls_algorithms.h> #include <gnutls_dh.h> +#ifdef DEBUG +# warning MAX ALGORITHM PARAMS == 2, ok for RSA +#endif + /* KX mappings to PK algorithms */ typedef struct { KXAlgorithm kx_algorithm; @@ -70,7 +74,6 @@ PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm) return ret; } -#define GNUTLS_FREE(x) if(x!=NULL) gnutls_free(x) void gnutls_free_cert(gnutls_cert cert) { int n, i; @@ -86,9 +89,7 @@ void gnutls_free_cert(gnutls_cert cert) for (i = 0; i < n; i++) { _gnutls_mpi_release(&cert.params[i]); } - if (cert.params != NULL) - gnutls_free(cert.params); - + gnutls_free_datum(&cert.raw); return; @@ -448,7 +449,7 @@ int gnutls_set_x509_dh_bits(X509PKI_CREDENTIALS res, int bits) } -static int _read_rsa_params(opaque * der, int dersize, MPI ** params) +static int _read_rsa_params(opaque * der, int dersize, MPI * params) { opaque str[MAX_X509_CERT_SIZE]; int len, result; @@ -477,16 +478,8 @@ static int _read_rsa_params(opaque * der, int dersize, MPI ** params) return GNUTLS_E_ASN1_PARSING_ERROR; } - /* allocate size for the parameters (2) */ - *params = gnutls_calloc(1, 2 * sizeof(MPI)); - if (*params==NULL) { + if (_gnutls_mpi_scan(¶ms[0], GCRYMPI_FMT_USG, str, &len) != 0) { gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (_gnutls_mpi_scan(&(*params)[0], GCRYMPI_FMT_USG, str, &len) != 0) { - gnutls_assert(); - gnutls_free((*params)); asn1_delete_structure(spk); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -497,17 +490,14 @@ static int _read_rsa_params(opaque * der, int dersize, MPI ** params) &len); if (result != ASN_OK) { gnutls_assert(); - _gnutls_mpi_release(&(*params)[0]); - gnutls_free((*params)); + _gnutls_mpi_release(¶ms[0]); asn1_delete_structure(spk); return GNUTLS_E_ASN1_PARSING_ERROR; } - - if (_gnutls_mpi_scan(&(*params)[1], GCRYMPI_FMT_USG, str, &len) != 0) { + if (_gnutls_mpi_scan(¶ms[1], GCRYMPI_FMT_USG, str, &len) != 0) { gnutls_assert(); - _gnutls_mpi_release(&(*params)[0]); - gnutls_free((*params)); + _gnutls_mpi_release(¶ms[0]); asn1_delete_structure(spk); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -807,6 +797,7 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert) _gnutls_log("Decoding error %d\n", result); #endif gnutls_assert(); + asn1_delete_structure(c2); return GNUTLS_E_ASN1_PARSING_ERROR; } @@ -838,12 +829,21 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert) if (result != ASN_OK) { gnutls_assert(); + asn1_delete_structure(c2); return GNUTLS_E_ASN1_PARSING_ERROR; } + if ((sizeof( gCert->params)/sizeof(MPI)) < 2) { + gnutls_assert(); + /* internal error. Increase the MPIs in params */ + asn1_delete_structure(c2); + return GNUTLS_E_UNKNOWN_ERROR; + } + if ((result = - _read_rsa_params(str, len / 8, &gCert->params)) < 0) { + _read_rsa_params(str, len / 8, gCert->params)) < 0) { gnutls_assert(); + asn1_delete_structure(c2); return result; } @@ -854,10 +854,10 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert) gnutls_assert(); #ifdef DEBUG _gnutls_log("ALGORITHM: %s\n", str); + asn1_delete_structure(c2); return GNUTLS_E_UNIMPLEMENTED_FEATURE; #endif gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN; - gCert->params = NULL; } diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 06e416c70a..b9743ad9fc 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -5,8 +5,9 @@ #include <x509_asn1.h> #include <gnutls_ui.h> +#define MAX_PARAMS_SIZE 2 /* ok for RSA */ typedef struct gnutls_cert { - MPI *params; /* the size of params depends on the public + MPI params[MAX_PARAMS_SIZE]; /* the size of params depends on the public * key algorithm */ PKAlgorithm subject_pk_algorithm; @@ -38,7 +39,7 @@ typedef struct gnutls_cert { } gnutls_cert; typedef struct { - MPI *params; /* the size of params depends on the public + MPI params[MAX_PARAMS_SIZE];/* the size of params depends on the public * key algorithm */ PKAlgorithm pk_algorithm; diff --git a/lib/gnutls_compress_int.c b/lib/gnutls_compress_int.c index 9dbc4bb3f5..8eea99f6d2 100644 --- a/lib/gnutls_compress_int.c +++ b/lib/gnutls_compress_int.c @@ -22,7 +22,7 @@ #include "gnutls_compress.h" #include "gnutls_errors.h" #include "gnutls_compress_int.h" -#ifdef HAVE_ZLIB_H +#ifdef HAVE_LIBZ #include <zlib.h> #endif diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index 207a624e7c..4adb3081bb 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -23,22 +23,6 @@ #include <x509_asn1.h> #include <gnutls_dh.h> -#ifdef USE_SIGNALS - -# ifdef HAVE_SIGNAL_H -# include <signal.h> -# endif - -# ifndef SIGFUNC -# define SIGFUNC - typedef void Sigfunc(int); -# endif -static Sigfunc *Signal( int signo, Sigfunc *func); - -static Sigfunc *old_sig_handler; - -#endif - /* created by asn1c */ extern const static_asn pkcs1_asn1_tab[]; @@ -93,10 +77,6 @@ static void dlog( const char* str) { * You must call gnutls_global_deinit() when gnutls usage is no longer needed * Returns zero on success. * - * If signals are supported in your system, this function sets SIGPIPE, - * to SIG_IGN. The old signal handler will be restored when calling - * gnutls_global_deinit(). - * **/ int gnutls_global_init() { @@ -105,11 +85,6 @@ int gnutls_global_init() /* for gcrypt in order to be able to allocate memory */ gcry_set_allocation_handler(gnutls_malloc, secure_malloc, _gnutls_is_secure_memory, gnutls_realloc, gnutls_free); - /* we need this */ -#ifdef USE_SIGNALS - old_sig_handler = Signal( SIGPIPE, SIG_IGN); -#endif - /* set default recv/send functions */ gnutls_global_set_log_func( dlog); @@ -147,10 +122,6 @@ int gnutls_global_init() void gnutls_global_deinit() { - /* restore signal handler */ -#ifdef USE_SIGNALS - Signal( SIGPIPE, old_sig_handler); -#endif asn1_delete_structure( PKCS1_ASN); asn1_delete_structure( PKIX1_ASN); @@ -158,45 +129,6 @@ void gnutls_global_deinit() { } -#ifdef USE_SIGNALS - -/* This is an emulation of the signal() function, using the - * POSIX sigaction() (if present). - */ -static Sigfunc * - Signal(int signo, Sigfunc * func) -{ -#ifdef HAVE_SIGACTION - - struct sigaction act, oact; - - act.sa_handler = func; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - if (signo == SIGALRM) { -#ifdef SA_INTERRUPT - act.sa_flags |= SA_INTERRUPT; /* SunOs 4.x */ -#endif - } else { -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */ -#endif - } - - if (sigaction(signo, &act, &oact) < 0) - return (SIG_ERR); - return (oact.sa_handler); - -#else /* ifdef HAVE_SIGACTION */ -#ifdef HAVE_SIGNAL - return signal(signo, func); -#else - return (Sigfunc *) 0; /* Do nothing */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ -} -#endif /* USE_SIGNALS */ - /* These functions should be elsewere. Kept here for * historical reasons. diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index dc7e4f1f94..11111c47a4 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -588,7 +588,9 @@ int _gnutls_send_handshake(SOCKET cd, GNUTLS_STATE state, void *i_data, /* we are resuming a previously interrupted * send. */ - return _gnutls_write_flush( cd, state); + ret = _gnutls_handshake_write_flush( cd, state); + return ret; + } if (i_data==NULL && i_datasize > 0) { @@ -820,7 +822,6 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data, } ret = GNUTLS_E_UNKNOWN_ERROR; - if (data != NULL && length32 > 0) *data = dataptr; @@ -1070,10 +1071,17 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state, int again) return GNUTLS_E_MEMORY_ERROR; } - hver = _gnutls_version_max(state); + /* if we are resuming a session then we set the + * version number to the previously established. + */ + if (SessionID==NULL) + hver = _gnutls_version_max(state); + else + hver = gnutls_get_current_version(state); + data[pos++] = _gnutls_version_get_major(hver); data[pos++] = _gnutls_version_get_minor(hver); - + _gnutls_create_random(random); _gnutls_set_client_random(state, random); @@ -1166,7 +1174,7 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state, int again) static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state, int again) { - char *data = NULL; + opaque *data; opaque *extdata; int extdatalen; int pos = 0; @@ -1270,24 +1278,6 @@ int ret; return ret; } -/* Sends the appropriate alert, depending - * on the error message. - */ -static int _gnutls_handshake_send_appropriate_alert( SOCKET cd, GNUTLS_STATE state, int err) { -int ret; - switch (err) { /* send appropriate alert */ - case GNUTLS_E_ILLEGAL_PARAMETER: - ret = gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_ILLEGAL_PARAMETER); - break; - default: - ret = gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); - break; - } - - return ret; -} - - /* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a * hello message is expected. It uses the security_parameters.current_cipher_suite * and gnutls_internals.compression_method. @@ -1300,7 +1290,6 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data, if (state->security_parameters.entity == GNUTLS_CLIENT) { ret = _gnutls_read_server_hello(state, data, datalen); if (ret < 0) { - _gnutls_handshake_send_appropriate_alert( cd, state, ret); gnutls_assert(); return ret; } @@ -1308,7 +1297,6 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data, ret = _gnutls_read_client_hello(state, data, datalen); if (ret < 0) { - _gnutls_handshake_send_appropriate_alert( cd, state, ret); gnutls_assert(); return ret; } @@ -1393,7 +1381,8 @@ int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state) * and the connection should be terminated. * * This function may also return the non-fatal errors GNUTLS_E_AGAIN, or - * GNUTLS_E_INTERRUPTED, and you may resume this handshake later. + * GNUTLS_E_INTERRUPTED. In that case you may resume the handshake + * (call this function, until it returns ok) * **/ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) @@ -1415,6 +1404,8 @@ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) STATE = STATE0; + _gnutls_clear_handshake_buffers( state); + return 0; } @@ -1423,7 +1414,6 @@ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) if (gnutls_is_fatal_error(ret)==0) return ret; \ gnutls_assert(); \ ERR( str, ret); \ - _gnutls_handshake_send_appropriate_alert( cd, state, ret); \ gnutls_clear_handshake_buffer(state); \ return ret; \ } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index ac51a5dec6..8efed39c8f 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -25,16 +25,15 @@ #include <defines.h> /* -#define IO_DEBUG 5 // define this to check non blocking behaviour +#define IO_DEBUG 3 // define this to check non blocking behaviour #define BUFFERS_DEBUG #define HARD_DEBUG -#define READ_DEBUG #define WRITE_DEBUG #define READ_DEBUG #define HANDSHAKE_DEBUG // Prints some information on handshake -#define RECORD_DEBUG +#define RECORD_DEBUG*/ #define DEBUG -*/ + /* It might be a good idea to replace int with void* * here. @@ -77,9 +76,9 @@ /* the maximum size of encrypted packets */ #define DEFAULT_MAX_RECORD_SIZE 16384 -#define MAX_ENC_LEN state->security_parameters.max_record_size #define RECORD_HEADER_SIZE 5 -#define MAX_RECV_SIZE 18432+RECORD_HEADER_SIZE /* 2^14+2048+RECORD_HEADER_SIZE */ +#define MAX_RECORD_SIZE state->security_parameters.max_record_size +#define MAX_RECV_SIZE 2048+MAX_RECORD_SIZE+RECORD_HEADER_SIZE /* 2^14+2048+RECORD_HEADER_SIZE */ #define HANDSHAKE_HEADER_SIZE 4 @@ -150,6 +149,10 @@ typedef enum CompressionMethod { GNUTLS_NULL_COMPRESSION=1, GNUTLS_ZLIB } Compre typedef enum ValidSession { VALID_TRUE, VALID_FALSE } ValidSession; typedef enum ResumableSession { RESUME_TRUE, RESUME_FALSE } ResumableSession; +/* Record Protocol */ +typedef enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE, + GNUTLS_APPLICATION_DATA } ContentType; + /* STATE (stop) */ @@ -376,6 +379,17 @@ typedef struct { /* sockets internals */ int lowat; + /* These buffers are used in the handshake + * protocol only. freed using _gnutls_clear_handshake_buffers(); + */ + gnutls_datum handshake_send_buffer; + size_t handshake_send_buffer_prev_size; + ContentType handshake_send_buffer_type; + HandshakeType handshake_send_buffer_htype; + ContentType handshake_recv_buffer_type; + HandshakeType handshake_recv_buffer_htype; + gnutls_datum handshake_recv_buffer; + /* this buffer holds a record packet -mostly used for * non blocking IO. */ @@ -384,10 +398,10 @@ typedef struct { * for the gnutls_write_buffered() * function. */ - int send_buffer_prev_size; /* holds the + size_t send_buffer_prev_size; /* holds the * data written in the previous runs. */ - int send_buffer_user_size; /* holds the + size_t send_buffer_user_size; /* holds the * size of the user specified data to * send. */ @@ -433,10 +447,12 @@ typedef struct { int (*x509_client_cert_callback)(void*,void*,int, void*, int); gnutls_cert peer_cert; int max_handshake_data_buffer_size; + /* PUSH & PULL functions. */ PULL_FUNC _gnutls_pull_func; PUSH_FUNC _gnutls_push_func; + /* STORE & RETRIEVE functions. Only used if other * backend than gdbm is used. */ @@ -444,6 +460,11 @@ typedef struct { DB_RETR_FUNC db_retrieve_func; DB_REMOVE_FUNC db_remove_func; void* db_ptr; + + /* Holds the record size requested by the + * user. + */ + uint16 proposed_record_size; } GNUTLS_INTERNALS; struct GNUTLS_STATE_INT { @@ -457,9 +478,6 @@ struct GNUTLS_STATE_INT { typedef struct GNUTLS_STATE_INT *GNUTLS_STATE; -/* Record Protocol */ -typedef enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE, - GNUTLS_APPLICATION_DATA } ContentType; /* functions */ @@ -471,7 +489,7 @@ svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label, void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version); GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state); -/* These macros return the advertized TLS version of +/* These two macros return the advertized TLS version of * the peer. */ #define _gnutls_get_adv_version_major( state) \ @@ -480,4 +498,13 @@ GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state); #define _gnutls_get_adv_version_minor( state) \ state->gnutls_internals.adv_version_minor +#define _gnutls_clear_handshake_buffers( state) \ + gnutls_free( state->gnutls_internals.handshake_send_buffer.data); \ + gnutls_free( state->gnutls_internals.handshake_recv_buffer.data); \ + state->gnutls_internals.handshake_send_buffer.data = NULL; \ + state->gnutls_internals.handshake_recv_buffer.data = NULL; \ + state->gnutls_internals.handshake_send_buffer.size = 0; \ + state->gnutls_internals.handshake_recv_buffer.size = 0; \ + state->gnutls_internals.handshake_send_buffer_prev_size = 0 + #endif /* GNUTLS_INT_H */ diff --git a/lib/gnutls_mem.c b/lib/gnutls_mem.c index 9cde853528..6ed871a93f 100644 --- a/lib/gnutls_mem.c +++ b/lib/gnutls_mem.c @@ -105,6 +105,9 @@ void *gnutls_realloc(void *_ptr, size_t size) return ret; } +/* This realloc only returns a new pointer if you + * request more data than the data into the pointer. + */ void *gnutls_realloc_fast(void *ptr, size_t size) { @@ -117,7 +120,6 @@ void *gnutls_realloc_fast(void *ptr, size_t size) return gnutls_realloc(ptr, size); } - void gnutls_free(void *_ptr) { opaque *ptr = _ptr; @@ -205,3 +207,4 @@ char *gnutls_strdup(const char *s) return ret; } #endif /* USE_DMALLOC */ + diff --git a/lib/gnutls_mem.h b/lib/gnutls_mem.h index 920a9fe5b4..fbe0375cc6 100644 --- a/lib/gnutls_mem.h +++ b/lib/gnutls_mem.h @@ -35,3 +35,4 @@ void gnutls_free( void* ptr); char* gnutls_strdup( const char* s); #endif + diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 7a64d6b3f0..f17971ce74 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -41,15 +41,17 @@ int _gnutls_pkcs1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum cert) { pkey->pk_algorithm = GNUTLS_PK_RSA; - /* we do return 2 MPIs - */ - pkey->params = gnutls_malloc(2*sizeof(MPI)); - if (asn1_create_structure( _gnutls_get_pkcs(), "PKCS-1.RSAPrivateKey", &pkcs_asn, "rsakey")!=ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_ERROR; } + if ((sizeof( pkey->params)/sizeof(MPI)) < 2) { + gnutls_assert(); + /* internal error. Increase the MPIs in params */ + return GNUTLS_E_UNKNOWN_ERROR; + } + result = asn1_get_der( pkcs_asn, cert.data, cert.size); if (result != ASN_OK) { gnutls_assert(); @@ -117,7 +119,7 @@ int n, i; for (i=0;i<n;i++) { _gnutls_mpi_release( &pkey.params[i]); } - if (pkey.params!=NULL) gnutls_free(pkey.params); + gnutls_free_datum( &pkey.raw); return; diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index fca32d02dd..dfb6f2956d 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -121,11 +121,12 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end) /* set the default maximum record size for TLS */ (*state)->security_parameters.max_record_size = DEFAULT_MAX_RECORD_SIZE; + (*state)->gnutls_internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE; /* everything else not initialized here is initialized * as NULL or 0. This is why calloc is used. */ - + return 0; } @@ -151,6 +152,8 @@ int gnutls_deinit(GNUTLS_STATE state) gdbm_close(state->gnutls_internals.db_reader); #endif + _gnutls_clear_handshake_buffers( state); + gnutls_sfree_datum(&state->connection_state.read_mac_secret); gnutls_sfree_datum(&state->connection_state.write_mac_secret); @@ -384,8 +387,24 @@ int gnutls_send_alert(SOCKET cd, GNUTLS_STATE state, AlertLevel level, AlertDesc /* Sends the appropriate alert, depending * on the error message. */ -int _gnutls_send_appropriate_alert( SOCKET cd, GNUTLS_STATE state, int err) { -int ret; +/** + * gnutls_send_appropriate_alert - This function sends an alert to the peer depending on the error code + * @cd: is a connection descriptor. + * @state: is a &GNUTLS_STATE structure. + * @err: is an integer + * + * Sends an alert to the peer depending on the error code returned by a gnutls + * function. All alerts sent by this function are fatal, so connection should + * be considered terminated after calling this function. + * + * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED. + * + * If the return value is GNUTLS_E_UNIMPLEMENTED_FEATURE, then no alert has + * been sent to the peer. + * + **/ +int gnutls_send_appropriate_alert( SOCKET cd, GNUTLS_STATE state, int err) { +int ret = GNUTLS_E_UNIMPLEMENTED_FEATURE; switch (err) { /* send appropriate alert */ case GNUTLS_E_MAC_FAILED: ret = gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_BAD_RECORD_MAC); @@ -396,8 +415,11 @@ int ret; case GNUTLS_E_DECOMPRESSION_FAILED: ret = gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_DECOMPRESSION_FAILURE); break; + case GNUTLS_E_ILLEGAL_PARAMETER: + ret = gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_ILLEGAL_PARAMETER); + break; + } - return ret; } @@ -461,7 +483,7 @@ int gnutls_bye(SOCKET cd, GNUTLS_STATE state, CloseRequest how) * send (if called by the user the Content is specific) * It is intended to transfer data, under the current state. * - * Oct 30 2001: Removed capability to send data more than MAX_ENC_SIZE. + * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE. * This makes the function much easier to read, and more error resistant * (there were cases were the old function could mess everything up). * --nmav @@ -510,16 +532,20 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha (int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata); #endif - if ( sizeofdata > MAX_ENC_LEN) - data2send = MAX_ENC_LEN; + if ( sizeofdata > 128) //MAX_RECORD_SIZE) + data2send = 128; //MAX_RECORD_SIZE; else data2send = sizeofdata; /* Only encrypt if we don't have data to send * from the previous run. - probably interrupted. */ - if (state->gnutls_internals.send_buffer.size != 0) { + if (state->gnutls_internals.send_buffer.size > 0) { ret = _gnutls_write_flush(cd, state); + if (ret > 0) cipher_size = ret; + cipher = NULL; + + retval = state->gnutls_internals.send_buffer_user_size; } else { cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, data, data2send, &cipher, type); if (cipher_size <= 0) { @@ -541,10 +567,9 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha return GNUTLS_E_RECORD_LIMIT_REACHED; } - ret = _gnutls_write_buffered(cd, state, cipher, cipher_size); } - + if ( ret != cipher_size) { gnutls_free( cipher); if ( ret < 0 && gnutls_is_fatal_error(ret)==0) { @@ -554,6 +579,12 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha gnutls_assert(); return ret; } + + if (ret > 0) { + gnutls_assert(); + ret = GNUTLS_E_UNKNOWN_ERROR; + } + state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); @@ -644,7 +675,11 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha */ if ( (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && gnutls_get_data_buffer_size(type, state) > 0) { ret = gnutls_get_data_buffer(type, state, data, sizeofdata); - + if (ret < 0) { + gnutls_assert(); + return ret; + } + /* if the buffer just got empty */ if (gnutls_get_data_buffer_size(type, state)==0) { if ( (ret2=_gnutls_clear_peeked_data( cd, state)) < 0) { @@ -770,7 +805,6 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha */ tmplen = _gnutls_decrypt( state, ciphertext, length, &tmpdata, recv_type); if (tmplen < 0) { - _gnutls_send_appropriate_alert( cd, state, tmplen); state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); @@ -897,6 +931,10 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha /* Get Application data from buffer */ if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) { ret = gnutls_get_data_buffer(type, state, data, sizeofdata); + if (ret < 0) { + gnutls_assert(); + return ret; + } /* if the buffer just got empty */ if (gnutls_get_data_buffer_size(type, state)==0) { @@ -1067,8 +1105,7 @@ AlertDescription gnutls_get_last_alert( GNUTLS_STATE state) { * same parameters. Otherwise the write operation will be * corrupted and the connection will be terminated. * - * Returns the number of bytes received, zero on EOF, or - * a negative error code. + * Returns the number of bytes sent, or a negative error code. * **/ ssize_t gnutls_write(SOCKET cd, GNUTLS_STATE state, const void *data, size_t sizeofdata) { @@ -1120,7 +1157,9 @@ size_t gnutls_get_max_record_size( GNUTLS_STATE state) { * choose not to accept the requested size. * * Acceptable values are $2^{9}, 2^{10}, 2^{11}$ and $2^{12}$. - * Returns the new record size. + * Returns 0 on success. The requested record size does not + * get in effect immediately. It will be used after a successful + * handshake. * **/ size_t gnutls_set_max_record_size( GNUTLS_STATE state, size_t size) { @@ -1136,7 +1175,7 @@ size_t new_size; return new_size; } - state->security_parameters.max_record_size = size; + state->gnutls_internals.proposed_record_size = size; - return state->security_parameters.max_record_size; + return 0; } diff --git a/lib/io_debug.h b/lib/io_debug.h index faa16dbe20..d79fabf7ea 100644 --- a/lib/io_debug.h +++ b/lib/io_debug.h @@ -17,11 +17,9 @@ */ /* This debug file was contributed by - * Paul Sheer <psheer@icon.co.za> - * - * It does return EAGAIN errors in recv() and - * send() calls in order to check, whether - * non blocking support is ok. + * Paul Sheer <psheer@icon.co.za>. Some changes were made by nmav. + * It's purpose it to debug non blocking behaviour of gnutls. The included + * send() and recv() functions return EAGAIN errors in random. * */ @@ -66,6 +64,6 @@ static int send_debug (int fd, const char *buf, int len, int flags) return send (fd, buf, len, flags); } -#define send send_debug +//#define send send_debug #endif |