From d01c14e840dcfbfa9ad86de892df51bc525870aedaf27fa881aa90f9faab9cb2 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Mon, 26 Sep 2011 08:05:51 +0000 Subject: [PATCH] Accepting request 84674 from Base:System Add patch fixing connection issues with some xmpp servers (forwarded request 84657 from vuntz) OBS-URL: https://build.opensuse.org/request/show/84674 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/gnutls?expand=0&rev=36 --- baselibs.conf | 3 + gnutls-fix-compression.patch | 842 +++++++++++++++++++++++++++++++++++ gnutls.changes | 12 + gnutls.spec | 3 + 4 files changed, 860 insertions(+) create mode 100644 gnutls-fix-compression.patch diff --git a/baselibs.conf b/baselibs.conf index c11f1e2..efa44dc 100644 --- a/baselibs.conf +++ b/baselibs.conf @@ -1,2 +1,5 @@ libgnutls28 obsoletes "gnutls-" +libgnutls-devel + requires -libgnutls- + requires "libgnutls28- = " diff --git a/gnutls-fix-compression.patch b/gnutls-fix-compression.patch new file mode 100644 index 0000000..18be79a --- /dev/null +++ b/gnutls-fix-compression.patch @@ -0,0 +1,842 @@ +From f3abb3c8e37dfdb0881c23499abf4fe3aa779e14 Mon Sep 17 00:00:00 2001 +From: Nikos Mavrogiannopoulos +Date: Thu, 22 Sep 2011 18:48:07 +0200 +Subject: [PATCH] Simplified and corrected decompression and compression. + Added test program. + +--- + lib/gnutls_cipher.c | 203 +++++++++++++++++++++++-------------------------- + lib/gnutls_compress.c | 137 ++++----------------------------- + lib/gnutls_compress.h | 15 +--- + lib/gnutls_record.c | 5 +- + tests/Makefile.am | 2 +- + tests/eagain-common.h | 5 + + tests/mini-deflate.c | 113 +++++++++++++++++++++++++++ + 7 files changed, 234 insertions(+), 246 deletions(-) + create mode 100644 tests/mini-deflate.c + +diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c +index 1629b4d..75ca6ab 100644 +--- a/lib/gnutls_cipher.c ++++ b/lib/gnutls_cipher.c +@@ -41,15 +41,16 @@ + #include + #include + +-static int _gnutls_compressed2ciphertext (gnutls_session_t session, ++static int compressed_to_ciphertext (gnutls_session_t session, + opaque * cipher_data, int cipher_size, +- gnutls_datum_t compressed, ++ gnutls_datum_t *compressed, + content_type_t _type, + record_parameters_st * params); +-static int _gnutls_ciphertext2compressed (gnutls_session_t session, ++static int ciphertext_to_compressed (gnutls_session_t session, ++ gnutls_datum_t *ciphertext, + opaque * compress_data, + int compress_size, +- gnutls_datum_t ciphertext, uint8_t type, ++ uint8_t type, + record_parameters_st * params, uint64* sequence); + + inline static int +@@ -83,45 +84,47 @@ _gnutls_encrypt (gnutls_session_t session, const opaque * headers, + size_t ciphertext_size, content_type_t type, + record_parameters_st * params) + { +- gnutls_datum_t plain; + gnutls_datum_t comp; ++ int free_comp = 0; + int ret; +- int free_comp = 1; +- record_parameters_st *cur_record_params; + +- ret = _gnutls_epoch_get (session, EPOCH_WRITE_CURRENT, &cur_record_params); +- if (ret < 0) +- return gnutls_assert_val(ret); +- +- plain.data = (opaque *) data; +- plain.size = data_size; +- +- if (plain.size == 0 || is_write_comp_null (cur_record_params) == 0) ++ if (data_size == 0 || is_write_comp_null (params) == 0) + { +- comp = plain; +- free_comp = 0; ++ comp.data = (opaque*)data; ++ comp.size = data_size; + } + else + { + /* Here comp is allocated and must be + * freed. + */ +- ret = _gnutls_m_plaintext2compressed (session, &comp, &plain, params); ++ free_comp = 1; ++ ++ comp.size = ciphertext_size - headers_size; ++ comp.data = gnutls_malloc(comp.size); ++ 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); + if (ret < 0) +- return gnutls_assert_val(ret); ++ { ++ gnutls_free(comp.data); ++ return gnutls_assert_val(ret); ++ } ++ ++ comp.size = ret; + } + +- ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size], ++ ret = compressed_to_ciphertext (session, &ciphertext[headers_size], + ciphertext_size - headers_size, +- comp, type, params); ++ &comp, type, params); + + if (free_comp) +- _gnutls_free_datum (&comp); ++ gnutls_free(comp.data); + + if (ret < 0) + return gnutls_assert_val(ret); + +- + /* copy the headers */ + memcpy (ciphertext, headers, headers_size); + +@@ -142,14 +145,8 @@ _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext, + size_t max_data_size, content_type_t type, + record_parameters_st * params, uint64 *sequence) + { +- gnutls_datum_t gtxt; + gnutls_datum_t gcipher; +- int ret; +- record_parameters_st *cur_record_params; +- +- ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &cur_record_params); +- if (ret < 0) +- return gnutls_assert_val(ret); ++ int ret, data_size; + + if (ciphertext_size == 0) + return 0; +@@ -157,57 +154,43 @@ _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext, + gcipher.size = ciphertext_size; + gcipher.data = ciphertext; + +- ret = +- _gnutls_ciphertext2compressed (session, data, max_data_size, +- gcipher, type, params, sequence); +- if (ret < 0) ++ if (is_read_comp_null (params) == 0) + { ++ ret = ++ ciphertext_to_compressed (session, &gcipher, data, max_data_size, ++ type, params, sequence); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ + return ret; + } +- +- if (ret == 0 || is_read_comp_null (cur_record_params) == 0) +- { +- /* ret == ret */ +- +- } + else + { +- gnutls_datum_t gcomp; +- +- /* compression has this malloc overhead. +- */ +- +- gcomp.data = data; +- gcomp.size = ret; +- ret = _gnutls_m_compressed2plaintext (session, >xt, &gcomp, params); ++ opaque* tmp_data; ++ ++ tmp_data = gnutls_malloc(max_data_size); ++ if (tmp_data == NULL) ++ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ++ ++ ret = ++ ciphertext_to_compressed (session, &gcipher, tmp_data, max_data_size, ++ type, params, sequence); + if (ret < 0) ++ goto leave; ++ ++ data_size = ret; ++ ++ if (ret != 0) + { +- return ret; +- } +- +- if (gtxt.size > MAX_RECORD_RECV_SIZE(session)) +- { +- _gnutls_free_datum (>xt); +- /* This shouldn't have happen and +- * is a TLS fatal error. +- */ +- return gnutls_assert_val(GNUTLS_E_DECOMPRESSION_FAILED); +- } +- +- /* This check is not really needed */ +- if (max_data_size < MAX_RECORD_RECV_SIZE(session)) +- { +- _gnutls_free_datum (>xt); +- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ++ ret = _gnutls_decompress(params->read.compression_state, tmp_data, data_size, data, max_data_size); ++ if (ret < 0) ++ goto leave; + } +- +- memcpy (data, gtxt.data, gtxt.size); +- ret = gtxt.size; +- +- _gnutls_free_datum (>xt); ++ ++leave: ++ gnutls_free(tmp_data); ++ return ret; + } +- +- return ret; + } + + +@@ -305,9 +288,9 @@ make_preamble (opaque * uint64_data, opaque type, int length, + * return the actual encrypted data length. + */ + static int +-_gnutls_compressed2ciphertext (gnutls_session_t session, ++compressed_to_ciphertext (gnutls_session_t session, + opaque * cipher_data, int cipher_size, +- gnutls_datum_t compressed, ++ gnutls_datum_t *compressed, + content_type_t type, + record_parameters_st * params) + { +@@ -336,15 +319,16 @@ _gnutls_compressed2ciphertext (gnutls_session_t session, + _gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n", + session, gnutls_cipher_get_name(params->cipher_algorithm), gnutls_mac_get_name(params->mac_algorithm), + (unsigned int)params->epoch); ++ + preamble_size = + make_preamble (UINT64DATA + (params->write.sequence_number), +- type, compressed.size, ver, preamble); ++ type, compressed->size, ver, preamble); + + /* Calculate the encrypted length (padding etc.) + */ + length_to_encrypt = length = +- calc_enc_length (session, compressed.size, tag_size, &pad, ++ calc_enc_length (session, compressed->size, tag_size, &pad, + random_pad, block_algo, auth_cipher, blocksize); + if (length < 0) + { +@@ -411,8 +395,8 @@ _gnutls_compressed2ciphertext (gnutls_session_t session, + if (auth_cipher) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + +- memcpy (data_ptr, compressed.data, compressed.size); +- data_ptr += compressed.size; ++ memcpy (data_ptr, compressed->data, compressed->size); ++ data_ptr += compressed->size; + + if (tag_size > 0) + { +@@ -431,7 +415,7 @@ _gnutls_compressed2ciphertext (gnutls_session_t session, + */ + ret = + _gnutls_auth_cipher_encrypt_tag (¶ms->write.cipher_state, +- cipher_data, length_to_encrypt, tag_ptr, tag_size, compressed.size); ++ cipher_data, length_to_encrypt, tag_ptr, tag_size, compressed->size); + if (ret < 0) + return gnutls_assert_val(ret); + +@@ -443,11 +427,12 @@ _gnutls_compressed2ciphertext (gnutls_session_t session, + * Returns the actual compressed packet size. + */ + static int +-_gnutls_ciphertext2compressed (gnutls_session_t session, +- opaque * compress_data, +- int compress_size, +- gnutls_datum_t ciphertext, uint8_t type, +- record_parameters_st * params, uint64* sequence) ++ciphertext_to_compressed (gnutls_session_t session, ++ gnutls_datum_t *ciphertext, ++ opaque * compress_data, ++ int compress_size, ++ uint8_t type, record_parameters_st * params, ++ uint64* sequence) + { + uint8_t tag[MAX_HASH_SIZE]; + uint8_t pad; +@@ -478,28 +463,28 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + if (params->read.IV.data == NULL || params->read.IV.size != 4) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + +- if (ciphertext.size < tag_size+AEAD_EXPLICIT_DATA_SIZE) ++ if (ciphertext->size < tag_size+AEAD_EXPLICIT_DATA_SIZE) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + + memcpy(nonce, params->read.IV.data, AEAD_IMPLICIT_DATA_SIZE); +- memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE], ciphertext.data, AEAD_EXPLICIT_DATA_SIZE); ++ memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE], ciphertext->data, AEAD_EXPLICIT_DATA_SIZE); + + _gnutls_auth_cipher_setiv(¶ms->read.cipher_state, nonce, AEAD_EXPLICIT_DATA_SIZE+AEAD_IMPLICIT_DATA_SIZE); + +- ciphertext.data += AEAD_EXPLICIT_DATA_SIZE; +- ciphertext.size -= AEAD_EXPLICIT_DATA_SIZE; ++ ciphertext->data += AEAD_EXPLICIT_DATA_SIZE; ++ ciphertext->size -= AEAD_EXPLICIT_DATA_SIZE; + +- length_to_decrypt = ciphertext.size - tag_size; ++ length_to_decrypt = ciphertext->size - tag_size; + } + else + { +- if (ciphertext.size < tag_size) ++ if (ciphertext->size < tag_size) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + +- length_to_decrypt = ciphertext.size; ++ length_to_decrypt = ciphertext->size; + } + +- length = ciphertext.size - tag_size; ++ length = ciphertext->size - tag_size; + + /* Pass the type, version, length and compressed through + * MAC. +@@ -512,12 +497,12 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + + if ((ret = + _gnutls_auth_cipher_decrypt (¶ms->read.cipher_state, +- ciphertext.data, length_to_decrypt)) < 0) ++ ciphertext->data, length_to_decrypt)) < 0) + return gnutls_assert_val(ret); + + break; + case CIPHER_BLOCK: +- if (ciphertext.size < MAX(blocksize, tag_size) || (ciphertext.size % blocksize != 0)) ++ if (ciphertext->size < MAX(blocksize, tag_size) || (ciphertext->size % blocksize != 0)) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + + /* ignore the IV in TLS 1.1+ +@@ -525,12 +510,12 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + if (explicit_iv) + { + _gnutls_auth_cipher_setiv(¶ms->read.cipher_state, +- ciphertext.data, blocksize); ++ ciphertext->data, blocksize); + +- ciphertext.size -= blocksize; +- ciphertext.data += blocksize; ++ ciphertext->size -= blocksize; ++ ciphertext->data += blocksize; + +- if (ciphertext.size == 0) ++ if (ciphertext->size == 0) + { + gnutls_assert (); + return GNUTLS_E_DECRYPTION_FAILED; +@@ -544,32 +529,32 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + */ + if ((ret = + _gnutls_cipher_decrypt (¶ms->read.cipher_state.cipher, +- ciphertext.data, ciphertext.size)) < 0) ++ ciphertext->data, ciphertext->size)) < 0) + return gnutls_assert_val(ret); + +- pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */ ++ pad = ciphertext->data[ciphertext->size - 1] + 1; /* pad */ + +- if ((int) pad > (int) ciphertext.size - tag_size) ++ if ((int) pad > (int) ciphertext->size - tag_size) + { + gnutls_assert (); + _gnutls_record_log + ("REC[%p]: Short record length %d > %d - %d (under attack?)\n", +- session, pad, ciphertext.size, tag_size); ++ session, pad, ciphertext->size, tag_size); + /* We do not fail here. We check below for the + * the pad_failed. If zero means success. + */ + pad_failed = GNUTLS_E_DECRYPTION_FAILED; + } + +- length = ciphertext.size - tag_size - pad; ++ length = ciphertext->size - tag_size - pad; + + /* Check the pading bytes (TLS 1.x) + */ + if (ver != GNUTLS_SSL3 && pad_failed == 0) + for (i = 2; i < pad; i++) + { +- if (ciphertext.data[ciphertext.size - i] != +- ciphertext.data[ciphertext.size - 1]) ++ if (ciphertext->data[ciphertext->size - i] != ++ ciphertext->data[ciphertext->size - 1]) + pad_failed = GNUTLS_E_DECRYPTION_FAILED; + } + +@@ -583,7 +568,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + make_preamble (UINT64DATA(*sequence), type, + length, ver, preamble); + _gnutls_auth_cipher_add_auth (¶ms->read.cipher_state, preamble, preamble_size); +- _gnutls_auth_cipher_add_auth (¶ms->read.cipher_state, ciphertext.data, length); ++ _gnutls_auth_cipher_add_auth (¶ms->read.cipher_state, ciphertext->data, length); + + break; + default: +@@ -602,7 +587,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + + /* HMAC was not the same. + */ +- if (memcmp (tag, &ciphertext.data[length], tag_size) != 0) ++ if (memcmp (tag, &ciphertext->data[length], tag_size) != 0) + return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); + + /* copy the decrypted stuff to compress_data. +@@ -610,8 +595,8 @@ _gnutls_ciphertext2compressed (gnutls_session_t session, + if (compress_size < length) + return gnutls_assert_val(GNUTLS_E_DECOMPRESSION_FAILED); + +- if (compress_data != ciphertext.data) +- memcpy (compress_data, ciphertext.data, length); ++ if (compress_data != ciphertext->data) ++ memcpy (compress_data, ciphertext->data, length); + + return length; + } +diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c +index 52d4a15..e7a5114 100644 +--- a/lib/gnutls_compress.c ++++ b/lib/gnutls_compress.c +@@ -32,57 +32,6 @@ + #include + #include + +-/* These functions allocate the return value internally +- */ +-int +-_gnutls_m_plaintext2compressed (gnutls_session_t session, +- gnutls_datum_t * compressed, +- const gnutls_datum_t * plaintext, +- const record_parameters_st * params) +-{ +- int size; +- opaque *data; +- +- size = +- _gnutls_compress (params->write.compression_state, +- plaintext->data, plaintext->size, &data, +- MAX_RECORD_SEND_SIZE(session) + EXTRA_COMP_SIZE); +- if (size < 0) +- { +- gnutls_assert (); +- return GNUTLS_E_COMPRESSION_FAILED; +- } +- compressed->data = data; +- compressed->size = size; +- +- return 0; +-} +- +-int +-_gnutls_m_compressed2plaintext (gnutls_session_t session, +- gnutls_datum_t * plain, +- const gnutls_datum_t * compressed, +- const record_parameters_st * params) +-{ +- int size; +- opaque *data; +- +- size = +- _gnutls_decompress (params->read.compression_state, +- compressed->data, compressed->size, &data, +- MAX_RECORD_RECV_SIZE(session)); +- if (size < 0) +- { +- gnutls_assert (); +- return GNUTLS_E_DECOMPRESSION_FAILED; +- } +- plain->data = data; +- plain->size = size; +- +- return 0; +-} +- +- + /* Compression Section */ + #define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \ + { #name, name, id, wb, ml, cl} +@@ -397,7 +346,7 @@ _gnutls_comp_deinit (comp_hd_t handle, int d) + + int + _gnutls_compress (comp_hd_t handle, const opaque * plain, +- size_t plain_size, opaque ** compressed, ++ size_t plain_size, opaque * compressed, + size_t max_comp_size) + { + int compressed_size = GNUTLS_E_COMPRESSION_FAILED; +@@ -419,32 +368,19 @@ _gnutls_compress (comp_hd_t handle, const opaque * plain, + z_stream *zhandle; + int err; + +- size = (plain_size + plain_size) + 10; +- *compressed = gnutls_malloc (size); +- if (*compressed == NULL) +- { +- gnutls_assert (); +- return GNUTLS_E_MEMORY_ERROR; +- } +- + zhandle = handle->handle; + + zhandle->next_in = (Bytef *) plain; + zhandle->avail_in = plain_size; +- zhandle->next_out = (Bytef *) * compressed; +- zhandle->avail_out = size; ++ zhandle->next_out = (Bytef *) compressed; ++ zhandle->avail_out = max_comp_size; + + err = deflate (zhandle, Z_SYNC_FLUSH); +- + if (err != Z_OK || zhandle->avail_in != 0) +- { +- gnutls_assert (); +- gnutls_free (*compressed); +- *compressed = NULL; +- return GNUTLS_E_COMPRESSION_FAILED; +- } ++ return gnutls_assert_val(GNUTLS_E_COMPRESSION_FAILED); + +- compressed_size = size - zhandle->avail_out; ++ ++ compressed_size = max_comp_size - zhandle->avail_out; + break; + } + #endif +@@ -458,13 +394,6 @@ _gnutls_compress (comp_hd_t handle, const opaque * plain, + (float) ((float) compressed_size / (float) plain_size)); + #endif + +- if ((size_t) compressed_size > max_comp_size) +- { +- gnutls_free (*compressed); +- *compressed = NULL; +- return GNUTLS_E_COMPRESSION_FAILED; +- } +- + return compressed_size; + } + +@@ -472,12 +401,12 @@ _gnutls_compress (comp_hd_t handle, const opaque * plain, + + int + _gnutls_decompress (comp_hd_t handle, opaque * compressed, +- size_t compressed_size, opaque ** plain, +- size_t max_record_size) ++ size_t compressed_size, opaque * plain, ++ size_t max_plain_size) + { + int plain_size = GNUTLS_E_DECOMPRESSION_FAILED; + +- if (compressed_size > max_record_size + EXTRA_COMP_SIZE) ++ if (compressed_size > max_plain_size + EXTRA_COMP_SIZE) + { + gnutls_assert (); + return GNUTLS_E_DECOMPRESSION_FAILED; +@@ -499,51 +428,21 @@ _gnutls_decompress (comp_hd_t handle, opaque * compressed, + { + uLongf out_size; + z_stream *zhandle; +- int cur_pos; + int err; + +- *plain = NULL; +- out_size = compressed_size + compressed_size; +- plain_size = 0; +- + zhandle = handle->handle; + + zhandle->next_in = (Bytef *) compressed; + zhandle->avail_in = compressed_size; + +- cur_pos = 0; +- +- do +- { +- out_size += 512; +- *plain = gnutls_realloc_fast (*plain, out_size); +- if (*plain == NULL) +- { +- gnutls_assert (); +- return GNUTLS_E_MEMORY_ERROR; +- } +- +- zhandle->next_out = (Bytef *) (*plain + cur_pos); +- zhandle->avail_out = out_size - cur_pos; +- +- err = inflate (zhandle, Z_SYNC_FLUSH); +- +- cur_pos = out_size - zhandle->avail_out; +- +- } +- while ((err == Z_BUF_ERROR && zhandle->avail_out == 0 +- && out_size < max_record_size) +- || (err == Z_OK && zhandle->avail_in != 0)); ++ zhandle->next_out = (Bytef *) plain; ++ zhandle->avail_out = max_plain_size; ++ err = inflate (zhandle, Z_SYNC_FLUSH); + + if (err != Z_OK) +- { +- gnutls_assert (); +- gnutls_free (*plain); +- *plain = NULL; +- return GNUTLS_E_DECOMPRESSION_FAILED; +- } ++ return gnutls_assert_val(GNUTLS_E_DECOMPRESSION_FAILED); + +- plain_size = out_size - zhandle->avail_out; ++ plain_size = max_plain_size - zhandle->avail_out; + break; + } + #endif +@@ -552,13 +451,5 @@ _gnutls_decompress (comp_hd_t handle, opaque * compressed, + return GNUTLS_E_INTERNAL_ERROR; + } /* switch */ + +- if ((size_t) plain_size > max_record_size) +- { +- gnutls_assert (); +- gnutls_free (*plain); +- *plain = NULL; +- return GNUTLS_E_DECOMPRESSION_FAILED; +- } +- + return plain_size; + } +diff --git a/lib/gnutls_compress.h b/lib/gnutls_compress.h +index 2bc88c5..7f3545c 100644 +--- a/lib/gnutls_compress.h ++++ b/lib/gnutls_compress.h +@@ -22,15 +22,6 @@ + #ifndef GNUTLS_COMPRESS_H + #define GNUTLS_COMPRESS_H + +-int _gnutls_m_plaintext2compressed (gnutls_session_t session, +- gnutls_datum_t * compressed, +- const gnutls_datum_t * plaintext, +- const record_parameters_st * params); +-int _gnutls_m_compressed2plaintext (gnutls_session_t session, +- gnutls_datum_t * plain, +- const gnutls_datum_t * compressed, +- const record_parameters_st * params); +- + /* Algorithm handling. */ + int _gnutls_supported_compression_methods (gnutls_session_t session, + uint8_t * comp, size_t max_comp); +@@ -54,10 +45,10 @@ comp_hd_t _gnutls_comp_init (gnutls_compression_method_t, int d); + void _gnutls_comp_deinit (comp_hd_t handle, int d); + + int _gnutls_decompress (comp_hd_t handle, opaque * compressed, +- size_t compressed_size, opaque ** plain, +- size_t max_record_size); ++ size_t compressed_size, opaque * plain, ++ size_t max_plain_size); + int _gnutls_compress (comp_hd_t, const opaque * plain, size_t plain_size, +- opaque ** compressed, size_t max_comp_size); ++ opaque * compressed, size_t max_comp_size); + + struct gnutls_compression_entry + { +diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c +index 22e4923..4ff2951 100644 +--- a/lib/gnutls_record.c ++++ b/lib/gnutls_record.c +@@ -986,7 +986,10 @@ begin: + if (bufel == NULL) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + +- decrypted = _mbuffer_alloc(record.length+EXTRA_COMP_SIZE, record.length+EXTRA_COMP_SIZE); ++ /* We allocate the maximum possible to allow few compressed bytes to expand to a ++ * full record. ++ */ ++ decrypted = _mbuffer_alloc(MAX_RECORD_RECV_SIZE(session), MAX_RECORD_RECV_SIZE(session)); + if (decrypted == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 63ae665..7ed9d25 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -58,7 +58,7 @@ noinst_LTLIBRARIES = libutils.la + libutils_la_SOURCES = utils.h utils.c + + ctests = simple gc set_pkcs12_cred certder certuniqueid mpi \ +- certificate_set_x509_crl dn parse_ca moredn mini \ ++ certificate_set_x509_crl dn parse_ca moredn mini mini-deflate \ + hostname-check cve-2008-4989 pkcs12_s2k chainverify crq_key_id \ + x509sign-verify cve-2009-1415 cve-2009-1416 crq_apis \ + init_roundtrip pkcs12_s2k_pem dn2 mini-eagain \ +diff --git a/tests/eagain-common.h b/tests/eagain-common.h +index c55e97c..07d5148 100644 +--- a/tests/eagain-common.h ++++ b/tests/eagain-common.h +@@ -32,6 +32,9 @@ + ret = gnutls_record_send (c, msg, msglen); \ + } \ + while(ret == GNUTLS_E_AGAIN); \ ++ \ ++ if (ret < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \ ++ \ + do \ + { \ + do \ +@@ -54,6 +57,7 @@ + ns = gnutls_record_send (server, msg, msglen); \ + } \ + while (ns == GNUTLS_E_AGAIN); \ ++ if (ns < 0) fail ("server send error: %s\n", gnutls_strerror (ret)); \ + do \ + { \ + ret = gnutls_record_recv (client, buf, buflen); \ +@@ -81,6 +85,7 @@ + ns = gnutls_record_send (client, buf, msglen); \ + } \ + while (ns == GNUTLS_E_AGAIN); \ ++ if (ns < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \ + transferred += ret; \ + if (debug) \ + fputs (".", stdout); \ +diff --git a/tests/mini-deflate.c b/tests/mini-deflate.c +new file mode 100644 +index 0000000..4edd4db +--- /dev/null ++++ b/tests/mini-deflate.c +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (C) 2008, 2010 Free Software Foundation, Inc. ++ * ++ * Author: Simon Josefsson ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GnuTLS; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include "eagain-common.h" ++ ++#include "utils.h" ++ ++static void ++tls_log_func (int level, const char *str) ++{ ++ fprintf (stderr, "|<%d>| %s", level, str); ++} ++ ++#define MAX_BUF 6*1024 ++#define MSG "Hello TLS, and Hello and Hello and Hello" ++ ++void ++doit (void) ++{ ++ /* Server stuff. */ ++ gnutls_anon_server_credentials_t s_anoncred; ++ const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; ++ static gnutls_dh_params_t dh_params; ++ gnutls_session_t server; ++ int sret = GNUTLS_E_AGAIN; ++ /* Client stuff. */ ++ gnutls_anon_client_credentials_t c_anoncred; ++ gnutls_session_t client; ++ int cret = GNUTLS_E_AGAIN; ++ /* Need to enable anonymous KX specifically. */ ++ char buffer[MAX_BUF + 1]; ++ ssize_t ns; ++ int ret, transferred = 0, msglen; ++ ++ /* General init. */ ++ gnutls_global_init (); ++ gnutls_global_set_log_function (tls_log_func); ++ if (debug) ++ gnutls_global_set_log_level (4711); ++ ++ /* Init server */ ++ gnutls_anon_allocate_server_credentials (&s_anoncred); ++ gnutls_dh_params_init (&dh_params); ++ gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); ++ gnutls_anon_set_server_dh_params (s_anoncred, dh_params); ++ gnutls_init (&server, GNUTLS_SERVER); ++ gnutls_priority_set_direct (server, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-DEFLATE:+ANON-DH", NULL); ++ gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred); ++ gnutls_dh_set_prime_bits (server, 1024); ++ gnutls_transport_set_push_function (server, server_push); ++ gnutls_transport_set_pull_function (server, server_pull); ++ gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server); ++ ++ /* Init client */ ++ gnutls_anon_allocate_client_credentials (&c_anoncred); ++ gnutls_init (&client, GNUTLS_CLIENT); ++ gnutls_priority_set_direct (client, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-DEFLATE:+ANON-DH", NULL); ++ gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred); ++ gnutls_transport_set_push_function (client, client_push); ++ gnutls_transport_set_pull_function (client, client_pull); ++ gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client); ++ ++ HANDSHAKE(client, server); ++ ++ if (debug) ++ success ("Handshake established\n"); ++ ++ msglen = strlen(MSG); ++ TRANSFER(client, server, MSG, msglen, buffer, MAX_BUF); ++ if (debug) ++ fputs ("\n", stdout); ++ ++ gnutls_bye (client, GNUTLS_SHUT_RDWR); ++ gnutls_bye (server, GNUTLS_SHUT_RDWR); ++ ++ gnutls_deinit (client); ++ gnutls_deinit (server); ++ ++ gnutls_anon_free_client_credentials (c_anoncred); ++ gnutls_anon_free_server_credentials (s_anoncred); ++ ++ gnutls_dh_params_deinit (dh_params); ++ ++ gnutls_global_deinit (); ++} +-- +1.7.2.5 diff --git a/gnutls.changes b/gnutls.changes index ec40d1c..4a3c640 100644 --- a/gnutls.changes +++ b/gnutls.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Sat Sep 24 13:10:41 UTC 2011 - vuntz@opensuse.org + +- Add gnutls-fix-compression.patch: fix some + decompression/compression issues that caused connection failures + to some XMPP servers. Patch taken from git. + +------------------------------------------------------------------- +Fri Sep 23 10:38:45 CEST 2011 - meissner@suse.de + +- added libgnutls-devel to baselibs.conf for 32bit Wine on 64bit build + ------------------------------------------------------------------- Tue Sep 20 16:03:50 UTC 2011 - vuntz@opensuse.org diff --git a/gnutls.spec b/gnutls.spec index 2b71479..0b2dddf 100644 --- a/gnutls.spec +++ b/gnutls.spec @@ -30,6 +30,8 @@ Url: http://www.gnutls.org/ Group: Productivity/Networking/Security Source0: %{name}-%{version}.tar.xz Source1: baselibs.conf +# PATCH-FIX-UPSTREAM gnutls-fix-compression.patch vuntz@opensuse.org -- Taken from git, fix decompression/compression +Patch0: gnutls-fix-compression.patch BuildRequires: gcc-c++ BuildRequires: libnettle-devel >= 2.2 BuildRequires: p11-kit-devel @@ -153,6 +155,7 @@ implements the proposed standards of the IETF's TLS working group. %prep %setup -q +%patch0 -p1 %build %configure \