summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos <nmav@crystal.(none)>2007-12-16 10:22:00 +0200
committerNikos <nmav@crystal.(none)>2007-12-16 10:22:00 +0200
commitc3ff3005e7fae67895b19c47bef79805f07e74dd (patch)
tree3e6ffb95f62d42bae48b4f76e228795f8a59da14
parent07233885bdb09113f62673e62968b5e492f61c74 (diff)
downloadgnutls-c3ff3005e7fae67895b19c47bef79805f07e74dd.tar.gz
Changes for post_client_hello_function(). The extensions are now parsed in a
callback friendly way. Extensions are now split to APPLICATION and TLS layer. The APPLICATION layer extensions are parsed before the callback function is called and the others afterwards. This allows the callback to change the behavior of the TLS layer parsers by using the data of the APPLICATION layer extensions. Currently the only application layer extension is defined to be the server name indication extension.
-rw-r--r--NEWS3
-rw-r--r--lib/gnutls_extensions.c20
-rw-r--r--lib/gnutls_extensions.h5
-rw-r--r--lib/gnutls_handshake.c13
-rw-r--r--lib/gnutls_int.h12
5 files changed, 42 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 3b134b3392..bfe9f28e34 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ See the end for copying conditions.
* Version 2.2.1 (unreleased)
+** Fixes the post_client_hello_function(). The extensions are now parsed
+in a callback friendly way.
+
** Fix for certificate selection in servers with certificate callbacks.
* Version 2.2.0 (released 2007-12-14)
diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c
index 1b804fd60f..ad1babad6d 100644
--- a/lib/gnutls_extensions.c
+++ b/lib/gnutls_extensions.c
@@ -39,8 +39,8 @@
#include <gnutls_num.h>
/* Key Exchange Section */
-#define GNUTLS_EXTENSION_ENTRY(type, ext_func_recv, ext_func_send) \
- { #type, type, ext_func_recv, ext_func_send }
+#define GNUTLS_EXTENSION_ENTRY(type, parse_type, ext_func_recv, ext_func_send) \
+ { #type, type, parse_type, ext_func_recv, ext_func_send }
#define MAX_EXT_SIZE 10
@@ -48,25 +48,31 @@ const int _gnutls_extensions_size = MAX_EXT_SIZE;
gnutls_extension_entry _gnutls_extensions[MAX_EXT_SIZE] = {
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_MAX_RECORD_SIZE,
+ EXTENSION_TLS,
_gnutls_max_record_recv_params,
_gnutls_max_record_send_params),
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_CERT_TYPE,
+ EXTENSION_TLS,
_gnutls_cert_type_recv_params,
_gnutls_cert_type_send_params),
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SERVER_NAME,
+ EXTENSION_APPLICATION,
_gnutls_server_name_recv_params,
_gnutls_server_name_send_params),
#ifdef ENABLE_OPRFI
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_OPAQUE_PRF_INPUT,
+ EXTENSION_TLS,
_gnutls_oprfi_recv_params,
_gnutls_oprfi_send_params),
#endif
#ifdef ENABLE_SRP
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SRP,
+ EXTENSION_TLS,
_gnutls_srp_recv_params,
_gnutls_srp_send_params),
#endif
GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_INNER_APPLICATION,
+ EXTENSION_TLS,
_gnutls_inner_application_recv_params,
_gnutls_inner_application_send_params),
{0, 0, 0, 0}
@@ -83,10 +89,10 @@ gnutls_extension_entry _gnutls_extensions[MAX_EXT_SIZE] = {
/* EXTENSION functions */
ext_recv_func
-_gnutls_ext_func_recv (uint16_t type)
+_gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t parse_type)
{
ext_recv_func ret = NULL;
- GNUTLS_EXTENSION_LOOP (ret = p->gnutls_ext_func_recv);
+ GNUTLS_EXTENSION_LOOP (if (parse_type == EXTENSION_ANY || p->parse_type == parse_type) ret = p->gnutls_ext_func_recv);
return ret;
}
@@ -132,8 +138,8 @@ _gnutls_extension_list_check (gnutls_session_t session, uint16_t type)
}
int
-_gnutls_parse_extensions (gnutls_session_t session, const opaque * data,
- int data_size)
+_gnutls_parse_extensions (gnutls_session_t session, tls_ext_parse_type_t parse_type,
+ const opaque * data, int data_size)
{
int next, ret;
int pos = 0;
@@ -185,7 +191,7 @@ _gnutls_parse_extensions (gnutls_session_t session, const opaque * data,
sdata = &data[pos];
pos += size;
- ext_recv = _gnutls_ext_func_recv (type);
+ ext_recv = _gnutls_ext_func_recv (type, parse_type);
if (ext_recv == NULL)
continue;
if ((ret = ext_recv (session, sdata, size)) < 0)
diff --git a/lib/gnutls_extensions.h b/lib/gnutls_extensions.h
index 3a7ee2f6c3..c305846c14 100644
--- a/lib/gnutls_extensions.h
+++ b/lib/gnutls_extensions.h
@@ -25,7 +25,7 @@
#include <gnutls_int.h>
const char *_gnutls_extension_get_name (uint16_t type);
-int _gnutls_parse_extensions (gnutls_session_t, const opaque *, int);
+int _gnutls_parse_extensions (gnutls_session_t, tls_ext_parse_type_t, const opaque *, int);
int _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
size_t data_size);
@@ -33,12 +33,13 @@ typedef int (*ext_recv_func) (gnutls_session_t, const opaque *, size_t); /* recv
typedef int (*ext_send_func) (gnutls_session_t, opaque *, size_t); /* send data */
ext_send_func _gnutls_ext_func_send (uint16_t type);
-ext_recv_func _gnutls_ext_func_recv (uint16_t type);
+ext_recv_func _gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t);
typedef struct
{
const char *name;
uint16_t type;
+ tls_ext_parse_type_t parse_type;
ext_recv_func gnutls_ext_func_recv;
ext_send_func gnutls_ext_func_send;
} gnutls_extension_entry;
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 737f5855fa..2737edff85 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -429,7 +429,7 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
*/
if (neg_version >= GNUTLS_TLS1)
{
- ret = _gnutls_parse_extensions (session, &data[pos], len); /* len is the rest of the parsed length */
+ ret = _gnutls_parse_extensions (session, EXTENSION_APPLICATION, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0)
{
gnutls_assert ();
@@ -444,6 +444,15 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
return ret;
}
+ if (neg_version >= GNUTLS_TLS1)
+ {
+ ret = _gnutls_parse_extensions (session, EXTENSION_TLS, &data[pos], len); /* len is the rest of the parsed length */
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+ }
/* select an appropriate cipher suite
*/
@@ -1535,7 +1544,7 @@ _gnutls_read_server_hello (gnutls_session_t session,
*/
if (version >= GNUTLS_TLS1)
{
- ret = _gnutls_parse_extensions (session, &data[pos], len); /* len is the rest of the parsed length */
+ ret = _gnutls_parse_extensions (session, EXTENSION_ANY, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0)
{
gnutls_assert ();
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 541a73192b..d8d94c706d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -290,6 +290,18 @@ typedef struct
uint16_t oprfi_server_len;
} tls_ext_st;
+/* This flag indicates for an extension whether
+ * it is useful to application level or TLS level only.
+ * This is used to parse the application level extensions
+ * before the user_hello callback is called.
+ */
+typedef enum tls_ext_parse_type_t
+{
+ EXTENSION_ANY,
+ EXTENSION_APPLICATION,
+ EXTENSION_TLS
+} tls_ext_parse_type_t;
+
/* auth_info_t structures now MAY contain malloced
* elements.
*/