summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-06-12 10:16:10 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-06-12 10:16:14 +0200
commit64abc885ee83884d2ec117ef63ce33ed7404b5b4 (patch)
tree53b6428b37dfe670283dcb392bd80cb595e8ce58
parent739239e33499d350a3fb9697e303fc2d2333d223 (diff)
downloadgnutls-tmp-fix-order-extensions.tar.gz
_gnutls_parse_hello_extensions: enforce that pre-shared-key extension is lasttmp-fix-order-extensions
This is a requirement in draft-ietf-tls-tls13-28 4.2.11 section: The "pre_shared_key" extension MUST be the last extension in the ClientHello (this facilitates implementation as described below). Servers MUST check that it is the last extension and otherwise fail the handshake with an "illegal_parameter" alert. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/ext/pre_shared_key.c2
-rw-r--r--lib/ext/pre_shared_key.h2
-rw-r--r--lib/hello_ext.c16
3 files changed, 16 insertions, 4 deletions
diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
index dce24d80a1..b12d853af8 100644
--- a/lib/ext/pre_shared_key.c
+++ b/lib/ext/pre_shared_key.c
@@ -749,7 +749,7 @@ static int _gnutls_psk_recv_params(gnutls_session_t session,
const hello_ext_entry_st ext_pre_shared_key = {
.name = "Pre Shared Key",
- .tls_id = 41,
+ .tls_id = PRE_SHARED_KEY_TLS_ID,
.gid = GNUTLS_EXTENSION_PRE_SHARED_KEY,
.parse_type = GNUTLS_EXT_TLS,
.validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO,
diff --git a/lib/ext/pre_shared_key.h b/lib/ext/pre_shared_key.h
index 2e830ff52e..1168750656 100644
--- a/lib/ext/pre_shared_key.h
+++ b/lib/ext/pre_shared_key.h
@@ -5,6 +5,8 @@
#include <hello_ext.h>
#include "tls13/session_ticket.h"
+#define PRE_SHARED_KEY_TLS_ID 41
+
extern const hello_ext_entry_st ext_pre_shared_key;
inline static
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index d9f548457f..a3027130a6 100644
--- a/lib/hello_ext.c
+++ b/lib/hello_ext.c
@@ -195,6 +195,7 @@ typedef struct hello_ext_ctx_st {
gnutls_ext_flags_t msg;
gnutls_ext_parse_type_t parse_type;
const hello_ext_entry_st *ext; /* used during send */
+ unsigned seen_pre_shared_key;
} hello_ext_ctx_st;
static
@@ -205,6 +206,14 @@ int hello_ext_parse(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned d
const hello_ext_entry_st *ext;
int ret;
+ if (tls_id == PRE_SHARED_KEY_TLS_ID) {
+ ctx->seen_pre_shared_key = 1;
+ } else if (ctx->seen_pre_shared_key) {
+ /* the pre-shared key extension must always be the last one,
+ * draft-ietf-tls-tls13-28: 4.2.11 */
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ }
+
ext = tls_id_to_ext_entry(session, tls_id, ctx->parse_type);
if (ext == NULL || ext->recv_func == NULL) {
goto ignore;
@@ -270,9 +279,9 @@ int hello_ext_parse(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned d
int
_gnutls_parse_hello_extensions(gnutls_session_t session,
- gnutls_ext_flags_t msg,
- gnutls_ext_parse_type_t parse_type,
- const uint8_t * data, int data_size)
+ gnutls_ext_flags_t msg,
+ gnutls_ext_parse_type_t parse_type,
+ const uint8_t * data, int data_size)
{
int ret;
hello_ext_ctx_st ctx;
@@ -282,6 +291,7 @@ _gnutls_parse_hello_extensions(gnutls_session_t session,
ctx.session = session;
ctx.msg = msg;
ctx.parse_type = parse_type;
+ ctx.seen_pre_shared_key = 0;
ret = _gnutls_extv_parse(&ctx, hello_ext_parse, data, data_size);
if (ret < 0)