@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
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);
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;
{
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;
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);
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
{
/* 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];
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;
* @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.
**/
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
* @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: