]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Simplified and made more safe the packing of data for session storage. Extensions use
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 11 Jun 2010 18:17:33 +0000 (20:17 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 13 Jun 2010 19:46:03 +0000 (21:46 +0200)
the internal API to store/retrieve during resumption.

Removed OPRFI since it was never standardized and was never actually included in gnutls
since it was in inactive ifdef. This was instead of rewriting it to use the new API.

47 files changed:
NEWS
doc/cha-gtls-app.texi
lib/auth_srp.c
lib/ext_cert_type.c
lib/ext_cert_type.h
lib/ext_max_record.c
lib/ext_max_record.h
lib/ext_oprfi.c [deleted file]
lib/ext_oprfi.h [deleted file]
lib/ext_safe_renegotiation.c
lib/ext_safe_renegotiation.h
lib/ext_server_name.c
lib/ext_server_name.h
lib/ext_session_ticket.c
lib/ext_session_ticket.h
lib/ext_signature.c
lib/ext_signature.h
lib/ext_srp.c
lib/ext_srp.h
lib/gnutls_buffers.c
lib/gnutls_constate.c
lib/gnutls_extensions.c
lib/gnutls_extensions.h
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_mbuffers.c
lib/gnutls_mbuffers.h
lib/gnutls_record.c
lib/gnutls_session_pack.c
lib/gnutls_state.c
lib/gnutls_str.c
lib/gnutls_str.h
lib/includes/gnutls/compat.h
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
lib/pkcs11.c
lib/x509/dn.c
libextra/ext_inner_application.c
libextra/ext_inner_application.h
libextra/gnutls_extra.c
libextra/gnutls_ia.c
src/cli.c
src/serv.c
tests/Makefile.am
tests/oprfi.c [deleted file]
tests/tlsia.c

diff --git a/NEWS b/NEWS
index 3d947da787a5a368b4453873acdb35de6427708c..5213f18e18caf58d919787bd533c6aa8f3d1af5b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ See the end for copying conditions.
 
 * Version 2.11.0 (unreleased)
 
+** libgnutls: Internal API for extensions augmented to allow
+safe storing and loading of data on resumption. OPRFI extension
+was removed.
+
 ** libgnutls: Added support for DSA-SHA256 and DSA-SHA224
 
 ** libgnutls: Added PKCS #11 support and an API to access objects in
index 13651a442ff57d87b97828150fd0af4d387248a4..a29a0924a582ee8f1e7c18ca327ad951ebb7682b 100644 (file)
@@ -10,7 +10,6 @@
 * Server examples::
 * Miscellaneous examples::
 * Compatibility with the OpenSSL library::
-* Opaque PRF Input TLS Extension::
 * Keying Material Exporters::
 @end menu
 
@@ -454,20 +453,6 @@ Current limitations imposed by the compatibility layer include:
 
 @end itemize
 
-@node Opaque PRF Input TLS Extension
-@section Opaque PRF Input TLS Extension
-@cindex Opaque PRF Input
-
-GnuTLS supports the Opaque PRF Input TLS extension
-(@code{draft-rescorla-tls-opaque-prf-input-00.txt}).  The API consists
-of one API for use in the client, @ref{gnutls_oprfi_enable_client},
-and one API for use in the server, @ref{gnutls_oprfi_enable_server}.
-You must invoke both functions before calling @ref{gnutls_handshake}.
-The server utilizes a callback function into the application.  The
-callback can look at the random string provided by the client, and
-also set the server string.  The string lengths must be equal
-according to the protocol.
-
 @node Keying Material Exporters
 @section Keying Material Exporters
 @cindex Keying Material Exporters
index 8ab237c21a54a2d5b75d4a180265ceb6e798f548..43e463b2aab5734f63fc007d1a59ddbbd712b98c 100644 (file)
@@ -36,6 +36,7 @@
 #include "auth_srp.h"
 #include <gnutls_str.h>
 #include <gnutls_datum.h>
+#include <ext_srp.h>
 
 const mod_auth_st srp_auth_struct = {
   "SRP",
@@ -142,6 +143,16 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
   size_t n_b, tmp_size;
   char buf[64];
   uint8_t *data_b;
+  extension_priv_data_t epriv;
+  srp_ext_st * priv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SRP, &epriv);
+  if (ret < 0) /* peer didn't send a username */
+    {
+      gnutls_assert();
+      return GNUTLS_E_UNKNOWN_SRP_USERNAME;
+    }
+  priv = epriv.ptr;
 
   if ((ret =
        _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
@@ -154,8 +165,7 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
   info = _gnutls_get_auth_info (session);
   username = info->username;
 
-  _gnutls_str_cpy (username, MAX_SRP_USERNAME,
-                  session->security_parameters.extensions.srp_username);
+  _gnutls_str_cpy (username, MAX_SRP_USERNAME, priv->username);
 
   ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);
 
@@ -264,7 +274,16 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
   char *username, *password;
   char buf[64];
   gnutls_srp_client_credentials_t cred;
+  extension_priv_data_t epriv;
+  srp_ext_st * priv;
 
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SRP, &epriv);
+  if (ret < 0) /* peer didn't send a username */
+    {
+      gnutls_assert();
+      return GNUTLS_E_UNKNOWN_SRP_USERNAME;
+    }
+  priv = epriv.ptr;
 
   cred = (gnutls_srp_client_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
@@ -275,15 +294,16 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  if (session->internals.srp_username == NULL)
+  if (priv->username == NULL)
     {
       username = cred->username;
       password = cred->password;
     }
   else
     {
-      username = session->internals.srp_username;
-      password = session->internals.srp_password;
+
+      username = priv->username;
+      password = priv->password;
     }
 
   if (username == NULL || password == NULL)
@@ -716,6 +736,16 @@ _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
   char *username, *password;
   ssize_t data_size = _data_size;
   gnutls_srp_client_credentials_t cred;
+  extension_priv_data_t epriv;
+  srp_ext_st * priv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SRP, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return GNUTLS_E_UNKNOWN_SRP_USERNAME;
+    }
+  priv = epriv.ptr;
 
   cred = (gnutls_srp_client_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
@@ -726,15 +756,15 @@ _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  if (session->internals.srp_username == NULL)
+  if (priv->username == NULL)
     {
       username = cred->username;
       password = cred->password;
     }
   else
     {
-      username = session->internals.srp_username;
-      password = session->internals.srp_password;
+      username = priv->username;
+      password = priv->password;
     }
 
   if (username == NULL || password == NULL)
index 1351092acdeb1706768cd6929cce3afb25062e73..ea98511704280da44c384e6aa163fb298e91b80c 100644 (file)
 #include <gnutls_state.h>
 #include <gnutls_num.h>
 
+/* Maps record size to numbers according to the
+ * extensions draft.
+ */
 inline static int _gnutls_num2cert_type (int num);
 inline static int _gnutls_cert_type2num (int record_size);
+static int _gnutls_cert_type_recv_params (gnutls_session_t session,
+                                  const opaque * data, size_t data_size);
+static int _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
+                                  size_t);
+
+extension_entry_st ext_mod_cert_type = {
+    .name = "CERT TYPE",
+    .type = GNUTLS_EXTENSION_CERT_TYPE,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = _gnutls_cert_type_recv_params,
+    .send_func = _gnutls_cert_type_send_params,
+    .pack_func = NULL,
+    .unpack_func = NULL,
+    .deinit_func = NULL
+};
 
 /* 
  * In case of a server: if a CERT_TYPE extension type is received then it stores
@@ -46,7 +65,7 @@ inline static int _gnutls_cert_type2num (int record_size);
  *
  */
 
-int
+static int
 _gnutls_cert_type_recv_params (gnutls_session_t session,
                               const opaque * data, size_t _data_size)
 {
@@ -142,7 +161,7 @@ _gnutls_cert_type_recv_params (gnutls_session_t session,
 
 /* returns data_size or a negative number on failure
  */
-int
+static int
 _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
                               size_t data_size)
 {
index 3ab9f2a073c57840d8c2fccf5b9616d6e1c00641..dc3b421c4a3382d58c82305abece18638bd7c989 100644 (file)
  *
  */
 
-/* Maps record size to numbers according to the
- * extensions draft.
- */
-int _gnutls_cert_type_recv_params (gnutls_session_t session,
-                                  const opaque * data, size_t data_size);
-int _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
-                                  size_t);
+#ifndef EXT_CERT_TYPE_H
+#define EXT_CERT_TYPE_H
+
+#include <gnutls_extensions.h>
+
+extern extension_entry_st ext_mod_cert_type;
+
+#endif
index 32bc918dba9ab5c9f76260aee59970392f3c9e14..98326686b2acae55086d983eae22cdc2943f1f5b 100644 (file)
 #include "gnutls_int.h"
 #include "gnutls_errors.h"
 #include "gnutls_num.h"
+#include <gnutls_extensions.h>
 #include <ext_max_record.h>
 
+static int _gnutls_max_record_recv_params (gnutls_session_t session,
+                                   const opaque * data, size_t data_size);
+static int _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
+                                   size_t);
+
+static int _gnutls_max_record_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static int _gnutls_max_record_pack(extension_priv_data_t _priv, gnutls_buffer_st* ps);
+
+/* Maps record size to numbers according to the
+ * extensions draft.
+ */
+static int _gnutls_mre_num2record (int num);
+static int _gnutls_mre_record2num (uint16_t record_size);
+
+
+extension_entry_st ext_mod_max_record_size = {
+    .name = "MAX RECORD SIZE",
+    .type = GNUTLS_EXTENSION_MAX_RECORD_SIZE,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = _gnutls_max_record_recv_params,
+    .send_func = _gnutls_max_record_send_params,
+    .pack_func = _gnutls_max_record_pack,
+    .unpack_func = _gnutls_max_record_unpack,
+    .deinit_func = NULL
+};
+
 /* 
  * In case of a server: if a MAX_RECORD_SIZE extension type is received then it stores
  * into the session the new value. The server may use gnutls_get_max_record_size(),
  *
  */
 
-int
+static int
 _gnutls_max_record_recv_params (gnutls_session_t session,
                                const opaque * data, size_t _data_size)
 {
   ssize_t new_size;
   ssize_t data_size = _data_size;
+  extension_priv_data_t epriv;
+  int ret;
 
   if (session->security_parameters.entity == GNUTLS_SERVER)
     {
@@ -66,10 +96,17 @@ _gnutls_max_record_recv_params (gnutls_session_t session,
        }
     }
   else
-    {                          /* CLIENT SIDE - we must check if the sent record size is the right one 
-                                */
+    {  /* CLIENT SIDE - we must check if the sent record size is the right one 
+        */
       if (data_size > 0)
        {
+         ret = _gnutls_ext_get_session_data( session, 
+           GNUTLS_EXTENSION_MAX_RECORD_SIZE, &epriv);
+         if (ret < 0)
+           {
+               gnutls_assert();
+               return GNUTLS_E_INTERNAL_ERROR;
+           }
 
          if (data_size != 1)
            {
@@ -79,8 +116,7 @@ _gnutls_max_record_recv_params (gnutls_session_t session,
 
          new_size = _gnutls_mre_num2record (data[0]);
 
-         if (new_size < 0
-             || new_size != session->internals.proposed_record_size)
+         if (new_size < 0 || new_size != epriv.num)
            {
              gnutls_assert ();
              return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
@@ -88,7 +124,7 @@ _gnutls_max_record_recv_params (gnutls_session_t session,
          else
            {
              session->security_parameters.max_record_recv_size =
-               session->internals.proposed_record_size;
+               epriv.num;
            }
 
        }
@@ -101,16 +137,26 @@ _gnutls_max_record_recv_params (gnutls_session_t session,
 
 /* returns data_size or a negative number on failure
  */
-int
+static int
 _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
                                size_t data_size)
 {
   uint16_t len;
+  int ret;
+   
   /* this function sends the client extension data (dnsname) */
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
+      extension_priv_data_t epriv;
+      
+      ret = _gnutls_ext_get_session_data( session, 
+       GNUTLS_EXTENSION_MAX_RECORD_SIZE, &epriv);
+      if (ret < 0) /* it is ok not to have it */
+        {
+         return 0;
+       }
 
-      if (session->internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE)
+      if (epriv.num != DEFAULT_MAX_RECORD_SIZE)
        {
          len = 1;
          if (data_size < len)
@@ -120,8 +166,7 @@ _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
            }
 
          data[0] =
-           (uint8_t) _gnutls_mre_record2num (session->
-                                             internals.proposed_record_size);
+           (uint8_t) _gnutls_mre_record2num (epriv.num);
          return len;
        }
 
@@ -152,10 +197,36 @@ _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
   return 0;
 }
 
+
+static int _gnutls_max_record_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+int ret;
+
+  BUFFER_APPEND_NUM(ps, epriv.num);
+
+  return 0;
+   
+}
+
+static int _gnutls_max_record_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+extension_priv_data_t epriv;
+int ret;
+
+  BUFFER_POP_NUM(ps, epriv.num);
+  
+  *_priv = epriv;
+  
+  ret = 0;  
+error:
+  return ret;
+}
+
+
 /* Maps numbers to record sizes according to the
  * extensions draft.
  */
-int
+static int
 _gnutls_mre_num2record (int num)
 {
   switch (num)
@@ -176,7 +247,7 @@ _gnutls_mre_num2record (int num)
 /* Maps record size to numbers according to the
  * extensions draft.
  */
-int
+static int
 _gnutls_mre_record2num (uint16_t record_size)
 {
   switch (record_size)
@@ -194,3 +265,67 @@ _gnutls_mre_record2num (uint16_t record_size)
     }
 
 }
+
+/**
+ * gnutls_record_get_max_size:
+ * @session: is a #gnutls_session_t structure.
+ *
+ * Get the record size.  The maximum record size is negotiated by the
+ * client after the first handshake message.
+ *
+ * Returns: The maximum record packet size in this connection.
+ **/
+size_t
+gnutls_record_get_max_size (gnutls_session_t session)
+{
+  /* Recv will hold the negotiated max record size
+   * always.
+   */
+  return session->security_parameters.max_record_recv_size;
+}
+
+
+/**
+ * gnutls_record_set_max_size:
+ * @session: is a #gnutls_session_t structure.
+ * @size: is the new size
+ *
+ * This function sets the maximum record packet size in this
+ * connection.  This property can only be set to clients.  The server
+ * may choose not to accept the requested size.
+ *
+ * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
+ * 4096(=2^12).  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.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
+ *   otherwise an error code is returned.
+ **/
+ssize_t
+gnutls_record_set_max_size (gnutls_session_t session, size_t size)
+{
+  ssize_t new_size;
+  extension_priv_data_t epriv;
+
+  if (session->security_parameters.entity == GNUTLS_SERVER)
+    return GNUTLS_E_INVALID_REQUEST;
+
+  new_size = _gnutls_mre_record2num (size);
+
+  if (new_size < 0)
+    {
+      gnutls_assert ();
+      return new_size;
+    }
+
+  session->security_parameters.max_record_send_size = size;
+  epriv.num = size;
+
+  _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_MAX_RECORD_SIZE, epriv);
+
+  return 0;
+}
index bfc465fa3648c81774a61f0f30a365cba82b786b..d159b278150168b62976a40847b2eb1ccd0d6599 100644 (file)
  *
  */
 
-/* Maps record size to numbers according to the
- * extensions draft.
- */
-int _gnutls_mre_num2record (int num);
-int _gnutls_mre_record2num (uint16_t record_size);
-int _gnutls_max_record_recv_params (gnutls_session_t session,
-                                   const opaque * data, size_t data_size);
-int _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
-                                   size_t);
+#ifndef EXT_MAX_RECORD_H
+#define EXT_MAX_RECORD_H
+
+#include <gnutls_extensions.h>
+
+extern extension_entry_st ext_mod_max_record_size;
+
+#endif
diff --git a/lib/ext_oprfi.c b/lib/ext_oprfi.c
deleted file mode 100644 (file)
index 1fad660..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
- *
- * Author: Simon Josefsson
- *
- * This file is part of GnuTLS.
- *
- * The GnuTLS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA
- *
- */
-
-/* Implementation of Opaque PRF Input:
- * http://tools.ietf.org/id/draft-rescorla-tls-opaque-prf-input-00.txt
- *
- */
-
-#include <ext_oprfi.h>
-
-#include <gnutls_errors.h>
-#include <gnutls_num.h>
-
-int
-oprfi_recv_server (gnutls_session_t session,
-                  const opaque * data, size_t _data_size)
-{
-  ssize_t data_size = _data_size;
-  uint16_t len;
-  int ret;
-
-  if (!session->internals.oprfi_cb)
-    {
-      gnutls_assert ();
-      return 0;
-    }
-
-  DECR_LEN (data_size, 2);
-  len = _gnutls_read_uint16 (data);
-  data += 2;
-
-  if (len != data_size)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
-    }
-
-  /* Store incoming data. */
-  session->security_parameters.extensions.oprfi_client_len = len;
-  session->security_parameters.extensions.oprfi_client = gnutls_malloc (len);
-  if (!session->security_parameters.extensions.oprfi_client)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-  memcpy (session->security_parameters.extensions.oprfi_client, data, len);
-
-  return 0;
-}
-
-int
-oprfi_recv_client (gnutls_session_t session,
-                  const opaque * data, size_t _data_size)
-{
-  ssize_t data_size = _data_size;
-  uint16_t len;
-  int ret;
-
-  if (session->security_parameters.extensions.oprfi_client == NULL)
-    {
-      gnutls_assert ();
-      return 0;
-    }
-
-  DECR_LEN (data_size, 2);
-  len = _gnutls_read_uint16 (data);
-  data += 2;
-
-  if (len != data_size)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
-    }
-
-  if (len != session->security_parameters.extensions.oprfi_client_len)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
-    }
-
-  /* Store incoming data. */
-  session->security_parameters.extensions.oprfi_server_len = len;
-  session->security_parameters.extensions.oprfi_server = gnutls_malloc (len);
-  if (!session->security_parameters.extensions.oprfi_server)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-  memcpy (session->security_parameters.extensions.oprfi_server, data, len);
-
-  return 0;
-}
-
-int
-_gnutls_oprfi_recv_params (gnutls_session_t session,
-                          const opaque * data, size_t data_size)
-{
-  if (session->security_parameters.entity == GNUTLS_CLIENT)
-    return oprfi_recv_client (session, data, data_size);
-  else
-    return oprfi_recv_server (session, data, data_size);
-}
-
-int
-oprfi_send_client (gnutls_session_t session, opaque * data, size_t _data_size)
-{
-  opaque *p = data;
-  ssize_t data_size = _data_size;
-  int oprf_size = session->security_parameters.extensions.oprfi_client_len;
-
-  if (oprf_size == 0)
-    return 0;
-
-  DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
-  _gnutls_write_uint16 (oprf_size, p);
-  p += 2;
-
-  DECR_LENGTH_RET (data_size, oprf_size, GNUTLS_E_SHORT_MEMORY_BUFFER);
-
-  memcpy (p, session->security_parameters.extensions.oprfi_client, oprf_size);
-
-  return 2 + oprf_size;
-}
-
-int
-oprfi_send_server (gnutls_session_t session, opaque * data, size_t _data_size)
-{
-  opaque *p = data;
-  int ret;
-  ssize_t data_size = _data_size;
-  size_t len;
-
-  if (!session->security_parameters.extensions.oprfi_client ||
-      !session->internals.oprfi_cb)
-    return 0;
-
-  /* Allocate buffer for outgoing data. */
-  session->security_parameters.extensions.oprfi_server_len =
-    session->security_parameters.extensions.oprfi_client_len;
-  session->security_parameters.extensions.oprfi_server =
-    gnutls_malloc (session->security_parameters.extensions.oprfi_server_len);
-  if (!session->security_parameters.extensions.oprfi_server)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  /* Get outgoing data. */
-  ret = session->internals.oprfi_cb
-    (session, session->internals.oprfi_userdata,
-     session->security_parameters.extensions.oprfi_client_len,
-     session->security_parameters.extensions.oprfi_client,
-     session->security_parameters.extensions.oprfi_server);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      gnutls_free (session->security_parameters.extensions.oprfi_server);
-      return ret;
-    }
-
-  DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
-  _gnutls_write_uint16 (session->security_parameters.extensions.
-                       oprfi_server_len, p);
-  p += 2;
-
-  DECR_LENGTH_RET (data_size,
-                  session->security_parameters.extensions.oprfi_server_len,
-                  GNUTLS_E_SHORT_MEMORY_BUFFER);
-
-  memcpy (p, session->security_parameters.extensions.oprfi_server,
-         session->security_parameters.extensions.oprfi_server_len);
-
-  return 2 + session->security_parameters.extensions.oprfi_server_len;
-}
-
-int
-_gnutls_oprfi_send_params (gnutls_session_t session,
-                          opaque * data, size_t data_size)
-{
-  if (session->security_parameters.entity == GNUTLS_CLIENT)
-    return oprfi_send_client (session, data, data_size);
-  else
-    return oprfi_send_server (session, data, data_size);
-}
-
-/**
- * gnutls_oprfi_enable_client:
- * @session: is a #gnutls_session_t structure.
- * @len: length of Opaque PRF data to use in client.
- * @data: Opaque PRF data to use in client.
- *
- * Request that the client should attempt to negotiate the Opaque PRF
- * Input TLS extension, using the given data as the client's Opaque
- * PRF input.
- *
- * The data is copied into the session context after this call, so you
- * may de-allocate it immediately after calling this function.
- **/
-void
-gnutls_oprfi_enable_client (gnutls_session_t session,
-                           size_t len, unsigned char *data)
-{
-  session->security_parameters.extensions.oprfi_client_len = len;
-  session->security_parameters.extensions.oprfi_client = data;
-}
-
-/**
- * gnutls_oprfi_enable_server:
- * @session: is a #gnutls_session_t structure.
- * @cb: function pointer to Opaque PRF extension server callback.
- * @userdata: hook passed to callback function for passing application state.
- *
- * Request that the server should attempt to accept the Opaque PRF
- * Input TLS extension.  If the client requests the extension, the
- * provided callback @cb will be invoked.  The callback must have the
- * following prototype:
- *
- * int callback (gnutls_session_t session, void *userdata,
- *               size_t oprfi_len, const unsigned char *in_oprfi,
- *               unsigned char *out_oprfi);
- *
- * The callback can inspect the client-provided data in the input
- * parameters, and specify its own opaque prf input data in the output
- * variable.  The function must return 0 on success, otherwise the
- * handshake will be aborted.
- **/
-void
-gnutls_oprfi_enable_server (gnutls_session_t session,
-                           gnutls_oprfi_callback_func cb, void *userdata)
-{
-  session->internals.oprfi_cb = cb;
-  session->internals.oprfi_userdata = userdata;
-}
diff --git a/lib/ext_oprfi.h b/lib/ext_oprfi.h
deleted file mode 100644 (file)
index 3df9d12..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
- *
- * Author: Simon Josefsson
- *
- * This file is part of GnuTLS.
- *
- * The GnuTLS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA
- *
- */
-
-#include <gnutls_int.h>
-
-int _gnutls_oprfi_recv_params (gnutls_session_t state,
-                              const opaque * data, size_t data_size);
-
-int _gnutls_oprfi_send_params (gnutls_session_t state,
-                              opaque * data, size_t data_size);
index 14392b34ab82ef46198c20c2cc14b5f5b2b20848..1e67f3831a15d36c5f93b25621557cae8ea95e16 100644 (file)
 #include <ext_safe_renegotiation.h>
 #include <gnutls_errors.h>
 
-int
-_gnutls_safe_renegotiation_recv_params (gnutls_session_t session,
+
+static int _gnutls_sr_recv_params (gnutls_session_t state,
+                                           const opaque * data,
+                                           size_t data_size);
+static int _gnutls_sr_send_params (gnutls_session_t state,
+                                           opaque * data, size_t);
+static int _gnutls_sr_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps);
+static int _gnutls_sr_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static void _gnutls_sr_deinit_data(extension_priv_data_t priv);
+
+extension_entry_st ext_mod_sr = {
+    .name = "SAFE RENEGOTIATION",
+    .type = GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
+    .parse_type = GNUTLS_EXT_MANDATORY,
+
+    .recv_func = _gnutls_sr_recv_params,
+    .send_func = _gnutls_sr_send_params,
+    .pack_func = NULL,
+    .unpack_func = NULL,
+    .deinit_func = _gnutls_sr_deinit_data,
+};
+
+int _gnutls_ext_sr_finished( gnutls_session_t session, void* vdata, size_t vdata_size, int dir)
+{
+int ret;
+sr_ext_st* priv;
+extension_priv_data_t epriv;
+
+  if (session->internals.priorities.sr == SR_DISABLED)
+    {
+      return 0;
+    }
+
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
+
+  /* Save data for safe renegotiation. 
+   */
+  if (vdata_size > MAX_VERIFY_DATA_SIZE)
+   {
+     gnutls_assert ();
+     return GNUTLS_E_INTERNAL_ERROR;
+   }
+
+  if ((session->security_parameters.entity == GNUTLS_CLIENT && dir == 0) ||
+    (session->security_parameters.entity == GNUTLS_SERVER && dir == 1))
+    {
+       priv->client_verify_data_len = vdata_size;
+       memcpy (priv->client_verify_data, vdata, vdata_size);
+    }
+  else
+    {
+       priv->server_verify_data_len = vdata_size;
+       memcpy (priv->server_verify_data, vdata, vdata_size);
+    }
+
+  return 0;
+}
+
+int _gnutls_ext_sr_verify(gnutls_session_t session)
+{
+int ret;
+sr_ext_st* priv = NULL;
+extension_priv_data_t epriv;
+
+  if (session->internals.priorities.sr == SR_DISABLED)
+    {
+      gnutls_assert ();
+      return 0;
+    }
+
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret >= 0)
+    priv = epriv.ptr;
+
+  /* Safe renegotiation */
+
+  if (priv && priv->safe_renegotiation_received)
+    {
+      if ((priv->ri_extension_data_len < priv->client_verify_data_len) ||
+         (memcmp (priv->ri_extension_data,
+                  priv->client_verify_data, priv->client_verify_data_len)))
+        {
+          gnutls_assert ();
+          _gnutls_handshake_log ("HSK[%p]: Safe renegotiation failed [1]\n",
+                     session);
+          return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
+        }
+
+      if (session->security_parameters.entity == GNUTLS_CLIENT)
+        {
+          if ((priv->ri_extension_data_len !=
+               priv->client_verify_data_len + priv->server_verify_data_len) ||
+              memcmp (priv->ri_extension_data + priv->client_verify_data_len,
+                  priv->server_verify_data,
+                  priv->server_verify_data_len) != 0)
+            {
+              gnutls_assert ();
+              _gnutls_handshake_log
+            ("HSK[%p]: Safe renegotiation failed [2]\n", session);
+              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
+            }
+        }
+      else                     /* Make sure there are 0 extra bytes */
+        {
+          if (priv->ri_extension_data_len != priv->client_verify_data_len)
+            {
+              gnutls_assert ();
+              _gnutls_handshake_log
+            ("HSK[%p]: Safe renegotiation failed [3]\n", session);
+              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
+            }
+        }
+
+      _gnutls_handshake_log ("HSK[%p]: Safe renegotiation succeeded\n",
+                            session);
+    }
+  else /* safe renegotiation not received... */
+    {
+      if (priv && priv->connection_using_safe_renegotiation)
+        {
+          gnutls_assert ();
+          _gnutls_handshake_log
+            ("HSK[%p]: Peer previously asked for safe renegotiation\n",
+             session);
+          return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
+        }
+
+      /* Clients can't tell if it's an initial negotiation */
+      if (session->internals.initial_negotiation_completed)
+        {
+          if (session->internals.priorities.sr < SR_PARTIAL)
+            {
+              _gnutls_handshake_log
+            ("HSK[%p]: Allowing unsafe (re)negotiation\n", session);
+            }
+          else
+            {
+              gnutls_assert ();
+              _gnutls_handshake_log
+            ("HSK[%p]: Denying unsafe (re)negotiation\n", session);
+                  return GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED;
+            }
+        }
+      else
+        {
+          if (session->internals.priorities.sr < SR_SAFE)
+            {
+              _gnutls_handshake_log
+            ("HSK[%p]: Allowing unsafe initial negotiation\n", session);
+            }
+          else
+            {
+              gnutls_assert ();
+              _gnutls_handshake_log
+            ("HSK[%p]: Denying unsafe initial negotiation\n", session);
+              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
+            }
+        }
+    }
+    
+    return 0;
+}
+
+/* if a server received the special ciphersuite.
+ */
+int _gnutls_ext_sr_recv_cs(gnutls_session_t session)
+{
+  int ret, set = 0;
+  sr_ext_st* priv;
+  extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret < 0)
+    {
+      set = 1;
+    }
+  else if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  if (set != 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+             gnutls_assert();
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+      epriv.ptr = priv;
+    }
+  else
+    priv = epriv.ptr;
+    
+  priv->safe_renegotiation_received = 1;
+  priv->connection_using_safe_renegotiation = 1;
+
+  if (set != 0)
+    _gnutls_ext_set_session_data( session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
+
+  return 0;    
+}
+
+static int
+_gnutls_sr_recv_params (gnutls_session_t session,
                                        const opaque * data,
                                        size_t _data_size)
 {
-  tls_ext_st *ext = &session->security_parameters.extensions;
   int len = data[0];
   ssize_t data_size = _data_size;
+  sr_ext_st* priv;
+  extension_priv_data_t epriv;
+  int set = 0, ret;
 
   DECR_LEN (data_size, len + 1 /* count the first byte and payload */ );
 
@@ -43,38 +258,65 @@ _gnutls_safe_renegotiation_recv_params (gnutls_session_t session,
       return 0;
     }
 
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret < 0 && session->security_parameters.entity == GNUTLS_SERVER)
+    {
+      set = 1;
+    }
+  else if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  if (set != 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+             gnutls_assert();
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+      epriv.ptr = priv;
+    }
+  else
+    priv = epriv.ptr;
+
   /* It is not legal to receive this extension on a renegotiation and
    * not receive it on the initial negotiation.
    */
   if (session->internals.initial_negotiation_completed != 0 &&
-      session->internals.connection_using_safe_renegotiation == 0)
+      priv->connection_using_safe_renegotiation == 0)
     {
       gnutls_assert ();
       return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
     }
 
-  if (len > sizeof (ext->ri_extension_data))
+  if (len > sizeof (priv->ri_extension_data))
     {
       gnutls_assert ();
       return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
     }
 
   if (len > 0)
-    memcpy (ext->ri_extension_data, &data[1], len);
-  ext->ri_extension_data_len = len;
+    memcpy (priv->ri_extension_data, &data[1], len);
+  priv->ri_extension_data_len = len;
 
   /* "safe renegotiation received" means on *this* handshake; "connection using
    * safe renegotiation" means that the initial hello received on the connection
    * indicated safe renegotiation.
    */
-  session->internals.safe_renegotiation_received = 1;
-  session->internals.connection_using_safe_renegotiation = 1;
+  priv->safe_renegotiation_received = 1;
+  priv->connection_using_safe_renegotiation = 1;
 
+  if (set != 0)
+    _gnutls_ext_set_session_data( session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
   return 0;
 }
 
-int
-_gnutls_safe_renegotiation_send_params (gnutls_session_t session,
+static int
+_gnutls_sr_send_params (gnutls_session_t session,
                                        opaque * data, size_t _data_size)
 {
   /* The format of this extension is a one-byte length of verify data followed
@@ -83,7 +325,9 @@ _gnutls_safe_renegotiation_send_params (gnutls_session_t session,
    * the minimum extension is one byte: 0x00.
    */
   ssize_t data_size = _data_size;
-  tls_ext_st *ext = &session->security_parameters.extensions;
+  sr_ext_st* priv;
+  int ret, set = 0;
+  extension_priv_data_t epriv;
 
   if (session->internals.priorities.sr == SR_DISABLED)
     {
@@ -91,31 +335,52 @@ _gnutls_safe_renegotiation_send_params (gnutls_session_t session,
       return 0;
     }
 
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret < 0)
+    {
+      set = 1;
+    }
+
+  if (set != 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+             gnutls_assert();
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+      epriv.ptr = priv;
+     
+      _gnutls_ext_set_session_data( session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
+    }
+  else
+    priv = epriv.ptr;
+
   data[0] = 0;
 
   /* Always offer the extension if we're a client */
-  if (session->internals.connection_using_safe_renegotiation ||
+  if (priv->connection_using_safe_renegotiation ||
       session->security_parameters.entity == GNUTLS_CLIENT)
     {
       DECR_LEN (data_size, 1);
-      data[0] = ext->client_verify_data_len;
+      data[0] = priv->client_verify_data_len;
 
-      DECR_LEN (data_size, ext->client_verify_data_len);
+      DECR_LEN (data_size, priv->client_verify_data_len);
 
-      if (ext->client_verify_data_len > 0)
-       memcpy (&data[1], ext->client_verify_data,
-               ext->client_verify_data_len);
+      if (priv->client_verify_data_len > 0)
+        memcpy (&data[1], priv->client_verify_data, priv->client_verify_data_len);
 
       if (session->security_parameters.entity == GNUTLS_SERVER)
-       {
-         data[0] += ext->server_verify_data_len;
+           {
+             data[0] += priv->server_verify_data_len;
 
-         DECR_LEN (data_size, ext->server_verify_data_len);
+             DECR_LEN (data_size, priv->server_verify_data_len);
 
-         if (ext->server_verify_data_len > 0)
-           memcpy (&data[1 + ext->client_verify_data_len],
-                   ext->server_verify_data, ext->server_verify_data_len);
-       }
+          if (priv->server_verify_data_len > 0)
+            memcpy (&data[1 + priv->client_verify_data_len],
+                priv->server_verify_data, priv->server_verify_data_len);
+        }
     }
   else
     return 0;
@@ -123,6 +388,58 @@ _gnutls_safe_renegotiation_send_params (gnutls_session_t session,
   return 1 + data[0];          /* don't forget the length byte */
 }
 
+static void _gnutls_sr_deinit_data(extension_priv_data_t priv)
+{
+    gnutls_free(priv.ptr);
+}
+
+#if 0
+
+static int _gnutls_sr_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+sr_ext_st* priv = epriv.ptr;
+int ret;
+
+  BUFFER_APPEND_PFX(ps, priv->client_verify_data, priv->client_verify_data_len);
+  BUFFER_APPEND_PFX(ps, priv->server_verify_data, priv->server_verify_data_len);
+  BUFFER_APPEND_PFX(ps, priv->ri_extension_data, priv->ri_extension_data_len);
+  
+  return 0;
+}
+
+static int _gnutls_sr_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+sr_ext_st* priv;
+int ret;
+extension_priv_data_t epriv;
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  BUFFER_POP_NUM(ps, priv->client_verify_data_len);
+  BUFFER_POP(ps, priv->client_verify_data, priv->client_verify_data_len);
+
+  BUFFER_POP_NUM(ps, priv->server_verify_data_len);
+  BUFFER_POP(ps, priv->server_verify_data, priv->server_verify_data_len);
+
+  BUFFER_POP_NUM(ps, priv->ri_extension_data_len);
+  BUFFER_POP(ps, priv->ri_extension_data, priv->ri_extension_data_len);
+  
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
+  ret = 0;
+
+error:
+  return ret;
+}
+
+#endif
+
 /**
  * gnutls_safe_renegotiation_status:
  * @session: is a #gnutls_session_t structure.
@@ -138,5 +455,19 @@ _gnutls_safe_renegotiation_send_params (gnutls_session_t session,
 int
 gnutls_safe_renegotiation_status (gnutls_session_t session)
 {
-  return session->internals.connection_using_safe_renegotiation;
+int ret;
+sr_ext_st* priv;
+extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data( session, 
+    GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return 0;
+    }
+  priv = epriv.ptr;
+
+  return priv->connection_using_safe_renegotiation;
 }
+
index ca4fb7a92cd86a60b29cec1a8f64947259cf95e7..f79cca3db57cb2c98efec2a5ccbb0457eeeb3e68 100644 (file)
 #ifndef EXT_SAFE_RENEGOTIATION_H
 # define EXT_SAFE_RENEGOTIATION_H
 
-int _gnutls_safe_renegotiation_recv_params (gnutls_session_t state,
-                                           const opaque * data,
-                                           size_t data_size);
-int _gnutls_safe_renegotiation_send_params (gnutls_session_t state,
-                                           opaque * data, size_t);
+#include <gnutls_extensions.h>
+
+typedef struct {
+  uint8_t client_verify_data[MAX_VERIFY_DATA_SIZE];
+  size_t client_verify_data_len;
+  uint8_t server_verify_data[MAX_VERIFY_DATA_SIZE];
+  size_t server_verify_data_len;
+  uint8_t ri_extension_data[MAX_VERIFY_DATA_SIZE * 2];  /* max signal is 72 bytes in s->c sslv3 */
+  size_t ri_extension_data_len;
+
+  int safe_renegotiation_received:1;
+  int initial_negotiation_completed:1;
+  int connection_using_safe_renegotiation:1;
+} sr_ext_st;
+
+extern extension_entry_st ext_mod_sr;
+
+int _gnutls_ext_sr_finished( gnutls_session_t session, void* vdata, 
+    size_t vdata_size, int dir);
+int _gnutls_ext_sr_recv_cs(gnutls_session_t session);
+int _gnutls_ext_sr_verify(gnutls_session_t session);
 
 #endif /* EXT_SAFE_RENEGOTIATION_H */
index 85ff9107bd7e8b0f680576a050d2114465d4ebfe..7b2face4bb6f27e590149c7db9c301f4d6b60a5f 100644 (file)
 #include "gnutls_num.h"
 #include <ext_server_name.h>
 
+static int _gnutls_server_name_recv_params (gnutls_session_t session,
+                                    const opaque * data, size_t data_size);
+static int _gnutls_server_name_send_params (gnutls_session_t session,
+                                    opaque * data, size_t);
+
+static int _gnutls_server_name_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static int _gnutls_server_name_pack(extension_priv_data_t _priv, gnutls_buffer_st* ps);
+static void _gnutls_server_name_deinit_data(extension_priv_data_t priv);
+
+
+extension_entry_st ext_mod_server_name = {
+    .name = "SERVER NAME",
+    .type = GNUTLS_EXTENSION_SERVER_NAME,
+    .parse_type = GNUTLS_EXT_APPLICATION,
+
+    .recv_func = _gnutls_server_name_recv_params,
+    .send_func = _gnutls_server_name_send_params,
+    .pack_func = _gnutls_server_name_pack,
+    .unpack_func = _gnutls_server_name_unpack,
+    .deinit_func = _gnutls_server_name_deinit_data,
+};
+
 /*
  * In case of a server: if a NAME_DNS extension type is received then
  * it stores into the session the value of NAME_DNS. The server may
@@ -38,9 +60,7 @@
  * in the session then it sends the extension to the peer.
  *
  */
-
-int
-_gnutls_server_name_recv_params (gnutls_session_t session,
+static int _gnutls_server_name_recv_params (gnutls_session_t session,
                                 const opaque * data, size_t _data_size)
 {
   int i;
@@ -48,7 +68,9 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
   uint16_t len, type;
   ssize_t data_size = _data_size;
   int server_names = 0;
-
+  server_name_ext_st* priv;
+  extension_priv_data_t epriv;
+  
   if (session->security_parameters.entity == GNUTLS_SERVER)
     {
       DECR_LENGTH_RET (data_size, 2, 0);
@@ -98,11 +120,17 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
          server_names = MAX_SERVER_NAME_EXTENSIONS;
        }
 
-      session->security_parameters.extensions.server_names_size =
-       server_names;
       if (server_names == 0)
        return 0;               /* no names found */
 
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+           gnutls_assert();
+           return GNUTLS_E_MEMORY_ERROR;
+       }
+
+      priv->server_names_size = server_names;
 
       p = data + 2;
       for (i = 0; i < server_names; i++)
@@ -115,15 +143,12 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
 
          switch (type)
            {
-           case 0:             /* NAME_DNS */
+           case 0: /* NAME_DNS */
              if (len <= MAX_SERVER_NAME_SIZE)
                {
-                 memcpy (session->security_parameters.
-                         extensions.server_names[i].name, p, len);
-                 session->security_parameters.extensions.server_names[i].
-                   name_length = len;
-                 session->security_parameters.extensions.server_names[i].
-                   type = GNUTLS_NAME_DNS;
+                 memcpy (priv->server_names[i].name, p, len);
+                 priv->server_names[i].name_length = len;
+                 priv->server_names[i].type = GNUTLS_NAME_DNS;
                  break;
                }
            }
@@ -131,13 +156,18 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
          /* move to next record */
          p += len;
        }
+
+      epriv.ptr = priv;
+      _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SERVER_NAME, epriv);
+
     }
+
   return 0;
 }
 
 /* returns data_size or a negative number on failure
  */
-int
+static int
 _gnutls_server_name_send_params (gnutls_session_t session,
                                 opaque * data, size_t _data_size)
 {
@@ -145,27 +175,33 @@ _gnutls_server_name_send_params (gnutls_session_t session,
   opaque *p;
   unsigned i;
   ssize_t data_size = _data_size;
-  int total_size = 0;
+  int total_size = 0, ret;
+  server_name_ext_st* priv;
+  extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SERVER_NAME, &epriv);
+  if (ret < 0)
+    return 0;
+
 
   /* this function sends the client extension data (dnsname)
    */
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
+      priv = epriv.ptr;
 
-      if (session->security_parameters.extensions.server_names_size == 0)
+      if (priv->server_names_size == 0)
        return 0;
 
       /* uint16_t
        */
       total_size = 2;
       for (i = 0;
-          i < session->security_parameters.extensions.server_names_size; i++)
+          i < priv->server_names_size; i++)
        {
          /* count the total size
           */
-         len =
-           session->security_parameters.extensions.
-           server_names[i].name_length;
+         len = priv->server_names[i].name_length;
 
          /* uint8_t + uint16_t + size
           */
@@ -179,19 +215,14 @@ _gnutls_server_name_send_params (gnutls_session_t session,
       DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
       _gnutls_write_uint16 (total_size - 2, p);
       p += 2;
-
       for (i = 0;
-          i < session->security_parameters.extensions.server_names_size; i++)
+          i < priv->server_names_size; i++)
        {
 
-         switch (session->security_parameters.extensions.server_names[i].
-                 type)
+         switch (priv->server_names[i].type)
            {
            case GNUTLS_NAME_DNS:
-
-             len =
-               session->security_parameters.extensions.server_names[i].
-               name_length;
+             len = priv->server_names[i].name_length;
              if (len == 0)
                break;
 
@@ -208,9 +239,7 @@ _gnutls_server_name_send_params (gnutls_session_t session,
              _gnutls_write_uint16 (len, p);
              p += 2;
 
-             memcpy (p,
-                     session->security_parameters.extensions.server_names[i].
-                     name, len);
+             memcpy (p, priv->server_names[i].name, len);
              p += len;
              break;
            default:
@@ -257,28 +286,37 @@ gnutls_server_name_get (gnutls_session_t session, void *data,
                        unsigned int *type, unsigned int indx)
 {
   char *_data = data;
+  server_name_ext_st* priv;
+  int ret;
+  extension_priv_data_t epriv;
 
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
     }
+  
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SERVER_NAME, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+    }
+  priv = epriv.ptr;
 
-  if (indx + 1 > session->security_parameters.extensions.server_names_size)
+  if (indx + 1 > priv->server_names_size)
     {
       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     }
 
-  *type = session->security_parameters.extensions.server_names[indx].type;
+  *type = priv->server_names[indx].type;
 
-  if (*data_length >           /* greater since we need one extra byte for the null */
-      session->security_parameters.extensions.server_names[indx].name_length)
+  if (*data_length > /* greater since we need one extra byte for the null */
+      priv->server_names[indx].name_length)
     {
-      *data_length =
-       session->security_parameters.extensions.
-       server_names[indx].name_length;
-      memcpy (data,
-             session->security_parameters.extensions.server_names[indx].name,
+      *data_length = priv->server_names[indx].name_length;
+      memcpy (data, priv->server_names[indx].name,
              *data_length);
 
       if (*type == GNUTLS_NAME_DNS)    /* null terminate */
@@ -287,9 +325,7 @@ gnutls_server_name_get (gnutls_session_t session, void *data,
     }
   else
     {
-      *data_length =
-       session->security_parameters.extensions.
-       server_names[indx].name_length;
+      *data_length = priv->server_names[indx].name_length;
       return GNUTLS_E_SHORT_MEMORY_BUFFER;
     }
 
@@ -321,7 +357,10 @@ gnutls_server_name_set (gnutls_session_t session,
                        gnutls_server_name_type_t type,
                        const void *name, size_t name_length)
 {
-  int server_names;
+  int server_names, ret;
+  server_name_ext_st* priv;
+  extension_priv_data_t epriv;
+  int set = 0;
 
   if (session->security_parameters.entity == GNUTLS_SERVER)
     {
@@ -332,21 +371,95 @@ gnutls_server_name_set (gnutls_session_t session,
   if (name_length > MAX_SERVER_NAME_SIZE)
     return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
-  server_names =
-    session->security_parameters.extensions.server_names_size + 1;
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SERVER_NAME, &epriv);
+  if (ret < 0)
+    {
+      set = 1;
+    }
+
+  if (set != 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+           gnutls_assert();
+           return GNUTLS_E_MEMORY_ERROR;
+       }
+      epriv.ptr = priv;
+    }
+  else
+    priv = epriv.ptr;
+  
+  server_names = priv->server_names_size + 1;
 
   if (server_names > MAX_SERVER_NAME_EXTENSIONS)
     server_names = MAX_SERVER_NAME_EXTENSIONS;
 
-  session->security_parameters.extensions.server_names
-    [server_names - 1].type = type;
-  memcpy (session->security_parameters.
-         extensions.server_names[server_names - 1].name, name, name_length);
-  session->security_parameters.extensions.server_names[server_names -
-                                                      1].name_length =
-    name_length;
+  priv->server_names[server_names - 1].type = type;
+  memcpy (priv->server_names[server_names - 1].name, name, name_length);
+  priv->server_names[server_names - 1].name_length = name_length;
+
+  priv->server_names_size++;
+  
+  if (set != 0)
+    _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SERVER_NAME, epriv);
+
+  return 0;
+}
+
+static void _gnutls_server_name_deinit_data(extension_priv_data_t priv)
+{
+    gnutls_free(priv.ptr);
+}
+
+static int _gnutls_server_name_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+server_name_ext_st* priv = epriv.ptr;
+int i, ret;
+
+  BUFFER_APPEND_NUM(ps, priv->server_names_size);
+  for (i = 0; i < priv->server_names_size;i++)
+    {
+      BUFFER_APPEND_NUM(ps, priv->server_names[i].type);
+      BUFFER_APPEND_PFX(ps, priv->server_names[i].name, 
+       priv->server_names[i].name_length);
+    }
+  return 0;
+}
+
+static int _gnutls_server_name_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+server_name_ext_st* priv;
+int i, ret;
+extension_priv_data_t epriv;
 
-  session->security_parameters.extensions.server_names_size++;
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
 
+  BUFFER_POP_NUM(ps, priv->server_names_size);
+  for (i = 0; i < priv->server_names_size;i++)
+    {
+      BUFFER_POP_NUM(ps, priv->server_names[i].type);
+      BUFFER_POP_NUM(ps, priv->server_names[i].name_length);
+      if (priv->server_names[i].name_length > sizeof(priv->server_names[i].name))
+        {
+         gnutls_assert();
+         return GNUTLS_E_PARSING_ERROR;
+       }
+      BUFFER_POP(ps, priv->server_names[i].name, priv->server_names[i].name_length);
+    }
+
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
   return 0;
+
+error:
+  gnutls_free(priv);
+  return ret;
 }
+
index a598e1c5f09ba14e0034c83313839e8bed8357c0..af36ce849f069e7e45af9cdff514bb2906ff9af1 100644 (file)
  * USA
  *
  */
+#ifndef EXT_SERVER_NAME_H
+#define EXT_SERVER_NAME_H
 
-int _gnutls_server_name_recv_params (gnutls_session_t session,
-                                    const opaque * data, size_t data_size);
-int _gnutls_server_name_send_params (gnutls_session_t session,
-                                    opaque * data, size_t);
+#include <gnutls_extensions.h>
+
+typedef struct
+{
+  opaque name[MAX_SERVER_NAME_SIZE];
+  unsigned name_length;
+  gnutls_server_name_type_t type;
+} server_name_st;
+
+#define MAX_SERVER_NAME_EXTENSIONS 3
+
+typedef struct {
+  server_name_st server_names[MAX_SERVER_NAME_EXTENSIONS];
+  /* limit server_name extensions */
+  unsigned server_names_size;
+} server_name_ext_st;
+
+extern extension_entry_st ext_mod_server_name;
+
+#endif
index 2f000fe63cf69fa7e4cb571a83b75ccfcfd55a2f..fafb1747b273cf4f79b4e34d4ea323e05f3febd7 100644 (file)
@@ -33,6 +33,7 @@
 #include <random.h>
 #include <ext_session_ticket.h>
 #include <gnutls_mbuffers.h>
+#include <gnutls_extensions.h>
 
 #ifdef ENABLE_SESSION_TICKET
 
 
 #define MAC_SIZE 32
 
+static int session_ticket_recv_params (gnutls_session_t session,
+                                       const opaque * data,
+                                       size_t data_size);
+static int session_ticket_send_params (gnutls_session_t session,
+                                       opaque * data, size_t data_size);
+static int session_ticket_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static int session_ticket_pack(extension_priv_data_t _priv, gnutls_buffer_st* ps);
+static void session_ticket_deinit_data(extension_priv_data_t priv);
+
+extension_entry_st ext_mod_session_ticket = {
+    .name = "SESSION TICKET",
+    .type = GNUTLS_EXTENSION_SESSION_TICKET,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = session_ticket_recv_params,
+    .send_func = session_ticket_send_params,
+    .pack_func = session_ticket_pack,
+    .unpack_func = session_ticket_unpack,
+    .deinit_func = session_ticket_deinit_data,
+};
+
+struct gnutls_session_ticket_key_st
+{
+  opaque key_name[SESSION_TICKET_KEY_NAME_SIZE];
+  opaque key[SESSION_TICKET_KEY_SIZE];
+  opaque mac_secret[SESSION_TICKET_MAC_SECRET_SIZE];
+};
+
+typedef struct {
+    int session_ticket_enable;
+    int session_ticket_renew;
+    opaque session_ticket_IV[SESSION_TICKET_IV_SIZE];
+
+    opaque* session_ticket;
+    int session_ticket_len;
+
+    struct gnutls_session_ticket_key_st key;
+} session_ticket_ext_st;
+
 struct ticket
 {
   opaque key_name[KEY_NAME_SIZE];
@@ -79,17 +119,16 @@ digest_ticket (const gnutls_datum_t * key, struct ticket *ticket,
 }
 
 static int
-decrypt_ticket (gnutls_session_t session, struct ticket *ticket)
+decrypt_ticket (gnutls_session_t session, session_ticket_ext_st* priv, struct ticket *ticket)
 {
   cipher_hd_st cipher_hd;
   gnutls_datum_t key, IV, mac_secret, state;
-  opaque final[32];
+  opaque final[MAC_SECRET_SIZE];
   time_t timestamp = time (0);
   int ret;
 
   /* Check the integrity of ticket using HMAC-SHA-256. */
-  mac_secret.data = (void *)
-    session->internals.session_ticket_key->mac_secret;
+  mac_secret.data = (void *) priv->key.mac_secret;
   mac_secret.size = MAC_SECRET_SIZE;
   ret = digest_ticket (&mac_secret, ticket, final);
   if (ret < 0)
@@ -105,7 +144,7 @@ decrypt_ticket (gnutls_session_t session, struct ticket *ticket)
     }
 
   /* Decrypt encrypted_state using 128-bit AES in CBC mode. */
-  key.data = (void *) session->internals.session_ticket_key->key;
+  key.data = (void *) priv->key.key;
   key.size = KEY_SIZE;
   IV.data = ticket->IV;
   IV.size = IV_SIZE;
@@ -149,7 +188,7 @@ decrypt_ticket (gnutls_session_t session, struct ticket *ticket)
 }
 
 static int
-encrypt_ticket (gnutls_session_t session, struct ticket *ticket)
+encrypt_ticket (gnutls_session_t session, session_ticket_ext_st* priv, struct ticket *ticket)
 {
   cipher_hd_st cipher_hd;
   gnutls_datum_t key, IV, mac_secret, state, encrypted_state;
@@ -164,6 +203,7 @@ encrypt_ticket (gnutls_session_t session, struct ticket *ticket)
       return ret;
     }
   blocksize = gnutls_cipher_get_block_size (GNUTLS_CIPHER_AES_128_CBC);
+
   encrypted_state.size =
     ((state.size + blocksize - 1) / blocksize) * blocksize;
   encrypted_state.data = gnutls_malloc (encrypted_state.size);
@@ -178,9 +218,9 @@ encrypt_ticket (gnutls_session_t session, struct ticket *ticket)
   _gnutls_free_datum (&state);
 
   /* Encrypt state using 128-bit AES in CBC mode. */
-  key.data = (void *) session->internals.session_ticket_key->key;
+  key.data = (void *) priv->key.key;
   key.size = KEY_SIZE;
-  IV.data = session->internals.session_ticket_IV;
+  IV.data = priv->session_ticket_IV;
   IV.size = IV_SIZE;
   ret =
     _gnutls_cipher_init (&cipher_hd, GNUTLS_CIPHER_AES_128_CBC, &key, &IV);
@@ -202,14 +242,12 @@ encrypt_ticket (gnutls_session_t session, struct ticket *ticket)
     }
 
   /* Fill the ticket structure to compute MAC. */
-  memcpy (ticket->key_name,
-         session->internals.session_ticket_key->key_name, KEY_NAME_SIZE);
+  memcpy (ticket->key_name, priv->key.key_name, KEY_NAME_SIZE);
   memcpy (ticket->IV, IV.data, IV.size);
   ticket->encrypted_state_len = encrypted_state.size;
   ticket->encrypted_state = encrypted_state.data;
 
-  mac_secret.data =
-    (void *) session->internals.session_ticket_key->mac_secret;
+  mac_secret.data = priv->key.mac_secret;
   mac_secret.size = MAC_SECRET_SIZE;
   ret = digest_ticket (&mac_secret, ticket, ticket->mac);
   if (ret < 0)
@@ -222,13 +260,24 @@ encrypt_ticket (gnutls_session_t session, struct ticket *ticket)
   return 0;
 }
 
-int
-_gnutls_session_ticket_recv_params (gnutls_session_t session,
+static int
+session_ticket_recv_params (gnutls_session_t session,
                                    const opaque * data, size_t _data_size)
 {
   ssize_t data_size = _data_size;
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
+  int ret;
 
-  if (!session->internals.session_ticket_enable)
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SESSION_TICKET, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
+
+  if (!priv->session_ticket_enable)
     return 0;
 
   if (session->security_parameters.entity == GNUTLS_SERVER)
@@ -240,7 +289,7 @@ _gnutls_session_ticket_recv_params (gnutls_session_t session,
       /* The client requested a new session ticket. */
       if (data_size == 0)
        {
-         session->internals.session_ticket_renew = 1;
+         priv->session_ticket_renew = 1;
          return 0;
        }
 
@@ -250,11 +299,9 @@ _gnutls_session_ticket_recv_params (gnutls_session_t session,
 
       /* If the key name of the ticket does not match the one that we
          hold, issue a new ticket. */
-      if (memcmp (ticket.key_name,
-                 session->internals.session_ticket_key->key_name,
-                 KEY_NAME_SIZE))
+      if (memcmp (ticket.key_name, priv->key.key_name, KEY_NAME_SIZE))
        {
-         session->internals.session_ticket_renew = 1;
+         priv->session_ticket_renew = 1;
          return 0;
        }
 
@@ -283,19 +330,19 @@ _gnutls_session_ticket_recv_params (gnutls_session_t session,
       memcpy (ticket.encrypted_state, encrypted_state,
              ticket.encrypted_state_len);
 
-      ret = decrypt_ticket (session, &ticket);
+      ret = decrypt_ticket (session, priv, &ticket);
       gnutls_free (ticket.encrypted_state);
       if (ret < 0)
        {
-         session->internals.session_ticket_renew = 1;
+         priv->session_ticket_renew = 1;
          return 0;
        }
     }
-  else
+  else /* Client */
     {
       if (data_size == 0)
        {
-         session->internals.session_ticket_renew = 1;
+         priv->session_ticket_renew = 1;
          return 0;
        }
     }
@@ -306,39 +353,44 @@ _gnutls_session_ticket_recv_params (gnutls_session_t session,
 /* returns a positive number if we send the extension data, zero if we
    do not want to send it, and a negative number on failure.
  */
-int
-_gnutls_session_ticket_send_params (gnutls_session_t session,
+static int
+session_ticket_send_params (gnutls_session_t session,
                                    opaque * data, size_t _data_size)
 {
   ssize_t data_size = _data_size;
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
+  int ret;
 
-  if (!session->internals.session_ticket_enable)
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SESSION_TICKET, &epriv);
+  if (ret >= 0)
+    priv = epriv.ptr;
+
+  if (priv == NULL || !priv->session_ticket_enable)
     return 0;
 
   if (session->security_parameters.entity == GNUTLS_SERVER)
     {
-      if (session->internals.session_ticket_renew)
+      if (priv && priv->session_ticket_renew)
        {
          return GNUTLS_E_INT_RET_0;
        }
     }
   else
     {
-      if (session->internals.resumed_security_parameters.
-         extensions.session_ticket_len > 0)
+      ret = _gnutls_ext_get_resumed_session_data( session, GNUTLS_EXTENSION_SESSION_TICKET, &epriv);
+      if (ret >= 0)
+       priv = epriv.ptr;
+
+      if (ret < 0 || !priv->session_ticket_enable)
+       return 0;
+
+      if (priv->session_ticket_len > 0)
        {
-         DECR_LENGTH_RET (data_size,
-                          session->internals.
-                          resumed_security_parameters.extensions.
-                          session_ticket_len, GNUTLS_E_SHORT_MEMORY_BUFFER);
-         memcpy (data,
-                 session->internals.resumed_security_parameters.
-                 extensions.session_ticket,
-                 session->internals.resumed_security_parameters.
-                 extensions.session_ticket_len);
-
-         return session->internals.resumed_security_parameters.extensions.
-           session_ticket_len;
+         DECR_LENGTH_RET (data_size, priv->session_ticket_len, GNUTLS_E_SHORT_MEMORY_BUFFER);
+         memcpy (data, priv->session_ticket, priv->session_ticket_len);
+
+         return priv->session_ticket_len;
        }
       else
        {
@@ -348,6 +400,55 @@ _gnutls_session_ticket_send_params (gnutls_session_t session,
   return 0;
 }
 
+
+static void session_ticket_deinit_data(extension_priv_data_t epriv)
+{
+session_ticket_ext_st* priv = epriv.ptr;
+
+    gnutls_free(priv->session_ticket);
+    gnutls_free(priv);
+}
+
+static int session_ticket_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+session_ticket_ext_st* priv = epriv.ptr;
+int ret;
+
+  BUFFER_APPEND_PFX(ps, priv->session_ticket, priv->session_ticket_len);
+
+  return 0;
+}
+
+static int session_ticket_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+session_ticket_ext_st* priv=NULL;
+int ret;
+extension_priv_data_t epriv;
+gnutls_datum ticket;
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  
+  BUFFER_POP_DATUM(ps, &ticket);
+  priv->session_ticket = ticket.data;
+  priv->session_ticket_len = ticket.size;
+
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
+  ret = 0;
+
+error:
+  gnutls_free(priv);
+  return ret;
+}
+
+
+
 /**
  * gnutls_session_ticket_key_generate:
  * @key: is a pointer to a #gnutls_datum_t which will contain a newly
@@ -400,13 +501,27 @@ gnutls_session_ticket_key_generate (gnutls_datum_t * key)
 int
 gnutls_session_ticket_enable_client (gnutls_session_t session)
 {
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
+
   if (!session)
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  session->internals.session_ticket_enable = 1;
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+       gnutls_assert();
+       return GNUTLS_E_MEMORY_ERROR;
+    }
+  priv->session_ticket_enable = 1;
+  epriv.ptr = priv;
+
+  _gnutls_ext_set_session_data(session, 
+    GNUTLS_EXTENSION_SESSION_TICKET, epriv);
+  
   return 0;
 }
 
@@ -429,6 +544,8 @@ gnutls_session_ticket_enable_server (gnutls_session_t session,
                                     const gnutls_datum_t * key)
 {
   int ret;
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
 
   if (!session || !key
       || key->size != sizeof (struct gnutls_session_ticket_key_st))
@@ -437,33 +554,31 @@ gnutls_session_ticket_enable_server (gnutls_session_t session,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+       gnutls_assert();
+       return GNUTLS_E_MEMORY_ERROR;
+    }
+  epriv.ptr = priv;
+
   ret = _gnutls_rnd (GNUTLS_RND_RANDOM,
-                    session->internals.session_ticket_IV, IV_SIZE);
+                    priv->session_ticket_IV, IV_SIZE);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  session->internals.session_ticket_key =
-    (struct gnutls_session_ticket_key_st *) key->data;
-  session->internals.session_ticket_enable = 1;
+  memcpy(&priv->key, key->data, key->size);
+  priv->session_ticket_enable = 1;
+
+  _gnutls_ext_set_session_data(session, 
+    GNUTLS_EXTENSION_SESSION_TICKET, epriv);
+
   return 0;
 }
 
-int
-_gnutls_send_new_session_ticket (gnutls_session_t session, int again)
-{
-  mbuffer_st *bufel = NULL;
-  uint8_t *data = NULL, *p;
-  int data_size = 0;
-  int ret;
-  struct ticket ticket;
-  uint16_t ticket_len;
-  gnutls_cipher_algorithm_t write_bulk_cipher_algorithm;
-  gnutls_mac_algorithm_t write_mac_algorithm;
-  gnutls_compression_method_t write_compression_algorithm;
-
 #define SAVE_WRITE_SECURITY_PARAMETERS                                 \
   do                                                                   \
     {                                                                  \
@@ -488,8 +603,31 @@ _gnutls_send_new_session_ticket (gnutls_session_t session, int again)
     }                                                                  \
   while (0)
 
+int
+_gnutls_send_new_session_ticket (gnutls_session_t session, int again)
+{
+  mbuffer_st *bufel = NULL;
+  uint8_t *data = NULL, *p;
+  int data_size = 0;
+  int ret;
+  struct ticket ticket;
+  uint16_t ticket_len;
+  gnutls_cipher_algorithm_t write_bulk_cipher_algorithm;
+  gnutls_mac_algorithm_t write_mac_algorithm;
+  gnutls_compression_method_t write_compression_algorithm;
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
+
   if (again == 0)
     {
+      ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SESSION_TICKET, &epriv);
+      if (ret < 0)
+        return 0;
+      priv = epriv.ptr;
+      
+      if (!priv->session_ticket_renew)
+       return 0;
+      
       /* XXX: Temporarily set write algorithms to be used.
          _gnutls_write_connection_state_init() does this job, but it also
          triggers encryption, while NewSessionTicket should not be
@@ -514,7 +652,7 @@ _gnutls_send_new_session_ticket (gnutls_session_t session, int again)
       if (ret < 0)
        return ret;
 
-      ret = encrypt_ticket (session, &ticket);
+      ret = encrypt_ticket (session, priv, &ticket);
       RESTORE_WRITE_SECURITY_PARAMETERS;
       if (ret < 0)
        {
@@ -535,9 +673,8 @@ _gnutls_send_new_session_ticket (gnutls_session_t session, int again)
 
       data = _mbuffer_get_udata_ptr(bufel);
       p = data;
-      /* FIXME: ticket lifetime is fixed to 10 days, which should be
-         customizable. */
-      _gnutls_write_uint32 (864000, p);
+
+      _gnutls_write_uint32 ( session->internals.expire_time, p);
       p += 4;
 
       _gnutls_write_uint16 (ticket_len, p);
@@ -576,6 +713,19 @@ _gnutls_recv_new_session_ticket (gnutls_session_t session)
   uint32_t lifetime_hint;
   uint16_t ticket_len;
   int ret;
+  session_ticket_ext_st* priv=NULL;
+  extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SESSION_TICKET, &epriv);
+  if (ret < 0)
+    {
+       gnutls_assert();
+       return 0;
+    }
+  priv = epriv.ptr;
+
+  if (!priv->session_ticket_renew)
+    return 0;
 
   ret = _gnutls_recv_handshake (session, &data, &data_size,
                                GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
@@ -596,29 +746,26 @@ _gnutls_recv_new_session_ticket (gnutls_session_t session)
   p += 2;
 
   DECR_LENGTH_COM (data_size, ticket_len, goto error);
-  session->security_parameters.extensions.session_ticket =
-    gnutls_realloc (session->security_parameters.extensions.session_ticket,
-                   ticket_len);
-  if (!session->security_parameters.extensions.session_ticket)
+  priv->session_ticket = gnutls_realloc (priv->session_ticket, ticket_len);
+  if (!priv->session_ticket)
     {
       gnutls_assert ();
       gnutls_free (data);
       return GNUTLS_E_MEMORY_ERROR;
     }
-  memcpy (session->security_parameters.extensions.session_ticket,
-         p, ticket_len);
+  memcpy (priv->session_ticket, p, ticket_len);
   gnutls_free (data);
-  session->security_parameters.extensions.session_ticket_len = ticket_len;
+  priv->session_ticket_len = ticket_len;
 
   /* Discard the current session ID.  (RFC5077 3.4) */
   ret = _gnutls_generate_session_id (session->security_parameters.session_id,
-                                    &session->
-                                    security_parameters.session_id_size);
+                                    &session->security_parameters.session_id_size);
   if (ret < 0)
     {
       gnutls_assert ();
       gnutls_free (data);
-      gnutls_free (session->security_parameters.extensions.session_ticket);
+      gnutls_free (priv->session_ticket);
+      priv->session_ticket = NULL;
       return GNUTLS_E_INTERNAL_ERROR;
     }
   return 0;
index 85a518044b0f600c9ca3b722db796eddf3aad89f..e8a531b909b26e197493f741575e4eec3dc9c9d3 100644 (file)
  *
  */
 
-#ifdef ENABLE_SESSION_TICKET
+#ifndef EXT_SESSION_TICKET_H
+# define EXT_SESSION_TICKET_H
 
-int _gnutls_session_ticket_recv_params (gnutls_session_t session,
-                                       const opaque * data,
-                                       size_t data_size);
-int _gnutls_session_ticket_send_params (gnutls_session_t session,
-                                       opaque * data, size_t data_size);
+# ifdef ENABLE_SESSION_TICKET
+
+#include <gnutls_extensions.h>
+
+extern extension_entry_st ext_mod_session_ticket;
 
 int _gnutls_send_new_session_ticket (gnutls_session_t session, int again);
 int _gnutls_recv_new_session_ticket (gnutls_session_t session);
 
+# endif
 #endif
index e41e785dda5c8141e4f4b1486aecbf0054888db8..6936ff0975c50f61e64f5d83fd58ef0da7a56c08 100644 (file)
 #include <gnutls_num.h>
 #include <gnutls_algorithms.h>
 
+static int _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
+                                            const opaque * data,
+                                            size_t data_size);
+static int _gnutls_signature_algorithm_send_params (gnutls_session_t session,
+                                            opaque * data, size_t);
+static void signature_algorithms_deinit_data(extension_priv_data_t priv);
+static int signature_algorithms_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps);
+static int signature_algorithms_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+
+extension_entry_st ext_mod_sig = {
+    .name = "SIGNATURE ALGORITHMS",
+    .type = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = _gnutls_signature_algorithm_recv_params,
+    .send_func = _gnutls_signature_algorithm_send_params,
+    .pack_func = signature_algorithms_pack,
+    .unpack_func = signature_algorithms_unpack,
+    .deinit_func = signature_algorithms_deinit_data,
+};
+
+typedef struct {
+  /* TLS 1.2 signature algorithms */
+  gnutls_sign_algorithm_t sign_algorithms[MAX_SIGNATURE_ALGORITHMS];
+  uint16_t sign_algorithms_size;
+} sig_ext_st;
+
 /* generates a SignatureAndHashAlgorithm structure with length as prefix
  * by using the setup priorities.
  */
@@ -70,6 +97,7 @@ _gnutls_sign_algorithm_write_params (gnutls_session_t session, opaque * data,
   return len + 2;
 }
 
+
 /* Parses the Signature Algorithm structure and stores data into
  * session->security_parameters.extensions.
  */
@@ -78,8 +106,15 @@ _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
                                   const opaque * data, size_t data_size)
 {
   int sig, i;
+  sig_ext_st * priv;
+  extension_priv_data_t epriv;
 
-  session->security_parameters.extensions.sign_algorithms_size = 0;
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+       gnutls_assert();
+       return GNUTLS_E_MEMORY_ERROR;
+    }
 
   for (i = 0; i < data_size; i += 2)
     {
@@ -91,16 +126,16 @@ _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
       sig = _gnutls_tls_aid_to_sign (&aid);
       if (sig != GNUTLS_SIGN_UNKNOWN)
        {
-         session->security_parameters.extensions.sign_algorithms[session->
-                                                                 security_parameters.
-                                                                 extensions.sign_algorithms_size++]
+         priv->sign_algorithms[priv->sign_algorithms_size++]
            = sig;
-         if (session->security_parameters.extensions.sign_algorithms_size ==
-             MAX_SIGNATURE_ALGORITHMS)
+         if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS)
            break;
        }
     }
 
+  epriv.ptr = priv;    
+  _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv);
+
   return 0;
 }
 
@@ -113,7 +148,7 @@ _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
  * then it is an error;
  */
 
-int
+static int
 _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
                                         const opaque * data,
                                         size_t _data_size)
@@ -139,7 +174,6 @@ _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
        {
          uint16_t len;
 
-
          DECR_LEN (data_size, 2);
          len = _gnutls_read_uint16 (data);
          DECR_LEN (data_size, len);
@@ -158,7 +192,7 @@ _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
 
 /* returns data_size or a negative number on failure
  */
-int
+static int
 _gnutls_signature_algorithm_send_params (gnutls_session_t session,
                                         opaque * data, size_t data_size)
 {
@@ -196,11 +230,22 @@ _gnutls_session_get_sign_algo (gnutls_session_t session,
                               gnutls_digest_algorithm_t * hash)
 {
   unsigned i;
+  int ret;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+  sig_ext_st * priv;
+  extension_priv_data_t epriv;
 
+  ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
+    &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
   if (!_gnutls_version_has_selectable_sighash (ver)
-      || session->security_parameters.extensions.sign_algorithms_size == 0)
+      || priv->sign_algorithms_size == 0)
     /* none set, allow all */
     {
       *hash = GNUTLS_DIG_SHA1;
@@ -208,15 +253,14 @@ _gnutls_session_get_sign_algo (gnutls_session_t session,
     }
 
   for (i = 0;
-       i < session->security_parameters.extensions.sign_algorithms_size; i++)
+       i < priv->sign_algorithms_size; i++)
     {
       if (_gnutls_sign_get_pk_algorithm
-         (session->security_parameters.extensions.sign_algorithms[i]) == pk)
+         (priv->sign_algorithms[i]) == pk)
        {
          *hash =
-           _gnutls_sign_get_hash_algorithm (session->security_parameters.
-                                            extensions.sign_algorithms[i]);
-         return session->security_parameters.extensions.sign_algorithms[i];
+           _gnutls_sign_get_hash_algorithm (priv->sign_algorithms[i]);
+         return priv->sign_algorithms[i];
        }
     }
 
@@ -233,19 +277,31 @@ _gnutls_session_sign_algo_requested (gnutls_session_t session,
                                     gnutls_sign_algorithm_t sig)
 {
   unsigned i;
+  int ret;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+  sig_ext_st * priv;
+  extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
+    &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
   if (!_gnutls_version_has_selectable_sighash (ver)
-      || session->security_parameters.extensions.sign_algorithms_size == 0)
+      || priv->sign_algorithms_size == 0)
     /* none set, allow all */
     {
       return 0;
     }
 
   for (i = 0;
-       i < session->security_parameters.extensions.sign_algorithms_size; i++)
+       i < priv->sign_algorithms_size; i++)
     {
-      if (session->security_parameters.extensions.sign_algorithms[i] == sig)
+      if (priv->sign_algorithms[i] == sig)
        {
          return 0;             /* ok */
        }
@@ -263,10 +319,22 @@ _gnutls_session_sign_algo_enabled (gnutls_session_t session,
                                   gnutls_sign_algorithm_t sig)
 {
   unsigned i;
+  int ret;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+  sig_ext_st * priv;
+  extension_priv_data_t epriv;
+
+  ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
+    &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return 0;
+    }
+  priv = epriv.ptr;
 
   if (!_gnutls_version_has_selectable_sighash (ver)
-      || session->security_parameters.extensions.sign_algorithms_size == 0)
+      || priv->sign_algorithms_size == 0)
     /* none set, allow all */
     {
       return 0;
@@ -283,6 +351,55 @@ _gnutls_session_sign_algo_enabled (gnutls_session_t session,
   return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
 }
 
+static void signature_algorithms_deinit_data(extension_priv_data_t priv)
+{
+    gnutls_free(priv.ptr);
+}
+
+static int signature_algorithms_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+sig_ext_st* priv = epriv.ptr;
+int ret, i;
+
+  BUFFER_APPEND_NUM(ps, priv->sign_algorithms_size);
+  for (i = 0; i < priv->sign_algorithms_size;i++)
+    {
+      BUFFER_APPEND_NUM(ps, priv->sign_algorithms[i]);
+    }
+  return 0;
+}
+
+static int signature_algorithms_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+sig_ext_st* priv;
+int i, ret;
+extension_priv_data_t epriv;
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  BUFFER_POP_NUM(ps, priv->sign_algorithms_size);
+  for (i = 0; i < priv->sign_algorithms_size;i++)
+    {
+      BUFFER_POP_NUM(ps, priv->sign_algorithms[i]);
+    }
+
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
+  return 0;
+
+error:
+  gnutls_free(priv);
+  return ret;
+}
+
+
+
 /**
  * gnutls_sign_algorithm_get_requested:
  * @session: is a #gnutls_session_t structure.
@@ -310,16 +427,28 @@ gnutls_sign_algorithm_get_requested (gnutls_session_t session,
                                     gnutls_sign_algorithm_t * algo)
 {
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+  sig_ext_st * priv;
+  extension_priv_data_t epriv;
+  int ret;
+
+  ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
+    &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
   if (!_gnutls_version_has_selectable_sighash (ver)
-      || session->security_parameters.extensions.sign_algorithms_size == 0)
+      || priv->sign_algorithms_size == 0)
     {
       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     }
 
-  if (indx < session->security_parameters.extensions.sign_algorithms_size)
+  if (indx < priv->sign_algorithms_size)
     {
-      *algo = session->security_parameters.extensions.sign_algorithms[indx];
+      *algo = priv->sign_algorithms[indx];
       return 0;
     }
   else
index 69a05b741dc815e9ab95a6a7a023f716da067934..2e41b602687940599fe0a2ff854037b934639715 100644 (file)
 
 /* signature algorithms extension
  */
-int _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
-                                            const opaque * data,
-                                            size_t data_size);
-int _gnutls_signature_algorithm_send_params (gnutls_session_t session,
-                                            opaque * data, size_t);
+#ifndef EXT_SIGNATURE_H
+# define EXT_SIGNATURE_H
+
+#include <gnutls_extensions.h>
+
+extern extension_entry_st ext_mod_sig;
+
 int _gnutls_session_sign_algo_requested (gnutls_session_t session,
                                         gnutls_sign_algorithm_t sig);
 gnutls_sign_algorithm_t _gnutls_session_get_sign_algo (gnutls_session_t
@@ -44,3 +46,5 @@ int _gnutls_sign_algorithm_write_params (gnutls_session_t session,
                                         opaque * data, size_t max_data_size);
 int _gnutls_session_sign_algo_enabled (gnutls_session_t session,
                                       gnutls_sign_algorithm_t sig);
+
+#endif
index 650e27e758f4248ed994aa13ab4a77402d3f398f..7c36de0ffe7bcc953e288a2704ef0a794270a667 100644 (file)
 #include "gnutls_errors.h"
 #include "gnutls_algorithms.h"
 #include <gnutls_num.h>
+#include <gnutls_extensions.h>
 
-int
+static int _gnutls_srp_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static int _gnutls_srp_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps);
+static void _gnutls_srp_deinit_data(extension_priv_data_t epriv);
+static int _gnutls_srp_recv_params (gnutls_session_t state, const opaque * data,
+                            size_t data_size);
+static int _gnutls_srp_send_params (gnutls_session_t state, opaque * data, size_t);
+
+extension_entry_st ext_mod_srp = {
+    .name = "SRP",
+    .type = GNUTLS_EXTENSION_SRP,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = _gnutls_srp_recv_params,
+    .send_func = _gnutls_srp_send_params,
+    .pack_func = _gnutls_srp_pack,
+    .unpack_func = _gnutls_srp_unpack,
+    .deinit_func = _gnutls_srp_deinit_data
+};
+
+
+static int
 _gnutls_srp_recv_params (gnutls_session_t session, const opaque * data,
                         size_t _data_size)
 {
   uint8_t len;
   ssize_t data_size = _data_size;
-
+  extension_priv_data_t epriv;
+  srp_ext_st * priv;
+  
   if (session->security_parameters.entity == GNUTLS_SERVER)
     {
       if (data_size > 0)
@@ -53,10 +76,24 @@ _gnutls_srp_recv_params (gnutls_session_t session, const opaque * data,
              gnutls_assert ();
              return GNUTLS_E_ILLEGAL_SRP_USERNAME;
            }
-         memcpy (session->security_parameters.extensions.srp_username,
-                 &data[1], len);
-         /* null terminated */
-         session->security_parameters.extensions.srp_username[len] = 0;
+       
+         priv = gnutls_calloc(1, sizeof(*priv));
+         if (priv == NULL)
+           {
+             gnutls_assert();
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+
+         priv->username = gnutls_malloc(len+1);
+         if (priv->username)
+           {
+             memcpy (priv->username, &data[1], len);
+             /* null terminated */
+             priv->username[len] = 0;
+           }
+
+         epriv.ptr = priv;
+         _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SRP, epriv);
        }
     }
   return 0;
@@ -65,11 +102,13 @@ _gnutls_srp_recv_params (gnutls_session_t session, const opaque * data,
 /* returns data_size or a negative number on failure
  * data is allocated locally
  */
-int
+static int
 _gnutls_srp_send_params (gnutls_session_t session, opaque * data,
                         size_t data_size)
 {
   unsigned len;
+  extension_priv_data_t epriv;
+  srp_ext_st * priv;
 
   if (_gnutls_kx_priority (session, GNUTLS_KX_SRP) < 0 &&
       _gnutls_kx_priority (session, GNUTLS_KX_SRP_DSS) < 0 &&
@@ -126,8 +165,18 @@ _gnutls_srp_send_params (gnutls_session_t session, opaque * data,
              return GNUTLS_E_SHORT_MEMORY_BUFFER;
            }
 
-         session->internals.srp_username = username;
-         session->internals.srp_password = password;
+         priv = gnutls_malloc(sizeof(*priv));
+         if (priv == NULL)
+           {
+             gnutls_assert();
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+
+         priv->username = username;
+         priv->password = password;
+
+         epriv.ptr = priv;
+         _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SRP, epriv);
 
          data[0] = (uint8_t) len;
          memcpy (&data[1], username, len);
@@ -137,4 +186,63 @@ _gnutls_srp_send_params (gnutls_session_t session, opaque * data,
   return 0;
 }
 
+static void _gnutls_srp_deinit_data(extension_priv_data_t epriv)
+{
+    srp_ext_st * priv = epriv.ptr;
+
+    gnutls_free(priv->username);
+    gnutls_free(priv->password);
+    gnutls_free(priv);
+}
+
+static int _gnutls_srp_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+srp_ext_st* priv = epriv.ptr;
+int ret;
+int password_len = 0, username_len = 0;
+
+  if (priv->username)
+    username_len = strlen(priv->username);
+
+  if (priv->password)
+    password_len = strlen(priv->password);
+
+  BUFFER_APPEND_PFX(ps, priv->username, username_len);
+  BUFFER_APPEND_PFX(ps, priv->password, password_len);
+
+  return 0;
+}
+
+static int _gnutls_srp_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+srp_ext_st* priv;
+int ret;
+extension_priv_data_t epriv;
+gnutls_datum username = { NULL, 0 }, password = {NULL, 0};
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  BUFFER_POP_DATUM(ps, &username);
+  BUFFER_POP_DATUM(ps, &password);
+  
+  priv->username = username.data;
+  priv->password = password.data;
+  
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
+  return 0;
+
+error:
+  _gnutls_free_datum(&username);
+  _gnutls_free_datum(&password);
+  return ret;
+}
+
+
 #endif /* ENABLE_SRP */
index 44918230262d6ed3a7cba2c562ae16ce882447f1..a1146b024a80c79f97fff473d0d1d4d03976408a 100644 (file)
  *
  */
 
-#ifdef ENABLE_SRP
+#ifndef EXT_SRP_H
+#define EXT_SRP_H
 
-#define IS_SRP_KX(kx) ((kx == GNUTLS_KX_SRP || (kx == GNUTLS_KX_SRP_RSA) || \
+#include <gnutls_extensions.h>
+
+# ifdef ENABLE_SRP
+
+#  define IS_SRP_KX(kx) ((kx == GNUTLS_KX_SRP || (kx == GNUTLS_KX_SRP_RSA) || \
           kx == GNUTLS_KX_SRP_DSS)?1:0)
 
-int _gnutls_srp_recv_params (gnutls_session_t state, const opaque * data,
-                            size_t data_size);
-int _gnutls_srp_send_params (gnutls_session_t state, opaque * data, size_t);
+extern extension_entry_st ext_mod_srp;
+
+typedef struct {
+    char* username;
+    char* password;
+} srp_ext_st;
+
+# endif
 
 #endif
index 0b6b88bbcde97680a033199608fcb7ad53fe3c6a..78aa8b76ee7c926274a4995156f2d61576a5044a 100644 (file)
@@ -218,14 +218,14 @@ _gnutls_record_buffer_get (content_type_t type,
   switch (type)
     {
     case GNUTLS_APPLICATION_DATA:
-      _gnutls_buffer_get_data (&session->internals.application_data_buffer,
+      _gnutls_buffer_pop_data (&session->internals.application_data_buffer,
                               data, &length);
       _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
                           (int) length, (int) type);
       break;
 
     case GNUTLS_HANDSHAKE:
-      _gnutls_buffer_get_data (&session->internals.handshake_data_buffer,
+      _gnutls_buffer_pop_data (&session->internals.handshake_data_buffer,
                               data, &length);
       _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
                           (int) length, (int) type);
@@ -233,7 +233,7 @@ _gnutls_record_buffer_get (content_type_t type,
 
     case GNUTLS_INNER_APPLICATION:
 
-      _gnutls_buffer_get_data (&session->internals.ia_data_buffer, data,
+      _gnutls_buffer_pop_data (&session->internals.ia_data_buffer, data,
                               &length);
       _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
                           (int) length, (int) type);
@@ -839,14 +839,14 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session,
          gnutls_assert ();
 
          tmp = sizeOfPtr;
-         _gnutls_buffer_get_data (&session->internals.handshake_recv_buffer,
+         _gnutls_buffer_pop_data (&session->internals.handshake_recv_buffer,
                                   iptr, &tmp);
          return tmp;
        }
       gnutls_assert ();
 
       tmp = sizeOfPtr;
-      _gnutls_buffer_get_data (&session->internals.handshake_recv_buffer,
+      _gnutls_buffer_pop_data (&session->internals.handshake_recv_buffer,
                               iptr, &tmp);
       left -= tmp;
 
index f6d58cc4301f3a4aa038ab6d908ea45d51dcd6b8..b91abc46576ad4544c9e32a8f77227f4a4e4e475 100644 (file)
@@ -35,6 +35,7 @@
 #include <gnutls_num.h>
 #include <gnutls_datum.h>
 #include <gnutls_state.h>
+#include <gnutls_extensions.h>
 
 static const char keyexp[] = "key expansion";
 static const int keyexp_length = sizeof (keyexp) - 1;
@@ -381,13 +382,6 @@ _gnutls_set_write_keys (gnutls_session_t session)
                           export_flag);
 }
 
-#define CPY_EXTENSIONS \
-        gnutls_free(dst->extensions.session_ticket); \
-        gnutls_free(dst->extensions.oprfi_client); \
-        gnutls_free(dst->extensions.oprfi_server); \
-       memcpy(&dst->extensions.server_names, &src->extensions, sizeof(src->extensions)); \
-       memset(&src->extensions, 0, sizeof(src->extensions))    /* avoid duplicate free's */
-
 #define CPY_COMMON dst->entity = src->entity; \
        dst->kx_algorithm = src->kx_algorithm; \
        memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(cipher_suite_st)); \
@@ -400,8 +394,7 @@ _gnutls_set_write_keys (gnutls_session_t session)
        dst->timestamp = src->timestamp; \
        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->inner_secret, &src->inner_secret, GNUTLS_MASTER_SIZE)
+       dst->version = src->version
 
 static void
 _gnutls_cpy_read_security_parameters (security_parameters_st *
@@ -419,7 +412,6 @@ _gnutls_cpy_write_security_parameters (security_parameters_st *
                                       dst, security_parameters_st * src)
 {
   CPY_COMMON;
-  CPY_EXTENSIONS;              /* only do once */
 
   dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm;
   dst->write_mac_algorithm = src->write_mac_algorithm;
@@ -493,7 +485,7 @@ _gnutls_read_connection_state_init (gnutls_session_t session)
        return rc;
     }
   else
-    {                          /* RESUME_TRUE */
+    { /* RESUME_TRUE */
       _gnutls_cpy_read_security_parameters (&session->security_parameters,
                                            &session->
                                            internals.resumed_security_parameters);
@@ -681,6 +673,7 @@ _gnutls_write_connection_state_init (gnutls_session_t session)
       _gnutls_cpy_write_security_parameters (&session->security_parameters,
                                             &session->
                                             internals.resumed_security_parameters);
+      _gnutls_ext_restore_resumed_session(session);
     }
 
   rc = _gnutls_set_write_keys (session);
index 9a1b8f9a255e60db81108dba66a50b5d851d4b16..f316d5c7cedebfc92db5141e212361cbecb23b9a 100644 (file)
@@ -34,7 +34,6 @@
 #include "ext_max_record.h"
 #include <ext_cert_type.h>
 #include <ext_server_name.h>
-#include <ext_oprfi.h>
 #include <ext_srp.h>
 #include <ext_session_ticket.h>
 #include <ext_safe_renegotiation.h>
 #include <ext_safe_renegotiation.h>
 #include <gnutls_num.h>
 
-typedef struct
-{
-  const char *name;
-  uint16_t type;
-  gnutls_ext_parse_type_t parse_type;
 
-  /* this function must return 0 when Not Applicable
-   * size of extension data if ok
-   * < 0 on other error.
-   */
-  gnutls_ext_recv_func recv_func;
+static void _gnutls_ext_unset_resumed_session_data(gnutls_session_t session, uint16_t type);
 
-  /* this function must return 0 when Not Applicable
-   * size of extension data if ok
-   * GNUTLS_E_INT_RET_0 if extension data size is zero
-   * < 0 on other error.
-   */
-  gnutls_ext_send_func send_func;
-} gnutls_extension_entry;
 
 static size_t extfunc_size = 0;
-static gnutls_extension_entry *extfunc = NULL;
+static extension_entry_st *extfunc = NULL;
+
+static gnutls_ext_parse_type_t 
+_gnutls_ext_parse_type (uint16_t type)
+{
+  size_t i;
+
+  for (i = 0; i < extfunc_size; i++)
+    {
+      if (extfunc[i].type == type)
+        return extfunc[i].parse_type;
+    }
+
+  return GNUTLS_EXT_NONE;
+}
 
 static gnutls_ext_recv_func
 _gnutls_ext_func_recv (uint16_t type, gnutls_ext_parse_type_t parse_type)
@@ -78,6 +75,31 @@ _gnutls_ext_func_recv (uint16_t type, gnutls_ext_parse_type_t parse_type)
   return NULL;
 }
 
+static gnutls_ext_deinit_data_func
+_gnutls_ext_func_deinit (uint16_t type)
+{
+  size_t i;
+
+  for (i = 0; i < extfunc_size; i++)
+    if (extfunc[i].type == type)
+       return extfunc[i].deinit_func;
+
+  return NULL;
+}
+
+static gnutls_ext_unpack_func
+_gnutls_ext_func_unpack (uint16_t type)
+{
+  size_t i;
+
+  for (i = 0; i < extfunc_size; i++)
+    if (extfunc[i].type == type)
+       return extfunc[i].unpack_func;
+
+  return NULL;
+}
+
+
 static const char *
 _gnutls_extension_get_name (uint16_t type)
 {
@@ -236,7 +258,7 @@ _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
   pos += 2;
   for (i = 0; i < extfunc_size; i++)
     {
-      gnutls_extension_entry *p = &extfunc[i];
+      extension_entry_st *p = &extfunc[i];
 
       if (p->send_func == NULL)
        continue;
@@ -272,8 +294,8 @@ _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
           */
          _gnutls_extension_list_add (session, p->type);
 
-         _gnutls_debug_log ("EXT[%p]: Sending extension %s\n",
-                            session, p->name);
+         _gnutls_debug_log ("EXT[%p]: Sending extension %s (%d bytes)\n",
+                            session, p->name, size);
        }
       else if (size < 0)
        {
@@ -303,73 +325,37 @@ _gnutls_ext_init (void)
 {
   int ret;
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_MAX_RECORD_SIZE,
-                            "MAX_RECORD_SIZE",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_max_record_recv_params,
-                            _gnutls_max_record_send_params);
+  ret = _gnutls_ext_register (&ext_mod_max_record_size);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_CERT_TYPE,
-                            "CERT_TYPE",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_cert_type_recv_params,
-                            _gnutls_cert_type_send_params);
+  ret = _gnutls_ext_register (&ext_mod_cert_type);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_SERVER_NAME,
-                            "SERVER_NAME",
-                            GNUTLS_EXT_APPLICATION,
-                            _gnutls_server_name_recv_params,
-                            _gnutls_server_name_send_params);
-  if (ret != GNUTLS_E_SUCCESS)
-    return ret;
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
-                            "SAFE_RENEGOTIATION",
-                            GNUTLS_EXT_MANDATORY,
-                            _gnutls_safe_renegotiation_recv_params,
-                            _gnutls_safe_renegotiation_send_params);
+  ret = _gnutls_ext_register (&ext_mod_server_name);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 
-#ifdef ENABLE_OPRFI
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_OPAQUE_PRF_INPUT,
-                            "OPAQUE_PRF_INPUT",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_oprfi_recv_params,
-                            _gnutls_oprfi_send_params);
+  ret = _gnutls_ext_register (&ext_mod_sr);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
-#endif
 
 #ifdef ENABLE_SRP
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_SRP,
-                            "SRP",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_srp_recv_params,
-                            _gnutls_srp_send_params);
+  ret = _gnutls_ext_register (&ext_mod_srp);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 #endif
 
+
 #ifdef ENABLE_SESSION_TICKET
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_SESSION_TICKET,
-                            "SESSION_TICKET",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_session_ticket_recv_params,
-                            _gnutls_session_ticket_send_params);
+  ret = _gnutls_ext_register (&ext_mod_session_ticket);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 #endif
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
-                            "SIGNATURE_ALGORITHMS",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_signature_algorithm_recv_params,
-                            _gnutls_signature_algorithm_send_params);
+  ret = _gnutls_ext_register (&ext_mod_sig);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 
@@ -384,6 +370,27 @@ _gnutls_ext_deinit (void)
   extfunc_size = 0;
 }
 
+int
+_gnutls_ext_register (extension_entry_st* mod)
+{
+  extension_entry_st *p;
+
+  p = gnutls_realloc (extfunc, sizeof (*extfunc) * (extfunc_size + 1));
+  if (!p)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  extfunc = p;
+
+  memcpy(&extfunc[extfunc_size], mod, sizeof(*mod));
+
+  extfunc_size++;
+
+  return GNUTLS_E_SUCCESS;
+}
+
 /**
  * gnutls_ext_register:
  * @type: the 16-bit integer referring to the extension type
@@ -405,23 +412,288 @@ gnutls_ext_register (int type,
                     gnutls_ext_recv_func recv_func,
                     gnutls_ext_send_func send_func)
 {
-  gnutls_extension_entry *p;
+extension_entry_st ee;
+
+  memset(&ee, 0, sizeof(ee));
+  
+  ee.type = type;
+  ee.name = name;
+  ee.parse_type = parse_type;
+  ee.recv_func = recv_func;
+  ee.send_func = send_func;
+    /* FIXME: Why is this exported? Should it be removed? */
+  return _gnutls_ext_register (&ee);
+}
 
-  p = gnutls_realloc (extfunc, sizeof (*extfunc) * (extfunc_size + 1));
-  if (!p)
+int _gnutls_ext_pack(gnutls_session_t session, gnutls_buffer_st* packed)
+{
+int i, ret;
+extension_priv_data_t data;
+int cur_size;
+void* size_pos;
+void* total_exts_pos;
+int exts = 0;
+
+  total_exts_pos = packed->data + packed->length;
+  
+  BUFFER_APPEND_NUM(packed, 0);
+
+  for (i = 0; i < extfunc_size; i++) 
     {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      ret = _gnutls_ext_get_session_data(session, extfunc[i].type, &data);
+      if (ret >= 0 && extfunc[i].pack_func != NULL) 
+        {
+         BUFFER_APPEND_NUM(packed, extfunc[i].type);
+         
+         size_pos = packed->data + packed->length;
+         
+         BUFFER_APPEND_NUM(packed, 0);
+         
+         cur_size = packed->length;
+         
+         ret = extfunc[i].pack_func(data, packed);
+         if (ret < 0) 
+           {
+             gnutls_assert();
+             return ret;
+           }
+         
+         exts++;
+         /* write the actual size */
+         _gnutls_write_uint32(packed->length-cur_size, size_pos);
+        }
     }
-  extfunc = p;
 
-  extfunc[extfunc_size].type = type;
-  extfunc[extfunc_size].name = name;
-  extfunc[extfunc_size].parse_type = parse_type;
-  extfunc[extfunc_size].recv_func = recv_func;
-  extfunc[extfunc_size].send_func = send_func;
+  _gnutls_write_uint32(exts, total_exts_pos);
 
-  extfunc_size++;
+  return 0;
+    
+}
 
-  return GNUTLS_E_SUCCESS;
+void _gnutls_ext_restore_resumed_session(gnutls_session_t session)
+{
+int i;
+
+
+  /* clear everything except MANDATORY extensions */
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.extension_int_data[i].set != 0 && 
+          _gnutls_ext_parse_type(session->internals.extension_int_data[i].type) != GNUTLS_EXT_MANDATORY)
+        {
+          _gnutls_ext_unset_session_data(session, session->internals.extension_int_data[i].type);
+        }
+    }
+
+  /* copy resumed to main */
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.resumed_extension_int_data[i].set != 0 && 
+          _gnutls_ext_parse_type(session->internals.resumed_extension_int_data[i].type) != GNUTLS_EXT_MANDATORY)
+        {
+          _gnutls_ext_set_session_data(session, session->internals.resumed_extension_int_data[i].type, 
+              session->internals.resumed_extension_int_data[i].priv);
+          session->internals.resumed_extension_int_data[i].set = 0;
+        }
+    }
+
+}
+
+
+static void _gnutls_ext_set_resumed_session_data(gnutls_session_t session, uint16_t type, 
+    extension_priv_data_t data)
+{
+int i;
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.resumed_extension_int_data[i].type == type)
+       {
+           
+           if (session->internals.resumed_extension_int_data[i].set != 0)
+             _gnutls_ext_unset_resumed_session_data(session, type);
+
+           session->internals.resumed_extension_int_data[i].type = type;
+           session->internals.resumed_extension_int_data[i].priv = data;
+           session->internals.resumed_extension_int_data[i].set = 1;
+           return;
+        }
+    }
+}
+
+int _gnutls_ext_unpack(gnutls_session_t session, gnutls_buffer_st* packed)
+{
+int i, ret;
+extension_priv_data_t data;
+gnutls_ext_unpack_func unpack;
+int max_exts = 0;
+uint16_t type;
+int size_for_type, cur_pos;
+
+  BUFFER_POP_NUM(packed, max_exts);
+  for (i = 0; i < max_exts; i++) 
+    {
+      BUFFER_POP_NUM(packed, type);
+      BUFFER_POP_NUM(packed, size_for_type);
+    
+      cur_pos = packed->length;
+
+      unpack = _gnutls_ext_func_unpack(type);
+      if (unpack == NULL)
+        {
+         gnutls_assert();
+         return GNUTLS_E_PARSING_ERROR;
+       }
+    
+      ret = unpack(packed, &data);
+      if (ret < 0) 
+       {
+         gnutls_assert();
+         return ret;
+       }
+      
+      /* verify that unpack read the correct bytes */
+      cur_pos = cur_pos - packed->length;
+      if (cur_pos /* read length */ != size_for_type)
+        {
+         gnutls_assert();
+         return GNUTLS_E_PARSING_ERROR;
+       }
+      _gnutls_ext_set_resumed_session_data(session, type, data);
+    }
+
+  return 0;
+
+error:
+  return ret;    
+}
+
+void _gnutls_ext_unset_session_data(gnutls_session_t session, uint16_t type)
+{
+gnutls_ext_deinit_data_func deinit;
+extension_priv_data_t data;
+int ret, i;
+
+  deinit = _gnutls_ext_func_deinit (type);
+  ret = _gnutls_ext_get_session_data(session, type, &data);
+
+  if (ret >= 0 && deinit != NULL)
+    {
+       deinit(data);
+    }
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.extension_int_data[i].type == type)
+       {
+         session->internals.extension_int_data[i].set = 0;
+         return;
+        }
+    }
+
+}
+
+static void _gnutls_ext_unset_resumed_session_data(gnutls_session_t session, uint16_t type)
+{
+gnutls_ext_deinit_data_func deinit;
+extension_priv_data_t data;
+int ret, i;
+
+  deinit = _gnutls_ext_func_deinit (type);
+  ret = _gnutls_ext_get_resumed_session_data(session, type, &data);
+
+  if (ret >= 0 && deinit != NULL)
+    {
+       deinit(data);
+    }
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.resumed_extension_int_data[i].type == type)
+       {
+         session->internals.resumed_extension_int_data[i].set = 0;
+         return;
+        }
+    }
+
+}
+
+/* Deinitializes all data that are associated with TLS extensions.
+ */
+void _gnutls_ext_free_session_data(gnutls_session_t session)
+{
+int i;
+
+  for (i = 0; i < extfunc_size; i++) 
+    {
+      _gnutls_ext_unset_session_data(session, extfunc[i].type);
+    }
+
+  for (i = 0; i < extfunc_size; i++) 
+    {
+      _gnutls_ext_unset_resumed_session_data(session, extfunc[i].type);
+    }
+
+}
+
+/* This function allows and extension to store data in the current session
+ * and retrieve them later on. We use functions instead of a pointer to a
+ * private pointer, to allow API additions by individual extensions.
+ */
+void _gnutls_ext_set_session_data(gnutls_session_t session, uint16_t type, 
+    extension_priv_data_t data)
+{
+int i;
+gnutls_ext_deinit_data_func deinit;
+
+  deinit = _gnutls_ext_func_deinit (type);
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.extension_int_data[i].type == type || session->internals.extension_int_data[i].set == 0)
+       {
+           if (session->internals.extension_int_data[i].set != 0)
+             {
+               if (deinit) deinit(session->internals.extension_int_data[i].priv);
+             }
+           session->internals.extension_int_data[i].type = type;
+           session->internals.extension_int_data[i].priv = data;
+           session->internals.extension_int_data[i].set = 1;
+           return;
+        }
+    }
+}
+
+int _gnutls_ext_get_session_data(gnutls_session_t session, 
+    uint16_t type, extension_priv_data_t* data)
+{
+int i;
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.extension_int_data[i].set != 0 &&
+        session->internals.extension_int_data[i].type == type)
+       {
+           *data = session->internals.extension_int_data[i].priv;
+           return 0;
+        }
+    }
+  return GNUTLS_E_INVALID_REQUEST;
+}
+
+int _gnutls_ext_get_resumed_session_data(gnutls_session_t session, 
+    uint16_t type, extension_priv_data_t* data)
+{
+int i;
+
+  for (i=0;i<MAX_EXT_TYPES;i++) 
+    {
+      if (session->internals.resumed_extension_int_data[i].set != 0 && 
+        session->internals.resumed_extension_int_data[i].type == type)
+       {
+           *data = session->internals.resumed_extension_int_data[i].priv;
+           return 0;
+        }
+    }
+  return GNUTLS_E_INVALID_REQUEST;
 }
index 6c6f891793b0d0d9f66e304cf292c237960f33bd..3c450e89935be1f07f3a0a599a6625ec8a09b1d5 100644 (file)
@@ -23,6 +23,9 @@
  *
  */
 
+#ifndef GNUTLS_EXTENSIONS_H
+#define GNUTLS_EXTENSIONS_H
+
 int _gnutls_parse_extensions (gnutls_session_t session,
                              gnutls_ext_parse_type_t parse_type,
                              const opaque * data, int data_size);
@@ -32,3 +35,56 @@ int _gnutls_ext_init (void);
 void _gnutls_ext_deinit (void);
 
 void _gnutls_extension_list_add (gnutls_session_t session, uint16_t type);
+
+typedef void (*gnutls_ext_deinit_data_func) (extension_priv_data_t data);
+typedef int (*gnutls_ext_pack_func) (extension_priv_data_t data, gnutls_buffer_st* packed_data);
+typedef int (*gnutls_ext_unpack_func) (gnutls_buffer_st* packed_data, extension_priv_data_t* data);
+
+void _gnutls_ext_free_session_data(gnutls_session_t session);
+
+/* functions to be used by extensions internally
+ */
+void _gnutls_ext_unset_session_data(gnutls_session_t session, uint16_t type);
+void _gnutls_ext_set_session_data(gnutls_session_t session, uint16_t type, 
+    extension_priv_data_t);
+int _gnutls_ext_get_session_data(gnutls_session_t session, 
+    uint16_t type, extension_priv_data_t*);
+int _gnutls_ext_get_resumed_session_data(gnutls_session_t session,
+    uint16_t type, extension_priv_data_t* data);
+
+void _gnutls_ext_restore_resumed_session(gnutls_session_t session);
+
+/* for session packing */
+int _gnutls_ext_pack(gnutls_session_t session, gnutls_buffer_st* packed);
+int _gnutls_ext_unpack(gnutls_session_t session, gnutls_buffer_st* packed);
+
+typedef struct
+{
+  const char *name;
+  uint16_t type;
+  gnutls_ext_parse_type_t parse_type;
+
+  /* this function must return 0 when Not Applicable
+   * size of extension data if ok
+   * < 0 on other error.
+   */
+  gnutls_ext_recv_func recv_func;
+
+  /* this function must return 0 when Not Applicable
+   * size of extension data if ok
+   * GNUTLS_E_INT_RET_0 if extension data size is zero
+   * < 0 on other error.
+   */
+  gnutls_ext_send_func send_func;
+  
+  gnutls_ext_deinit_data_func deinit_func; /* this will be called to deinitialize
+       * internal data 
+       */
+  gnutls_ext_pack_func pack_func; /* packs internal data to machine independent format */
+  gnutls_ext_unpack_func unpack_func; /* unpacks internal data */
+  
+} extension_entry_st;
+
+int _gnutls_ext_register (extension_entry_st*);
+
+#endif
index 95bbb3ddcd3555cf069db74093951e18f4cd0daa..278c7c6a8cf7ff2c6e3af1fd064378cd3fd9d4e5 100644 (file)
@@ -697,27 +697,12 @@ _gnutls_send_finished (gnutls_session_t session, int again)
       if (session->internals.finished_func)
        session->internals.finished_func (session, data, vdata_size);
 
-      /* Save data for safe renegotiation. 
-       */
-      if (vdata_size > MAX_VERIFY_DATA_SIZE)
-       {
-         gnutls_assert ();
-         return GNUTLS_E_INTERNAL_ERROR;
-       }
-
-       if (session->security_parameters.entity == GNUTLS_CLIENT)
-         {
-           session->security_parameters.extensions.client_verify_data_len =
-           vdata_size;
-
-           memcpy (session->security_parameters.extensions.client_verify_data, data, vdata_size);
-         }
-       else
-         {
-           session->security_parameters.extensions.server_verify_data_len = vdata_size;
-           memcpy (session->security_parameters.extensions.server_verify_data,
-             data, vdata_size);
-         }
+      ret = _gnutls_ext_sr_finished( session, data, vdata_size, 0);
+      if (ret < 0)
+        {
+         gnutls_assert();
+         return ret;
+       }
 
       ret = _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_FINISHED);
     }
@@ -739,7 +724,6 @@ _gnutls_recv_finished (gnutls_session_t session)
   int data_size;
   int ret;
   int vrfysize;
-  tls_ext_st *ext;
 
   ret =
     _gnutls_recv_handshake (session, &vrfy, &vrfysize,
@@ -797,24 +781,11 @@ _gnutls_recv_finished (gnutls_session_t session)
     }
   gnutls_free (vrfy);
 
-  /* Save peer's verify data for safe renegotiation */
-  if (data_size > MAX_VERIFY_DATA_SIZE)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
-    }
-
-  ext = &session->security_parameters.extensions;
-
-  if (session->security_parameters.entity == GNUTLS_CLIENT)
-    {
-      memcpy (ext->server_verify_data, data, data_size);
-      ext->server_verify_data_len = data_size;
-    }
-  else
+  ret = _gnutls_ext_sr_finished( session, data, data_size, 1);
+  if (ret < 0)
     {
-      memcpy (ext->client_verify_data, data, data_size);
-      ext->client_verify_data_len = data_size;
+      gnutls_assert();
+      return ret;
     }
 
   session->internals.initial_negotiation_completed = 1;
@@ -886,8 +857,12 @@ _gnutls_server_select_suite (gnutls_session_t session, opaque * data,
          {
            _gnutls_handshake_log
              ("HSK[%p]: Received safe renegotiation CS\n", session);
-           session->internals.safe_renegotiation_received = 1;
-           session->internals.connection_using_safe_renegotiation = 1;
+           retval = _gnutls_ext_sr_recv_cs(session);
+           if (retval < 0)
+             {
+               gnutls_assert();
+               return retval;
+             }
            break;
          }
       }
@@ -1938,7 +1913,7 @@ _gnutls_copy_comp_methods (gnutls_session_t session,
 /* This should be sufficient by now. It should hold all the extensions
  * plus the headers in a hello message.
  */
-#define MAX_EXT_DATA_LENGTH 1024
+#define MAX_EXT_DATA_LENGTH 4096
 
 /* This function sends the client hello handshake message.
  */
@@ -1976,10 +1951,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again)
          return GNUTLS_E_MEMORY_ERROR;
        }
       data = _mbuffer_get_udata_ptr(bufel);
-      extdatalen = MAX_EXT_DATA_LENGTH
-       +
-       session->internals.resumed_security_parameters.
-       extensions.session_ticket_len;
+      extdatalen = MAX_EXT_DATA_LENGTH;
 
       extdata = gnutls_malloc (extdatalen);
       if (extdata == NULL)
@@ -2079,7 +2051,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again)
 
       if (ret > 0)
        {
-         bufel = _mbuffer_append_data (bufel, extdata, ret);
+         bufel = _mbuffer_push_data (bufel, extdata, ret);
          if (bufel == NULL)
            {
              gnutls_assert ();
@@ -2103,7 +2075,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again)
       ret = _gnutls_copy_comp_methods (session, extdata, extdatalen);
       if (ret > 0)
        {
-         bufel = _mbuffer_append_data (bufel, extdata, ret);
+         bufel = _mbuffer_push_data (bufel, extdata, ret);
          if (bufel == NULL)
            {
              gnutls_assert ();
@@ -2137,7 +2109,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again)
 
       if (ret > 0)
        {
-         bufel = _mbuffer_append_data (bufel, extdata, ret);
+         bufel = _mbuffer_push_data (bufel, extdata, ret);
          if (bufel == NULL)
            {
              gnutls_assert ();
@@ -2176,28 +2148,6 @@ _gnutls_send_server_hello (gnutls_session_t session, int again)
 
   datalen = 0;
 
-#ifdef ENABLE_SRP
-  if (IS_SRP_KX
-      (_gnutls_cipher_suite_get_kx_algo
-       (&session->security_parameters.current_cipher_suite)))
-    {
-      /* While resuming we cannot check the username extension since it is
-       * not available at this point. It will be copied on connection
-       * state activation.
-       */
-      if (session->internals.resumed == RESUME_FALSE &&
-         session->security_parameters.extensions.srp_username[0] == 0)
-       {
-         /* The peer didn't send a valid SRP extension with the
-          * SRP username. The draft requires that we send a fatal
-          * alert and abort.
-          */
-         gnutls_assert ();
-         return GNUTLS_E_UNKNOWN_SRP_USERNAME;
-       }
-    }
-#endif
-
   if (again == 0)
     {
       datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE + 3;
@@ -2269,8 +2219,6 @@ _gnutls_send_hello (gnutls_session_t session, int again)
 {
   int ret;
 
-  session->internals.safe_renegotiation_received = 0;
-
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
       ret = _gnutls_send_client_hello (session, again);
@@ -2292,7 +2240,6 @@ int
 _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen)
 {
   int ret;
-  tls_ext_st *ext;
 
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
@@ -2314,101 +2261,14 @@ _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen)
        }
     }
 
-  if (session->internals.priorities.sr == SR_DISABLED)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  /* Safe renegotiation */
-  ext = &session->security_parameters.extensions;
-
-  if (session->internals.safe_renegotiation_received)
-    {
-      if ((ext->ri_extension_data_len < ext->client_verify_data_len) ||
-         (memcmp (ext->ri_extension_data,
-                  ext->client_verify_data, ext->client_verify_data_len)))
-       {
-         gnutls_assert ();
-         _gnutls_handshake_log ("HSK[%p]: Safe renegotiation failed [1]\n",
-                                session);
-         return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
-       }
-
-      if (session->security_parameters.entity == GNUTLS_CLIENT)
-       {
-         if ((ext->ri_extension_data_len !=
-              ext->client_verify_data_len + ext->server_verify_data_len) ||
-             memcmp (ext->ri_extension_data + ext->client_verify_data_len,
-                     ext->server_verify_data,
-                     ext->server_verify_data_len) != 0)
-           {
-             gnutls_assert ();
-             _gnutls_handshake_log
-               ("HSK[%p]: Safe renegotiation failed [2]\n", session);
-             return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
-           }
-       }
-      else                     /* Make sure there are 0 extra bytes */
-       {
-         if (ext->ri_extension_data_len != ext->client_verify_data_len)
-           {
-             gnutls_assert ();
-             _gnutls_handshake_log
-               ("HSK[%p]: Safe renegotiation failed [3]\n", session);
-             return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
-           }
-       }
-
-      _gnutls_handshake_log ("HSK[%p]: Safe renegotiation succeeded\n",
-                            session);
-    }
-  else /* safe renegotiation not received... */
+  ret = _gnutls_ext_sr_verify(session);
+  if (ret < 0)
     {
-      if (session->internals.connection_using_safe_renegotiation)
-       {
-         gnutls_assert ();
-         _gnutls_handshake_log
-           ("HSK[%p]: Peer previously asked for safe renegotiation\n",
-            session);
-         return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
-       }
-
-      /* Clients can't tell if it's an initial negotiation */
-      if (session->internals.initial_negotiation_completed)
-       {
-
-          if (session->internals.priorities.sr < SR_PARTIAL)
-           {
-             _gnutls_handshake_log
-               ("HSK[%p]: Allowing unsafe (re)negotiation\n", session);
-           }
-         else
-           {
-             gnutls_assert ();
-             _gnutls_handshake_log
-               ("HSK[%p]: Denying unsafe (re)negotiation\n", session);
-              return GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED;
-           }
-       }
-      else
-       {
-         if (session->internals.priorities.sr < SR_SAFE)
-           {
-             _gnutls_handshake_log
-               ("HSK[%p]: Allowing unsafe initial negotiation\n", session);
-           }
-         else
-           {
-             gnutls_assert ();
-             _gnutls_handshake_log
-               ("HSK[%p]: Denying unsafe initial negotiation\n", session);
-             return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
-           }
-       }
+       gnutls_assert();
+       return ret;
     }
 
-  return ret;
+  return 0;
 }
 
 /* The packets in gnutls_handshake (it's more broad than original TLS handshake)
@@ -2767,7 +2627,7 @@ _gnutls_handshake_client (gnutls_session_t session)
       IMED_RET ("recv hello", ret, 1);
 
     case STATE70:
-      if (session->security_parameters.extensions.do_recv_supplemental)
+      if (session->security_parameters.do_recv_supplemental)
        {
          ret = _gnutls_recv_supplemental (session);
          STATE = STATE70;
@@ -2808,7 +2668,7 @@ _gnutls_handshake_client (gnutls_session_t session)
       IMED_RET ("recv server hello done", ret, 1);
 
     case STATE71:
-      if (session->security_parameters.extensions.do_send_supplemental)
+      if (session->security_parameters.do_send_supplemental)
        {
          ret = _gnutls_send_supplemental (session, AGAIN (STATE71));
          STATE = STATE71;
@@ -2867,7 +2727,6 @@ _gnutls_send_handshake_final (gnutls_session_t session, int init)
          gnutls_assert ();
          return ret;
        }
-
       /* Initialize the connection session (start encryption) - in case of client 
        */
       if (init == TRUE)
@@ -2991,7 +2850,7 @@ _gnutls_handshake_server (gnutls_session_t session)
       IMED_RET ("send hello", ret, 0);
 
     case STATE70:
-      if (session->security_parameters.extensions.do_send_supplemental)
+      if (session->security_parameters.do_send_supplemental)
        {
          ret = _gnutls_send_supplemental (session, AGAIN (STATE70));
          STATE = STATE70;
@@ -3033,7 +2892,7 @@ _gnutls_handshake_server (gnutls_session_t session)
       IMED_RET ("send server hello done", ret, 0);
 
     case STATE71:
-      if (session->security_parameters.extensions.do_recv_supplemental)
+      if (session->security_parameters.do_recv_supplemental)
        {
          ret = _gnutls_recv_supplemental (session);
          STATE = STATE71;
@@ -3091,13 +2950,9 @@ _gnutls_handshake_common (gnutls_session_t session)
        {
        case STATE0:
        case STATE40:
-         if (session->internals.session_ticket_renew)
-           {
-             ret =
-               _gnutls_send_new_session_ticket (session, AGAIN (STATE40));
-             STATE = STATE40;
-             IMED_RET ("send handshake new session ticket", ret, 0);
-           }
+          ret = _gnutls_send_new_session_ticket (session, AGAIN (STATE40));
+          STATE = STATE40;
+          IMED_RET ("send handshake new session ticket", ret, 0);
          STATE = STATE0;
        default:
          break;
@@ -3125,12 +2980,9 @@ _gnutls_handshake_common (gnutls_session_t session)
        {
        case STATE0:
        case STATE41:
-         if (session->internals.session_ticket_renew)
-           {
-             ret = _gnutls_recv_new_session_ticket (session);
-             STATE = STATE41;
-             IMED_RET ("recv handshake new session ticket", ret, 1);
-           }
+          ret = _gnutls_recv_new_session_ticket (session);
+         STATE = STATE41;
+         IMED_RET ("recv handshake new session ticket", ret, 1);
          STATE = STATE0;
        default:
          break;
index aa727c16bffb0d3ba8bc51e7babf3fe04b0c607e..b099f111c08cfd796a5acf8cad4910490365c61a 100644 (file)
@@ -95,7 +95,7 @@ typedef struct
 
 /* we can receive up to MAX_EXT_TYPES extensions.
  */
-#define MAX_EXT_TYPES 64
+#define MAX_EXT_TYPES 32
 
 /* The initial size of the receive
  * buffer size. This will grow if larger
@@ -172,9 +172,6 @@ typedef enum extensions_t
 { GNUTLS_EXTENSION_SERVER_NAME = 0,
   GNUTLS_EXTENSION_MAX_RECORD_SIZE = 1,
   GNUTLS_EXTENSION_CERT_TYPE = 9,
-#ifdef ENABLE_OPRFI
-  GNUTLS_EXTENSION_OPAQUE_PRF_INPUT = ENABLE_OPRFI,
-#endif
   GNUTLS_EXTENSION_SRP = 12,
   GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS = 13,
   GNUTLS_EXTENSION_SESSION_TICKET = 35,
@@ -185,12 +182,8 @@ typedef enum extensions_t
 typedef enum
 { CIPHER_STREAM, CIPHER_BLOCK } cipher_type_t;
 
-typedef enum valid_session_t
-{ VALID_TRUE, VALID_FALSE } valid_session_t;
-typedef enum resumable_session_t
-{ RESUME_TRUE,
-  RESUME_FALSE
-} resumable_session_t;
+#define RESUME_TRUE 0
+#define RESUME_FALSE -1
 
 /* Record Protocol */
 typedef enum content_type_t
@@ -315,69 +308,10 @@ typedef struct
  * structures also - see SRP).
  */
 
-typedef struct
-{
-  opaque name[MAX_SERVER_NAME_SIZE];
-  unsigned name_length;
-  gnutls_server_name_type_t type;
-} server_name_st;
-
-#define MAX_SERVER_NAME_EXTENSIONS 3
 #define MAX_SIGNATURE_ALGORITHMS 16
 
-struct gnutls_session_ticket_key_st
-{
-  opaque key_name[SESSION_TICKET_KEY_NAME_SIZE];
-  opaque key[SESSION_TICKET_KEY_SIZE];
-  opaque mac_secret[SESSION_TICKET_MAC_SECRET_SIZE];
-};
-
 #define MAX_VERIFY_DATA_SIZE 36        /* in SSL 3.0, 12 in TLS 1.0 */
 
-/* If you want the extension data to be kept across resuming sessions
- * then modify CPY_EXTENSIONS in gnutls_constate.c
- */
-typedef struct
-{
-  server_name_st server_names[MAX_SERVER_NAME_EXTENSIONS];
-  /* limit server_name extensions */
-  unsigned server_names_size;
-
-  opaque srp_username[MAX_SRP_USERNAME + 1];
-
-  /* TLS 1.2 signature algorithms */
-  gnutls_sign_algorithm_t sign_algorithms[MAX_SIGNATURE_ALGORITHMS];
-  uint16_t sign_algorithms_size;
-
-  /* TLS/IA data. */
-  int gnutls_ia_enable, gnutls_ia_peer_enable;
-  int gnutls_ia_allowskip, gnutls_ia_peer_allowskip;
-
-  /* Used by extensions that enable supplemental data. */
-  int do_recv_supplemental, do_send_supplemental;
-
-  opaque *session_ticket;
-  uint16_t session_ticket_len;
-
-  /*** Those below do not get copied when resuming session 
-   ***/
-
-  /* Opaque PRF input. */
-  opaque *oprfi_client;
-  uint16_t oprfi_client_len;
-  opaque *oprfi_server;
-  uint16_t oprfi_server_len;
-
-  /* Safe renegotiation. */
-  uint8_t client_verify_data[MAX_VERIFY_DATA_SIZE];
-  size_t client_verify_data_len;
-  uint8_t server_verify_data[MAX_VERIFY_DATA_SIZE];
-  size_t server_verify_data_len;
-  uint8_t ri_extension_data[MAX_VERIFY_DATA_SIZE * 2]; /* max signal is 72 bytes in s->c sslv3 */
-  size_t ri_extension_data_len;
-
-} tls_ext_st;
-
 /* auth_info_t structures now MAY contain malloced 
  * elements.
  */
@@ -424,7 +358,6 @@ typedef struct
   opaque session_id[TLS_MAX_SESSION_ID_SIZE];
   uint8_t session_id_size;
   time_t timestamp;
-  tls_ext_st extensions;
 
   /* The send size is the one requested by the programmer.
    * The recv size is the one negotiated with the peer.
@@ -435,8 +368,14 @@ typedef struct
   gnutls_certificate_type_t cert_type;
   gnutls_protocol_t version;   /* moved here */
 
-  /* For TLS/IA.  XXX: Move to IA credential? */
-  opaque inner_secret[GNUTLS_MASTER_SIZE];
+  /* FIXME: The following are not saved in the session storage
+   * for session resumption.
+   */
+
+  /* Used by extensions that enable supplemental data: Which ones
+   * do that? Do they belong in security parameters?
+   */
+  int do_recv_supplemental, do_send_supplemental;
 } security_parameters_st;
 
 /* This structure holds the generated keys
@@ -529,6 +468,11 @@ typedef struct
   gnutls_handshake_description_t recv_type;
 } handshake_header_buffer_st;
 
+typedef union 
+{
+  void* ptr;
+  uint32_t num;
+} extension_priv_data_t;
 
 typedef struct
 {
@@ -552,7 +496,7 @@ typedef struct
 
   gnutls_buffer_st handshake_data_buffer;      /* this is a buffer that holds the current handshake message */
   gnutls_buffer_st ia_data_buffer;     /* holds inner application data (TLS/IA) */
-  resumable_session_t resumable;       /* TRUE or FALSE - if we can resume that session */
+  int resumable:1;     /* TRUE or FALSE - if we can resume that session */
   handshake_state_t handshake_state;   /* holds
                                         * a number which indicates where
                                         * the handshake procedure has been
@@ -560,12 +504,12 @@ typedef struct
                                         * no interruption has happened.
                                         */
 
-  valid_session_t valid_connection;    /* true or FALSE - if this session is valid */
+  int invalid_connection:1;    /* true or FALSE - if this session is valid */
 
-  int may_not_read;            /* if it's 0 then we can read/write, otherwise it's forbiden to read/write
+  int may_not_read:1;          /* if it's 0 then we can read/write, otherwise it's forbiden to read/write
                                 */
-  int may_not_write;
-  int read_eof;                        /* non-zero if we have received a closure alert. */
+  int may_not_write:1;
+  int read_eof:1;                      /* non-zero if we have received a closure alert. */
 
   int last_alert;              /* last alert received */
 
@@ -581,7 +525,7 @@ typedef struct
   struct gnutls_priority_st priorities;
 
   /* resumed session */
-  resumable_session_t resumed; /* RESUME_TRUE or FALSE - if we are resuming a session */
+  int resumed:1;       /* RESUME_TRUE or FALSE - if we are resuming a session */
   security_parameters_st resumed_security_parameters;
 
   /* sockets internals */
@@ -607,7 +551,7 @@ typedef struct
 
   /* 0 if no peeked data was kept, 1 otherwise.
    */
-  int have_peeked_data;
+  int have_peeked_data:1;
 
   int expire_time;             /* after expire_time seconds this session will expire */
   struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */
@@ -662,11 +606,6 @@ typedef struct
    */
   gnutls_handshake_post_client_hello_func user_hello_func;
 
-  /* Holds the record size requested by the
-   * user.
-   */
-  uint16_t proposed_record_size;
-
   /* holds the selected certificate and key.
    * use _gnutls_selected_certs_deinit() and _gnutls_selected_certs_set()
    * to change them.
@@ -674,7 +613,7 @@ typedef struct
   gnutls_cert *selected_cert_list;
   int selected_cert_list_length;
   struct gnutls_privkey_st *selected_key;
-  int selected_need_free;
+  int selected_need_free:1;
 
   /* holds the extensions we sent to the peer
    * (in case of a client)
@@ -691,8 +630,6 @@ typedef struct
    * record packet will have. */
   opaque default_record_version[2];
 
-  int cbc_protection_hack;
-
   void *user_ptr;
 
   int enable_private;          /* non zero to
@@ -721,9 +658,6 @@ typedef struct
    */
   opaque rsa_pms_version[2];
 
-  char *srp_username;
-  char *srp_password;
-
   /* Here we cache the DH or RSA parameters got from the
    * credentials structure, or from a callback. That is to
    * minimize external calls.
@@ -759,19 +693,19 @@ typedef struct
    */
   uint16_t srp_prime_bits;
 
-  int session_ticket_enable, session_ticket_renew;
-
-  int safe_renegotiation_received:1;
   int initial_negotiation_completed:1;
-  int connection_using_safe_renegotiation:1;
-
-  /* Oprfi */
-  gnutls_oprfi_callback_func oprfi_cb;
-  const void *oprfi_userdata;
 
-  /* Session Ticket */
-  struct gnutls_session_ticket_key_st *session_ticket_key;
-  opaque session_ticket_IV[SESSION_TICKET_IV_SIZE];
+  struct {
+      uint16_t type;
+      extension_priv_data_t priv;
+      int set:1;
+  } extension_int_data[MAX_EXT_TYPES];
+
+  struct {
+      uint16_t type;
+      extension_priv_data_t priv;
+      int set:1;
+  } resumed_extension_int_data[MAX_EXT_TYPES];
 
   /* If you add anything here, check _gnutls_handshake_internal_state_clear().
    */
index 9d3cae961623e398643f8f5edd124bc404ac9c4f..9f1f5a792762e7e7a8e6c97f190874586c54e78f 100644 (file)
@@ -39,6 +39,7 @@
 #include <gnutls_datum.h>
 #include <gnutls_rsa_export.h>
 #include <gnutls_mbuffers.h>
+#include "../libextra/ext_inner_application.h" /* isn't this too much? */
 
 /* This is a temporary function to be used before the generate_*
    internal API is changed to use mbuffers. For now we don't avoid the
@@ -123,64 +124,6 @@ generate_normal_master (gnutls_session_t session, int keep_premaster)
                                      security_parameters.master_secret);
 
     }
-  else if (session->security_parameters.extensions.oprfi_client_len > 0 &&
-          session->security_parameters.extensions.oprfi_server_len > 0)
-    {
-      opaque *rnd;
-      size_t rndlen = 2 * GNUTLS_RANDOM_SIZE;
-
-      rndlen += session->security_parameters.extensions.oprfi_client_len;
-      rndlen += session->security_parameters.extensions.oprfi_server_len;
-
-      rnd = gnutls_malloc (rndlen + 1);
-      if (!rnd)
-       {
-         gnutls_assert ();
-         return GNUTLS_E_MEMORY_ERROR;
-       }
-
-      _gnutls_hard_log ("INT: CLIENT OPRFI[%d]: %s\n",
-                       session->security_parameters.extensions.
-                       oprfi_server_len,
-                       _gnutls_bin2hex (session->
-                                        security_parameters.extensions.
-                                        oprfi_client,
-                                        session->
-                                        security_parameters.extensions.
-                                        oprfi_client_len, buf,
-                                        sizeof (buf), NULL));
-      _gnutls_hard_log ("INT: SERVER OPRFI[%d]: %s\n",
-                       session->security_parameters.extensions.
-                       oprfi_server_len,
-                       _gnutls_bin2hex (session->
-                                        security_parameters.extensions.
-                                        oprfi_server,
-                                        session->
-                                        security_parameters.extensions.
-                                        oprfi_server_len, buf,
-                                        sizeof (buf), NULL));
-
-      memcpy (rnd, session->security_parameters.client_random,
-             GNUTLS_RANDOM_SIZE);
-      memcpy (rnd + GNUTLS_RANDOM_SIZE,
-             session->security_parameters.extensions.oprfi_client,
-             session->security_parameters.extensions.oprfi_client_len);
-      memcpy (rnd + GNUTLS_RANDOM_SIZE +
-             session->security_parameters.extensions.oprfi_client_len,
-             session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
-      memcpy (rnd + GNUTLS_RANDOM_SIZE +
-             session->security_parameters.extensions.oprfi_client_len +
-             GNUTLS_RANDOM_SIZE,
-             session->security_parameters.extensions.oprfi_server,
-             session->security_parameters.extensions.oprfi_server_len);
-
-      ret = _gnutls_PRF (session, PREMASTER.data, PREMASTER.size,
-                        MASTER_SECRET, strlen (MASTER_SECRET),
-                        rnd, rndlen, GNUTLS_MASTER_SIZE,
-                        session->security_parameters.master_secret);
-
-      gnutls_free (rnd);
-    }
   else
     {
       opaque rnd[2 * GNUTLS_RANDOM_SIZE + 1];
@@ -198,8 +141,7 @@ generate_normal_master (gnutls_session_t session, int keep_premaster)
     }
 
   /* TLS/IA inner secret is derived from the master secret. */
-  memcpy (session->security_parameters.inner_secret,
-         session->security_parameters.master_secret, GNUTLS_MASTER_SIZE);
+  _gnutls_ia_derive_inner_secret(session);
 
   if (!keep_premaster)
     _gnutls_free_datum (&PREMASTER);
index 2c9e9d8135dc4abee5d7762d0b4566fddf774bd1..db9763bc4b2e84419d5fce36143450a5b54b65a9 100644 (file)
@@ -152,7 +152,7 @@ _mbuffer_alloc (size_t payload_size)
 }
 
 mbuffer_st*
-_mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size)
+_mbuffer_push_data (mbuffer_st *bufel, void* newdata, size_t newdata_size)
 {
   bufel = gnutls_realloc_fast (bufel, bufel->msg.size+newdata_size+sizeof (mbuffer_st));
   if (bufel == NULL)
index a1a6065328e23da9bcc617841b6b5e02c6411f76..3580a420e21ca705073e1533e73822aea81e2855 100644 (file)
@@ -37,7 +37,7 @@ mbuffer_st* _mbuffer_alloc (size_t payload_size);
 /* This is dangerous since it will replace bufel with a new
  * one.
  */
-mbuffer_st* _mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size);
+mbuffer_st* _mbuffer_push_data (mbuffer_st *bufel, void* newdata, size_t newdata_size);
 
 
 /* For "user" use. One can have buffer data and header.
index a3a0409e7180a3feea9cfcd0291746a3bd57b6d6..c2c3a9b30a7deffd30fa25e7d108dedf3d40e738 100644 (file)
@@ -273,7 +273,7 @@ gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
 inline static void
 session_invalidate (gnutls_session_t session)
 {
-  session->internals.valid_connection = VALID_FALSE;
+  session->internals.invalid_connection = 1;
 }
 
 
@@ -288,7 +288,7 @@ session_unresumable (gnutls_session_t session)
 inline static int
 session_is_valid (gnutls_session_t session)
 {
-  if (session->internals.valid_connection == VALID_FALSE)
+  if (session->internals.invalid_connection != 0)
     return GNUTLS_E_INVALID_SESSION;
 
   return 0;
@@ -1173,64 +1173,3 @@ gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
                           sizeofdata);
 }
 
-/**
- * gnutls_record_get_max_size:
- * @session: is a #gnutls_session_t structure.
- *
- * Get the record size.  The maximum record size is negotiated by the
- * client after the first handshake message.
- *
- * Returns: The maximum record packet size in this connection.
- **/
-size_t
-gnutls_record_get_max_size (gnutls_session_t session)
-{
-  /* Recv will hold the negotiated max record size
-   * always.
-   */
-  return session->security_parameters.max_record_recv_size;
-}
-
-
-/**
- * gnutls_record_set_max_size:
- * @session: is a #gnutls_session_t structure.
- * @size: is the new size
- *
- * This function sets the maximum record packet size in this
- * connection.  This property can only be set to clients.  The server
- * may choose not to accept the requested size.
- *
- * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
- * 4096(=2^12).  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.
- *
- * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
- *   otherwise an error code is returned.
- **/
-ssize_t
-gnutls_record_set_max_size (gnutls_session_t session, size_t size)
-{
-  ssize_t new_size;
-
-  if (session->security_parameters.entity == GNUTLS_SERVER)
-    return GNUTLS_E_INVALID_REQUEST;
-
-  new_size = _gnutls_mre_record2num (size);
-
-  if (new_size < 0)
-    {
-      gnutls_assert ();
-      return new_size;
-    }
-
-  session->security_parameters.max_record_send_size = size;
-
-  session->internals.proposed_record_size = size;
-
-  return 0;
-}
index 0ca3b0c29f22b9a6d45ec2faf4739394c09e917e..03e7909cd25402886156624c5a2165fa26117293 100644 (file)
 #include <gnutls_session_pack.h>
 #include <gnutls_datum.h>
 #include <gnutls_num.h>
+#include <gnutls_extensions.h>
 
-#define PACK_HEADER_SIZE 1
-#define MAX_SEC_PARAMS 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+165
 static int pack_certificate_auth_info (gnutls_session_t,
-                                      gnutls_datum_t * packed_session);
+                                      gnutls_buffer_st * packed_session);
 static int unpack_certificate_auth_info (gnutls_session_t,
-                                        const gnutls_datum_t *
+                                        gnutls_buffer_st *
                                         packed_session);
 
 static int unpack_srp_auth_info (gnutls_session_t session,
-                                const gnutls_datum_t * packed_session);
+                                gnutls_buffer_st * packed_session);
 static int pack_srp_auth_info (gnutls_session_t session,
-                              gnutls_datum_t * packed_session);
+                              gnutls_buffer_st * packed_session);
 
 static int unpack_psk_auth_info (gnutls_session_t session,
-                                const gnutls_datum_t * packed_session);
+                                gnutls_buffer_st * packed_session);
 static int pack_psk_auth_info (gnutls_session_t session,
-                              gnutls_datum_t * packed_session);
+                              gnutls_buffer_st * packed_session);
 
 static int unpack_anon_auth_info (gnutls_session_t session,
-                                 const gnutls_datum_t * packed_session);
+                                 gnutls_buffer_st * packed_session);
 static int pack_anon_auth_info (gnutls_session_t session,
-                               gnutls_datum_t * packed_session);
+                               gnutls_buffer_st * packed_session);
 
 static int unpack_security_parameters (gnutls_session_t session,
-                                      const gnutls_datum_t * packed_session);
+                                      gnutls_buffer_st * packed_session);
 static int pack_security_parameters (gnutls_session_t session,
-                                    gnutls_datum_t * packed_session);
+                                    gnutls_buffer_st * packed_session);
 
 
 /* Since auth_info structures contain malloced data, this function
@@ -84,6 +83,8 @@ _gnutls_session_pack (gnutls_session_t session,
                      gnutls_datum_t * packed_session)
 {
   int ret;
+  gnutls_buffer_st sb;
+  opaque id;
 
   if (packed_session == NULL)
     {
@@ -91,12 +92,16 @@ _gnutls_session_pack (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
+  _gnutls_buffer_init(&sb);
 
-  switch (gnutls_auth_get_type (session))
+  id = gnutls_auth_get_type (session);
+  BUFFER_APPEND(&sb, &id, 1);
+
+  switch (id)
     {
 #ifdef ENABLE_SRP
     case GNUTLS_CRD_SRP:
-      ret = pack_srp_auth_info (session, packed_session);
+      ret = pack_srp_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -106,7 +111,7 @@ _gnutls_session_pack (gnutls_session_t session,
 #endif
 #ifdef ENABLE_PSK
     case GNUTLS_CRD_PSK:
-      ret = pack_psk_auth_info (session, packed_session);
+      ret = pack_psk_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -116,7 +121,7 @@ _gnutls_session_pack (gnutls_session_t session,
 #endif
 #ifdef ENABLE_ANON
     case GNUTLS_CRD_ANON:
-      ret = pack_anon_auth_info (session, packed_session);
+      ret = pack_anon_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -125,7 +130,7 @@ _gnutls_session_pack (gnutls_session_t session,
       break;
 #endif
     case GNUTLS_CRD_CERTIFICATE:
-      ret = pack_certificate_auth_info (session, packed_session);
+      ret = pack_certificate_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -140,15 +145,25 @@ _gnutls_session_pack (gnutls_session_t session,
   /* Auth_info structures copied. Now copy security_parameters_st. 
    * packed_session must have allocated space for the security parameters.
    */
-  ret = pack_security_parameters (session, packed_session);
+  ret = pack_security_parameters (session, &sb);
   if (ret < 0)
     {
       gnutls_assert ();
-      _gnutls_free_datum (packed_session);
+      _gnutls_buffer_clear(&sb);
       return ret;
     }
-
-  return 0;
+    
+  ret = _gnutls_ext_pack(session, &sb);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      _gnutls_buffer_clear(&sb);
+      return ret;
+    }
+  
+  ret =  _gnutls_buffer_to_datum(&sb, packed_session);
+  
+  return ret;
 }
 
 
@@ -159,6 +174,10 @@ _gnutls_session_unpack (gnutls_session_t session,
                        const gnutls_datum_t * packed_session)
 {
   int ret;
+  gnutls_buffer_st sb;
+  opaque id;
+  
+  _gnutls_buffer_init(&sb);
 
   if (packed_session == NULL || packed_session->size == 0)
     {
@@ -166,36 +185,45 @@ _gnutls_session_unpack (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
+  ret = _gnutls_buffer_append_data(&sb, packed_session->data, packed_session->size);
+  if (ret < 0) 
+    {
+      gnutls_assert();
+      return ret;
+    }
+
   if (_gnutls_get_auth_info (session) != NULL)
     {
       _gnutls_free_auth_info (session);
     }
 
-  switch (packed_session->data[0])
+  BUFFER_POP(&sb, &id, 1);
+
+  switch (id)
     {
 #ifdef ENABLE_SRP
     case GNUTLS_CRD_SRP:
-      ret = unpack_srp_auth_info (session, packed_session);
+      ret = unpack_srp_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
-         return ret;
+         goto error;
        }
       break;
 #endif
 #ifdef ENABLE_PSK
     case GNUTLS_CRD_PSK:
-      ret = unpack_psk_auth_info (session, packed_session);
+      ret = unpack_psk_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
-         return ret;
+         goto error;
        }
       break;
 #endif
 #ifdef ENABLE_ANON
     case GNUTLS_CRD_ANON:
-      ret = unpack_anon_auth_info (session, packed_session);
+      ret = unpack_anon_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -204,33 +232,47 @@ _gnutls_session_unpack (gnutls_session_t session,
       break;
 #endif
     case GNUTLS_CRD_CERTIFICATE:
-      ret = unpack_certificate_auth_info (session, packed_session);
+      ret = unpack_certificate_auth_info (session, &sb);
       if (ret < 0)
        {
          gnutls_assert ();
-         return ret;
+         goto error;
        }
       break;
     default:
       gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      ret = GNUTLS_E_INTERNAL_ERROR;
+      goto error;
 
     }
 
   /* Auth_info structures copied. Now copy security_parameters_st. 
    * packed_session must have allocated space for the security parameters.
    */
-  ret = unpack_security_parameters (session, packed_session);
+  ret = unpack_security_parameters (session, &sb);
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
+      goto error;
+    }
+    
+  ret = _gnutls_ext_unpack(session, &sb);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto error;
     }
 
-  return 0;
+  ret = 0;
+
+error:
+  _gnutls_buffer_clear(&sb);
+  
+  return ret;
 }
 
 
+
 /* Format: 
  *      1 byte the credentials type
  *      4 bytes the size of the whole structure
@@ -255,78 +297,37 @@ _gnutls_session_unpack (gnutls_session_t session,
  */
 static int
 pack_certificate_auth_info (gnutls_session_t session,
-                           gnutls_datum_t * packed_session)
+                           gnutls_buffer_st * ps)
 {
-  unsigned int pos = 0, i;
-  int cert_size, pack_size;
+  unsigned int i;
+  int cur_size, ret;
   cert_auth_info_t info = _gnutls_get_auth_info (session);
+  void* size_pos;
 
-  if (info)
-    {
-      cert_size = 4;
+  size_pos = ps->data + ps->length; 
 
-      for (i = 0; i < info->ncerts; i++)
-       cert_size += 4 + info->raw_certificate_list[i].size;
-
-      pack_size = 2 + 4 + info->dh.prime.size +
-       4 + info->dh.generator.size + 4 + info->dh.public_key.size +
-       4 + info->rsa_export.modulus.size +
-       4 + info->rsa_export.exponent.size + cert_size;
-    }
-  else
-    pack_size = 0;
-
-  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
-
-  /* calculate the size and allocate the data.
-   */
-  packed_session->data =
-    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS + 2 +
-                  session->security_parameters.extensions.
-                  session_ticket_len);
+  BUFFER_APPEND_NUM(ps, 0);
+  cur_size = ps->length;
 
-  if (packed_session->data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  packed_session->data[0] = GNUTLS_CRD_CERTIFICATE;
-  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
-  pos += 4 + PACK_HEADER_SIZE;
-
-
-  if (pack_size > 0)
+  if (info)
     {
 
-      _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
-      pos += 2;
-
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
-      pos += 4 + info->dh.prime.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
-      pos += 4 + info->dh.generator.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
-      pos += 4 + info->dh.public_key.size;
+      BUFFER_APPEND_NUM( ps, info->dh.secret_bits);
+      BUFFER_APPEND_PFX( ps, info->dh.prime.data, info->dh.prime.size);
+      BUFFER_APPEND_PFX( ps, info->dh.generator.data, info->dh.generator.size);
+      BUFFER_APPEND_PFX( ps, info->dh.public_key.data, info->dh.public_key.size);
+      BUFFER_APPEND_PFX( ps, info->rsa_export.modulus.data, info->rsa_export.modulus.size);
+      BUFFER_APPEND_PFX( ps, info->rsa_export.exponent.data, info->rsa_export.exponent.size);
 
-      _gnutls_write_datum32 (&packed_session->data[pos],
-                            info->rsa_export.modulus);
-      pos += 4 + info->rsa_export.modulus.size;
-      _gnutls_write_datum32 (&packed_session->data[pos],
-                            info->rsa_export.exponent);
-      pos += 4 + info->rsa_export.exponent.size;
-
-      _gnutls_write_uint32 (info->ncerts, &packed_session->data[pos]);
-      pos += 4;
+      BUFFER_APPEND_NUM( ps, info->ncerts);
 
       for (i = 0; i < info->ncerts; i++)
-       {
-         _gnutls_write_datum32 (&packed_session->data[pos],
-                                info->raw_certificate_list[i]);
-         pos += sizeof (uint32_t) + info->raw_certificate_list[i].size;
-       }
+        BUFFER_APPEND_PFX( ps, info->raw_certificate_list[i].data, info->raw_certificate_list[i].size);
     }
 
+  /* write the real size */
+  _gnutls_write_uint32(ps->length-cur_size, size_pos);
+
   return 0;
 }
 
@@ -335,32 +336,18 @@ pack_certificate_auth_info (gnutls_session_t session,
  */
 static int
 unpack_certificate_auth_info (gnutls_session_t session,
-                             const gnutls_datum_t * packed_session)
+                             gnutls_buffer_st * ps)
 {
-  int pos = 0, size, ret;
-  unsigned int i = 0, j;
+  int ret;
+  unsigned int i = 0, j = 0;
   size_t pack_size;
-  cert_auth_info_t info;
-
-  if (packed_session->data[0] != GNUTLS_CRD_CERTIFICATE)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
+  cert_auth_info_t info = NULL;
 
-  pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
-  pos += PACK_HEADER_SIZE + 4;
+  BUFFER_POP_NUM(ps, pack_size);
 
   if (pack_size == 0)
     return 0;                  /* nothing to be done */
 
-  /* a simple check for integrity */
-  if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
   /* client and server have the same auth_info here
    */
   ret =
@@ -379,113 +366,49 @@ unpack_certificate_auth_info (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
-  info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
-
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
-
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
-                      size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
-
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->rsa_export.modulus,
-                      &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
+  BUFFER_POP_NUM(ps, info->dh.secret_bits);
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->rsa_export.exponent,
-                      &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
+  BUFFER_POP_DATUM(ps, &info->dh.prime);
+  BUFFER_POP_DATUM(ps, &info->dh.generator);
+  BUFFER_POP_DATUM(ps, &info->dh.public_key);
+  BUFFER_POP_DATUM(ps, &info->rsa_export.modulus);
+  BUFFER_POP_DATUM(ps, &info->rsa_export.exponent);
 
-  info->ncerts = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
+  BUFFER_POP_NUM(ps, info->ncerts);
 
   if (info->ncerts > 0)
     {
-      info->raw_certificate_list =
-       gnutls_calloc (info->ncerts, sizeof (gnutls_datum_t));
+      info->raw_certificate_list = gnutls_calloc (info->ncerts, sizeof (gnutls_datum_t));
       if (info->raw_certificate_list == NULL)
-       {
-         gnutls_assert ();
-         ret = GNUTLS_E_MEMORY_ERROR;
-         goto error;
-       }
+        {
+          gnutls_assert ();
+          ret = GNUTLS_E_MEMORY_ERROR;
+          goto error;
+        }
     }
 
   for (i = 0; i < info->ncerts; i++)
     {
-      size = _gnutls_read_uint32 (&packed_session->data[pos]);
-      pos += sizeof (uint32_t);
-
-      ret =
-       _gnutls_set_datum (&info->raw_certificate_list[i],
-                          &packed_session->data[pos], size);
-      pos += size;
-
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         goto error;
-       }
+      BUFFER_POP_DATUM(ps, &info->raw_certificate_list[i]);
     }
 
-
   return 0;
 
 error:
-  _gnutls_free_datum (&info->dh.prime);
-  _gnutls_free_datum (&info->dh.generator);
-  _gnutls_free_datum (&info->dh.public_key);
+  if (info)
+    {
+      _gnutls_free_datum (&info->dh.prime);
+      _gnutls_free_datum (&info->dh.generator);
+      _gnutls_free_datum (&info->dh.public_key);
 
-  _gnutls_free_datum (&info->rsa_export.modulus);
-  _gnutls_free_datum (&info->rsa_export.exponent);
+      _gnutls_free_datum (&info->rsa_export.modulus);
+      _gnutls_free_datum (&info->rsa_export.exponent);
 
-  for (j = 0; j < i; j++)
-    _gnutls_free_datum (&info->raw_certificate_list[j]);
+      for (j = 0; j < i; j++)
+        _gnutls_free_datum (&info->raw_certificate_list[j]);
 
-  gnutls_free (info->raw_certificate_list);
+      gnutls_free (info->raw_certificate_list);
+    }
 
   return ret;
 
@@ -501,37 +424,27 @@ error:
  *      x bytes the SRP username
  */
 static int
-pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
+pack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
 {
   srp_server_auth_info_t info = _gnutls_get_auth_info (session);
-  int pack_size;
+  int len, ret;
+  void* size_pos;
+  size_t cur_size;
 
   if (info && info->username)
-    pack_size = strlen (info->username) + 1;   /* include the terminating null */
+    len = strlen (info->username) + 1; /* include the terminating null */
   else
-    pack_size = 0;
+    len = 0;
 
-  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
+  size_pos = ps->data + ps->length;
 
-  /* calculate the size and allocate the data.
-   */
-  packed_session->data =
-    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS + 2 +
-                  session->security_parameters.extensions.
-                  session_ticket_len);
+  BUFFER_APPEND_NUM(ps, 0);
+  cur_size = ps->length;
 
-  if (packed_session->data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  packed_session->data[0] = GNUTLS_CRD_SRP;
-  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
+  BUFFER_APPEND_PFX(ps, info->username, len);
 
-  if (pack_size > 0)
-    memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
-           info->username, pack_size + 1);
+  /* write the real size */
+  _gnutls_write_uint32(ps->length-cur_size, size_pos);
 
   return 0;
 }
@@ -539,30 +452,19 @@ pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
 
 static int
 unpack_srp_auth_info (gnutls_session_t session,
-                     const gnutls_datum_t * packed_session)
+                     gnutls_buffer_st * ps)
 {
   size_t username_size;
   int ret;
   srp_server_auth_info_t info;
 
-  if (packed_session->data[0] != GNUTLS_CRD_SRP)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  username_size =
-    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
-
-  if (username_size == 0)
-    return 0;                  /* nothing to be done */
-
-  /* a simple check for integrity */
-  if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
+  BUFFER_POP_NUM(ps, username_size);
+  if (username_size > sizeof(info->username)) 
     {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
+      gnutls_assert();
+      return GNUTLS_E_INTERNAL_ERROR;
     }
+      
 
   ret =
     _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
@@ -580,11 +482,12 @@ unpack_srp_auth_info (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
-  memcpy (info->username,
-         &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
-         username_size);
+  BUFFER_POP(ps, info->username, username_size);
 
-  return 0;
+  ret = 0;
+  
+error:
+  return ret;
 }
 #endif
 
@@ -606,50 +509,27 @@ unpack_srp_auth_info (gnutls_session_t session,
  */
 static int
 pack_anon_auth_info (gnutls_session_t session,
-                    gnutls_datum_t * packed_session)
+                    gnutls_buffer_st * ps)
 {
+  int cur_size, ret;
   anon_auth_info_t info = _gnutls_get_auth_info (session);
-  int pos = 0;
-  size_t pack_size;
-
-  if (info)
-    pack_size = 2 + 4 * 3 + info->dh.prime.size +
-      info->dh.generator.size + info->dh.public_key.size;
-  else
-    pack_size = 0;
+  void* size_pos;
 
-  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
+  size_pos = ps->data + ps->length;
 
-  /* calculate the size and allocate the data.
-   */
-  packed_session->data =
-    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS + 2 +
-                  session->security_parameters.extensions.
-                  session_ticket_len);
+  BUFFER_APPEND_NUM(ps, 0);
+  cur_size = ps->length;
 
-  if (packed_session->data == NULL)
+  if (info)
     {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      BUFFER_APPEND_NUM( ps, info->dh.secret_bits);
+      BUFFER_APPEND_PFX( ps, info->dh.prime.data, info->dh.prime.size);
+      BUFFER_APPEND_PFX( ps, info->dh.generator.data, info->dh.generator.size);
+      BUFFER_APPEND_PFX( ps, info->dh.public_key.data, info->dh.public_key.size);
     }
 
-  packed_session->data[0] = GNUTLS_CRD_ANON;
-  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
-  pos += 4 + PACK_HEADER_SIZE;
-
-  if (pack_size > 0)
-    {
-      _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
-      pos += 2;
-
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
-      pos += 4 + info->dh.prime.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
-      pos += 4 + info->dh.generator.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
-      pos += 4 + info->dh.public_key.size;
-
-    }
+  /* write the real size */
+  _gnutls_write_uint32(ps->length-cur_size, size_pos);
 
   return 0;
 }
@@ -657,33 +537,18 @@ pack_anon_auth_info (gnutls_session_t session,
 
 static int
 unpack_anon_auth_info (gnutls_session_t session,
-                      const gnutls_datum_t * packed_session)
+                       gnutls_buffer_st * ps)
 {
+  int ret;
   size_t pack_size;
-  int pos = 0, size, ret;
-  anon_auth_info_t info;
-
-  if (packed_session->data[0] != GNUTLS_CRD_ANON)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
-  pos += PACK_HEADER_SIZE + 4;
+  anon_auth_info_t info = NULL;
 
+  BUFFER_POP_NUM(ps, pack_size);
 
   if (pack_size == 0)
-    return 0;                  /* nothing to be done */
+    return 0;  /* nothing to be done */
 
-  /* a simple check for integrity */
-  if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  /* client and serer have the same auth_info here
+  /* client and server have the same auth_info here
    */
   ret =
     _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
@@ -701,48 +566,22 @@ unpack_anon_auth_info (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
-  info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
+  BUFFER_POP_NUM(ps, info->dh.secret_bits);
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
+  BUFFER_POP_DATUM(ps, &info->dh.prime);
+  BUFFER_POP_DATUM(ps, &info->dh.generator);
+  BUFFER_POP_DATUM(ps, &info->dh.public_key);
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
+  return 0;
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
-                      size);
-  if (ret < 0)
+error:
+  if (info)
     {
-      gnutls_assert ();
-      goto error;
+      _gnutls_free_datum (&info->dh.prime);
+      _gnutls_free_datum (&info->dh.generator);
+      _gnutls_free_datum (&info->dh.public_key);
     }
-  pos += size;
-
-  return 0;
 
-error:
-  _gnutls_free_datum (&info->dh.prime);
-  _gnutls_free_datum (&info->dh.generator);
-  _gnutls_free_datum (&info->dh.public_key);
   return ret;
 }
 #endif /* ANON */
@@ -766,108 +605,53 @@ error:
  *      x bytes the public key
  */
 static int
-pack_psk_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
+pack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
 {
   psk_auth_info_t info;
-  int pack_size, username_size = 0, hint_size = 0, pos;
+  int username_len;
+  int hint_len, ret;
+  void* size_pos;
+  size_t cur_size;
 
   info = _gnutls_get_auth_info (session);
 
-  if (info)
-    {
-      username_size = strlen (info->username) + 1;     /* include the terminating null */
-      hint_size = strlen (info->hint) + 1;     /* include the terminating null */
-
-      pack_size = 1 + 4 + 4 + username_size + 4 + hint_size +
-       +2 + 4 + info->dh.prime.size + 4 + info->dh.generator.size +
-       4 + info->dh.public_key.size;
-    }
+  if (info && info->username)
+    username_len = strlen (info->username) + 1;        /* include the terminating null */
   else
-    pack_size = 0;
+    username_len = 0;
 
-  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
-
-  /* calculate the size and allocate the data.
-   */
-  packed_session->data =
-    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS + 2 +
-                  session->security_parameters.extensions.
-                  session_ticket_len);
-
-  if (packed_session->data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  pos = 0;
-
-  packed_session->data[pos] = GNUTLS_CRD_PSK;
-  pos++;
-
-  _gnutls_write_uint32 (pack_size, &packed_session->data[pos]);
-  pos += 4;
-
-  if (pack_size > 0)
-    {
-      _gnutls_write_uint32 (username_size, &packed_session->data[pos]);
-      pos += 4;
-
-      memcpy (&packed_session->data[pos], info->username, username_size);
-      pos += username_size;
+  if (info && info->hint)
+    hint_len = strlen (info->hint) + 1;        /* include the terminating null */
+  else
+    hint_len = 0;
 
-      _gnutls_write_uint32 (hint_size, &packed_session->data[pos]);
-      pos += 4;
+  size_pos = ps->data + ps->length;
 
-      memcpy (&packed_session->data[pos], info->hint, hint_size);
-      pos += hint_size;
+  BUFFER_APPEND_NUM(ps, 0);
+  cur_size = ps->length;
 
-      _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
-      pos += 2;
+  BUFFER_APPEND_PFX(ps, info->username, username_len);
+  BUFFER_APPEND_PFX(ps, info->hint, hint_len);
 
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
-      pos += 4 + info->dh.prime.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
-      pos += 4 + info->dh.generator.size;
-      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
-      pos += 4 + info->dh.public_key.size;
-    }
+  BUFFER_APPEND_NUM( ps, info->dh.secret_bits);
+  BUFFER_APPEND_PFX( ps, info->dh.prime.data, info->dh.prime.size);
+  BUFFER_APPEND_PFX( ps, info->dh.generator.data, info->dh.generator.size);
+  BUFFER_APPEND_PFX( ps, info->dh.public_key.data, info->dh.public_key.size);
 
+  /* write the real size */
+  _gnutls_write_uint32(ps->length-cur_size, size_pos);
 
   return 0;
 }
 
 static int
 unpack_psk_auth_info (gnutls_session_t session,
-                     const gnutls_datum_t * packed_session)
+                     gnutls_buffer_st * ps)
 {
   size_t username_size, hint_size;
-  size_t pack_size;
-  int pos = 0, size, ret;
+  int ret;
   psk_auth_info_t info;
 
-  if (packed_session->data[0] != GNUTLS_CRD_PSK)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
-  pos += PACK_HEADER_SIZE + 4;
-
-
-  if (pack_size == 0)
-    return 0;                  /* nothing to be done */
-
-  /* a simple check for integrity */
-  if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  /* client and serer have the same auth_info here
-   */
   ret =
     _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
                           sizeof (psk_auth_info_st), 1);
@@ -884,60 +668,36 @@ unpack_psk_auth_info (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
-  username_size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-
-  memcpy (info->username, &packed_session->data[pos], username_size);
-  pos += username_size;
-
-  hint_size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-
-  memcpy (info->hint, &packed_session->data[pos], hint_size);
-  pos += hint_size;
-
-  info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
-  if (ret < 0)
+  BUFFER_POP_NUM(ps, username_size);
+  if (username_size > sizeof(info->username)) 
     {
-      gnutls_assert ();
-      goto error;
+      gnutls_assert();
+      return GNUTLS_E_INTERNAL_ERROR;
     }
-  pos += size;
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto error;
-    }
-  pos += size;
+  BUFFER_POP(ps, info->username, username_size);
 
-  size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-  ret =
-    _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
-                      size);
-  if (ret < 0)
+  BUFFER_POP_NUM(ps, hint_size);
+  if (hint_size > sizeof(info->hint)) 
     {
-      gnutls_assert ();
-      goto error;
+      gnutls_assert();
+      return GNUTLS_E_INTERNAL_ERROR;
     }
-  pos += size;
+  BUFFER_POP(ps, info->hint, hint_size);
 
-  return 0;
+  BUFFER_POP_NUM(ps, info->dh.secret_bits);
+
+  BUFFER_POP_DATUM(ps, &info->dh.prime);
+  BUFFER_POP_DATUM(ps, &info->dh.generator);
+  BUFFER_POP_DATUM(ps, &info->dh.public_key);
 
+  ret = 0;
+  
 error:
   _gnutls_free_datum (&info->dh.prime);
   _gnutls_free_datum (&info->dh.generator);
   _gnutls_free_datum (&info->dh.public_key);
+
   return ret;
 }
 #endif
@@ -975,217 +735,97 @@ error:
  *            -------------------
  *                MAX: 165 bytes
  *
- *      EXTENSIONS:
- *      2 bytes the record send size
- *      2 bytes the record recv size
- *
- *      1 byte the SRP username size
- *      x bytes the SRP username (MAX_SRP_USERNAME)
- *
- *      2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
- *      1 byte the first name type
- *      2 bytes the size of the first name 
- *      x bytes the first name (MAX_SERVER_NAME_SIZE)
- *       and so on...
- *      2 bytes the session ticket size
- *      x bytes the session ticket (MAX_SESSION_TICKET_SIZE)
- *
- *           --------------------
- *                MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+MAX_SESSION_TICKET_SIZE
  */
 static int
 pack_security_parameters (gnutls_session_t session,
-                         gnutls_datum_t * packed_session)
+                         gnutls_buffer_st * ps)
 {
-  int pos = 0;
-  size_t len, init, i;
+
+  int ret;
+  void* size_pos;
+  size_t cur_size;
 
   /* move after the auth info stuff.
    */
-  init =
-    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
-    PACK_HEADER_SIZE;
-
-  pos = init + 4;              /* make some space to write later the size */
-
-  packed_session->data[pos++] = session->security_parameters.entity;
-  packed_session->data[pos++] = session->security_parameters.kx_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.read_bulk_cipher_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.read_mac_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.read_compression_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.write_bulk_cipher_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.write_mac_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.write_compression_algorithm;
-  packed_session->data[pos++] =
-    session->security_parameters.current_cipher_suite.suite[0];
-  packed_session->data[pos++] =
-    session->security_parameters.current_cipher_suite.suite[1];
-
-  packed_session->data[pos++] = session->security_parameters.cert_type;
-  packed_session->data[pos++] = session->security_parameters.version;
-
-  memcpy (&packed_session->data[pos],
-         session->security_parameters.master_secret, GNUTLS_MASTER_SIZE);
-  pos += GNUTLS_MASTER_SIZE;
-
-  memcpy (&packed_session->data[pos],
-         session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
-  pos += GNUTLS_RANDOM_SIZE;
-  memcpy (&packed_session->data[pos],
-         session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
-  pos += GNUTLS_RANDOM_SIZE;
-
-  packed_session->data[pos++] = session->security_parameters.session_id_size;
-  memcpy (&packed_session->data[pos], session->security_parameters.session_id,
-         session->security_parameters.session_id_size);
-  pos += session->security_parameters.session_id_size;
-
-  _gnutls_write_uint32 (session->security_parameters.timestamp,
-                       &packed_session->data[pos]);
-  pos += 4;
-
-  /* Extensions */
-  _gnutls_write_uint16 (session->security_parameters.max_record_send_size,
-                       &packed_session->data[pos]);
-  pos += 2;
-
-  _gnutls_write_uint16 (session->security_parameters.max_record_recv_size,
-                       &packed_session->data[pos]);
-  pos += 2;
-
-  /* SRP */
-  len =
-    strlen ((char *) session->security_parameters.extensions.srp_username);
-  packed_session->data[pos++] = len;
-  memcpy (&packed_session->data[pos],
-         session->security_parameters.extensions.srp_username, len);
-  pos += len;
-
-  _gnutls_write_uint16 (session->security_parameters.
-                       extensions.server_names_size,
-                       &packed_session->data[pos]);
-  pos += 2;
-
-  for (i = 0; i < session->security_parameters.extensions.server_names_size;
-       i++)
-    {
-      packed_session->data[pos++] =
-       session->security_parameters.extensions.server_names[i].type;
-      _gnutls_write_uint16 (session->security_parameters.
-                           extensions.server_names[i].name_length,
-                           &packed_session->data[pos]);
-      pos += 2;
-
-      memcpy (&packed_session->data[pos],
-             session->security_parameters.extensions.server_names[i].name,
-             session->security_parameters.extensions.
-             server_names[i].name_length);
-      pos +=
-       session->security_parameters.extensions.server_names[i].name_length;
-    }
+  size_pos = ps->data + ps->length;
+
+  BUFFER_APPEND_NUM(ps, 0);
+  cur_size = ps->length;
+
 
-  _gnutls_write_uint16 (session->security_parameters.
-                       extensions.session_ticket_len,
-                       &packed_session->data[pos]);
-  pos += 2;
-  memcpy (&packed_session->data[pos],
-         session->security_parameters.extensions.session_ticket,
-         session->security_parameters.extensions.session_ticket_len);
-  pos += session->security_parameters.extensions.session_ticket_len;
+  BUFFER_APPEND(ps, &session->security_parameters.entity, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.kx_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.read_bulk_cipher_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.read_mac_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.read_compression_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.write_bulk_cipher_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.write_mac_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.write_compression_algorithm, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.current_cipher_suite.suite[0], 1);
+  BUFFER_APPEND(ps, &session->security_parameters.current_cipher_suite.suite[1], 1);
+  BUFFER_APPEND(ps, &session->security_parameters.cert_type, 1);
+  BUFFER_APPEND(ps, &session->security_parameters.version, 1);
 
-  /* write the total size */
-  _gnutls_write_uint32 (pos - init - 4, &packed_session->data[init]);
-  packed_session->size += pos - init;
+  BUFFER_APPEND(ps, session->security_parameters.master_secret, GNUTLS_MASTER_SIZE);
+  BUFFER_APPEND(ps, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
+  BUFFER_APPEND(ps, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
+  BUFFER_APPEND_NUM(ps, session->security_parameters.session_id_size);
+  BUFFER_APPEND_NUM(ps, session->security_parameters.max_record_send_size);
+  BUFFER_APPEND_NUM(ps, session->security_parameters.max_record_recv_size);
+  BUFFER_APPEND(ps, session->security_parameters.session_id, session->security_parameters.session_id_size);
+
+  BUFFER_APPEND_NUM(ps, session->security_parameters.timestamp);
+
+  _gnutls_write_uint32(ps->length-cur_size, size_pos);
 
   return 0;
 }
 
-
 static int
 unpack_security_parameters (gnutls_session_t session,
-                           const gnutls_datum_t * packed_session)
+                           gnutls_buffer_st * ps)
 {
-  size_t pack_size, init, i;
-  int pos = 0, len;
+  size_t pack_size;
+  int ret;
   time_t timestamp = time (0);
 
-
-  /* skip the auth info stuff */
-  init =
-    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
-    PACK_HEADER_SIZE;
-
-  pos = init;
-
-  pack_size = _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
-
+  BUFFER_POP_NUM(ps, pack_size);
 
   if (pack_size == 0)
     return GNUTLS_E_INVALID_REQUEST;
 
-  /* a simple check for integrity */
-  if (pack_size > MAX_SEC_PARAMS + 2 + MAX_SESSION_TICKET_SIZE)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
   memset (&session->internals.resumed_security_parameters, 0,
          sizeof (session->internals.resumed_security_parameters));
-  session->internals.resumed_security_parameters.entity =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.kx_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.read_bulk_cipher_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.read_mac_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.read_compression_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.write_bulk_cipher_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.write_mac_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.write_compression_algorithm =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.
-    current_cipher_suite.suite[0] = packed_session->data[pos++];
-  session->internals.resumed_security_parameters.
-    current_cipher_suite.suite[1] = packed_session->data[pos++];
-
-  session->internals.resumed_security_parameters.cert_type =
-    packed_session->data[pos++];
-  session->internals.resumed_security_parameters.version =
-    packed_session->data[pos++];
-
-  memcpy (session->internals.resumed_security_parameters.master_secret,
-         &packed_session->data[pos], GNUTLS_MASTER_SIZE);
-  pos += GNUTLS_MASTER_SIZE;
-
-  memcpy (session->internals.resumed_security_parameters.client_random,
-         &packed_session->data[pos], GNUTLS_RANDOM_SIZE);
-  pos += GNUTLS_RANDOM_SIZE;
-  memcpy (session->internals.resumed_security_parameters.server_random,
-         &packed_session->data[pos], GNUTLS_RANDOM_SIZE);
-  pos += GNUTLS_RANDOM_SIZE;
-
-  session->internals.resumed_security_parameters.session_id_size =
-    packed_session->data[pos++];
-  memcpy (session->internals.resumed_security_parameters.session_id,
-         &packed_session->data[pos],
+
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.entity, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.kx_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.read_bulk_cipher_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.read_mac_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.read_compression_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.write_bulk_cipher_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.write_mac_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.write_compression_algorithm, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.current_cipher_suite.suite[0], 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.
+    current_cipher_suite.suite[1], 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.cert_type, 1);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.version, 1);
+
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.master_secret,
+         GNUTLS_MASTER_SIZE);
+
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.client_random,
+         GNUTLS_RANDOM_SIZE);
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.server_random,
+         GNUTLS_RANDOM_SIZE);
+  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters.session_id_size);
+
+  BUFFER_POP(ps, &session->internals.resumed_security_parameters.session_id,
          session->internals.resumed_security_parameters.session_id_size);
-  pos += session->internals.resumed_security_parameters.session_id_size;
 
-  session->internals.resumed_security_parameters.timestamp =
-    _gnutls_read_uint32 (&packed_session->data[pos]);
-  pos += 4;
+  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters.timestamp);
+  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters.max_record_send_size);
+  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters.max_record_recv_size);
 
   if (timestamp - session->internals.resumed_security_parameters.timestamp >
       session->internals.expire_time
@@ -1195,60 +835,8 @@ unpack_security_parameters (gnutls_session_t session,
       return GNUTLS_E_EXPIRED;
     }
 
-  /* Extensions */
-  session->internals.resumed_security_parameters.max_record_send_size =
-    _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-
-  session->internals.resumed_security_parameters.max_record_recv_size =
-    _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-
-
-  /* SRP */
-  len = packed_session->data[pos++];   /* srp username length */
-  memcpy (session->internals.resumed_security_parameters.
-         extensions.srp_username, &packed_session->data[pos], len);
-  session->internals.resumed_security_parameters.
-    extensions.srp_username[len] = 0;
-  pos += len;
-
-  session->internals.resumed_security_parameters.
-    extensions.server_names_size =
-    _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-  for (i = 0;
-       i <
-       session->internals.resumed_security_parameters.
-       extensions.server_names_size; i++)
-    {
-      session->internals.resumed_security_parameters.
-       extensions.server_names[i].type = packed_session->data[pos++];
-      session->internals.resumed_security_parameters.
-       extensions.server_names[i].name_length =
-       _gnutls_read_uint16 (&packed_session->data[pos]);
-      pos += 2;
-
-      memcpy (session->internals.resumed_security_parameters.
-             extensions.server_names[i].name, &packed_session->data[pos],
-             session->internals.resumed_security_parameters.
-             extensions.server_names[i].name_length);
-      pos +=
-       session->internals.resumed_security_parameters.
-       extensions.server_names[i].name_length;
-    }
-
-  session->internals.resumed_security_parameters.
-    extensions.session_ticket_len =
-    _gnutls_read_uint16 (&packed_session->data[pos]);
-  pos += 2;
-  session->internals.resumed_security_parameters.extensions.session_ticket =
-    gnutls_malloc (session->internals.resumed_security_parameters.
-                  extensions.session_ticket_len);
-  memcpy (session->internals.resumed_security_parameters.
-         extensions.session_ticket, &packed_session->data[pos],
-         session->internals.resumed_security_parameters.
-         extensions.session_ticket_len);
+  ret = 0;
 
-  return 0;
+error:
+  return ret;
 }
index eca8a644a41663e747d80d66c635e368ce678f32..b5769de176dea9ce0d546fceba8ece9538151cef 100644 (file)
@@ -45,6 +45,7 @@
 #include <auth_psk.h>
 #include <gnutls_algorithms.h>
 #include <gnutls_rsa_export.h>
+#include <gnutls_extensions.h>
 
 /* These should really be static, but src/tests.c calls them.  Make
    them public functions?  */
@@ -216,7 +217,6 @@ _gnutls_handshake_internal_state_init (gnutls_session_t session)
   session->internals.extensions_sent_size = 0;
 
   /* by default no selected certificate */
-  session->internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
   session->internals.adv_version_major = 0;
   session->internals.adv_version_minor = 0;
   session->internals.v2_hello = 0;
@@ -225,7 +225,6 @@ _gnutls_handshake_internal_state_init (gnutls_session_t session)
   session->internals.adv_version_minor = 0;
   session->internals.adv_version_minor = 0;
   session->internals.direction = 0;
-  session->internals.safe_renegotiation_received = 0;
 
   /* use out of band data for the last
    * handshake messages received.
@@ -385,6 +384,7 @@ gnutls_deinit (gnutls_session_t session)
 
   _gnutls_handshake_internal_state_clear (session);
   _gnutls_handshake_io_buffer_clear (session);
+  _gnutls_ext_free_session_data (session);
 
   _gnutls_free_datum (&session->connection_state.read_mac_secret);
   _gnutls_free_datum (&session->connection_state.write_mac_secret);
@@ -439,19 +439,6 @@ gnutls_deinit (gnutls_session_t session)
       session->key = NULL;
     }
 
-  gnutls_free (session->internals.srp_username);
-
-  if (session->internals.srp_password)
-    {
-      memset (session->internals.srp_password, 0,
-             strlen (session->internals.srp_password));
-      gnutls_free (session->internals.srp_password);
-    }
-
-  gnutls_free (session->security_parameters.extensions.session_ticket);
-  gnutls_free (session->internals.resumed_security_parameters.
-              extensions.session_ticket);
-
   memset (session, 0, sizeof (struct gnutls_session_int));
   gnutls_free (session);
 }
index 0667886449b3d14611c43022d1989a1595ab5749..4975ddee03f94ef94d8cfffa0200b09470490fbe 100644 (file)
@@ -112,7 +112,7 @@ _gnutls_buffer_clear (gnutls_buffer_st * str)
   str->length = 0;
 }
 
-#define MIN_CHUNK 256
+#define MIN_CHUNK 1024
 
 int
 _gnutls_buffer_append_data (gnutls_buffer_st * dest, const void *data,
@@ -211,7 +211,7 @@ _gnutls_buffer_append_str (gnutls_buffer_st * dest, const char *src)
  * data are appended in the buffer.
  */
 void
-_gnutls_buffer_get_datum (gnutls_buffer_st * str, gnutls_datum_t * data,
+_gnutls_buffer_pop_datum (gnutls_buffer_st * str, gnutls_datum_t * data,
                          size_t req_size)
 {
 
@@ -240,14 +240,48 @@ _gnutls_buffer_get_datum (gnutls_buffer_st * str, gnutls_datum_t * data,
   return;
 }
 
+/* converts the buffer to a datum if possible. After this call the buffer
+ * is at an usable state and might not be used or deinitialized */
+int
+_gnutls_buffer_to_datum (gnutls_buffer_st * str, gnutls_datum_t * data)
+{
+
+  if (str->length == 0)
+    {
+      data->data = NULL;
+      data->size = 0;
+      return 0;
+    }
+
+  if (str->allocd != str->data)
+    {
+      data->data = gnutls_malloc(str->length);
+      if (data->data == NULL)
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
+      memcpy(data->data, str->data, str->length);
+      data->size = str->length;
+      _gnutls_buffer_clear(str);
+    }
+  else
+    {
+      data->data = str->data;
+      data->size = str->length;
+    }
+
+  return 0;
+}
+
 /* returns data from a string in a constant buffer.
  */
 void
-_gnutls_buffer_get_data (gnutls_buffer_st * str, void *data, size_t * req_size)
+_gnutls_buffer_pop_data (gnutls_buffer_st * str, void *data, size_t * req_size)
 {
   gnutls_datum_t tdata;
 
-  _gnutls_buffer_get_datum (str, &tdata, *req_size);
+  _gnutls_buffer_pop_datum (str, &tdata, *req_size);
 
   *req_size = tdata.size;
   memcpy (data, tdata.data, tdata.size);
@@ -509,3 +543,90 @@ _gnutls_hostname_compare (const char *certname,
 
   return 0;
 }
+
+int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size)
+{
+    opaque ss[4];
+    _gnutls_write_uint32(data_size, ss);
+    return _gnutls_buffer_append_data(buf, ss, 4);
+}
+
+/* Reads an uint32 number from the buffer. If check is non zero it will also check whether
+ * the number read, is less than the data in the buffer
+ */
+int _gnutls_buffer_pop_prefix (gnutls_buffer_st * buf, size_t *data_size, int check)
+{
+    size_t size;
+    
+    if (buf->length < 4) {
+       gnutls_assert();
+       return GNUTLS_E_PARSING_ERROR;
+    }
+    
+    size = _gnutls_read_uint32(buf->data);
+    if (check && size > buf->length-4) {
+       gnutls_assert();
+       return GNUTLS_E_PARSING_ERROR;
+    }
+    
+    buf->data+=4;
+    buf->length-=4;
+    
+    *data_size = size;
+    
+    return 0;
+}
+
+int _gnutls_buffer_pop_datum_prefix (gnutls_buffer_st * buf, gnutls_datum_t* data)
+{
+    size_t size;
+    int ret;
+    
+    ret = _gnutls_buffer_pop_prefix(buf, &size, 1);
+    if (ret < 0) {
+       gnutls_assert();
+       return ret;
+    }
+
+    if (size > 0) {
+       size_t osize = size;
+       _gnutls_buffer_pop_datum(buf, data, size);
+       if (osize != data->size) {
+           gnutls_assert();
+           return GNUTLS_E_PARSING_ERROR;
+       }
+    } else {
+       data->size = 0;
+       data->data = NULL;
+    }
+    
+    return 0;
+}
+
+int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, const void *data,
+                               size_t data_size)
+{
+    _gnutls_buffer_append_prefix(buf, data_size);
+    if (data_size > 0)
+      return _gnutls_buffer_append_data(buf, data, data_size);
+    
+    return 0;
+}
+
+int _gnutls_buffer_pop_data_prefix (gnutls_buffer_st * buf, void * data, size_t * data_size)
+{
+    size_t size;
+    int ret;
+    
+    ret = _gnutls_buffer_pop_prefix(buf, &size, 1);
+    if (ret < 0) {
+       gnutls_assert();
+       return ret;
+    }
+
+    if (size > 0)
+       _gnutls_buffer_pop_data(buf, data, data_size);
+    
+    return 0;
+}
+
index 63b8761a8759dc03e61323704ebb08b79de19795..7d7df473ba9e05a3291308f88e9fe041480cd9ab 100644 (file)
@@ -27,6 +27,7 @@
 # define GNUTLS_STR_H
 
 #include <gnutls_int.h>
+#include <gnutls_datum.h>
 
 void _gnutls_str_cpy (char *dest, size_t dest_tot_size, const char *src);
 void _gnutls_mem_cpy (char *dest, size_t dest_tot_size, const char *src,
@@ -49,10 +50,23 @@ int _gnutls_buffer_append_str (gnutls_buffer_st *, const char *str);
 int _gnutls_buffer_append_data (gnutls_buffer_st *, const void *data,
                                size_t data_size);
 
-void _gnutls_buffer_get_data (gnutls_buffer_st *, void *, size_t * size);
-void _gnutls_buffer_get_datum (gnutls_buffer_st *, gnutls_datum_t *,
+#include <gnutls_num.h>
+
+int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size);
+
+int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, 
+    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 *,
                               size_t max_size);
 
+int _gnutls_buffer_pop_prefix (gnutls_buffer_st * buf, size_t *data_size, int check);
+
+int _gnutls_buffer_pop_data_prefix (gnutls_buffer_st * buf, void * data, size_t * data_size);
+
+int _gnutls_buffer_pop_datum_prefix (gnutls_buffer_st * buf, gnutls_datum_t* data);
+int _gnutls_buffer_to_datum (gnutls_buffer_st * str, gnutls_datum_t * data);
+
 int _gnutls_buffer_escape(gnutls_buffer_st * dest, const char *const invalid_chars);
 int _gnutls_buffer_unescape(gnutls_buffer_st * dest);
 
@@ -75,4 +89,60 @@ int _gnutls_hostname_compare (const char *certname, size_t certnamesize,
                              const char *hostname);
 #define MAX_CN 256
 
+#define BUFFER_APPEND(b, x, s) { \
+        ret = _gnutls_buffer_append_data(b, x, s); \
+        if (ret < 0) { \
+            gnutls_assert(); \
+            return ret; \
+        } \
+    }
+
+#define BUFFER_APPEND_PFX(b, x, s) { \
+        ret = _gnutls_buffer_append_data_prefix(b, x, s); \
+        if (ret < 0) { \
+            gnutls_assert(); \
+            return ret; \
+        } \
+    }
+
+#define BUFFER_APPEND_NUM(b, s) { \
+        ret = _gnutls_buffer_append_prefix(b, s); \
+        if (ret < 0) { \
+            gnutls_assert(); \
+            return ret; \
+        } \
+    }
+
+
+#define BUFFER_POP(b, x, s) { \
+        size_t is = s; \
+        _gnutls_buffer_pop_data(b, x, &is); \
+        if (is != s) { \
+            ret = GNUTLS_E_PARSING_ERROR; \
+            gnutls_assert(); \
+            goto error; \
+        } \
+    }
+
+#define BUFFER_POP_DATUM(b, o) { \
+        gnutls_datum_t d; \
+        ret = _gnutls_buffer_pop_datum_prefix(b, &d); \
+        if (ret >= 0) \
+            ret = _gnutls_set_datum (o, d.data, d.size); \
+        if (ret < 0) { \
+            gnutls_assert(); \
+            goto error; \
+        } \
+    }
+
+#define BUFFER_POP_NUM(b, o) { \
+        size_t s; \
+        ret = _gnutls_buffer_pop_prefix(b, &s, 0); \
+        if (ret < 0) { \
+            gnutls_assert(); \
+            goto error; \
+        } \
+        o = s; \
+    }
+
 #endif
index 5cae317ee8b3392ef6ac28cde0412ec108a8f38f..566f8c599fcf24faf4e54e6e8fc3ede9fa369c4b 100644 (file)
@@ -165,4 +165,10 @@ void gnutls_certificate_server_set_retrieve_function
     gnutls_sign_func
     gnutls_sign_callback_get (gnutls_session_t session, void **userdata);
 
+  int gnutls_ext_register (int type,
+                          const char *name,
+                          gnutls_ext_parse_type_t parse_type,
+                          gnutls_ext_recv_func recv_func,
+                          gnutls_ext_send_func send_func) _GNUTLS_GCC_ATTR_DEPRECATED;
+
 #endif /* _GNUTLS_COMPAT_H */
index 441b42850c1867baef2466b9d5ca2deaf9199df3..7ea6ea36164c8dd81012592e0591cdea555b8e11 100644 (file)
@@ -817,11 +817,6 @@ extern "C"
     GNUTLS_EXT_NONE = 4,
   } gnutls_ext_parse_type_t;
 
-  int gnutls_ext_register (int type,
-                          const char *name,
-                          gnutls_ext_parse_type_t parse_type,
-                          gnutls_ext_recv_func recv_func,
-                          gnutls_ext_send_func send_func);
 
   /**
    * gnutls_server_name_type_t:
index 527c618912a1985fe4361eaf5ce479527cb0d2f3..cc93d6cd1f7200e33bb790e2748f46287d90390b 100644 (file)
@@ -706,6 +706,13 @@ GNUTLS_PRIVATE {
     _gnutls_hash_init;
     _gnutls_hash_deinit;
     _gnutls_hash;
+    _gnutls_ext_get_session_data;
+    _gnutls_ext_set_session_data;
+    _gnutls_ext_register;
+    _gnutls_buffer_append_prefix;
+    _gnutls_buffer_append_data_prefix;
+    _gnutls_buffer_pop_data;
+    _gnutls_buffer_pop_prefix;
 
     # Internal symbols needed by psktool:
 
index ecd203308140745f04a7ab8b6633b01d4efd2b53..f2b3708d3a5419d5e5bd647838f63aaebdb6c72f 100644 (file)
@@ -375,7 +375,7 @@ static int unescape_string (char* output, const char* input, size_t* size, char
         return ret;
     }
 
-    _gnutls_buffer_get_data(&str, output, size);
+    _gnutls_buffer_pop_data(&str, output, size);
 
     _gnutls_buffer_clear(&str);
 
index d8f2791d3dc510955e761d229a41c4f7c2db654d..4288470081eff4d0d6c081ab30d372763a779675 100644 (file)
@@ -309,7 +309,7 @@ _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
 
   if (buf)
     {
-      _gnutls_buffer_get_data (&out_str, buf, sizeof_buf);
+      _gnutls_buffer_pop_data (&out_str, buf, sizeof_buf);
       buf[*sizeof_buf] = 0;
     }
   else
index 0dcc9aca9ecc78110d9fdccbe9016f1cad2983b2..bad812e4a91cc18bec6ca920d204a57a13857d50 100644 (file)
 #define NO 0
 #define YES 1
 
-int
+static int _gnutls_inner_application_recv_params (gnutls_session_t session,
+                                          const opaque * data,
+                                          size_t data_size);
+static int _gnutls_inner_application_send_params (gnutls_session_t session,
+                                          opaque * data, size_t);
+static int ia_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv);
+static int ia_pack(extension_priv_data_t _priv, gnutls_buffer_st* ps);
+static void ia_deinit_data(extension_priv_data_t priv);
+
+extension_entry_st ext_mod_ia = {
+    .name = "INNER APPLICATION",
+    .type = GNUTLS_EXTENSION_INNER_APPLICATION,
+    .parse_type = GNUTLS_EXT_TLS,
+
+    .recv_func = _gnutls_inner_application_recv_params,
+    .send_func = _gnutls_inner_application_send_params,
+    .pack_func = ia_pack,
+    .unpack_func = ia_unpack,
+    .deinit_func = ia_deinit_data,
+};
+
+static int
 _gnutls_inner_application_recv_params (gnutls_session_t session,
                                       const opaque * data, size_t data_size)
 {
-  tls_ext_st *ext = &session->security_parameters.extensions;
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
+  int ret;
 
   if (data_size != 1)
     {
@@ -43,13 +66,29 @@ _gnutls_inner_application_recv_params (gnutls_session_t session,
       return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
     }
 
-  ext->gnutls_ia_peer_enable = 1;
-  ext->gnutls_ia_peer_allowskip = 0;
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
+
+      epriv.ptr = priv;
+      _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_INNER_APPLICATION, epriv);
+    }
+  else
+    priv = epriv.ptr;
+
+  priv->flags |= IA_PEER_ENABLE;
+  priv->flags &= ~IA_PEER_ALLOW_SKIP;
 
   switch ((unsigned char) *data)
     {
-    case NO:                   /* Peer's ia_on_resume == no */
-      ext->gnutls_ia_peer_allowskip = 1;
+    case NO: /* Peer's ia_on_resume == no */
+      priv->flags |= IA_PEER_ALLOW_SKIP;
       break;
 
     case YES:
@@ -59,17 +98,36 @@ _gnutls_inner_application_recv_params (gnutls_session_t session,
       gnutls_assert ();
     }
 
+
   return 0;
 }
 
 
 /* returns data_size or a negative number on failure
  */
-int
+static int
 _gnutls_inner_application_send_params (gnutls_session_t session,
                                       opaque * data, size_t data_size)
 {
-  tls_ext_st *ext = &session->security_parameters.extensions;
+  extension_priv_data_t epriv;
+  ia_ext_st * priv = NULL;
+  int ret;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      priv = gnutls_calloc(1, sizeof(*priv));
+      if (priv == NULL)
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
+
+      epriv.ptr = priv;
+      _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_INNER_APPLICATION, epriv);
+    }
+  else
+    priv = epriv.ptr;
 
   /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA
      credential in the session. */
@@ -77,29 +135,31 @@ _gnutls_inner_application_send_params (gnutls_session_t session,
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
       gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
-       _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
+        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
 
       if (cred)
-       ext->gnutls_ia_enable = 1;
+        priv->flags |= IA_ENABLE;
     }
-  else
+  else /* SERVER */
     {
-      gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t)
-       _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
+      gnutls_ia_server_credentials_t cred;
+
+      cred = (gnutls_ia_server_credentials_t)
+        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
 
       if (cred)
-       ext->gnutls_ia_enable = 1;
+        priv->flags |= IA_PEER_ENABLE;
     }
 
   /* If we don't want gnutls_ia locally, or we are a server and the
    * client doesn't want it, don't advertise TLS/IA support at all, as
    * required. */
 
-  if (!ext->gnutls_ia_enable)
+  if (!(priv->flags & IA_ENABLE))
     return 0;
 
   if (session->security_parameters.entity == GNUTLS_SERVER &&
-      !ext->gnutls_ia_peer_enable)
+      !(priv->flags & IA_PEER_ENABLE))
     return 0;
 
   /* We'll advertise. Check if there's room in the hello buffer. */
@@ -119,8 +179,8 @@ _gnutls_inner_application_send_params (gnutls_session_t session,
 
       /* Client: value follows local setting */
 
-      if (ext->gnutls_ia_allowskip)
-       *data = NO;
+      if (priv->flags & IA_ALLOW_SKIP)
+        *data = NO;
     }
   else
     {
@@ -137,11 +197,60 @@ _gnutls_inner_application_send_params (gnutls_session_t session,
        * always skip IA on resumption, because recv_ext isn't even called
        * to record the peer's support for IA at all. Simon? */
 
-      if (ext->gnutls_ia_allowskip &&
-         ext->gnutls_ia_peer_allowskip &&
-         session->internals.resumed == RESUME_TRUE)
-       *data = NO;
+      if ((priv->flags & IA_ALLOW_SKIP) &&
+        (priv->flags & IA_PEER_ALLOW_SKIP) &&
+        session->internals.resumed == RESUME_TRUE)
+        *data = NO;
     }
 
   return 1;
 }
+
+static void ia_deinit_data(extension_priv_data_t priv)
+{
+    gnutls_free(priv.ptr);
+}
+
+static int ia_pack(extension_priv_data_t epriv, gnutls_buffer_st* ps)
+{
+ia_ext_st* priv = epriv.ptr;
+int ret;
+
+  BUFFER_APPEND_NUM(ps, priv->flags);
+  BUFFER_APPEND_PFX(ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
+
+  return 0;
+}
+
+static int ia_unpack(gnutls_buffer_st* ps, extension_priv_data_t* _priv)
+{
+ia_ext_st* priv;
+int size, ret;
+extension_priv_data_t epriv;
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  BUFFER_POP_NUM(ps, priv->flags);
+  BUFFER_POP_NUM(ps, size);
+  if (size != GNUTLS_MASTER_SIZE)
+    {
+      gnutls_assert();
+      return GNUTLS_E_PARSING_ERROR;
+    }
+  BUFFER_POP(ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
+
+  epriv.ptr = priv;
+  *_priv = epriv;
+  
+  return 0;
+
+error:
+  gnutls_free(priv);
+  return ret;
+}
+
index a75ee604f90606b0be00339df91d54cd72e95e28..3a037cde467ad45e7390653584c2b524fde3e479 100644 (file)
  *
  */
 
-int _gnutls_inner_application_recv_params (gnutls_session_t session,
-                                          const opaque * data,
-                                          size_t data_size);
-int _gnutls_inner_application_send_params (gnutls_session_t session,
-                                          opaque * data, size_t);
+#ifndef EXT_IA_H
+#define EXT_IA_H
+
+#include <gnutls_extensions.h>
+
+#define IA_PEER_ENABLE (1 << 1)
+#define IA_PEER_ALLOW_SKIP (1 << 2)
+#define IA_ENABLE (1 << 3)
+#define IA_ALLOW_SKIP (1 << 4)
+
+extension_entry_st ext_mod_ia;
+
+typedef struct {
+  unsigned int flags;
+  /* For TLS/IA.  XXX: Move to IA credential? */
+  opaque inner_secret[GNUTLS_MASTER_SIZE];
+} ia_ext_st;
+
+inline static void _gnutls_ia_derive_inner_secret(gnutls_session_t session)
+{
+extension_priv_data_t epriv;
+ia_ext_st *priv;
+int ret;
+  
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      return ;
+    }
+  priv = epriv.ptr;
+  
+  memcpy (priv->inner_secret,
+         session->security_parameters.master_secret, GNUTLS_MASTER_SIZE);
+
+}
+
+#endif
index f8866cfc072ba21464c22f7539b9b0f3e834acb8..490f0c5ab73cfb9f205fd4351cd07f608445f6f3 100644 (file)
@@ -126,11 +126,7 @@ gnutls_global_init_extra (void)
   if (_gnutls_init_extra != 1)
     return 0;
 
-  ret = gnutls_ext_register (GNUTLS_EXTENSION_INNER_APPLICATION,
-                            "INNER_APPLICATION",
-                            GNUTLS_EXT_TLS,
-                            _gnutls_inner_application_recv_params,
-                            _gnutls_inner_application_send_params);
+  ret = _gnutls_ext_register (&ext_mod_ia);
   if (ret != GNUTLS_E_SUCCESS)
     return ret;
 
index 804ed3f4f155cadc838a812df3e6959dda3385bf..f3f1e4a9a7ee2f188fbe986b2e92ad396b55d712 100644 (file)
@@ -26,6 +26,7 @@
 #include "gnutls_num.h"
 #include "gnutls_state.h"
 #include <gnutls/extra.h>
+#include <ext_inner_application.h>
 
 #define CHECKSUM_SIZE 12
 
@@ -171,6 +172,16 @@ _gnutls_ia_prf (gnutls_session_t session,
   int ret;
   opaque *seed;
   size_t seedsize = 2 * GNUTLS_RANDOM_SIZE + extra_size;
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
   seed = gnutls_malloc (seedsize);
   if (!seed)
@@ -185,7 +196,7 @@ _gnutls_ia_prf (gnutls_session_t session,
          session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
   memcpy (seed + 2 * GNUTLS_RANDOM_SIZE, extra, extra_size);
 
-  ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
+  ret = _gnutls_PRF (session, priv->inner_secret,
                     GNUTLS_MASTER_SIZE,
                     label, label_size, seed, seedsize, outsize, out);
 
@@ -213,13 +224,25 @@ gnutls_ia_permute_inner_secret (gnutls_session_t session,
                                size_t session_keys_size,
                                const char *session_keys)
 {
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
+  int ret;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
+
   return _gnutls_ia_prf (session,
                         sizeof (inner_permutation_label) - 1,
                         inner_permutation_label,
                         session_keys_size,
                         session_keys,
                         GNUTLS_RANDOM_SIZE,
-                        session->security_parameters.inner_secret);
+                        priv->inner_secret);
 }
 
 /**
@@ -261,8 +284,19 @@ gnutls_ia_generate_challenge (gnutls_session_t session,
 void
 gnutls_ia_extract_inner_secret (gnutls_session_t session, char *buffer)
 {
-  memcpy (buffer, session->security_parameters.inner_secret,
-         GNUTLS_MASTER_SIZE);
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
+  int ret;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return;
+    }
+  priv = epriv.ptr;
+
+  memcpy (buffer, priv->inner_secret, GNUTLS_MASTER_SIZE);
 }
 
 /**
@@ -290,8 +324,18 @@ gnutls_ia_endphase_send (gnutls_session_t session, int final_p)
     sizeof (server_finished_label);
   ssize_t len;
   int ret;
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
-  ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
+  ret = _gnutls_PRF (session, priv->inner_secret,
                     GNUTLS_MASTER_SIZE, label, size_of_label - 1,
                     /* XXX specification unclear on seed. */
                     "", 0, CHECKSUM_SIZE, local_checksum);
@@ -343,8 +387,18 @@ gnutls_ia_verify_endphase (gnutls_session_t session, const char *checksum)
   int size_of_label = client ? sizeof (server_finished_label) :
     sizeof (client_finished_label);
   int ret;
+  extension_priv_data_t epriv;
+  ia_ext_st *priv;
 
-  ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_INNER_APPLICATION, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
+
+  ret = _gnutls_PRF (session, priv->inner_secret,
                     GNUTLS_MASTER_SIZE,
                     label, size_of_label - 1,
                     "", 0, CHECKSUM_SIZE, local_checksum);
@@ -610,22 +664,32 @@ _gnutls_ia_server_handshake (gnutls_session_t session)
 int
 gnutls_ia_handshake_p (gnutls_session_t session)
 {
-  tls_ext_st *ext = &session->security_parameters.extensions;
+  extension_priv_data_t epriv;
+  ia_ext_st * priv;
+  int ret;
+
+  ret = _gnutls_ext_get_session_data( session, GNUTLS_EXTENSION_SERVER_NAME, &epriv);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  priv = epriv.ptr;
 
   /* Either local side or peer doesn't do TLS/IA: don't do IA */
 
-  if (!ext->gnutls_ia_enable || !ext->gnutls_ia_peer_enable)
+  if (!(priv->flags & IA_ENABLE) || !(priv->flags & IA_PEER_ENABLE))
     return 0;
 
   /* Not resuming or we don't allow skipping on resumption locally: do IA */
 
-  if (!ext->gnutls_ia_allowskip || !gnutls_session_is_resumed (session))
+  if (!(priv->flags & IA_ALLOW_SKIP) || !gnutls_session_is_resumed (session))
     return 1;
 
   /* If we're resuming and we and the peer both allow skipping on resumption: 
    * don't do IA */
 
-  return !ext->gnutls_ia_peer_allowskip;
+  return !(priv->flags & IA_PEER_ALLOW_SKIP);
 }
 
 
@@ -902,10 +966,24 @@ gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred)
  * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_*
  * functions.
  **/
-void
-gnutls_ia_enable (gnutls_session_t session, int allow_skip_on_resume)
+void gnutls_ia_enable (gnutls_session_t session, int allow_skip_on_resume)
 {
-  session->security_parameters.extensions.gnutls_ia_enable = 1;
-  session->security_parameters.extensions.gnutls_ia_allowskip =
-    allow_skip_on_resume;
+  extension_priv_data_t epriv;
+  ia_ext_st * priv;
+
+  priv = gnutls_calloc(1, sizeof(*priv));
+  if (priv == NULL)
+    {
+      gnutls_assert();
+      return;
+    }
+
+  epriv.ptr = priv;
+
+  priv->flags |= IA_ENABLE;
+  if (allow_skip_on_resume)
+    priv->flags |= IA_ALLOW_SKIP;
+
+  _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_INNER_APPLICATION, epriv);
+
 }
index 4d90b43191ee68eec3c93233e3a9d5e2172aa8d5..f0eba23a7ce592d7cdd0f5f254ffc74669c663a0 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -601,14 +601,8 @@ init_tls_session (const char *hostname)
        }
     }
 
-#ifdef ENABLE_OPRFI
-  if (info.opaque_prf_input)
-    gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
-                               info.opaque_prf_input);
-#endif
-
 #ifdef ENABLE_SESSION_TICKET
-  if (!info.noticket)
+  if (disable_extensions ==0 && !info.noticket)
     gnutls_session_ticket_enable_client (session);
 #endif
 
@@ -774,6 +768,7 @@ main (int argc, char **argv)
                                   &session_data_size);
 
          gnutls_session_get_id (hd.session, NULL, &session_id_size);
+
          session_id = malloc (session_id_size);
          gnutls_session_get_id (hd.session, session_id, &session_id_size);
 
index a2457ea78124fe375d8f65b156dd6e7228372497..eb7b892ab7168a4d8cc3d95b647d2e1ddb89bce5 100644 (file)
@@ -333,29 +333,6 @@ static int comp_priority[PRI_MAX];
 static int mac_priority[PRI_MAX];
 static int cert_type_priority[PRI_MAX];
 
-#if ENABLE_OPRFI
-int
-oprfi_callback (gnutls_session_t session,
-               void *userdata,
-               size_t oprfi_len,
-               const unsigned char *in_oprfi, unsigned char *out_oprfi)
-{
-  size_t ourlen = strlen (info.opaque_prf_input);
-  size_t i;
-
-  printf ("- Received Opaque PRF data of %d bytes\n", oprfi_len);
-  printf ("  data: ");
-  for (i = 0; i < oprfi_len; i++)
-    printf ("%02x", in_oprfi[i]);
-  printf ("\n");
-
-  memset (out_oprfi, 0, oprfi_len);
-  strncpy (out_oprfi, info.opaque_prf_input, oprfi_len);
-
-  return 0;
-}
-#endif
-
 static gnutls_session_t
 initialize_session (void)
 {
@@ -420,11 +397,6 @@ initialize_session (void)
        gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
     }
 
-#ifdef ENABLE_OPRFI
-  if (info.opaque_prf_input)
-    gnutls_oprfi_enable_server (session, oprfi_callback, NULL);
-#endif
-
   return session;
 }
 
index 165370a3c61b047f33e2ae8247510a0a4fcef1fc..a6dcb33a02748280ae64233a6834bee0a3e2dfb2 100644 (file)
@@ -83,10 +83,6 @@ endif
 tlsia_LDADD = ../libextra/libgnutls-extra.la $(LDADD) $(LTLIBREADLINE)
 endif
 
-if ENABLE_OPRFI
-ctests +=  oprfi
-endif
-
 check_PROGRAMS = $(ctests)
 dist_check_SCRIPTS = rfc2253-escape-test
 
diff --git a/tests/oprfi.c b/tests/oprfi.c
deleted file mode 100644 (file)
index ea6b8e4..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 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
- */
-
-/* Parts copied from GnuTLS example programs. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <gnutls/gnutls.h>
-
-#include "utils.h"
-
-static void
-tls_log_func (int level, const char *str)
-{
-  fprintf (stderr, "|<%d>| %s", level, str);
-}
-
-/* A very basic TLS client, with anonymous authentication.
- */
-
-#define MAX_BUF 1024
-#define MSG "Hello TLS"
-
-/* Connects to the peer and returns a socket
- * descriptor.
- */
-int
-tcp_connect (void)
-{
-  const char *PORT = "5556";
-  const char *SERVER = "127.0.0.1";
-  int err, sd;
-  struct sockaddr_in sa;
-
-  /* connects to server
-   */
-  sd = socket (AF_INET, SOCK_STREAM, 0);
-
-  memset (&sa, '\0', sizeof (sa));
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (atoi (PORT));
-  inet_pton (AF_INET, SERVER, &sa.sin_addr);
-
-  err = connect (sd, (struct sockaddr *) &sa, sizeof (sa));
-  if (err < 0)
-    {
-      fprintf (stderr, "Connect error\n");
-      exit (1);
-    }
-
-  return sd;
-}
-
-/* closes the given socket descriptor.
- */
-void
-tcp_close (int sd)
-{
-  shutdown (sd, SHUT_RDWR);    /* no more receptions */
-  close (sd);
-}
-
-void
-client (void)
-{
-  int ret, sd, ii;
-  gnutls_session_t session;
-  char buffer[MAX_BUF + 1];
-  gnutls_anon_client_credentials_t anoncred;
-  /* Need to enable anonymous KX specifically. */
-  const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
-
-  gnutls_global_init ();
-
-  gnutls_global_set_log_function (tls_log_func);
-  if (debug)
-    gnutls_global_set_log_level (4711);
-
-  gnutls_anon_allocate_client_credentials (&anoncred);
-
-  /* Initialize TLS session
-   */
-  gnutls_init (&session, GNUTLS_CLIENT);
-
-  /* Use default priorities */
-  gnutls_set_default_priority (session);
-  gnutls_kx_set_priority (session, kx_prio);
-
-  /* put the anonymous credentials to the current session
-   */
-  gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
-
-  gnutls_oprfi_enable_client (session, 3, "foo");
-
-  /* connect to the peer
-   */
-  sd = tcp_connect ();
-
-  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
-
-  /* Perform the TLS handshake
-   */
-  ret = gnutls_handshake (session);
-
-  if (ret < 0)
-    {
-      fail ("client: Handshake failed\n");
-      gnutls_perror (ret);
-      goto end;
-    }
-  else
-    {
-      success ("client: Handshake was completed\n");
-    }
-
-  success ("client: TLS version is: %s\n",
-          gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
-
-  gnutls_record_send (session, MSG, strlen (MSG));
-
-  ret = gnutls_record_recv (session, buffer, MAX_BUF);
-  if (ret == 0)
-    {
-      success ("client: Peer has closed the TLS connection\n");
-      goto end;
-    }
-  else if (ret < 0)
-    {
-      fail ("client: Error: %s\n", gnutls_strerror (ret));
-      goto end;
-    }
-
-  printf ("- Received %d bytes: ", ret);
-  for (ii = 0; ii < ret; ii++)
-    {
-      fputc (buffer[ii], stdout);
-    }
-  fputs ("\n", stdout);
-
-  gnutls_bye (session, GNUTLS_SHUT_RDWR);
-
-end:
-
-  tcp_close (sd);
-
-  gnutls_deinit (session);
-
-  gnutls_anon_free_client_credentials (anoncred);
-
-  gnutls_global_deinit ();
-}
-
-/* This is a sample TLS 1.0 echo server, for anonymous authentication only.
- */
-
-#define SA struct sockaddr
-#define MAX_BUF 1024
-#define PORT 5556              /* listen to 5556 port */
-#define DH_BITS 1024
-
-/* These are global */
-gnutls_anon_server_credentials_t anoncred;
-
-int
-oprfi_callback (gnutls_session_t session,
-               void *userdata,
-               size_t oprfi_len,
-               const unsigned char *in_oprfi, unsigned char *out_oprfi)
-{
-  size_t i;
-
-  puts ("cb");
-
-  for (i = 0; i < oprfi_len; i++)
-    printf ("OPRF[%d]: %02x %03d %c\n", i, in_oprfi[i],
-           in_oprfi[i], in_oprfi[i]);
-
-  memset (out_oprfi, 42, oprfi_len);
-
-  return 0;
-}
-
-gnutls_session_t
-initialize_tls_session (void)
-{
-  gnutls_session_t session;
-  const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
-
-  gnutls_init (&session, GNUTLS_SERVER);
-
-  /* avoid calling all the priority functions, since the defaults
-   * are adequate.
-   */
-  gnutls_set_default_priority (session);
-  gnutls_kx_set_priority (session, kx_prio);
-
-  gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
-
-  gnutls_dh_set_prime_bits (session, DH_BITS);
-
-  gnutls_oprfi_enable_server (session, oprfi_callback, NULL);
-
-  return session;
-}
-
-static gnutls_dh_params_t dh_params;
-
-static int
-generate_dh_params (void)
-{
-  const gnutls_datum_t p3 = { pkcs3, strlen (pkcs3) };
-  /* Generate Diffie-Hellman parameters - for use with DHE
-   * kx algorithms. These should be discarded and regenerated
-   * once a day, once a week or once a month. Depending on the
-   * security requirements.
-   */
-  gnutls_dh_params_init (&dh_params);
-  return gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
-}
-
-int err, listen_sd, i;
-int sd, ret;
-struct sockaddr_in sa_serv;
-struct sockaddr_in sa_cli;
-int client_len;
-char topbuf[512];
-gnutls_session_t session;
-char buffer[MAX_BUF + 1];
-int optval = 1;
-
-void
-server_start (void)
-{
-  /* this must be called once in the program
-   */
-  gnutls_global_init ();
-
-  gnutls_global_set_log_function (tls_log_func);
-  if (debug)
-    gnutls_global_set_log_level (4711);
-
-  gnutls_anon_allocate_server_credentials (&anoncred);
-
-  success ("Launched, generating DH parameters...\n");
-
-  generate_dh_params ();
-
-  gnutls_anon_set_server_dh_params (anoncred, dh_params);
-
-  /* Socket operations
-   */
-  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
-  if (err == -1)
-    {
-      perror ("socket");
-      fail ("server: socket failed\n");
-      return;
-    }
-
-  memset (&sa_serv, '\0', sizeof (sa_serv));
-  sa_serv.sin_family = AF_INET;
-  sa_serv.sin_addr.s_addr = INADDR_ANY;
-  sa_serv.sin_port = htons (PORT);     /* Server Port number */
-
-  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
-             sizeof (int));
-
-  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
-  if (err == -1)
-    {
-      perror ("bind");
-      fail ("server: bind failed\n");
-      return;
-    }
-
-  err = listen (listen_sd, 1024);
-  if (err == -1)
-    {
-      perror ("listen");
-      fail ("server: listen failed\n");
-      return;
-    }
-
-  success ("server: ready. Listening to port '%d'.\n", PORT);
-}
-
-void
-server (void)
-{
-  client_len = sizeof (sa_cli);
-
-  session = initialize_tls_session ();
-
-  sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
-
-  success ("server: connection from %s, port %d\n",
-          inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
-                     sizeof (topbuf)), ntohs (sa_cli.sin_port));
-
-  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
-  ret = gnutls_handshake (session);
-  if (ret < 0)
-    {
-      close (sd);
-      gnutls_deinit (session);
-      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
-      return;
-    }
-  success ("server: Handshake was completed\n");
-
-  success ("server: TLS version is: %s\n",
-          gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
-
-  /* see the Getting peer's information example */
-  /* print_info(session); */
-
-  i = 0;
-  for (;;)
-    {
-      memset (buffer, 0, MAX_BUF + 1);
-      ret = gnutls_record_recv (session, buffer, MAX_BUF);
-
-      if (ret == 0)
-       {
-         success ("server: Peer has closed the GnuTLS connection\n");
-         break;
-       }
-      else if (ret < 0)
-       {
-         fail ("server: Received corrupted data(%d). Closing...\n", ret);
-         break;
-       }
-      else if (ret > 0)
-       {
-         /* echo data back to the client
-          */
-         gnutls_record_send (session, buffer, strlen (buffer));
-       }
-    }
-  /* do not wait for the peer to close the connection.
-   */
-  gnutls_bye (session, GNUTLS_SHUT_WR);
-
-  close (sd);
-  gnutls_deinit (session);
-
-  close (listen_sd);
-
-  gnutls_anon_free_server_credentials (anoncred);
-
-  gnutls_global_deinit ();
-
-  success ("server: finished\n");
-}
-
-void
-doit (void)
-{
-  pid_t child;
-
-  server_start ();
-  if (error_count)
-    return;
-
-  child = fork ();
-  if (child < 0)
-    {
-      perror ("fork");
-      fail ("fork");
-      return;
-    }
-
-  if (child)
-    {
-      int status;
-      /* parent */
-      server ();
-      wait (&status);
-    }
-  else
-    client ();
-}
index dd42892af9c7c79e853eed6e1328f6a17d406c5e..c97ce9517fa4278fe706dd6ef1b1da526fa6f6f3 100644 (file)
 #define MAX_BUF 1024
 #define MSG "Hello TLS"
 
+static void
+tls_log_func (int level, const char *str)
+{
+  fprintf (stderr, "<%d>| %s", level, str);
+}
+
 static int
 client_avp (gnutls_session_t session, void *ptr,
            const char *last, size_t lastlen, char **new, size_t * newlen)
@@ -117,6 +123,10 @@ client (void)
   const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
 
   ret = gnutls_global_init ();
+  gnutls_global_set_log_function (tls_log_func);
+  if (debug)
+    gnutls_global_set_log_level (2);
+
   if (ret)
     fail ("global_init: %d\n", ret);
   ret = gnutls_global_init_extra ();
@@ -425,6 +435,10 @@ server (void)
   if (ret)
     fail ("global_init_extra: %d\n", ret);
 
+  gnutls_global_set_log_function (tls_log_func);
+  if (debug)
+    gnutls_global_set_log_level (2);
+
   gnutls_anon_allocate_server_credentials (&anoncred);
   gnutls_ia_allocate_server_credentials (&iacred);