summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-09-17 17:57:59 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-09-17 17:57:59 +0000
commit61d4c25ee8c5c48cc68ff79ce6293da84b798634 (patch)
treeb605220748dffe51d51bcc1105ce0c4eee85de9e /lib
parent2629ceb42edbdefe10ca3edfe1cfd96069a81561 (diff)
downloadgnutls-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.am3
-rw-r--r--lib/defines.h6
-rw-r--r--lib/gnutls.h.in.in3
-rw-r--r--lib/gnutls_algorithms.c40
-rw-r--r--lib/gnutls_algorithms.h12
-rw-r--r--lib/gnutls_compress_int.c139
-rw-r--r--lib/gnutls_errors.c4
-rw-r--r--lib/gnutls_errors_int.h10
-rw-r--r--lib/gnutls_handshake.c41
-rw-r--r--lib/gnutls_int.h5
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;