summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-07-15 15:29:29 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-07-15 15:29:29 +0000
commit3e0c6e040456fa12e2039526ecc666ac318ffed6 (patch)
tree8946a9ca46bacd6ecc9d06726291c26812a6cc29
parent099900892bc87e627c01285e75a0c8185eef112b (diff)
downloadgnutls-3e0c6e040456fa12e2039526ecc666ac318ffed6.tar.gz
Fixes in zlib compression code. gnutls_global_init_extra() in libgnutls-extra fails if library versions do not match. Semantic changes in gnutls_record_set_max_size(). The requested size is now immediately enforced at the output buffers.
-rw-r--r--NEWS9
-rw-r--r--lib/auth_cert.c8
-rw-r--r--lib/auth_dhe.c2
-rw-r--r--lib/auth_rsa.c2
-rw-r--r--lib/ext_max_record.c12
-rw-r--r--lib/gnutls_cert.c2
-rw-r--r--lib/gnutls_compress.c4
-rw-r--r--lib/gnutls_compress_int.c28
-rw-r--r--lib/gnutls_constate.c3
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_errors_int.h6
-rw-r--r--lib/gnutls_global.c81
-rw-r--r--lib/gnutls_int.h16
-rw-r--r--lib/gnutls_record.c92
-rw-r--r--lib/gnutls_state.c9
-rw-r--r--libextra/gnutls_extra.c10
16 files changed, 171 insertions, 115 deletions
diff --git a/NEWS b/NEWS
index 803bfb0bfd..c8f6c46a93 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,17 @@
-Version 0.5.?
+Version 0.5.1
- Corrected the m4 macros which used <gnutls.h> instead of
<gnutls/gnutls.h>
- Documentation fixes
- Added gnutls_transport_set_ptr2() function, which accepts two
different pointers, to be used while receiving, and
while sending data.
+- Semantic changes in gnutls_record_set_max_size(). The requested
+ size is now immediately enforced at the output buffers.
+- gnutls_global_init_extra() now fails if the library versions do
+ not match.
+- Fixes in client and server example programs. Null encryption can
+ be used in these programs, to assist in debuging.
+- Fixes in zlib compression code.
Version 0.5.0 (6/07/2002)
- Added X.509 certificate tests in tests/ directory
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 6448921abd..5f1378c10f 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -608,7 +608,7 @@ int _gnutls_gen_openpgp_certificate_fpr(GNUTLS_STATE state,
if (_E_gnutls_openpgp_fingerprint==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
if ( (ret=_E_gnutls_openpgp_fingerprint( &apr_cert_list[0].raw, pdata, &fpr_size)) < 0) {
@@ -861,7 +861,7 @@ int _gnutls_proc_openpgp_server_certificate(GNUTLS_STATE state,
*/
if (_E_gnutls_openpgp_request_key==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
if ( (ret=_E_gnutls_openpgp_request_key( &akey, cred, p, 20)) < 0) {
gnutls_assert();
@@ -920,7 +920,7 @@ int _gnutls_proc_openpgp_server_certificate(GNUTLS_STATE state,
gnutls_free_datum( &akey);
CLEAR_CERTS;
gnutls_afree(peer_certificate_list);
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
if ((ret =
@@ -1163,7 +1163,7 @@ int _gnutls_proc_cert_client_cert_vrfy(GNUTLS_STATE state, opaque * data,
case GNUTLS_CRT_OPENPGP:
if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
ret =
_E_gnutls_openpgp_cert2gnutls_cert(&peer_cert,
diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c
index 92abbe4d8e..e597b770b4 100644
--- a/lib/auth_dhe.c
+++ b/lib/auth_dhe.c
@@ -403,7 +403,7 @@ static int proc_dhe_server_kx(GNUTLS_STATE state, opaque * data,
case GNUTLS_CRT_OPENPGP:
if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
if ((ret =
_E_gnutls_openpgp_cert2gnutls_cert( &peer_cert,
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 5b9bfea96a..66474e4c0a 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -95,7 +95,7 @@ int i;
case GNUTLS_CRT_OPENPGP:
if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
if ((ret =
_E_gnutls_openpgp_cert2gnutls_cert( &peer_cert,
diff --git a/lib/ext_max_record.c b/lib/ext_max_record.c
index 2fccce533d..6dbe74b7bf 100644
--- a/lib/ext_max_record.c
+++ b/lib/ext_max_record.c
@@ -54,7 +54,8 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int
return new_size;
}
- state->security_parameters.max_record_size = new_size;
+ state->security_parameters.max_record_send_size = new_size;
+ state->security_parameters.max_record_recv_size = new_size;
}
} else { /* CLIENT SIDE - we must check if the sent record size is the right one
*/
@@ -70,8 +71,9 @@ int _gnutls_max_record_recv_params( GNUTLS_STATE state, const opaque* data, int
if (new_size < 0 || new_size != state->gnutls_internals.proposed_record_size) {
gnutls_assert();
return GNUTLS_E_ILLEGAL_PARAMETER;
- } else
- state->security_parameters.max_record_size = state->gnutls_internals.proposed_record_size;
+ } else {
+ state->security_parameters.max_record_recv_size = state->gnutls_internals.proposed_record_size;
+ }
}
@@ -104,14 +106,14 @@ int _gnutls_max_record_send_params( GNUTLS_STATE state, opaque* data, int data_s
} else { /* server side */
- if (state->security_parameters.max_record_size != DEFAULT_MAX_RECORD_SIZE) {
+ if (state->security_parameters.max_record_recv_size != DEFAULT_MAX_RECORD_SIZE) {
len = 1;
if (data_size < len) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
- data[0] = _gnutls_mre_record2num( state->security_parameters.max_record_size);
+ data[0] = _gnutls_mre_record2num( state->security_parameters.max_record_recv_size);
return len;
}
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 3b2525edd4..a189bef816 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -356,7 +356,7 @@ int _gnutls_openpgp_cert_verify_peers(GNUTLS_STATE state)
*/
if (_E_gnutls_openpgp_verify_key==NULL) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_INIT_LIBEXTRA;
}
verify = _E_gnutls_openpgp_verify_key( cred->pgp_trustdb, &cred->keyring, &info->raw_certificate_list[0],
peer_certificate_list_size);
diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c
index cebc3d21ea..03c34f394e 100644
--- a/lib/gnutls_compress.c
+++ b/lib/gnutls_compress.c
@@ -41,7 +41,7 @@ int _gnutls_m_plaintext2compressed(GNUTLS_STATE state,
data=NULL;
size = _gnutls_compress( state->connection_state.write_compression_state,
- plaintext.data, plaintext.size, &data, MAX_RECORD_SIZE+1024);
+ plaintext.data, plaintext.size, &data, MAX_RECORD_SEND_SIZE+1024);
if (size < 0) {
gnutls_assert();
return GNUTLS_E_COMPRESSION_FAILED;
@@ -63,7 +63,7 @@ int _gnutls_m_compressed2plaintext(GNUTLS_STATE state,
data=NULL;
size = _gnutls_decompress( state->connection_state.read_compression_state,
- compressed.data, compressed.size, &data, MAX_RECORD_SIZE);
+ compressed.data, compressed.size, &data, MAX_RECORD_RECV_SIZE);
if (size < 0) {
gnutls_assert();
return GNUTLS_E_DECOMPRESSION_FAILED;
diff --git a/lib/gnutls_compress_int.c b/lib/gnutls_compress_int.c
index 30f39663cd..69053088d7 100644
--- a/lib/gnutls_compress_int.c
+++ b/lib/gnutls_compress_int.c
@@ -155,8 +155,9 @@ int err;
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 size;
+uLongf out_size;
z_stream* zhandle;
+int cur_pos;
#endif
if (compressed_size > max_record_size+EXTRA_COMP_SIZE) {
@@ -171,36 +172,41 @@ z_stream* zhandle;
#ifdef HAVE_LIBZ
case GNUTLS_COMP_ZLIB:
*plain = NULL;
- size = compressed_size;
+ out_size = compressed_size;;
plain_size = 0;
zhandle = handle->handle;
zhandle->next_in = (Bytef*) compressed;
zhandle->avail_in = compressed_size;
-
+
+ cur_pos = 0;
+
do {
- size*=2;
- *plain = gnutls_realloc( *plain, size);
+ out_size += 128;
+ *plain = gnutls_realloc( *plain, out_size);
if (*plain==NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- zhandle->next_out = (Bytef*) *plain;
- zhandle->avail_out = size;
+ 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 && size < max_record_size);
-
- if (err!=Z_OK || zhandle->avail_in != 0) {
+ } while( (err==Z_BUF_ERROR && zhandle->avail_out==0 && out_size < max_record_size)
+ || ( err==Z_OK && zhandle->avail_in != 0));
+
+ if (err!=Z_OK) {
gnutls_assert();
gnutls_free( *plain);
return GNUTLS_E_DECOMPRESSION_FAILED;
}
- plain_size = size - zhandle->avail_out;
+ plain_size = out_size - zhandle->avail_out;
break;
#endif
default:
diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c
index e8e9300d57..85d7257c9b 100644
--- a/lib/gnutls_constate.c
+++ b/lib/gnutls_constate.c
@@ -176,7 +176,8 @@ int _gnutls_set_write_keys(GNUTLS_STATE state)
memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
dst->session_id_size = src->session_id_size; \
dst->timestamp = src->timestamp; \
- dst->max_record_size = src->max_record_size; \
+ dst->max_record_recv_size = src->max_record_recv_size; \
+ dst->max_record_send_size = src->max_record_send_size; \
dst->version = src->version; \
memcpy( &dst->extensions, &src->extensions, sizeof(TLSExtensions));
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 0b91e5332d..882d4603f4 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -115,6 +115,8 @@ static gnutls_error_entry error_algorithms[] = {
GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_SYNTAX_ERROR, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_DER_OVERFLOW, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_TOO_MANY_EMPTY_PACKETS, 1),
+ 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),
{0}
};
diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h
index 424fb4798a..2d7a4f0e6a 100644
--- a/lib/gnutls_errors_int.h
+++ b/lib/gnutls_errors_int.h
@@ -79,6 +79,12 @@
#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_UNIMPLEMENTED_FEATURE -250
/* _INT_ internal errors. Not exported */
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 77bbf28023..69cebc0735 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -250,3 +250,84 @@ void gnutls_transport_set_pull_function( GNUTLS_STATE state, GNUTLS_PULL_FUNC pu
void gnutls_transport_set_push_function( GNUTLS_STATE state, GNUTLS_PUSH_FUNC push_func) {
state->gnutls_internals._gnutls_push_func = push_func;
}
+
+
+/* Taken from libgcrypt. Needed to configure scripts.
+ */
+
+static const char*
+parse_version_number( const char *s, int *number )
+{
+ int val = 0;
+
+ if( *s == '0' && isdigit(s[1]) )
+ return NULL; /* leading zeros are not allowed */
+ for ( ; isdigit(*s); s++ ) {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+/* The parse version functions were copied from libgcrypt.
+ */
+static const char *
+parse_version_string( const char *s, int *major, int *minor, int *micro )
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, minor );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, micro );
+ if( !s )
+ return NULL;
+ return s; /* patchlevel */
+}
+
+/****************
+ * Check that the the version of the library is at minimum the requested one
+ * and return the version string; return NULL if the condition is not
+ * satisfied. If a NULL is passed to this function, no check is done,
+ * but the version string is simply returned.
+ */
+const char *
+gnutls_check_version( const char *req_version )
+{
+ const char *ver = GNUTLS_VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if ( !req_version )
+ return ver;
+
+ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
+ if ( !my_plvl )
+ return NULL; /* very strange our own version is bogus */
+ rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
+ &rq_micro );
+ if ( !rq_plvl )
+ return NULL; /* req version string is invalid */
+
+ if ( my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro
+ && strcmp( my_plvl, rq_plvl ) >= 0) ) {
+ return ver;
+ }
+ return NULL;
+}
+
+const char *
+_gnutls_return_version( void)
+{
+ return GNUTLS_VERSION;
+}
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index a8faa0465d..15c5dc34e2 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -33,9 +33,9 @@
#define READ_DEBUG
#define HANDSHAKE_DEBUG // Prints some information on handshake
#define X509_DEBUG
-#define RECORD_DEBUG
+#define RECORD_DEBUG*/
#define DEBUG
-*/
+
/* It might be a good idea to replace int with void*
* here.
@@ -81,11 +81,12 @@ typedef const int* GNUTLS_LIST;
/* the maximum size of encrypted packets */
#define DEFAULT_MAX_RECORD_SIZE 16384
#define RECORD_HEADER_SIZE 5
-#define MAX_RECORD_SIZE state->security_parameters.max_record_size
+#define MAX_RECORD_SEND_SIZE state->security_parameters.max_record_send_size
+#define MAX_RECORD_RECV_SIZE state->security_parameters.max_record_recv_size
#define MAX_PAD_SIZE 255
#define EXTRA_COMP_SIZE 2048
#define MAX_RECORD_OVERHEAD MAX_PAD_SIZE+EXTRA_COMP_SIZE
-#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_SIZE+RECORD_HEADER_SIZE
+#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE
#define HANDSHAKE_HEADER_SIZE 4
@@ -341,7 +342,12 @@ typedef struct {
uint8 session_id_size;
time_t timestamp;
TLSExtensions extensions;
- uint16 max_record_size;
+
+ /* The send size is the one requested by the programmer.
+ * The recv size is the one negotiated with the peer.
+ */
+ uint16 max_record_send_size;
+ uint16 max_record_recv_size;
/* holds the negotiated certificate type */
CertificateType cert_type;
GNUTLS_Version version; /* moved here */
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 473ca7e050..e76307e884 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -322,8 +322,8 @@ ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
_gnutls_record_log( "REC: Sending Packet[%d] %s(%d) with length: %d\n",
(int) _gnutls_uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
- if ( sizeofdata > MAX_RECORD_SIZE)
- data2send_size = MAX_RECORD_SIZE;
+ if ( sizeofdata > MAX_RECORD_SEND_SIZE)
+ data2send_size = MAX_RECORD_SEND_SIZE;
else
data2send_size = sizeofdata;
@@ -858,81 +858,6 @@ ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType hty
}
-/* Taken from libgcrypt */
-
-static const char*
-parse_version_number( const char *s, int *number )
-{
- int val = 0;
-
- if( *s == '0' && isdigit(s[1]) )
- return NULL; /* leading zeros are not allowed */
- for ( ; isdigit(*s); s++ ) {
- val *= 10;
- val += *s - '0';
- }
- *number = val;
- return val < 0? NULL : s;
-}
-
-
-/* The parse version functions were copied from libgcrypt.
- */
-static const char *
-parse_version_string( const char *s, int *major, int *minor, int *micro )
-{
- s = parse_version_number( s, major );
- if( !s || *s != '.' )
- return NULL;
- s++;
- s = parse_version_number( s, minor );
- if( !s || *s != '.' )
- return NULL;
- s++;
- s = parse_version_number( s, micro );
- if( !s )
- return NULL;
- return s; /* patchlevel */
-}
-
-/****************
- * Check that the the version of the library is at minimum the requested one
- * and return the version string; return NULL if the condition is not
- * satisfied. If a NULL is passed to this function, no check is done,
- * but the version string is simply returned.
- */
-const char *
-gnutls_check_version( const char *req_version )
-{
- const char *ver = GNUTLS_VERSION;
- int my_major, my_minor, my_micro;
- int rq_major, rq_minor, rq_micro;
- const char *my_plvl, *rq_plvl;
-
- if ( !req_version )
- return ver;
-
- my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
- if ( !my_plvl )
- return NULL; /* very strange our own version is bogus */
- rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
- &rq_micro );
- if ( !rq_plvl )
- return NULL; /* req version string is invalid */
-
- if ( my_major > rq_major
- || (my_major == rq_major && my_minor > rq_minor)
- || (my_major == rq_major && my_minor == rq_minor
- && my_micro > rq_micro)
- || (my_major == rq_major && my_minor == rq_minor
- && my_micro == rq_micro
- && strcmp( my_plvl, rq_plvl ) >= 0) ) {
- return ver;
- }
- return NULL;
-}
-
-
/**
* gnutls_record_send - sends to the peer the specified data
* @state: is a &GNUTLS_STATE structure.
@@ -986,7 +911,10 @@ ssize_t gnutls_record_recv( GNUTLS_STATE state, void *data, size_t sizeofdata) {
*
**/
size_t gnutls_record_get_max_size( GNUTLS_STATE state) {
- return state->security_parameters.max_record_size;
+ /* Recv will hold the negotiated max record size
+ * always.
+ */
+ return state->security_parameters.max_record_recv_size;
}
@@ -1000,9 +928,9 @@ size_t gnutls_record_get_max_size( GNUTLS_STATE state) {
* choose not to accept the requested size.
*
* Acceptable values are 2^9, 2^10, 2^11 and 2^12.
- * Returns 0 on success. The requested record size does not
- * get in effect immediately. It will be used after a successful
- * handshake.
+ * Returns 0 on success. The requested record size does
+ * get in effect immediately only while sending data. The receive
+ * part will take effect after a successful handshake.
*
* This function uses a TLS extension called 'max record size'.
* Not all TLS implementations use or even understand this extension.
@@ -1021,6 +949,8 @@ ssize_t new_size;
return new_size;
}
+ state->security_parameters.max_record_send_size = size;
+
state->gnutls_internals.proposed_record_size = size;
return 0;
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 244111b57e..60d2382485 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -195,12 +195,17 @@ int default_protocol_list[] = { GNUTLS_TLS1, 0 };
* the receive procedure slow.
*/
(*state)->gnutls_internals.record_recv_buffer.data = gnutls_malloc(INITIAL_RECV_BUFFER_SIZE);
+
+ /* set the socket pointers to -1;
+ */
+ (*state)->gnutls_internals.transport_recv_ptr = -1;
+ (*state)->gnutls_internals.transport_send_ptr = -1;
/* set the default maximum record size for TLS
*/
- (*state)->security_parameters.max_record_size = DEFAULT_MAX_RECORD_SIZE;
+ (*state)->security_parameters.max_record_recv_size = DEFAULT_MAX_RECORD_SIZE;
+ (*state)->security_parameters.max_record_send_size = DEFAULT_MAX_RECORD_SIZE;
-
/* everything else not initialized here is initialized
* as NULL or 0. This is why calloc is used.
*/
diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c
index 24edbf3714..65216adcff 100644
--- a/libextra/gnutls_extra.c
+++ b/libextra/gnutls_extra.c
@@ -99,6 +99,8 @@ static void _gnutls_add_openpgp_functions(void) {
static int _gnutls_init_extra = 0;
+const char* _gnutls_return_version( void);
+
/**
* gnutls_global_init_extra - This function initializes the global state of gnutls-extra
*
@@ -112,6 +114,14 @@ static int _gnutls_init_extra = 0;
**/
int gnutls_global_init_extra(void) {
int ret;
+
+ /* If the version of libgnutls != version of
+ * libextra, then do not initialize the library.
+ * This is because it may break things.
+ */
+ if (strcmp( _gnutls_return_version(), VERSION)!=0) {
+ return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
+ }
_gnutls_init_extra++;