diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-09-17 17:57:59 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-09-17 17:57:59 +0000 |
commit | 61d4c25ee8c5c48cc68ff79ce6293da84b798634 (patch) | |
tree | b605220748dffe51d51bcc1105ce0c4eee85de9e /lib | |
parent | 2629ceb42edbdefe10ca3edfe1cfd96069a81561 (diff) | |
download | gnutls-61d4c25ee8c5c48cc68ff79ce6293da84b798634.tar.gz |
Added support for the LZO compression library in gnutls-extra. Some fixes in the hello message parsing.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rw-r--r-- | lib/defines.h | 6 | ||||
-rw-r--r-- | lib/gnutls.h.in.in | 3 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 40 | ||||
-rw-r--r-- | lib/gnutls_algorithms.h | 12 | ||||
-rw-r--r-- | lib/gnutls_compress_int.c | 139 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 4 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 10 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 41 | ||||
-rw-r--r-- | lib/gnutls_int.h | 5 |
10 files changed, 198 insertions, 65 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index a59e6b1b13..72efed2012 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -18,8 +18,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \ gnutls-api.tex io_debug.h ext_max_record.h gnutls_session_pack.h \ gnutls_alert.h gnutls_str.h gnutls_state.h gnutls_x509.h \ - ext_cert_type.h gnutls_rsa_export.h - + ext_cert_type.h gnutls_rsa_export.h lib_LTLIBRARIES = libgnutls.la diff --git a/lib/defines.h b/lib/defines.h index dd918865d7..bd418f1fdd 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -93,7 +93,7 @@ typedef long ptrdiff_t; # define USE_MCRYPT #endif -#if SIZEOF_UNSIGNED_LONG_INT == 8 +#if SIZEOF_UNSIGNED_LONG == 8 # define HAVE_UINT64 /* only used native uint64 in 64 bit machines */ typedef unsigned long int uint64; @@ -107,7 +107,7 @@ typedef struct { #endif -#if SIZEOF_UNSIGNED_LONG_INT == 4 +#if SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long int uint32; typedef signed long int sint32; #elif SIZEOF_UNSIGNED_INT == 4 @@ -120,7 +120,7 @@ typedef signed int sint32; #if SIZEOF_UNSIGNED_INT == 2 typedef unsigned int uint16; typedef signed int sint16; -#elif SIZEOF_UNSIGNED_SHORT_INT == 2 +#elif SIZEOF_UNSIGNED_SHORT == 2 typedef unsigned short int uint16; typedef signed short int sint16; #else diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index 0c50ed415d..8c5a9a844f 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -58,9 +58,8 @@ typedef enum gnutls_digest_algorithm { GNUTLS_DIG_NULL=1, GNUTLS_DIG_MD5, GNUTLS */ #define GNUTLS_MAX_ALGORITHM_NUM 8 -#define GNUTLS_COMP_ZLIB GNUTLS_COMP_ZLIB_DEFAULT typedef enum gnutls_compression_method { GNUTLS_COMP_NULL=1, - GNUTLS_COMP_ZLIB_DEFAULT, GNUTLS_COMP_ZLIB_CONSTRAINED + GNUTLS_COMP_ZLIB, GNUTLS_COMP_LZO } gnutls_compression_method; typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end; diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 7c16192d6d..64f7f988e3 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -135,30 +135,24 @@ static const gnutls_hash_entry hash_algorithms[] = { #define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \ { #name, name, id, wb, ml, cl} -struct gnutls_compression_entry { - const char *name; - gnutls_compression_method id; - int num; /* the number reserved in TLS for the specific compression method */ - /* used in zlib compressor */ - int window_bits; - int mem_level; - int comp_level; -}; +#define MAX_COMP_METHODS 5 +const int _gnutls_comp_algorithms_size = MAX_COMP_METHODS; + +/* the compression entry is defined in gnutls_algorithms.h */ -typedef struct gnutls_compression_entry gnutls_compression_entry; -static const gnutls_compression_entry compression_algorithms[] = { +gnutls_compression_entry _gnutls_compression_algorithms[MAX_COMP_METHODS] = +{ GNUTLS_COMPRESSION_ENTRY(GNUTLS_COMP_NULL, 0x00, 0, 0, 0), #ifdef HAVE_LIBZ - GNUTLS_COMPRESSION_ENTRY(GNUTLS_COMP_ZLIB_DEFAULT, 0xf1, 15, 8, 3), - GNUTLS_COMPRESSION_ENTRY(GNUTLS_COMP_ZLIB_CONSTRAINED, 0xf2, 12, 5, 3), + GNUTLS_COMPRESSION_ENTRY(GNUTLS_COMP_ZLIB, 0xf1, 15, 8, 3), #endif {0} }; #define GNUTLS_COMPRESSION_LOOP(b) \ const gnutls_compression_entry *p; \ - for(p = compression_algorithms; p->name != NULL; p++) { b ; } + for(p = _gnutls_compression_algorithms; p->name != NULL; p++) { b ; } #define GNUTLS_COMPRESSION_ALG_LOOP(a) \ GNUTLS_COMPRESSION_LOOP( if(p->id == algorithm) { a; break; } ) #define GNUTLS_COMPRESSION_ALG_LOOP_NUM(a) \ @@ -1176,6 +1170,15 @@ _gnutls_supported_ciphersuites(gnutls_session session, *_ciphers = ciphers; gnutls_afree(tmp_ciphers); + + /* This function can no longer return 0 cipher suites. + * It returns an error code instead. + */ + if (ret_count == 0) { + gnutls_assert(); + gnutls_free( ciphers); + return GNUTLS_E_NO_CIPHER_SUITES; + } return ret_count; } @@ -1191,7 +1194,7 @@ _gnutls_supported_compression_methods(gnutls_session session, uint8 ** comp) { int i, tmp, j=0; - *comp = gnutls_malloc(SUPPORTED_COMPRESSION_METHODS); + *comp = gnutls_malloc( sizeof(uint8) * SUPPORTED_COMPRESSION_METHODS); if (*comp == NULL) return GNUTLS_E_MEMORY_ERROR; @@ -1199,7 +1202,7 @@ _gnutls_supported_compression_methods(gnutls_session session, uint8 ** comp) tmp = _gnutls_compression_get_num(session->internals. compression_method_priority. priority[i]); - + /* remove private compression algorithms, if requested. */ if (tmp == -1 || (session->internals.enable_private == 0 && @@ -1213,6 +1216,11 @@ _gnutls_supported_compression_methods(gnutls_session session, uint8 ** comp) j++; } + if (j==0) { + gnutls_assert(); + gnutls_free( *comp); + return GNUTLS_E_NO_COMPRESSION_ALGORITHMS; + } return j; } diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index 464e91d347..944996ae57 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -86,3 +86,15 @@ struct gnutls_kx_algo_entry { MOD_AUTH_STRUCT *auth_struct; }; typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry; + +struct gnutls_compression_entry { + const char *name; + gnutls_compression_method id; + int num; /* the number reserved in TLS for the specific compression method */ + + /* used in zlib compressor */ + int window_bits; + int mem_level; + int comp_level; +}; +typedef struct gnutls_compression_entry gnutls_compression_entry; diff --git a/lib/gnutls_compress_int.c b/lib/gnutls_compress_int.c index 4576717505..daa3d639d2 100644 --- a/lib/gnutls_compress_int.c +++ b/lib/gnutls_compress_int.c @@ -23,6 +23,15 @@ #include <gnutls_compress.h> #include <gnutls_algorithms.h> #include "gnutls_errors.h" +#include "../libextra/minilzo.h" /* get the prototypes only. + * Since LZO is a GPLed library, the gnutls_global_init_extra() has + * to be called, before LZO compression can be used. + */ + +typedef int (*LZO_FUNC)(); + +LZO_FUNC _gnutls_lzo1x_decompress_safe = NULL; +LZO_FUNC _gnutls_lzo1x_1_compress = NULL; /* The flag d is the direction (compressed, decompress). Non zero is * decompress. @@ -43,8 +52,7 @@ int err; #ifdef HAVE_LIBZ switch( method) { - case GNUTLS_COMP_ZLIB_DEFAULT: - case GNUTLS_COMP_ZLIB_CONSTRAINED: { + case GNUTLS_COMP_ZLIB: { int window_bits, mem_level; int comp_level; z_stream* zhandle; @@ -80,6 +88,20 @@ int err; } break; } + case GNUTLS_COMP_LZO: + if (d) /* LZO does not use memory on decompressor */ + ret->handle = NULL; + else { + ret->handle = gnutls_malloc( LZO1X_1_MEM_COMPRESS); + + if (ret->handle==NULL) { + gnutls_assert(); + return NULL; + } + } + + break; + default: } #endif @@ -91,9 +113,10 @@ int err; if (handle!=NULL) { switch( handle->algo) { + case GNUTLS_COMP_LZO: + break; #ifdef HAVE_LIBZ - case GNUTLS_COMP_ZLIB_CONSTRAINED: - case GNUTLS_COMP_ZLIB_DEFAULT: + case GNUTLS_COMP_ZLIB: if (d) err = inflateEnd( handle->handle); else @@ -113,22 +136,23 @@ int err; /* These functions are memory consuming */ -int _gnutls_compress( GNUTLS_COMP_HANDLE handle, const char* plain, int plain_size, char** compressed, int max_comp_size) { +int _gnutls_compress( GNUTLS_COMP_HANDLE handle, const char* plain, int plain_size, char** compressed, int max_comp_size) +{ int compressed_size=GNUTLS_E_COMPRESSION_FAILED; -#ifdef HAVE_LIBZ -uLongf size; -z_stream *zhandle; -#endif int err; /* NULL compression is not handled here */ switch( handle->algo) { -#ifdef HAVE_LIBZ - case GNUTLS_COMP_ZLIB_DEFAULT: - case GNUTLS_COMP_ZLIB_CONSTRAINED: - size = (plain_size*2)+10; + case GNUTLS_COMP_LZO: { + lzo_uint out_len; + size_t size; + + if ( _gnutls_lzo1x_1_compress == NULL) + return GNUTLS_E_COMPRESSION_FAILED; + + size = plain_size + plain_size / 64 + 16 + 3; *compressed=NULL; *compressed = gnutls_malloc(size); @@ -136,7 +160,33 @@ int err; gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } + + err = _gnutls_lzo1x_1_compress( plain, plain_size, *compressed, + &out_len, handle->handle); + + if (err!=LZO_E_OK) { + gnutls_assert(); + gnutls_free( *compressed); + return GNUTLS_E_COMPRESSION_FAILED; + } + + compressed_size = out_len; + break; + } +#ifdef HAVE_LIBZ + case GNUTLS_COMP_ZLIB: { + uLongf size; + z_stream *zhandle; + size = (plain_size+plain_size)+10; + *compressed=NULL; + + *compressed = gnutls_malloc(size); + if (*compressed==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + zhandle = handle->handle; zhandle->next_in = (Bytef*) plain; @@ -154,12 +204,17 @@ int err; compressed_size = size - zhandle->avail_out; break; + } #endif default: gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } /* switch */ +#ifdef COMPRESSION_DEBUG + _gnutls_log("Compression ratio: %f\n", (float)((float)compressed_size / (float)plain_size)); +#endif + if (compressed_size > max_comp_size) { gnutls_free(*compressed); return GNUTLS_E_COMPRESSION_FAILED; @@ -168,13 +223,13 @@ int err; return compressed_size; } -int _gnutls_decompress( GNUTLS_COMP_HANDLE handle, char* compressed, int compressed_size, char** plain, int max_record_size) { + + +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 out_size; -z_stream* zhandle; int cur_pos; -#endif if (compressed_size > max_record_size+EXTRA_COMP_SIZE) { gnutls_assert(); @@ -185,13 +240,50 @@ int cur_pos; */ switch(handle->algo) { + case GNUTLS_COMP_LZO: { + lzo_uint out_size; + lzo_uint new_size; + + if (_gnutls_lzo1x_decompress_safe == NULL) + return GNUTLS_E_DECOMPRESSION_FAILED; + + *plain = NULL; + out_size = compressed_size + compressed_size; + plain_size = 0; + + do { + out_size += 512; + *plain = gnutls_realloc_fast( *plain, out_size); + if (*plain==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + new_size = out_size; + err = _gnutls_lzo1x_decompress_safe(compressed,compressed_size, + *plain, &new_size,NULL); + + } while( (err==LZO_E_OUTPUT_OVERRUN && out_size < max_record_size)); + + if (err!=LZO_E_OK) { + gnutls_assert(); + gnutls_free( *plain); + return GNUTLS_E_DECOMPRESSION_FAILED; + } + + plain_size = new_size; + break; + } + #ifdef HAVE_LIBZ - case GNUTLS_COMP_ZLIB_DEFAULT: - case GNUTLS_COMP_ZLIB_CONSTRAINED: + case GNUTLS_COMP_ZLIB: { + uLongf out_size; + z_stream* zhandle; + *plain = NULL; - out_size = compressed_size;; + out_size = compressed_size + compressed_size; plain_size = 0; - + zhandle = handle->handle; zhandle->next_in = (Bytef*) compressed; @@ -200,7 +292,7 @@ int cur_pos; cur_pos = 0; do { - out_size += 128; + out_size += 512; *plain = gnutls_realloc_fast( *plain, out_size); if (*plain==NULL) { gnutls_assert(); @@ -225,6 +317,7 @@ int cur_pos; plain_size = out_size - zhandle->avail_out; break; + } #endif default: gnutls_assert(); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 24151005e8..78eb60ba52 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -87,7 +87,6 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_PARSING_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_PULL_ERROR, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPORT_CIPHER_SUITE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PUSH_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_RECORD_LIMIT_REACHED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_CERTIFICATE_ERROR, 1), @@ -120,6 +119,9 @@ static gnutls_error_entry error_algorithms[] = { 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), + GNUTLS_ERROR_ENTRY( GNUTLS_E_LZO_INIT_FAILED, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_COMPRESSION_ALGORITHMS, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_CIPHER_SUITES, 1), {0} }; diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index c108669412..dabd869064 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -81,18 +81,24 @@ #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_EXPORT_CIPHER_SUITE -83 +#define GNUTLS_E_LIBRARY_VERSION_MISMATCH -83 + /* returned if you need to generate temporary RSA * parameters. These are needed for export cipher suites. */ #define GNUTLS_E_NO_TEMPORARY_RSA_PARAMS -84 +#define GNUTLS_E_LZO_INIT_FAILED -85 +#define GNUTLS_E_NO_COMPRESSION_ALGORITHMS -86 +#define GNUTLS_E_NO_CIPHER_SUITES -87 + + #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250 /* _INT_ internal errors. Not exported */ diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 77033eebce..1811ca6dad 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -538,10 +538,9 @@ int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datale pk_algo = _gnutls_find_pk_algos_in_ciphersuites( data, datalen); x = _gnutls_supported_ciphersuites(session, &ciphers); - if (x<=0) { + if (x < 0) { /* the case x==0 is handled within the function. */ gnutls_assert(); - if (x<0) return x; - else return GNUTLS_E_INVALID_REQUEST; + return x; } /* Here we remove any ciphersuite that does not conform @@ -635,6 +634,11 @@ int _gnutls_server_select_comp_method(gnutls_session session, opaque * data, uint8 *ciphers; x = _gnutls_supported_compression_methods(session, &ciphers); + if (x < 0) { + gnutls_assert(); + return x; + } + memset( &session->internals.compression_method, '\0', sizeof(gnutls_compression_method)); for (j = 0; j < datalen; j++) { @@ -1065,12 +1069,17 @@ static int _gnutls_client_set_ciphersuite(gnutls_session session, { uint8 z; GNUTLS_CipherSuite *cipher_suites; - uint16 x; + int cipher_suite_num; int i, err; z = 1; - x = _gnutls_supported_ciphersuites(session, &cipher_suites); - for (i = 0; i < x; i++) { + cipher_suite_num = _gnutls_supported_ciphersuites(session, &cipher_suites); + if (cipher_suite_num < 0) { + gnutls_assert(); + return cipher_suite_num; + } + + for (i = 0; i < cipher_suite_num; i++) { if (memcmp(&cipher_suites[i], suite, 2) == 0) { z = 0; } @@ -1133,21 +1142,26 @@ static int _gnutls_client_set_ciphersuite(gnutls_session session, static int _gnutls_client_set_comp_method(gnutls_session session, opaque comp_method) { - uint8 z; + int comp_methods_num; uint8 *compression_methods; int i; - z = _gnutls_supported_compression_methods(session, + comp_methods_num = _gnutls_supported_compression_methods(session, &compression_methods); - for (i = 0; i < z; i++) { + if ( comp_methods_num < 0) { + gnutls_assert(); + return comp_methods_num; + } + + for (i = 0; i < comp_methods_num; i++) { if (compression_methods[i] == comp_method) { - z = 0; + comp_methods_num = 0; } } gnutls_free(compression_methods); - if (z != 0) { + if (comp_methods_num != 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } @@ -1309,10 +1323,9 @@ static int _gnutls_copy_ciphersuites(gnutls_session session, int datalen, pos; ret = _gnutls_supported_ciphersuites_sorted(session, &cipher_suites); - if (ret <= 0) { + if (ret < 0) { gnutls_assert(); - if (ret==0) return GNUTLS_E_INVALID_REQUEST; - else return ret; + return ret; } /* Here we remove any ciphersuite that does not conform diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index ace4ce16ef..fe01c26710 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -34,6 +34,7 @@ #define HANDSHAKE_DEBUG // Prints some information on handshake #define X509_DEBUG #define RECORD_DEBUG +#define COMPRESSION_DEBUG #define DEBUG */ @@ -160,8 +161,8 @@ typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, typedef enum gnutls_mac_algorithm { GNUTLS_MAC_NULL=1, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA } gnutls_mac_algorithm; -typedef enum gnutls_compression_method { GNUTLS_COMP_NULL=1, GNUTLS_COMP_ZLIB_DEFAULT, - GNUTLS_COMP_ZLIB_CONSTRAINED +typedef enum gnutls_compression_method { GNUTLS_COMP_NULL=1, GNUTLS_COMP_ZLIB, + GNUTLS_COMP_LZO } gnutls_compression_method; typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end; |