summaryrefslogtreecommitdiff
path: root/lib/hello_ext.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-05-07 09:52:32 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-05-17 13:54:03 +0200
commitf41df13ec8b77414ff8e682d8234c089bd24e7e9 (patch)
treebf9a12d81c1469c6aefa896393bd95f95cdea7f4 /lib/hello_ext.c
parent9c0b15a08a48b72fe63ccd5b046ff9199212d10b (diff)
downloadgnutls-f41df13ec8b77414ff8e682d8234c089bd24e7e9.tar.gz
handshake: do not send TLS extensions under DTLS and vice versatmp-prohibit-tls-dtls-mix
That is, introduce the notion of TLS-only and DTLS-only extensions, providing a framework to prevent sending extensions which are registered for example for TLS 1.3, under DTLS and vice versa. Resolves #440 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/hello_ext.c')
-rw-r--r--lib/hello_ext.c73
1 files changed, 59 insertions, 14 deletions
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index 57583231a3..d61f846f51 100644
--- a/lib/hello_ext.c
+++ b/lib/hello_ext.c
@@ -208,12 +208,21 @@ int hello_ext_parse(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned d
ext = tls_id_to_ext_entry(session, tls_id, ctx->parse_type);
if (ext == NULL || ext->recv_func == NULL) {
- if (ext) {
- _gnutls_hard_log
- ("EXT[%p]: Ignoring extension '%s/%d'\n", session,
- ext->name, (int)tls_id);
+ goto ignore;
+ }
+
+ /* we do not hard fail when extensions defined for TLS are used for
+ * DTLS and vice-versa. They may extend their role in the future. */
+ if (IS_DTLS(session)) {
+ if (!(ext->validity & GNUTLS_EXT_FLAG_DTLS)) {
+ gnutls_assert();
+ goto ignore;
+ }
+ } else {
+ if (!(ext->validity & GNUTLS_EXT_FLAG_TLS)) {
+ gnutls_assert();
+ goto ignore;
}
- return 0;
}
if (session->security_parameters.entity == GNUTLS_CLIENT) {
@@ -250,6 +259,14 @@ int hello_ext_parse(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned d
}
return 0;
+
+ ignore:
+ if (ext) {
+ _gnutls_handshake_log
+ ("EXT[%p]: Ignoring extension '%s/%d'\n", session,
+ ext->name, (int)tls_id);
+ }
+ return 0;
}
int
@@ -261,6 +278,8 @@ _gnutls_parse_hello_extensions(gnutls_session_t session,
int ret;
hello_ext_ctx_st ctx;
+ msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
+
ctx.session = session;
ctx.msg = msg;
ctx.parse_type = parse_type;
@@ -290,11 +309,20 @@ int hello_ext_send(void *_ctx, gnutls_buffer_st *buf)
return 0;
}
+ if (IS_DTLS(session)) {
+ if (!(p->validity & GNUTLS_EXT_FLAG_DTLS)) {
+ gnutls_assert();
+ goto skip;
+ }
+ } else {
+ if (!(p->validity & GNUTLS_EXT_FLAG_TLS)) {
+ gnutls_assert();
+ goto skip;
+ }
+ }
+
if ((ctx->msg & p->validity) == 0) {
- _gnutls_hard_log("EXT[%p]: Not sending extension (%s/%d) for '%s'\n", session,
- p->name, (int)p->tls_id,
- ext_msg_validity_to_str(ctx->msg));
- return 0;
+ goto skip;
} else {
_gnutls_handshake_log("EXT[%p]: Preparing extension (%s/%d) for '%s'\n", session,
p->name, (int)p->tls_id,
@@ -335,6 +363,12 @@ int hello_ext_send(void *_ctx, gnutls_buffer_st *buf)
}
return ret;
+
+ skip:
+ _gnutls_handshake_log("EXT[%p]: Not sending extension (%s/%d) for '%s'\n", session,
+ p->name, (int)p->tls_id,
+ ext_msg_validity_to_str(ctx->msg));
+ return 0;
}
int
@@ -347,6 +381,8 @@ _gnutls_gen_hello_extensions(gnutls_session_t session,
size_t i;
hello_ext_ctx_st ctx;
+ msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
+
ctx.session = session;
ctx.msg = msg;
ctx.parse_type = parse_type;
@@ -752,7 +788,8 @@ gnutls_ext_register(const char *name, int id, gnutls_ext_parse_type_t parse_type
tmp_mod->deinit_func = deinit_func;
tmp_mod->pack_func = pack_func;
tmp_mod->unpack_func = unpack_func;
- tmp_mod->validity = GNUTLS_EXT_FLAG_CLIENT_HELLO|GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO|GNUTLS_EXT_FLAG_EE;
+ tmp_mod->validity = GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO |
+ GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS;
assert(extfunc[gid] == NULL);
extfunc[gid] = tmp_mod;
@@ -760,9 +797,9 @@ gnutls_ext_register(const char *name, int id, gnutls_ext_parse_type_t parse_type
return 0;
}
-#define VALIDITY_MASK (GNUTLS_EXT_FLAG_CLIENT_HELLO|GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO| \
- GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO| \
- GNUTLS_EXT_FLAG_EE|GNUTLS_EXT_FLAG_HRR)
+#define VALIDITY_MASK (GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO | \
+ GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO | \
+ GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_HRR)
/**
* gnutls_session_ext_register:
@@ -854,7 +891,15 @@ gnutls_session_ext_register(gnutls_session_t session,
tmp_mod.validity = flags;
if ((tmp_mod.validity & VALIDITY_MASK) == 0) {
- tmp_mod.validity = GNUTLS_EXT_FLAG_CLIENT_HELLO|GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO|GNUTLS_EXT_FLAG_EE;
+ tmp_mod.validity = GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO |
+ GNUTLS_EXT_FLAG_EE;
+ }
+
+ if ((tmp_mod.validity & (GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS)) == 0) {
+ if (IS_DTLS(session))
+ tmp_mod.validity |= GNUTLS_EXT_FLAG_DTLS;
+ else
+ tmp_mod.validity |= GNUTLS_EXT_FLAG_TLS;
}
exts = gnutls_realloc(session->internals.rexts, (session->internals.rexts_size+1)*sizeof(*exts));