diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-07-15 15:29:29 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-07-15 15:29:29 +0000 |
commit | 3e0c6e040456fa12e2039526ecc666ac318ffed6 (patch) | |
tree | 8946a9ca46bacd6ecc9d06726291c26812a6cc29 | |
parent | 099900892bc87e627c01285e75a0c8185eef112b (diff) | |
download | gnutls-3e0c6e040456fa12e2039526ecc666ac318ffed6.tar.gz |
Fixes in zlib compression code. gnutls_global_init_extra() in libgnutls-extra fails if library versions do not match. Semantic changes in gnutls_record_set_max_size(). The requested size is now immediately enforced at the output buffers.
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | lib/auth_cert.c | 8 | ||||
-rw-r--r-- | lib/auth_dhe.c | 2 | ||||
-rw-r--r-- | lib/auth_rsa.c | 2 | ||||
-rw-r--r-- | lib/ext_max_record.c | 12 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 2 | ||||
-rw-r--r-- | lib/gnutls_compress.c | 4 | ||||
-rw-r--r-- | lib/gnutls_compress_int.c | 28 | ||||
-rw-r--r-- | lib/gnutls_constate.c | 3 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 2 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 6 | ||||
-rw-r--r-- | lib/gnutls_global.c | 81 | ||||
-rw-r--r-- | lib/gnutls_int.h | 16 | ||||
-rw-r--r-- | lib/gnutls_record.c | 92 | ||||
-rw-r--r-- | lib/gnutls_state.c | 9 | ||||
-rw-r--r-- | libextra/gnutls_extra.c | 10 |
16 files changed, 171 insertions, 115 deletions
@@ -1,10 +1,17 @@ -Version 0.5.? +Version 0.5.1 - Corrected the m4 macros which used <gnutls.h> instead of <gnutls/gnutls.h> - Documentation fixes - Added gnutls_transport_set_ptr2() function, which accepts two different pointers, to be used while receiving, and while sending data. +- Semantic changes in gnutls_record_set_max_size(). The requested + size is now immediately enforced at the output buffers. +- gnutls_global_init_extra() now fails if the library versions do + not match. +- Fixes in client and server example programs. Null encryption can + be used in these programs, to assist in debuging. +- Fixes in zlib compression code. Version 0.5.0 (6/07/2002) - Added X.509 certificate tests in tests/ directory diff --git a/lib/auth_cert.c b/lib/auth_cert.c index 6448921abd..5f1378c10f 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -608,7 +608,7 @@ int _gnutls_gen_openpgp_certificate_fpr(GNUTLS_STATE state, if (_E_gnutls_openpgp_fingerprint==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } if ( (ret=_E_gnutls_openpgp_fingerprint( &apr_cert_list[0].raw, pdata, &fpr_size)) < 0) { @@ -861,7 +861,7 @@ int _gnutls_proc_openpgp_server_certificate(GNUTLS_STATE state, */ if (_E_gnutls_openpgp_request_key==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } if ( (ret=_E_gnutls_openpgp_request_key( &akey, cred, p, 20)) < 0) { gnutls_assert(); @@ -920,7 +920,7 @@ int _gnutls_proc_openpgp_server_certificate(GNUTLS_STATE state, gnutls_free_datum( &akey); CLEAR_CERTS; gnutls_afree(peer_certificate_list); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } if ((ret = @@ -1163,7 +1163,7 @@ int _gnutls_proc_cert_client_cert_vrfy(GNUTLS_STATE state, opaque * data, case GNUTLS_CRT_OPENPGP: if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } ret = _E_gnutls_openpgp_cert2gnutls_cert(&peer_cert, diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index 92abbe4d8e..e597b770b4 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -403,7 +403,7 @@ static int proc_dhe_server_kx(GNUTLS_STATE state, opaque * data, case GNUTLS_CRT_OPENPGP: if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 5b9bfea96a..66474e4c0a 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -95,7 +95,7 @@ int i; case GNUTLS_CRT_OPENPGP: if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, diff --git a/lib/ext_max_record.c b/lib/ext_max_record.c index 2fccce533d..6dbe74b7bf 100644 --- a/lib/ext_max_record.c +++ b/lib/ext_max_record.c @@ -54,7 +54,8 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int return new_size; } - state->security_parameters.max_record_size = new_size; + state->security_parameters.max_record_send_size = new_size; + state->security_parameters.max_record_recv_size = new_size; } } else { /* CLIENT SIDE - we must check if the sent record size is the right one */ @@ -70,8 +71,9 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int 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; + } else { + state->security_parameters.max_record_recv_size = state->gnutls_internals.proposed_record_size; + } } @@ -104,14 +106,14 @@ int _gnutls_max_record_send_params( GNUTLS_STATE state, opaque* data, int data_s } else { /* server side */ - if (state->security_parameters.max_record_size != DEFAULT_MAX_RECORD_SIZE) { + if (state->security_parameters.max_record_recv_size != DEFAULT_MAX_RECORD_SIZE) { len = 1; if (data_size < len) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } - data[0] = _gnutls_mre_record2num( state->security_parameters.max_record_size); + data[0] = _gnutls_mre_record2num( state->security_parameters.max_record_recv_size); return len; } diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 3b2525edd4..a189bef816 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -356,7 +356,7 @@ int _gnutls_openpgp_cert_verify_peers(GNUTLS_STATE state) */ if (_E_gnutls_openpgp_verify_key==NULL) { gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; + return GNUTLS_E_INIT_LIBEXTRA; } verify = _E_gnutls_openpgp_verify_key( cred->pgp_trustdb, &cred->keyring, &info->raw_certificate_list[0], peer_certificate_list_size); diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c index cebc3d21ea..03c34f394e 100644 --- a/lib/gnutls_compress.c +++ b/lib/gnutls_compress.c @@ -41,7 +41,7 @@ int _gnutls_m_plaintext2compressed(GNUTLS_STATE state, data=NULL; size = _gnutls_compress( state->connection_state.write_compression_state, - plaintext.data, plaintext.size, &data, MAX_RECORD_SIZE+1024); + plaintext.data, plaintext.size, &data, MAX_RECORD_SEND_SIZE+1024); if (size < 0) { gnutls_assert(); return GNUTLS_E_COMPRESSION_FAILED; @@ -63,7 +63,7 @@ int _gnutls_m_compressed2plaintext(GNUTLS_STATE state, data=NULL; size = _gnutls_decompress( state->connection_state.read_compression_state, - compressed.data, compressed.size, &data, MAX_RECORD_SIZE); + compressed.data, compressed.size, &data, MAX_RECORD_RECV_SIZE); if (size < 0) { gnutls_assert(); return GNUTLS_E_DECOMPRESSION_FAILED; diff --git a/lib/gnutls_compress_int.c b/lib/gnutls_compress_int.c index 30f39663cd..69053088d7 100644 --- a/lib/gnutls_compress_int.c +++ b/lib/gnutls_compress_int.c @@ -155,8 +155,9 @@ int err; int _gnutls_decompress( GNUTLS_COMP_HANDLE handle, char* compressed, int compressed_size, char** plain, int max_record_size) { int plain_size=GNUTLS_E_DECOMPRESSION_FAILED, err; #ifdef HAVE_LIBZ -uLongf size; +uLongf out_size; z_stream* zhandle; +int cur_pos; #endif if (compressed_size > max_record_size+EXTRA_COMP_SIZE) { @@ -171,36 +172,41 @@ z_stream* zhandle; #ifdef HAVE_LIBZ case GNUTLS_COMP_ZLIB: *plain = NULL; - size = compressed_size; + out_size = compressed_size;; plain_size = 0; zhandle = handle->handle; zhandle->next_in = (Bytef*) compressed; zhandle->avail_in = compressed_size; - + + cur_pos = 0; + do { - size*=2; - *plain = gnutls_realloc( *plain, size); + out_size += 128; + *plain = gnutls_realloc( *plain, out_size); if (*plain==NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - zhandle->next_out = (Bytef*) *plain; - zhandle->avail_out = size; + zhandle->next_out = (Bytef*) (*plain + cur_pos); + zhandle->avail_out = out_size - cur_pos; err = inflate( zhandle, Z_SYNC_FLUSH); + + cur_pos = out_size - zhandle->avail_out; - } while( err==Z_BUF_ERROR && zhandle->avail_out==0 && size < max_record_size); - - if (err!=Z_OK || zhandle->avail_in != 0) { + } while( (err==Z_BUF_ERROR && zhandle->avail_out==0 && out_size < max_record_size) + || ( err==Z_OK && zhandle->avail_in != 0)); + + if (err!=Z_OK) { gnutls_assert(); gnutls_free( *plain); return GNUTLS_E_DECOMPRESSION_FAILED; } - plain_size = size - zhandle->avail_out; + plain_size = out_size - zhandle->avail_out; break; #endif default: diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index e8e9300d57..85d7257c9b 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -176,7 +176,8 @@ int _gnutls_set_write_keys(GNUTLS_STATE state) memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \ dst->session_id_size = src->session_id_size; \ dst->timestamp = src->timestamp; \ - dst->max_record_size = src->max_record_size; \ + dst->max_record_recv_size = src->max_record_recv_size; \ + dst->max_record_send_size = src->max_record_send_size; \ dst->version = src->version; \ memcpy( &dst->extensions, &src->extensions, sizeof(TLSExtensions)); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 0b91e5332d..882d4603f4 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -115,6 +115,8 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_SYNTAX_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_DER_OVERFLOW, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_TOO_MANY_EMPTY_PACKETS, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_INIT_LIBEXTRA, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_LIBRARY_VERSION_MISMATCH, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED, 1), {0} }; diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 424fb4798a..2d7a4f0e6a 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -79,6 +79,12 @@ #define GNUTLS_E_UNKNOWN_PK_ALGORITHM -80 #define GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED -81 +/* returned if libextra functionality was requested but + * gnutls_global_init_extra() was not called. + */ +#define GNUTLS_E_INIT_LIBEXTRA -82 +#define GNUTLS_E_LIBRARY_VERSION_MISMATCH -82 + #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250 /* _INT_ internal errors. Not exported */ diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index 77bbf28023..69cebc0735 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -250,3 +250,84 @@ void gnutls_transport_set_pull_function( GNUTLS_STATE state, GNUTLS_PULL_FUNC pu void gnutls_transport_set_push_function( GNUTLS_STATE state, GNUTLS_PUSH_FUNC push_func) { state->gnutls_internals._gnutls_push_func = push_func; } + + +/* Taken from libgcrypt. Needed to configure scripts. + */ + +static const char* +parse_version_number( const char *s, int *number ) +{ + int val = 0; + + if( *s == '0' && isdigit(s[1]) ) + return NULL; /* leading zeros are not allowed */ + for ( ; isdigit(*s); s++ ) { + val *= 10; + val += *s - '0'; + } + *number = val; + return val < 0? NULL : s; +} + +/* The parse version functions were copied from libgcrypt. + */ +static const char * +parse_version_string( const char *s, int *major, int *minor, int *micro ) +{ + s = parse_version_number( s, major ); + if( !s || *s != '.' ) + return NULL; + s++; + s = parse_version_number( s, minor ); + if( !s || *s != '.' ) + return NULL; + s++; + s = parse_version_number( s, micro ); + if( !s ) + return NULL; + return s; /* patchlevel */ +} + +/**************** + * Check that the the version of the library is at minimum the requested one + * and return the version string; return NULL if the condition is not + * satisfied. If a NULL is passed to this function, no check is done, + * but the version string is simply returned. + */ +const char * +gnutls_check_version( const char *req_version ) +{ + const char *ver = GNUTLS_VERSION; + int my_major, my_minor, my_micro; + int rq_major, rq_minor, rq_micro; + const char *my_plvl, *rq_plvl; + + if ( !req_version ) + return ver; + + my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); + if ( !my_plvl ) + return NULL; /* very strange our own version is bogus */ + rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor, + &rq_micro ); + if ( !rq_plvl ) + return NULL; /* req version string is invalid */ + + if ( my_major > rq_major + || (my_major == rq_major && my_minor > rq_minor) + || (my_major == rq_major && my_minor == rq_minor + && my_micro > rq_micro) + || (my_major == rq_major && my_minor == rq_minor + && my_micro == rq_micro + && strcmp( my_plvl, rq_plvl ) >= 0) ) { + return ver; + } + return NULL; +} + +const char * +_gnutls_return_version( void) +{ + return GNUTLS_VERSION; +} diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index a8faa0465d..15c5dc34e2 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -33,9 +33,9 @@ #define READ_DEBUG #define HANDSHAKE_DEBUG // Prints some information on handshake #define X509_DEBUG -#define RECORD_DEBUG +#define RECORD_DEBUG*/ #define DEBUG -*/ + /* It might be a good idea to replace int with void* * here. @@ -81,11 +81,12 @@ typedef const int* GNUTLS_LIST; /* the maximum size of encrypted packets */ #define DEFAULT_MAX_RECORD_SIZE 16384 #define RECORD_HEADER_SIZE 5 -#define MAX_RECORD_SIZE state->security_parameters.max_record_size +#define MAX_RECORD_SEND_SIZE state->security_parameters.max_record_send_size +#define MAX_RECORD_RECV_SIZE state->security_parameters.max_record_recv_size #define MAX_PAD_SIZE 255 #define EXTRA_COMP_SIZE 2048 #define MAX_RECORD_OVERHEAD MAX_PAD_SIZE+EXTRA_COMP_SIZE -#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_SIZE+RECORD_HEADER_SIZE +#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE #define HANDSHAKE_HEADER_SIZE 4 @@ -341,7 +342,12 @@ typedef struct { uint8 session_id_size; time_t timestamp; TLSExtensions extensions; - uint16 max_record_size; + + /* The send size is the one requested by the programmer. + * The recv size is the one negotiated with the peer. + */ + uint16 max_record_send_size; + uint16 max_record_recv_size; /* holds the negotiated certificate type */ CertificateType cert_type; GNUTLS_Version version; /* moved here */ diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 473ca7e050..e76307e884 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -322,8 +322,8 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty _gnutls_record_log( "REC: Sending Packet[%d] %s(%d) with length: %d\n", (int) _gnutls_uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata); - if ( sizeofdata > MAX_RECORD_SIZE) - data2send_size = MAX_RECORD_SIZE; + if ( sizeofdata > MAX_RECORD_SEND_SIZE) + data2send_size = MAX_RECORD_SEND_SIZE; else data2send_size = sizeofdata; @@ -858,81 +858,6 @@ ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType hty } -/* Taken from libgcrypt */ - -static const char* -parse_version_number( const char *s, int *number ) -{ - int val = 0; - - if( *s == '0' && isdigit(s[1]) ) - return NULL; /* leading zeros are not allowed */ - for ( ; isdigit(*s); s++ ) { - val *= 10; - val += *s - '0'; - } - *number = val; - return val < 0? NULL : s; -} - - -/* The parse version functions were copied from libgcrypt. - */ -static const char * -parse_version_string( const char *s, int *major, int *minor, int *micro ) -{ - s = parse_version_number( s, major ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, minor ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, micro ); - if( !s ) - return NULL; - return s; /* patchlevel */ -} - -/**************** - * Check that the the version of the library is at minimum the requested one - * and return the version string; return NULL if the condition is not - * satisfied. If a NULL is passed to this function, no check is done, - * but the version string is simply returned. - */ -const char * -gnutls_check_version( const char *req_version ) -{ - const char *ver = GNUTLS_VERSION; - int my_major, my_minor, my_micro; - int rq_major, rq_minor, rq_micro; - const char *my_plvl, *rq_plvl; - - if ( !req_version ) - return ver; - - my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); - if ( !my_plvl ) - return NULL; /* very strange our own version is bogus */ - rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor, - &rq_micro ); - if ( !rq_plvl ) - return NULL; /* req version string is invalid */ - - if ( my_major > rq_major - || (my_major == rq_major && my_minor > rq_minor) - || (my_major == rq_major && my_minor == rq_minor - && my_micro > rq_micro) - || (my_major == rq_major && my_minor == rq_minor - && my_micro == rq_micro - && strcmp( my_plvl, rq_plvl ) >= 0) ) { - return ver; - } - return NULL; -} - - /** * gnutls_record_send - sends to the peer the specified data * @state: is a &GNUTLS_STATE structure. @@ -986,7 +911,10 @@ ssize_t gnutls_record_recv( GNUTLS_STATE state, void *data, size_t sizeofdata) { * **/ size_t gnutls_record_get_max_size( GNUTLS_STATE state) { - return state->security_parameters.max_record_size; + /* Recv will hold the negotiated max record size + * always. + */ + return state->security_parameters.max_record_recv_size; } @@ -1000,9 +928,9 @@ size_t gnutls_record_get_max_size( GNUTLS_STATE state) { * choose not to accept the requested size. * * Acceptable values are 2^9, 2^10, 2^11 and 2^12. - * Returns 0 on success. The requested record size does not - * get in effect immediately. It will be used after a successful - * handshake. + * Returns 0 on success. The requested record size does + * get in effect immediately only while sending data. The receive + * part will take effect after a successful handshake. * * This function uses a TLS extension called 'max record size'. * Not all TLS implementations use or even understand this extension. @@ -1021,6 +949,8 @@ ssize_t new_size; return new_size; } + state->security_parameters.max_record_send_size = size; + state->gnutls_internals.proposed_record_size = size; return 0; diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 244111b57e..60d2382485 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -195,12 +195,17 @@ int default_protocol_list[] = { GNUTLS_TLS1, 0 }; * the receive procedure slow. */ (*state)->gnutls_internals.record_recv_buffer.data = gnutls_malloc(INITIAL_RECV_BUFFER_SIZE); + + /* set the socket pointers to -1; + */ + (*state)->gnutls_internals.transport_recv_ptr = -1; + (*state)->gnutls_internals.transport_send_ptr = -1; /* set the default maximum record size for TLS */ - (*state)->security_parameters.max_record_size = DEFAULT_MAX_RECORD_SIZE; + (*state)->security_parameters.max_record_recv_size = DEFAULT_MAX_RECORD_SIZE; + (*state)->security_parameters.max_record_send_size = DEFAULT_MAX_RECORD_SIZE; - /* everything else not initialized here is initialized * as NULL or 0. This is why calloc is used. */ diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c index 24edbf3714..65216adcff 100644 --- a/libextra/gnutls_extra.c +++ b/libextra/gnutls_extra.c @@ -99,6 +99,8 @@ static void _gnutls_add_openpgp_functions(void) { static int _gnutls_init_extra = 0; +const char* _gnutls_return_version( void); + /** * gnutls_global_init_extra - This function initializes the global state of gnutls-extra * @@ -112,6 +114,14 @@ static int _gnutls_init_extra = 0; **/ int gnutls_global_init_extra(void) { int ret; + + /* If the version of libgnutls != version of + * libextra, then do not initialize the library. + * This is because it may break things. + */ + if (strcmp( _gnutls_return_version(), VERSION)!=0) { + return GNUTLS_E_LIBRARY_VERSION_MISMATCH; + } _gnutls_init_extra++; |