gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-127-g110a773


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-127-g110a773
Date: Tue, 08 Feb 2011 20:10:46 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=110a7737b81ce1b3498aceacba41651983c9dbbc

The branch, master has been updated
       via  110a7737b81ce1b3498aceacba41651983c9dbbc (commit)
      from  065ada1a9228c12132b15ab8da2244178d33430c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 110a7737b81ce1b3498aceacba41651983c9dbbc
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Feb 8 21:10:11 2011 +0100

    Simplified code in authentication methods by using gnutls_buffer_st
    instead of malloc/realloc.

-----------------------------------------------------------------------

Summary of changes:
 lib/auth_anon.c       |    4 +-
 lib/auth_cert.c       |  235 +++++++++++++++++-------------------
 lib/auth_cert.h       |    8 +-
 lib/auth_dh_common.c  |   80 +++----------
 lib/auth_dh_common.h  |    6 +-
 lib/auth_dhe.c        |   40 +++---
 lib/auth_dhe_psk.c    |   37 ++----
 lib/auth_psk.c        |   30 +----
 lib/auth_rsa.c        |   21 ++--
 lib/auth_rsa_export.c |   61 +++-------
 lib/auth_srp.c        |  125 +++++++------------
 lib/auth_srp.h        |    4 +-
 lib/auth_srp_rsa.c    |   25 ++---
 lib/gnutls_auth.h     |   14 ++-
 lib/gnutls_kx.c       |  315 ++++++++++++++++++++++++-------------------------
 lib/gnutls_str.c      |   76 +++++++++++--
 lib/gnutls_str.h      |   12 ++-
 17 files changed, 497 insertions(+), 596 deletions(-)

diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index fce66d1..e9ee2fc 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -41,7 +41,7 @@
 #include <gnutls_state.h>
 #include <auth_dh_common.h>
 
-static int gen_anon_server_kx (gnutls_session_t, opaque **);
+static int gen_anon_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_anon_client_kx (gnutls_session_t, opaque *, size_t);
 static int proc_anon_server_kx (gnutls_session_t, opaque *, size_t);
 
@@ -63,7 +63,7 @@ const mod_auth_st anon_auth_struct = {
 };
 
 static int
-gen_anon_server_kx (gnutls_session_t session, opaque ** data)
+gen_anon_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   bigint_t g, p;
   const bigint_t *mpis;
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 033d3d7..dea7aae 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -753,10 +753,9 @@ cleanup:
  */
 
 static int
-_gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
+_gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
 {
   int ret, i;
-  opaque *pdata;
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length;
@@ -788,23 +787,19 @@ _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** 
data)
    * the one produced here )
    */
 
-  (*data) = gnutls_malloc (ret);
-  pdata = (*data);
+  ret = _gnutls_buffer_append_prefix(data, 24, ret - 3);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  if (pdata == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-  _gnutls_write_uint24 (ret - 3, pdata);
-  pdata += 3;
   for (i = 0; i < apr_cert_list_length; i++)
     {
-      _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
-      pdata += (3 + apr_cert_list[i].raw.size);
+      ret = _gnutls_buffer_append_data_prefix( data, 24, 
apr_cert_list[i].raw.data,
+        apr_cert_list[i].raw.size);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
-  return ret;
+  return data->length;
 }
 
 enum PGPKeyDescriptorType
@@ -812,13 +807,13 @@ enum PGPKeyDescriptorType
 
 #ifdef ENABLE_OPENPGP
 static int
-_gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
+_gnutls_gen_openpgp_certificate (gnutls_session_t session, gnutls_buffer_st * 
data)
 {
   int ret;
-  opaque *pdata;
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length;
+  uint8_t type;
 
   /* find the appropriate certificate */
   if ((ret =
@@ -840,56 +835,59 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t 
session, opaque ** data)
       ret += apr_cert_list[0].raw.size;
     }
 
-  (*data) = gnutls_malloc (ret);
-  pdata = (*data);
-
-  if (pdata == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _gnutls_write_uint24 (ret - 3, pdata);
-  pdata += 3;
+  ret = _gnutls_buffer_append_prefix( data, 24, ret - 3);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
 
   if (apr_cert_list_length > 0)
     {
       if (apr_cert_list[0].use_subkey != 0)
         {
-          *pdata = PGP_KEY_SUBKEY;
-          pdata++;
-          *pdata = sizeof (apr_cert_list[0].subkey_id);
-          pdata++;
-          memcpy (pdata, apr_cert_list[0].subkey_id,
-                  sizeof (apr_cert_list[0].subkey_id));
-          pdata += sizeof (apr_cert_list[0].subkey_id);
+          type = PGP_KEY_SUBKEY;
+
+          ret = _gnutls_buffer_append_data( data, &type, 1);
+          if (ret < 0)
+            return gnutls_assert_val(ret);
+
+          ret = _gnutls_buffer_append_data_prefix( data, 8, 
apr_cert_list[0].subkey_id,
+              sizeof (apr_cert_list[0].subkey_id));
+          if (ret < 0)
+            return gnutls_assert_val(ret);
         }
       else
         {
-          *pdata = PGP_KEY;
-          pdata++;
+          type = PGP_KEY;
+          ret = _gnutls_buffer_append_data( data, &type, 1);
+          if (ret < 0)
+            return gnutls_assert_val(ret);
         }
 
-      _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
-      pdata += (3 + apr_cert_list[0].raw.size);
+      ret = _gnutls_buffer_append_data_prefix( data, 24, 
apr_cert_list[0].raw.data,
+        apr_cert_list[0].raw.size);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
   else                          /* empty - no certificate */
     {
-      *pdata = PGP_KEY;
-      pdata++;
-      _gnutls_write_uint24 (0, pdata);
+      ret = _gnutls_buffer_append_data( data, &type, 1);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
+
+      ret = _gnutls_buffer_append_prefix( data, 24, 0);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
-  return ret;
+  return data->length;
 }
 
 static int
-_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
+_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, 
gnutls_buffer_st * data)
 {
   int ret, packet_size;
+  uint8_t type, fpr[20];
   size_t fpr_size;
-  opaque *pdata;
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length;
@@ -915,54 +913,50 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t 
session, opaque ** data)
   else                          /* empty certificate case */
     return _gnutls_gen_openpgp_certificate (session, data);
 
-  (*data) = gnutls_malloc (packet_size);
-  pdata = (*data);
-
-  if (pdata == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _gnutls_write_uint24 (packet_size - 3, pdata);
-  pdata += 3;
+  ret = _gnutls_buffer_append_prefix( data, 24, packet_size - 3);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
   if (apr_cert_list[0].use_subkey)
     {
-      *pdata = PGP_KEY_FINGERPRINT_SUBKEY;
-      pdata++;
-      *pdata = sizeof (apr_cert_list[0].subkey_id);
-      pdata++;
-      memcpy (pdata, apr_cert_list[0].subkey_id,
-              sizeof (apr_cert_list[0].subkey_id));
-      pdata += sizeof (apr_cert_list[0].subkey_id);
+      type = PGP_KEY_FINGERPRINT_SUBKEY;
+      ret = _gnutls_buffer_append_data( data, &type, 1);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
+      
+      ret = _gnutls_buffer_append_data_prefix( data, 8, 
+        apr_cert_list[0].subkey_id, sizeof(apr_cert_list[0].subkey_id));
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
   else
     {
-      *pdata = PGP_KEY_FINGERPRINT;     /* key fingerprint */
-      pdata++;
+      type = PGP_KEY_FINGERPRINT;     /* key fingerprint */
+      ret = _gnutls_buffer_append_data( data, &type, 1);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
-  *pdata = 20;
-  pdata++;
-
-  fpr_size = 20;
-
+  fpr_size = sizeof(fpr);
   if ((ret =
-       _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
+       _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, fpr,
                                     &fpr_size)) < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  return packet_size;
+  ret = _gnutls_buffer_append_data_prefix( data, 8, fpr, fpr_size);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  return data->length;
 }
 #endif
 
 
 int
-_gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
+_gnutls_gen_cert_client_certificate (gnutls_session_t session, 
gnutls_buffer_st * data)
 {
   switch (session->security_parameters.cert_type)
     {
@@ -983,7 +977,7 @@ _gnutls_gen_cert_client_certificate (gnutls_session_t 
session, opaque ** data)
 }
 
 int
-_gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
+_gnutls_gen_cert_server_certificate (gnutls_session_t session, 
gnutls_buffer_st * data)
 {
   switch (session->security_parameters.cert_type)
     {
@@ -1526,20 +1520,17 @@ _gnutls_proc_cert_cert_req (gnutls_session_t session, 
opaque * data,
 }
 
 int
-_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
+_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, gnutls_buffer_st 
* data)
 {
   int ret;
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
-  int apr_cert_list_length, size;
+  int apr_cert_list_length;
   gnutls_datum_t signature = { NULL, 0 };
   int total_data;
-  opaque *p;
   gnutls_sign_algorithm_t sign_algo;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
-  *data = NULL;
-
   /* find the appropriate certificate */
   if ((ret =
        _gnutls_get_selected_cert (session, &apr_cert_list,
@@ -1574,43 +1565,36 @@ _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t 
session, opaque ** data)
       total_data += 2;
     }
 
-  *data = gnutls_malloc (total_data);
-  if (*data == NULL)
-    {
-      _gnutls_free_datum (&signature);
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  p = *data;
   if (_gnutls_version_has_selectable_sighash (ver))
     {
       const sign_algorithm_st *aid;
+      uint8_t p[2];
       /* error checking is not needed here since we have used those algorithms 
*/
       aid = _gnutls_sign_to_tls_aid (sign_algo);
       if (aid == NULL)
-        {
-          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
-          goto cleanup;
-        }
+        return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
 
       p[0] = aid->hash_algorithm;
       p[1] = aid->sign_algorithm;
-      p += 2;
+      ret = _gnutls_buffer_append_data(data, p, 2);
+      if (ret < 0)
+        {
+          gnutls_assert();
+          goto cleanup;
+        }
     }
 
-  size = signature.size;
-  _gnutls_write_uint16 (size, p);
-
-  p += 2;
-  memcpy (p, signature.data, size);
-
-  _gnutls_free_datum (&signature);
+  ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, 
signature.size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
 
-  return total_data;
+  return data->length;
 
 cleanup:
   _gnutls_free_datum (&signature);
-  gnutls_free(*data);
   return ret;
 }
 
@@ -1692,14 +1676,14 @@ _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t 
session,
 
 
 #define CERTTYPE_SIZE 3
+#define SIGN_ALGO_SIZE (2 + MAX_SIGNATURE_ALGORITHMS * 2)
 int
-_gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
+_gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_buffer_st * 
data)
 {
   gnutls_certificate_credentials_t cred;
   int size, ret;
-  opaque *pdata;
+  uint8_t tmp_data[CERTTYPE_SIZE];
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
-  const int signalgosize = 2 + MAX_SIGNATURE_ALGORITHMS * 2;
 
   /* Now we need to generate the RDN sequence. This is
    * already in the CERTIFICATE_CRED structure, to improve
@@ -1724,27 +1708,22 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t 
session, opaque ** data)
   if (_gnutls_version_has_selectable_sighash (ver))
     /* Need two bytes to announce the number of supported hash
        functions (see below).  */
-    size += signalgosize;
-
-  (*data) = gnutls_malloc (size);
-  pdata = (*data);
-
-  if (pdata == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
+    size += SIGN_ALGO_SIZE;
 
-  pdata[0] = CERTTYPE_SIZE - 1;
+  tmp_data[0] = CERTTYPE_SIZE - 1;
+  tmp_data[1] = RSA_SIGN;
+  tmp_data[2] = DSA_SIGN;          /* only these for now */
 
-  pdata[1] = RSA_SIGN;
-  pdata[2] = DSA_SIGN;          /* only these for now */
-  pdata += CERTTYPE_SIZE;
+  ret = _gnutls_buffer_append_data( data, tmp_data, CERTTYPE_SIZE);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
   if (_gnutls_version_has_selectable_sighash (ver))
     {
+      uint8_t p[SIGN_ALGO_SIZE];
+
       ret =
-        _gnutls_sign_algorithm_write_params (session, pdata, signalgosize);
+        _gnutls_sign_algorithm_write_params (session, p, SIGN_ALGO_SIZE);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -1752,23 +1731,29 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t 
session, opaque ** data)
         }
 
       /* recalculate size */
-      size = size - signalgosize + ret;
-      pdata += ret;
+      size -= SIGN_ALGO_SIZE + ret;
+
+      ret = _gnutls_buffer_append_data( data, p, ret);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
   if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
       session->internals.ignore_rdn_sequence == 0)
     {
-      _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
-      /* pdata += cred->x509_rdn_sequence.size + 2; */
+      ret = _gnutls_buffer_append_data_prefix( data, 16, 
cred->x509_rdn_sequence.data,
+        cred->x509_rdn_sequence.size);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
   else
     {
-      _gnutls_write_uint16 (0, pdata);
-      /* pdata+=2; */
+      ret = _gnutls_buffer_append_prefix( data, 16, 0);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
-  return size;
+  return data->length;
 }
 
 
diff --git a/lib/auth_cert.h b/lib/auth_cert.h
index d447b71..71ecdfd 100644
--- a/lib/auth_cert.h
+++ b/lib/auth_cert.h
@@ -127,10 +127,10 @@ typedef struct cert_auth_info_st cert_auth_info_st;
 void _gnutls_free_rsa_info (rsa_info_st * rsa);
 
 /* AUTH X509 functions */
-int _gnutls_gen_cert_server_certificate (gnutls_session_t, opaque **);
-int _gnutls_gen_cert_client_certificate (gnutls_session_t, opaque **);
-int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, opaque **);
-int _gnutls_gen_cert_server_cert_req (gnutls_session_t, opaque **);
+int _gnutls_gen_cert_server_certificate (gnutls_session_t, gnutls_buffer_st *);
+int _gnutls_gen_cert_client_certificate (gnutls_session_t, gnutls_buffer_st *);
+int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, gnutls_buffer_st *);
+int _gnutls_gen_cert_server_cert_req (gnutls_session_t, gnutls_buffer_st *);
 int _gnutls_proc_cert_cert_req (gnutls_session_t, opaque *, size_t);
 int _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t, opaque *, size_t);
 int _gnutls_proc_cert_server_certificate (gnutls_session_t, opaque *, size_t);
diff --git a/lib/auth_dh_common.c b/lib/auth_dh_common.c
index 61f8a63..f0198b2 100644
--- a/lib/auth_dh_common.c
+++ b/lib/auth_dh_common.c
@@ -121,14 +121,11 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t 
session,
 }
 
 int
-_gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* 
data)
 {
   bigint_t x = NULL, X = NULL;
-  size_t n_X;
   int ret;
 
-  *data = NULL;
-
   X = gnutls_calc_dh_secret (&x, session->key->client_g,
                              session->key->client_p);
   if (X == NULL || x == NULL)
@@ -140,19 +137,13 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t 
session, opaque ** data)
 
   _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
 
-  _gnutls_mpi_print (X, NULL, &n_X);
-  (*data) = gnutls_malloc (n_X + 2);
-  if (*data == NULL)
+  ret = _gnutls_buffer_append_mpi( data, 16, X, 0);
+  if (ret < 0)
     {
-      ret = GNUTLS_E_MEMORY_ERROR;
+      gnutls_assert();
       goto error;
     }
 
-  _gnutls_mpi_print (X, &(*data)[2], &n_X);
-  _gnutls_mpi_release (&X);
-
-  _gnutls_write_uint16 (n_X, &(*data)[0]);
-
   /* calculate the key after calculating the message */
   session->key->KEY =
     gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
@@ -199,13 +190,11 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t 
session, opaque ** data)
       goto error;
     }
 
-  return n_X + 2;
+  return data->length;
 
 error:
   _gnutls_mpi_release (&x);
   _gnutls_mpi_release (&X);
-  gnutls_free (*data);
-  *data = NULL;
   return ret;
 }
 
@@ -306,13 +295,11 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t 
session,
  * be inserted */
 int
 _gnutls_dh_common_print_server_kx (gnutls_session_t session,
-                                   bigint_t g, bigint_t p, opaque ** data,
+                                   bigint_t g, bigint_t p, gnutls_buffer_st* 
data,
                                    int psk)
 {
   bigint_t x, X;
-  size_t n_X, n_g, n_p;
-  int ret, data_size, pos;
-  uint8_t *pdata;
+  int ret;
 
   X = gnutls_calc_dh_secret (&x, g, p);
   if (X == NULL || x == NULL)
@@ -324,51 +311,24 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t 
session,
   session->key->dh_secret = x;
   _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
 
-  _gnutls_mpi_print (g, NULL, &n_g);
-  _gnutls_mpi_print (p, NULL, &n_p);
-  _gnutls_mpi_print (X, NULL, &n_X);
-
-  data_size = n_g + n_p + n_X + 6;
   if (psk != 0)
-    data_size += 2;
-
-  (*data) = gnutls_malloc (data_size);
-  if (*data == NULL)
     {
-      _gnutls_mpi_release (&X);
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  pos = 0;
-  pdata = *data;
-
-  if (psk != 0)
-    {
-      _gnutls_write_uint16 (0, &pdata[pos]);
-      pos += 2;
+      ret = _gnutls_buffer_append_prefix(data, 16, 0);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
     }
 
-  _gnutls_mpi_print (p, &pdata[pos + 2], &n_p);
-  _gnutls_write_uint16 (n_p, &pdata[pos]);
-
-  pos += n_p + 2;
-
-  _gnutls_mpi_print (g, &pdata[pos + 2], &n_g);
-  _gnutls_write_uint16 (n_g, &pdata[pos]);
-
-  pos += n_g + 2;
-
-  _gnutls_mpi_print (X, &pdata[pos + 2], &n_X);
-  _gnutls_mpi_release (&X);
+  ret = _gnutls_buffer_append_mpi(data, 16, p, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  _gnutls_write_uint16 (n_X, &pdata[pos]);
+  ret = _gnutls_buffer_append_mpi(data, 16, g, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  /* do not use data_size. _gnutls_mpi_print() might
-   * have been pessimist and might have returned initially
-   * more data */
-  ret = n_g + n_p + n_X + 6;
-  if (psk != 0)
-    ret += 2;
+  ret = _gnutls_buffer_append_mpi(data, 16, X, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  return ret;
+  return data->length;
 }
diff --git a/lib/auth_dh_common.h b/lib/auth_dh_common.h
index 7a8be7c..ccfe5c0 100644
--- a/lib/auth_dh_common.h
+++ b/lib/auth_dh_common.h
@@ -26,6 +26,8 @@
 #ifndef AUTH_DH_COMMON
 #define AUTH_DH_COMMON
 
+#include <gnutls_auth.h>
+
 typedef struct
 {
   int secret_bits;
@@ -36,12 +38,12 @@ typedef struct
 } dh_info_st;
 
 void _gnutls_free_dh_info (dh_info_st * dh);
-int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **);
+int _gnutls_gen_dh_common_client_kx (gnutls_session_t, gnutls_buffer_st*);
 int _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
                                       opaque * data, size_t _data_size,
                                       bigint_t p, bigint_t g);
 int _gnutls_dh_common_print_server_kx (gnutls_session_t, bigint_t g,
-                                       bigint_t p, opaque ** data, int psk);
+                                       bigint_t p, gnutls_buffer_st* data, int 
psk);
 int _gnutls_proc_dh_common_server_kx (gnutls_session_t session, opaque * data,
                                       size_t _data_size, int psk);
 
diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c
index 87de684..b714e64 100644
--- a/lib/auth_dhe.c
+++ b/lib/auth_dhe.c
@@ -41,7 +41,7 @@
 #include <gnutls_state.h>
 #include <auth_dh_common.h>
 
-static int gen_dhe_server_kx (gnutls_session_t, opaque **);
+static int gen_dhe_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t);
 static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t);
 
@@ -81,7 +81,7 @@ const mod_auth_st dhe_dss_auth_struct = {
 
 
 static int
-gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
+gen_dhe_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   bigint_t g, p;
   const bigint_t *mpis;
@@ -143,8 +143,8 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
 
   /* Generate the signature. */
 
-  ddata.data = *data;
-  ddata.size = data_size;
+  ddata.data = data->data;
+  ddata.size = data->length;
 
   if (apr_cert_list_length > 0)
     {
@@ -164,17 +164,10 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** 
data)
       goto cleanup;
     }
 
-  *data = gnutls_realloc_fast (*data, data_size + signature.size + 4);
-  if (*data == NULL)
-    {
-      gnutls_assert ();
-      ret = GNUTLS_E_MEMORY_ERROR;
-      goto cleanup;
-    }
-
   if (_gnutls_version_has_selectable_sighash (ver))
     {
       const sign_algorithm_st *aid;
+      uint8_t p[2];
 
       if (sign_algo == GNUTLS_SIGN_UNKNOWN)
         {
@@ -190,20 +183,27 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** 
data)
           goto cleanup;
         }
       
-      (*data)[data_size++] = aid->hash_algorithm;
-      (*data)[data_size++] = aid->sign_algorithm;
+      p[0] = aid->hash_algorithm;
+      p[1] = aid->sign_algorithm;
+      
+      ret = _gnutls_buffer_append_data(data, p, 2);
+      if (ret < 0)
+        {
+          gnutls_assert();
+          goto cleanup;
+        }
     }
 
-  _gnutls_write_datum16 (&(*data)[data_size], signature);
-  data_size += signature.size + 2;
-
-  _gnutls_free_datum (&signature);
+  ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, 
signature.size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+    }
 
-  return data_size;
+  ret = data->length;
 
 cleanup:
   _gnutls_free_datum (&signature);
-  gnutls_free(*data);
   return ret;
 
 }
diff --git a/lib/auth_dhe_psk.c b/lib/auth_dhe_psk.c
index 85e1452..7899182 100644
--- a/lib/auth_dhe_psk.c
+++ b/lib/auth_dhe_psk.c
@@ -40,8 +40,8 @@
 #include <auth_dh_common.h>
 #include <gnutls_datum.h>
 
-static int gen_psk_server_kx (gnutls_session_t, opaque **);
-static int gen_psk_client_kx (gnutls_session_t, opaque **);
+static int gen_psk_server_kx (gnutls_session_t, gnutls_buffer_st*);
+static int gen_psk_client_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_psk_client_kx (gnutls_session_t, opaque *, size_t);
 static int proc_psk_server_kx (gnutls_session_t, opaque *, size_t);
 
@@ -63,11 +63,9 @@ const mod_auth_st dhe_psk_auth_struct = {
 };
 
 static int
-gen_psk_client_kx (gnutls_session_t session, opaque ** data)
+gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   int ret;
-  opaque *tmp_data = NULL;
-  int data_size, tmp_data_size;
   gnutls_psk_client_credentials_t cred;
 
   cred = (gnutls_psk_client_credentials_t)
@@ -85,38 +83,25 @@ gen_psk_client_kx (gnutls_session_t session, opaque ** data)
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  /* The PSK key is set in there */
-  ret = _gnutls_gen_dh_common_client_kx (session, &tmp_data);
+  ret = _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, 
cred->username.size);
   if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
+    return gnutls_assert_val(ret);
 
-  tmp_data_size = ret;
-  data_size = tmp_data_size + cred->username.size + 2;
 
-  (*data) = gnutls_malloc (data_size);
-  if ((*data) == NULL)
+  /* The PSK key is set in there */
+  ret = _gnutls_gen_dh_common_client_kx (session, data);
+  if (ret < 0)
     {
       gnutls_assert ();
-      ret = GNUTLS_E_MEMORY_ERROR;
-      goto error;
+      return ret;
     }
 
-  _gnutls_write_datum16 (*data, cred->username);
-  memcpy (&(*data)[cred->username.size + 2], tmp_data, tmp_data_size);
-
-  ret = data_size;
-
-error:
-  gnutls_free (tmp_data);
-  return ret;
+  return data->length;
 
 }
 
 static int
-gen_psk_server_kx (gnutls_session_t session, opaque ** data)
+gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   bigint_t g, p;
   const bigint_t *mpis;
diff --git a/lib/auth_psk.c b/lib/auth_psk.c
index 43f400a..c272bba 100644
--- a/lib/auth_psk.c
+++ b/lib/auth_psk.c
@@ -36,8 +36,8 @@
 #include <gnutls_str.h>
 #include <gnutls_datum.h>
 
-int _gnutls_gen_psk_server_kx (gnutls_session_t session, opaque ** data);
-int _gnutls_gen_psk_client_kx (gnutls_session_t, opaque **);
+int _gnutls_gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* 
data);
+int _gnutls_gen_psk_client_kx (gnutls_session_t, gnutls_buffer_st*);
 
 int _gnutls_proc_psk_client_kx (gnutls_session_t, opaque *, size_t);
 
@@ -154,7 +154,7 @@ error:
  *
  */
 int
-_gnutls_gen_psk_client_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   int ret;
   gnutls_psk_client_credentials_t cred;
@@ -211,16 +211,7 @@ _gnutls_gen_psk_client_kx (gnutls_session_t session, 
opaque ** data)
       return ret;
     }
 
-  (*data) = gnutls_malloc (2 + cred->username.size);
-  if ((*data) == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _gnutls_write_datum16 (*data, cred->username);
-
-  return (cred->username.size + 2);
+  return _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, 
cred->username.size);
 }
 
 
@@ -300,7 +291,7 @@ error:
  *
  */
 int
-_gnutls_gen_psk_server_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   gnutls_psk_server_credentials_t cred;
   gnutls_datum_t hint;
@@ -324,16 +315,7 @@ _gnutls_gen_psk_server_kx (gnutls_session_t session, 
opaque ** data)
   hint.data = cred->hint;
   hint.size = strlen (cred->hint);
 
-  (*data) = gnutls_malloc (2 + hint.size);
-  if ((*data) == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _gnutls_write_datum16 (*data, hint);
-
-  return hint.size + 2;
+  return _gnutls_buffer_append_data_prefix(data, 16, hint.data, hint.size);
 }
 
 
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 068c8e2..0ac5bae 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -43,7 +43,7 @@
 #include <random.h>
 #include <gnutls_mpi.h>
 
-int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
+int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
 
 const mod_auth_st rsa_auth_struct = {
@@ -252,7 +252,7 @@ proc_rsa_client_kx (gnutls_session_t session, opaque * data,
 /* return RSA(random) using the peers public key 
  */
 int
-_gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   cert_auth_info_t auth = session->key->auth_info;
   gnutls_datum_t sdata;         /* data to send */
@@ -323,19 +323,14 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, 
opaque ** data)
   if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
     {
       /* SSL 3.0 */
-      *data = sdata.data;
-      return sdata.size;
+      _gnutls_buffer_replace_data( data, &sdata);
+
+      return data->length;
     }
   else
-    {                           /* TLS 1 */
-      *data = gnutls_malloc (sdata.size + 2);
-      if (*data == NULL)
-        {
-          _gnutls_free_datum (&sdata);
-          return GNUTLS_E_MEMORY_ERROR;
-        }
-      _gnutls_write_datum16 (*data, sdata);
-      ret = sdata.size + 2;
+    {  /* TLS 1 */
+      ret = _gnutls_buffer_append_data_prefix( data, 16, sdata.data, 
sdata.size);
+
       _gnutls_free_datum (&sdata);
       return ret;
     }
diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c
index ed35fcc..26a0449 100644
--- a/lib/auth_rsa_export.c
+++ b/lib/auth_rsa_export.c
@@ -44,8 +44,8 @@
 #include <gnutls_state.h>
 #include <random.h>
 
-int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
-static int gen_rsa_export_server_kx (gnutls_session_t, opaque **);
+int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*);
+static int gen_rsa_export_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t);
 static int proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
                                       size_t _data_size);
@@ -234,13 +234,11 @@ proc_rsa_export_client_kx (gnutls_session_t session, 
opaque * data,
 }
 
 static int
-gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data)
+gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   gnutls_rsa_params_t rsa_params;
   const bigint_t *rsa_mpis;
-  size_t n_e, n_m;
-  uint8_t *data_e, *data_m;
-  int ret = 0, data_size;
+  int ret = 0;
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length;
@@ -295,32 +293,18 @@ gen_rsa_export_server_kx (gnutls_session_t session, 
opaque ** data)
 
   _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
 
-  _gnutls_mpi_print (rsa_mpis[0], NULL, &n_m);
-  _gnutls_mpi_print (rsa_mpis[1], NULL, &n_e);
-
-  (*data) = gnutls_malloc (n_e + n_m + 4);
-  if (*data == NULL)
-    {
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  data_m = &(*data)[0];
-  _gnutls_mpi_print (rsa_mpis[0], &data_m[2], &n_m);
-
-  _gnutls_write_uint16 (n_m, data_m);
-
-  data_e = &data_m[2 + n_m];
-  _gnutls_mpi_print (rsa_mpis[1], &data_e[2], &n_e);
-
-  _gnutls_write_uint16 (n_e, data_e);
-
-  data_size = n_m + n_e + 4;
+  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[0], 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
+  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[1], 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
   /* Generate the signature. */
 
-  ddata.data = *data;
-  ddata.size = data_size;
+  ddata.data = data->data;
+  ddata.size = data->length;
 
   if (apr_cert_list_length > 0)
     {
@@ -330,31 +314,22 @@ gen_rsa_export_server_kx (gnutls_session_t session, 
opaque ** data)
                                         &sign_algo)) < 0)
         {
           gnutls_assert ();
-          gnutls_free (*data);
-          *data = NULL;
           return ret;
         }
     }
   else
     {
       gnutls_assert ();
-      return data_size;         /* do not put a signature - ILLEGAL! */
-    }
-
-  *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
-  if (*data == NULL)
-    {
-      _gnutls_free_datum (&signature);
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      return data->length;         /* do not put a signature - ILLEGAL! */
     }
 
-  _gnutls_write_datum16 (&((*data)[data_size]), signature);
-  data_size += signature.size + 2;
-
+  ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, 
signature.size);
   _gnutls_free_datum (&signature);
 
-  return data_size;
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  return data->length;
 }
 
 /* if the peer's certificate is of 512 bits or less, returns non zero.
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index 714e50c..5a46a7b 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -131,18 +131,13 @@ check_a_mod_n (bigint_t a, bigint_t n)
  * Data is allocated by the caller, and should have data_size size.
  */
 int
-_gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_srp_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   int ret;
-  uint8_t *data_n, *data_s;
-  uint8_t *data_g;
   char *username;
   SRP_PWD_ENTRY *pwd_entry;
   srp_server_auth_info_t info;
-  ssize_t data_size;
-  size_t n_b, tmp_size;
-  char buf[64];
-  uint8_t *data_b;
+  size_t tmp_size;
   extension_priv_data_t epriv;
   srp_ext_st *priv;
 
@@ -180,21 +175,24 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, 
opaque ** data)
   if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, tmp_size) < 0)
     {
       gnutls_assert ();
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   tmp_size = pwd_entry->n.size;
   if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, tmp_size) < 0)
     {
       gnutls_assert ();
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   tmp_size = pwd_entry->v.size;
   if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, tmp_size) < 0)
     {
       gnutls_assert ();
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   /* Calculate:  B = (k*v + g^b) % N 
@@ -203,77 +201,67 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, 
opaque ** data)
   if (B == NULL)
     {
       gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  if (_gnutls_mpi_print (B, NULL, &n_b) != GNUTLS_E_SHORT_MEMORY_BUFFER)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MPI_PRINT_FAILED;
+      ret = GNUTLS_E_MEMORY_ERROR;
+      goto cleanup;
     }
 
-
-  /* Allocate size to hold the N, g, s, B 
+  /* copy N (mod n) 
    */
-
-  data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
-               pwd_entry->salt.size + 1) + (n_b + 2);
-
-  (*data) = gnutls_malloc (data_size);
-  if ((*data) == NULL)
+  ret = _gnutls_buffer_append_data_prefix( data, 16, pwd_entry->n.data,
+    pwd_entry->n.size);
+  if (ret < 0)
     {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      gnutls_assert();
+      goto cleanup;
     }
 
-  /* copy N (mod n) 
-   */
-  data_n = *data;
-  _gnutls_write_datum16 (data_n, pwd_entry->n);
-
-
   /* copy G (generator) to data 
    */
-  data_g = &data_n[2 + pwd_entry->n.size];
-  _gnutls_write_datum16 (data_g, pwd_entry->g);
-
+  ret = _gnutls_buffer_append_data_prefix( data, 16, pwd_entry->g.data,
+    pwd_entry->g.size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
 
   /* copy the salt 
    */
-  data_s = &data_g[2 + pwd_entry->g.size];
-  _gnutls_write_datum8 (data_s, pwd_entry->salt);
-
+  ret = _gnutls_buffer_append_data_prefix( data, 8, pwd_entry->salt.data,
+    pwd_entry->salt.size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
 
   /* Copy the B value
    */
 
-  data_b = &data_s[1 + pwd_entry->salt.size];
-  if (_gnutls_mpi_print (B, &data_b[2], &n_b) != 0)
+  ret = _gnutls_buffer_append_mpi( data, 16, B, 0);
+  if (ret < 0)
     {
-      gnutls_assert ();
-      return GNUTLS_E_MPI_PRINT_FAILED;
+      gnutls_assert();
+      goto cleanup;
     }
 
-  _gnutls_write_uint16 (n_b, data_b);
-
-  _gnutls_hard_log ("INT: SRP B[%d]: %s\n", (int) n_b,
-                    _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf),
-                                     NULL));
+  _gnutls_mpi_log ("SRP B: ", B);
 
   _gnutls_srp_entry_free (pwd_entry);
 
-  return data_size;
+  ret = data->length;
+
+cleanup:
+  _gnutls_srp_entry_free (pwd_entry);
+  return ret;
 }
 
 /* return A = g^a % N */
 int
-_gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
+_gnutls_gen_srp_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
-  size_t n_a;
   int ret;
-  uint8_t *data_a;
   char *username, *password;
-  char buf[64];
   gnutls_srp_client_credentials_t cred;
   extension_priv_data_t epriv;
   srp_ext_st *priv;
@@ -365,36 +353,15 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, 
opaque ** data)
       return ret;
     }
 
-  if (_gnutls_mpi_print (A, NULL, &n_a) != GNUTLS_E_SHORT_MEMORY_BUFFER)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MPI_PRINT_FAILED;
-    }
-
-  (*data) = gnutls_malloc (n_a + 2);
-  if ((*data) == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  /* copy A */
-  data_a = (*data);
-  if (_gnutls_mpi_print (A, &data_a[2], &n_a) != 0)
-    {
-      gnutls_free (*data);
-      return GNUTLS_E_MPI_PRINT_FAILED;
-    }
+  ret = _gnutls_buffer_append_mpi(data, 16, A, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  _gnutls_hard_log ("INT: SRP A[%d]: %s\n", (int) n_a,
-                    _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf),
-                                     NULL));
+  _gnutls_mpi_log ("SRP A: ", A);
 
   _gnutls_mpi_release (&A);
 
-  _gnutls_write_uint16 (n_a, data_a);
-
-  return n_a + 2;
+  return data->length;
 }
 
 
diff --git a/lib/auth_srp.h b/lib/auth_srp.h
index a60217f..f730afc 100644
--- a/lib/auth_srp.h
+++ b/lib/auth_srp.h
@@ -58,8 +58,8 @@ int _gnutls_proc_srp_server_hello (gnutls_session_t state,
 int _gnutls_gen_srp_server_hello (gnutls_session_t state, opaque * data,
                                   size_t data_size);
 
-int _gnutls_gen_srp_server_kx (gnutls_session_t, opaque **);
-int _gnutls_gen_srp_client_kx (gnutls_session_t, opaque **);
+int _gnutls_gen_srp_server_kx (gnutls_session_t, gnutls_buffer_st*);
+int _gnutls_gen_srp_client_kx (gnutls_session_t, gnutls_buffer_st*);
 
 int _gnutls_proc_srp_server_kx (gnutls_session_t, opaque *, size_t);
 int _gnutls_proc_srp_client_kx (gnutls_session_t, opaque *, size_t);
diff --git a/lib/auth_srp_rsa.c b/lib/auth_srp_rsa.c
index d926790..f997c78 100644
--- a/lib/auth_srp_rsa.c
+++ b/lib/auth_srp_rsa.c
@@ -42,7 +42,7 @@
 #include <auth_srp.h>
 #include <gnutls_x509.h>
 
-static int gen_srp_cert_server_kx (gnutls_session_t, opaque **);
+static int gen_srp_cert_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_srp_cert_server_kx (gnutls_session_t, opaque *, size_t);
 
 const mod_auth_st srp_rsa_auth_struct = {
@@ -80,7 +80,7 @@ const mod_auth_st srp_dss_auth_struct = {
 };
 
 static int
-gen_srp_cert_server_kx (gnutls_session_t session, opaque ** data)
+gen_srp_cert_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   ssize_t ret, data_size;
   gnutls_datum_t signature, ddata;
@@ -96,8 +96,8 @@ gen_srp_cert_server_kx (gnutls_session_t session, opaque ** 
data)
     return ret;
 
   data_size = ret;
-  ddata.data = *data;
-  ddata.size = data_size;
+  ddata.data = data->data;
+  ddata.size = data->length;
 
   cred = (gnutls_certificate_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
@@ -122,24 +122,17 @@ gen_srp_cert_server_kx (gnutls_session_t session, opaque 
** data)
                                     &sign_algo)) < 0)
     {
       gnutls_assert ();
-      gnutls_free (*data);
       return ret;
     }
 
-  *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
-  if (*data == NULL)
-    {
-      _gnutls_free_datum (&signature);
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _gnutls_write_datum16 (&(*data)[data_size], signature);
-  data_size += signature.size + 2;
+  ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, 
signature.size);
 
   _gnutls_free_datum (&signature);
 
-  return data_size;
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  return data->length;
 
 }
 
diff --git a/lib/gnutls_auth.h b/lib/gnutls_auth.h
index f4123b6..71c27f0 100644
--- a/lib/gnutls_auth.h
+++ b/lib/gnutls_auth.h
@@ -26,16 +26,18 @@
 #ifndef GNUTLS_AUTH_H
 #define GNUTLS_AUTH_H
 
+#include <gnutls_str.h>
+
 typedef struct mod_auth_st_int
 {
   const char *name;             /* null terminated */
-  int (*gnutls_generate_server_certificate) (gnutls_session_t, opaque **);
-  int (*gnutls_generate_client_certificate) (gnutls_session_t, opaque **);
-  int (*gnutls_generate_server_kx) (gnutls_session_t, opaque **);
-  int (*gnutls_generate_client_kx) (gnutls_session_t, opaque **);       /* 
used in SRP */
-  int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, opaque **);
+  int (*gnutls_generate_server_certificate) (gnutls_session_t, 
gnutls_buffer_st*);
+  int (*gnutls_generate_client_certificate) (gnutls_session_t, 
gnutls_buffer_st*);
+  int (*gnutls_generate_server_kx) (gnutls_session_t, gnutls_buffer_st*);
+  int (*gnutls_generate_client_kx) (gnutls_session_t, gnutls_buffer_st*);      
 /* used in SRP */
+  int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, gnutls_buffer_st 
*);
   int (*gnutls_generate_server_certificate_request) (gnutls_session_t,
-                                                     opaque **);
+                                                     gnutls_buffer_st *);
 
   int (*gnutls_process_server_certificate) (gnutls_session_t, opaque *,
                                             size_t);
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 9111aa4..24e0b83 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -163,45 +163,44 @@ generate_normal_master (gnutls_session_t session, int 
keep_premaster)
 int
 _gnutls_send_server_kx_message (gnutls_session_t session, int again)
 {
-  uint8_t *data = NULL;
-  int data_size = 0;
+  gnutls_buffer_st data;
   int ret = 0;
 
   if (session->internals.auth_struct->gnutls_generate_server_kx == NULL)
     return 0;
 
-  data = NULL;
-  data_size = 0;
+  _gnutls_buffer_init( &data);
 
   if (again == 0)
     {
-      data_size =
+      ret =
         session->internals.auth_struct->gnutls_generate_server_kx (session,
                                                                    &data);
 
-      if (data_size == GNUTLS_E_INT_RET_0)
+      if (ret == GNUTLS_E_INT_RET_0)
         {
           gnutls_assert ();
-          return 0;
+          ret = 0;
+          goto cleanup;
         }
 
-      if (data_size < 0)
+      if (ret < 0)
         {
           gnutls_assert ();
-          return data_size;
+          goto cleanup;
         }
     }
 
-  ret = send_handshake (session, data, data_size,
+  ret = send_handshake (session, data.data, data.length,
                         GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
-  gnutls_free (data);
-
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
     }
-  return data_size;
+  
+cleanup:
+  _gnutls_buffer_clear (&data);
+  return ret;
 }
 
 /* This function sends a certificate request message to the
@@ -210,8 +209,7 @@ _gnutls_send_server_kx_message (gnutls_session_t session, 
int again)
 int
 _gnutls_send_server_certificate_request (gnutls_session_t session, int again)
 {
-  uint8_t *data = NULL;
-  int data_size = 0;
+  gnutls_buffer_st data;
   int ret = 0;
 
   if (session->internals.
@@ -221,32 +219,32 @@ _gnutls_send_server_certificate_request (gnutls_session_t 
session, int again)
   if (session->internals.send_cert_req <= 0)
     return 0;
 
-  data = NULL;
-  data_size = 0;
+  _gnutls_buffer_init( &data);
 
   if (again == 0)
     {
-      data_size =
+      ret =
         session->internals.
         auth_struct->gnutls_generate_server_certificate_request (session,
                                                                  &data);
 
-      if (data_size < 0)
+      if (ret < 0)
         {
           gnutls_assert ();
-          return data_size;
+          goto cleanup;
         }
     }
-  ret = send_handshake (session, data, data_size,
-                        GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
-  gnutls_free (data);
 
+  ret = send_handshake (session, data.data, data.length,
+                        GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
     }
-  return data_size;
+  
+cleanup:
+  _gnutls_buffer_clear (&data);
+  return ret;
 }
 
 
@@ -256,38 +254,34 @@ _gnutls_send_server_certificate_request (gnutls_session_t 
session, int again)
 int
 _gnutls_send_client_kx_message (gnutls_session_t session, int again)
 {
-  uint8_t *data;
-  int data_size;
+  gnutls_buffer_st data;
   int ret = 0;
 
   if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
     return 0;
 
-
-  data = NULL;
-  data_size = 0;
+  _gnutls_buffer_init( &data);
 
   if (again == 0)
     {
-      data_size =
+      ret =
         session->internals.auth_struct->gnutls_generate_client_kx (session,
                                                                    &data);
-      if (data_size < 0)
+      if (ret < 0)
         {
-          gnutls_assert ();
-          return data_size;
+          gnutls_assert();
+          goto cleanup;
         }
     }
-  ret = send_handshake (session, data, data_size,
+  ret = send_handshake (session, data.data, data.length,
                         GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
-  gnutls_free (data);
-
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
     }
-
+  
+cleanup:
+  _gnutls_buffer_clear (&data);
   return ret;
 }
 
@@ -298,9 +292,8 @@ _gnutls_send_client_kx_message (gnutls_session_t session, 
int again)
 int
 _gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
 {
-  uint8_t *data;
+  gnutls_buffer_st data;
   int ret = 0;
-  int data_size;
 
   /* This is a packet that is only sent by the client
    */
@@ -312,6 +305,7 @@ _gnutls_send_client_certificate_verify (gnutls_session_t 
session, int again)
   if (session->key->certificate_requested == 0)
     return 0;
 
+
   if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy ==
       NULL)
     {
@@ -320,27 +314,134 @@ _gnutls_send_client_certificate_verify (gnutls_session_t 
session, int again)
                                  */
     }
 
-  data = NULL;
-  data_size = 0;
+  _gnutls_buffer_init( &data);
 
   if (again == 0)
     {
-      data_size =
+      ret =
         session->internals.
         auth_struct->gnutls_generate_client_cert_vrfy (session, &data);
-      if (data_size < 0)
+      if (ret < 0)
         {
-          gnutls_assert ();
-          return data_size;
+          gnutls_assert();
+          goto cleanup;
         }
-      if (data_size == 0)
-        return 0;
+
+      if (ret == 0)
+          goto cleanup;
 
     }
-  ret = send_handshake (session, data, data_size,
+  ret = send_handshake (session, data.data, data.length,
                         GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
-  gnutls_free (data);
 
+  if (ret < 0)
+    {
+      gnutls_assert ();
+    }
+  
+cleanup:
+  _gnutls_buffer_clear (&data);
+  return ret;
+}
+
+/* This is called when we want send our certificate
+ */
+int
+_gnutls_send_client_certificate (gnutls_session_t session, int again)
+{
+  gnutls_buffer_st data;
+  int ret = 0;
+
+
+  if (session->key->certificate_requested == 0)
+    return 0;
+
+  if (session->internals.auth_struct->gnutls_generate_client_certificate ==
+      NULL)
+    return 0;
+
+  _gnutls_buffer_init( &data);
+
+  if (again == 0)
+    {
+      if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
+          session->internals.selected_cert_list_length > 0)
+        {
+          /* TLS 1.0 or SSL 3.0 with a valid certificate 
+           */
+          ret =
+            session->internals.
+            auth_struct->gnutls_generate_client_certificate (session, &data);
+
+          if (ret < 0)
+            {
+              gnutls_assert();
+              goto cleanup;
+            }
+        }
+    }
+
+  /* In the SSL 3.0 protocol we need to send a
+   * no certificate alert instead of an
+   * empty certificate.
+   */
+  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
+      session->internals.selected_cert_list_length == 0)
+    {
+      ret =
+        gnutls_alert_send (session, GNUTLS_AL_WARNING,
+                           GNUTLS_A_SSL3_NO_CERTIFICATE);
+
+    }
+  else
+    {                           /* TLS 1.0 or SSL 3.0 with a valid certificate 
+                                 */
+      ret = send_handshake (session, data.data, data.length,
+                            GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
+    }
+
+cleanup:
+  _gnutls_buffer_clear (&data);
+  return ret;
+}
+
+
+/* This is called when we want send our certificate
+ */
+int
+_gnutls_send_server_certificate (gnutls_session_t session, int again)
+{
+  gnutls_buffer_st data;
+  int ret = 0;
+
+
+  if (session->internals.auth_struct->gnutls_generate_server_certificate ==
+      NULL)
+    return 0;
+
+  _gnutls_buffer_init( &data);
+
+  if (again == 0)
+    {
+      ret =
+        session->internals.
+        auth_struct->gnutls_generate_server_certificate (session, &data);
+
+        if (ret < 0)
+          {
+            gnutls_assert();
+            goto cleanup;
+          }
+    }
+  ret = send_handshake (session, data.data, data.length,
+                        GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+    }
+  
+cleanup:
+  _gnutls_buffer_clear (&data);
   return ret;
 }
 
@@ -464,116 +565,6 @@ _gnutls_recv_client_kx_message (gnutls_session_t session)
 }
 
 
-/* This is called when we want send our certificate
- */
-int
-_gnutls_send_client_certificate (gnutls_session_t session, int again)
-{
-  uint8_t *data = NULL;
-  int data_size = 0;
-  int ret = 0;
-
-
-  if (session->key->certificate_requested == 0)
-    return 0;
-
-  if (session->internals.auth_struct->gnutls_generate_client_certificate ==
-      NULL)
-    return 0;
-
-  data = NULL;
-  data_size = 0;
-
-  if (again == 0)
-    {
-      if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
-          session->internals.selected_cert_list_length > 0)
-        {
-          /* TLS 1.0 or SSL 3.0 with a valid certificate 
-           */
-          data_size =
-            session->internals.
-            auth_struct->gnutls_generate_client_certificate (session, &data);
-
-          if (data_size < 0)
-            {
-              gnutls_assert ();
-              return data_size;
-            }
-        }
-    }
-
-  /* In the SSL 3.0 protocol we need to send a
-   * no certificate alert instead of an
-   * empty certificate.
-   */
-  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
-      session->internals.selected_cert_list_length == 0)
-    {
-      ret =
-        gnutls_alert_send (session, GNUTLS_AL_WARNING,
-                           GNUTLS_A_SSL3_NO_CERTIFICATE);
-
-    }
-  else
-    {                           /* TLS 1.0 or SSL 3.0 with a valid certificate 
-                                 */
-      ret = send_handshake (session, data, data_size,
-                            GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
-      gnutls_free (data);
-    }
-
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  return data_size;
-}
-
-
-/* This is called when we want send our certificate
- */
-int
-_gnutls_send_server_certificate (gnutls_session_t session, int again)
-{
-  uint8_t *data = NULL;
-  int data_size = 0;
-  int ret = 0;
-
-
-  if (session->internals.auth_struct->gnutls_generate_server_certificate ==
-      NULL)
-    return 0;
-
-  data = NULL;
-  data_size = 0;
-
-  if (again == 0)
-    {
-      data_size =
-        session->internals.
-        auth_struct->gnutls_generate_server_certificate (session, &data);
-
-      if (data_size < 0)
-        {
-          gnutls_assert ();
-          return data_size;
-        }
-    }
-  ret = send_handshake (session, data, data_size,
-                        GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
-  gnutls_free (data);
-
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  return data_size;
-}
 
 
 int
diff --git a/lib/gnutls_str.c b/lib/gnutls_str.c
index 4b6fc63..edcbb86 100644
--- a/lib/gnutls_str.c
+++ b/lib/gnutls_str.c
@@ -100,6 +100,13 @@ _gnutls_buffer_init (gnutls_buffer_st * str)
   str->length = 0;
 }
 
+void _gnutls_buffer_replace_data( gnutls_buffer_st * buf, gnutls_datum_t * 
data)
+{
+    gnutls_free(buf->allocd);
+    buf->allocd = buf->data = data->data;
+    buf->max_length = buf->length = data->size;
+}
+
 void
 _gnutls_buffer_clear (gnutls_buffer_st * str)
 {
@@ -562,11 +569,34 @@ _gnutls_hostname_compare (const char *certname,
 }
 
 int
-_gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size)
+_gnutls_buffer_append_prefix (gnutls_buffer_st * buf, int pfx_size, size_t 
data_size)
 {
   opaque ss[4];
-  _gnutls_write_uint32 (data_size, ss);
-  return _gnutls_buffer_append_data (buf, ss, 4);
+
+  if (pfx_size == 32)
+    {
+      _gnutls_write_uint32 (data_size, ss);
+      pfx_size = 4;
+    }
+  else if (pfx_size == 24)
+    {
+      _gnutls_write_uint24 (data_size, ss);
+      pfx_size = 3;
+    }
+  else if (pfx_size == 16)
+    {
+      _gnutls_write_uint16 (data_size, ss);
+      pfx_size = 2;
+    }
+  else if (pfx_size == 8)
+    {
+      ss[0] = data_size;
+      pfx_size = 1;
+    }
+  else
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  return _gnutls_buffer_append_data (buf, ss, pfx_size);
 }
 
 /* Reads an uint32 number from the buffer. If check is non zero it will also 
check whether
@@ -633,14 +663,44 @@ _gnutls_buffer_pop_datum_prefix (gnutls_buffer_st * buf,
 }
 
 int
-_gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, const void *data,
-                                   size_t data_size)
+_gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, 
+    int pfx_size, const void *data, size_t data_size)
 {
-  _gnutls_buffer_append_prefix (buf, data_size);
+int ret = 0, ret1;
+
+  ret1 = _gnutls_buffer_append_prefix (buf, pfx_size, data_size);
+  if (ret1 < 0)
+    return gnutls_assert_val(ret1);
+
   if (data_size > 0)
-    return _gnutls_buffer_append_data (buf, data, data_size);
+    {
+      ret = _gnutls_buffer_append_data (buf, data, data_size);
 
-  return 0;
+      if (ret < 0)
+        return gnutls_assert_val(ret);
+    }
+
+  return ret + ret1;
+}
+
+int _gnutls_buffer_append_mpi (gnutls_buffer_st * buf, int pfx_size, bigint_t 
mpi, int lz)
+{
+gnutls_datum_t dd;
+int ret;
+
+  if (lz)
+    ret = _gnutls_mpi_dprint_lz (mpi, &dd);
+  else
+    ret = _gnutls_mpi_dprint (mpi, &dd);
+
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  ret = _gnutls_buffer_append_data_prefix(buf, pfx_size, dd.data, dd.size);
+  
+  _gnutls_free_datum(&dd);
+  
+  return ret;
 }
 
 int
diff --git a/lib/gnutls_str.h b/lib/gnutls_str.h
index 1b92815..39d9047 100644
--- a/lib/gnutls_str.h
+++ b/lib/gnutls_str.h
@@ -52,9 +52,13 @@ int _gnutls_buffer_append_data (gnutls_buffer_st *, const 
void *data,
 
 #include <gnutls_num.h>
 
-int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size);
+void _gnutls_buffer_replace_data( gnutls_buffer_st * buf, gnutls_datum_t * 
data);
 
-int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf,
+int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, int pfx_size, size_t 
data_size);
+
+int _gnutls_buffer_append_mpi (gnutls_buffer_st * buf, int pfx_size, bigint_t, 
int lz);
+
+int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, int pfx_size, 
                                        const void *data, size_t data_size);
 void _gnutls_buffer_pop_data (gnutls_buffer_st *, void *, size_t * size);
 void _gnutls_buffer_pop_datum (gnutls_buffer_st *, gnutls_datum_t *,
@@ -103,7 +107,7 @@ int _gnutls_hostname_compare (const char *certname, size_t 
certnamesize,
     }
 
 #define BUFFER_APPEND_PFX(b, x, s) { \
-        ret = _gnutls_buffer_append_data_prefix(b, x, s); \
+        ret = _gnutls_buffer_append_data_prefix(b, 32, x, s); \
         if (ret < 0) { \
             gnutls_assert(); \
             return ret; \
@@ -111,7 +115,7 @@ int _gnutls_hostname_compare (const char *certname, size_t 
certnamesize,
     }
 
 #define BUFFER_APPEND_NUM(b, s) { \
-        ret = _gnutls_buffer_append_prefix(b, s); \
+        ret = _gnutls_buffer_append_prefix(b, 32, s); \
         if (ret < 0) { \
             gnutls_assert(); \
             return ret; \


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]