From: Nikos Mavrogiannopoulos Date: Sat, 15 Sep 2012 10:25:45 +0000 (+0200) Subject: Added GNUTLS_STATELESS_COMPRESSION flag to gnutls_init(). X-Git-Tag: gnutls_3_1_2~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee0db686e1d6fbe944b703872a600f29826941bc;p=thirdparty%2Fgnutls.git Added GNUTLS_STATELESS_COMPRESSION flag to gnutls_init(). --- diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi index 07ba897393..e68058a24e 100644 --- a/doc/cha-intro-tls.texi +++ b/doc/cha-intro-tls.texi @@ -189,7 +189,9 @@ on @xcite{RFC3749}. The supported algorithms are shown below. @showenumdesc{gnutls_compression_method_t,Supported compression algorithms} Note that compression enables attacks such as traffic analysis, or even -plaintext recovery under certain circumstances. +plaintext recovery under certain circumstances. To avoid some of these +attacks GnuTLS allows each record to be compressed independently (i.e., +stateless compression), by using a flag to @funcref{gnutls_init}. @node Weaknesses and countermeasures @subsection Weaknesses and countermeasures diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index e79100324c..5266fbecb0 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -104,7 +104,8 @@ _gnutls_encrypt (gnutls_session_t session, const uint8_t * headers, if (comp.data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - ret = _gnutls_compress( ¶ms->write.compression_state, data, data_size, comp.data, comp.size); + ret = _gnutls_compress(¶ms->write.compression_state, data, data_size, + comp.data, comp.size, session->internals.stateless_compression); if (ret < 0) { gnutls_free(comp.data); diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c index 01728cace2..9d4380ae82 100644 --- a/lib/gnutls_compress.c +++ b/lib/gnutls_compress.c @@ -330,7 +330,7 @@ _gnutls_comp_deinit (comp_hd_st* handle, int d) int _gnutls_compress (comp_hd_st *handle, const uint8_t * plain, size_t plain_size, uint8_t * compressed, - size_t max_comp_size) + size_t max_comp_size, unsigned int stateless) { int compressed_size = GNUTLS_E_COMPRESSION_FAILED; @@ -349,6 +349,15 @@ _gnutls_compress (comp_hd_st *handle, const uint8_t * plain, { z_stream *zhandle; int err; + int type; + + if (stateless) + { +fprintf(stderr, "FULL FLUSH\n"); + type = Z_FULL_FLUSH; + } + else + type = Z_SYNC_FLUSH; zhandle = handle->handle; @@ -357,7 +366,7 @@ _gnutls_compress (comp_hd_st *handle, const uint8_t * plain, zhandle->next_out = (Bytef *) compressed; zhandle->avail_out = max_comp_size; - err = deflate (zhandle, Z_SYNC_FLUSH); + err = deflate (zhandle, type); if (err != Z_OK || zhandle->avail_in != 0) return gnutls_assert_val(GNUTLS_E_COMPRESSION_FAILED); diff --git a/lib/gnutls_compress.h b/lib/gnutls_compress.h index 151e54f6b7..938c2eb0ea 100644 --- a/lib/gnutls_compress.h +++ b/lib/gnutls_compress.h @@ -48,7 +48,7 @@ int _gnutls_decompress (comp_hd_st* handle, uint8_t * compressed, size_t compressed_size, uint8_t * plain, size_t max_plain_size); int _gnutls_compress (comp_hd_st*, const uint8_t * plain, size_t plain_size, - uint8_t * compressed, size_t max_comp_size); + uint8_t * compressed, size_t max_comp_size, unsigned int stateless); struct gnutls_compression_entry { diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 8e1a8113ec..7ec43afca4 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -881,6 +881,8 @@ typedef struct /* if set it means that the master key was set using * gnutls_session_set_master() rather than being negotiated. */ unsigned int premaster_set:1; + /* Whether stateless compression will be used */ + unsigned int stateless_compression:1; unsigned int cb_tls_unique_len; unsigned char cb_tls_unique[MAX_VERIFY_DATA_SIZE]; @@ -889,7 +891,7 @@ typedef struct unsigned int handshake_timeout_ms; /* timeout in milliseconds */ gnutls_buffer_st heartbeat_payload; /* store in-flight payload for heartbeat extension*/ - + /* If you add anything here, check _gnutls_handshake_internal_state_clear(). */ } internals_st; diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 349bfa1328..26d0ed9cd0 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -293,7 +293,8 @@ _gnutls_handshake_internal_state_clear (gnutls_session_t session) * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER. For a DTLS * entity, the flags %GNUTLS_DATAGRAM and %GNUTLS_NONBLOCK are * also available. The latter flag will enable a non-blocking - * operation of the DTLS timers. + * operation of the DTLS timers. The flag %GNUTLS_STATELESS_COMPRESSION + * would disable keeping state across records when compressing. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ @@ -393,6 +394,9 @@ gnutls_init (gnutls_session_t * session, unsigned int flags) else (*session)->internals.transport = GNUTLS_STREAM; + if (flags & GNUTLS_STATELESS_COMPRESSION) + (*session)->internals.stateless_compression = 1; + if (flags & GNUTLS_NONBLOCK) (*session)->internals.dtls.blocking = 0; else diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 53cdfa9181..52bd311423 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -295,13 +295,14 @@ extern "C" * @GNUTLS_CLIENT: Connection end is a client. * @GNUTLS_DATAGRAM: Connection is datagram oriented (DTLS). * @GNUTLS_NONBLOCK: Connection should not block (DTLS). + * @GNUTLS_STATELESS_COMPRESSION: Compression will be applied independently on each record. * - * Enumeration of different TLS connection end types. */ #define GNUTLS_SERVER 1 #define GNUTLS_CLIENT (1<<1) #define GNUTLS_DATAGRAM (1<<2) #define GNUTLS_NONBLOCK (1<<3) +#define GNUTLS_STATELESS_COMPRESSION (1<<4) /** * gnutls_alert_level_t: