]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added GNUTLS_STATELESS_COMPRESSION flag to gnutls_init().
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 15 Sep 2012 10:25:45 +0000 (12:25 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 15 Sep 2012 10:25:45 +0000 (12:25 +0200)
doc/cha-intro-tls.texi
lib/gnutls_cipher.c
lib/gnutls_compress.c
lib/gnutls_compress.h
lib/gnutls_int.h
lib/gnutls_state.c
lib/includes/gnutls/gnutls.h.in

index 07ba8973934faf17bec6785f8dbb3d1c0c38d2e4..e68058a24ea62c3eabc4724dc0b6a408e6762674 100644 (file)
@@ -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
index e79100324caeb49f190c5ff541d1d12d89391268..5266fbecb0f219b9553213b7d54fbf32c312b0b0 100644 (file)
@@ -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( &params->write.compression_state, data, data_size, comp.data, comp.size);
+      ret = _gnutls_compress(&params->write.compression_state, data, data_size, 
+                             comp.data, comp.size, session->internals.stateless_compression);
       if (ret < 0)
         {
           gnutls_free(comp.data);
index 01728cace2c567ad5952b43c42e7d461c926eadd..9d4380ae82ed381383fb0f5baa981b6e78408cbf 100644 (file)
@@ -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);
 
index 151e54f6b7fda78e3d142bf8c6ae77ca9121cd44..938c2eb0eafff4014d6f40d9df2ca8a3b13bb0dd 100644 (file)
@@ -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
 {
index 8e1a8113ec7af34c558876f4cabbeba6affcd413..7ec43afca4d372d0671aa843d6c6541c3229571f 100644 (file)
@@ -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;
index 349bfa1328df00f9998d4b2831058ff99e5909a0..26d0ed9cd0a5f7c97fba3f3daaf4d021aa8e5dd9 100644 (file)
@@ -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
index 53cdfa9181aaf96b7d3ba8cf17d185925db1a611..52bd3114234c619560196d580083788d352d8472 100644 (file)
@@ -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: