diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-06-12 10:16:10 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-06-12 10:16:14 +0200 |
commit | 64abc885ee83884d2ec117ef63ce33ed7404b5b4 (patch) | |
tree | 53b6428b37dfe670283dcb392bd80cb595e8ce58 | |
parent | 739239e33499d350a3fb9697e303fc2d2333d223 (diff) | |
download | gnutls-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.c | 2 | ||||
-rw-r--r-- | lib/ext/pre_shared_key.h | 2 | ||||
-rw-r--r-- | lib/hello_ext.c | 16 |
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) |