1 /*
2  * Copyright (C) 2001-2018 Free Software Foundation, Inc.
3  * Copyright (C) 2015-2018 Red Hat, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos, Simon Josefsson
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>
21  *
22  */
23 
24 /* Functions that relate to the TLS hello extension parsing.
25  * Hello extensions are packets appended in the TLS hello packet, and
26  * allow for extra functionality.
27  */
28 
29 #include "gnutls_int.h"
30 #include "hello_ext.h"
31 #include "errors.h"
32 #include "ext/max_record.h"
33 #include <ext/server_name.h>
34 #include <ext/srp.h>
35 #include <ext/heartbeat.h>
36 #include <ext/session_ticket.h>
37 #include <ext/safe_renegotiation.h>
38 #include <ext/signature.h>
39 #include <ext/safe_renegotiation.h>
40 #include "ext/supported_groups.h"
41 #include "ext/ec_point_formats.h"
42 #include <ext/status_request.h>
43 #include <ext/ext_master_secret.h>
44 #include <ext/supported_versions.h>
45 #include <ext/post_handshake.h>
46 #include <ext/srtp.h>
47 #include <ext/alpn.h>
48 #include <ext/dumbfw.h>
49 #include <ext/key_share.h>
50 #include <ext/pre_shared_key.h>
51 #include <ext/psk_ke_modes.h>
52 #include <ext/etm.h>
53 #include <ext/cookie.h>
54 #include <ext/early_data.h>
55 #include <ext/record_size_limit.h>
56 #include "extv.h"
57 #include <num.h>
58 #include <ext/client_cert_type.h>
59 #include <ext/server_cert_type.h>
60 
61 static void
62 unset_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *, unsigned idx);
63 
64 static void unset_resumed_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *, unsigned idx);
65 
66 static hello_ext_entry_st const *extfunc[MAX_EXT_TYPES+1] = {
67 	[GNUTLS_EXTENSION_EXT_MASTER_SECRET] = &ext_mod_ext_master_secret,
68 	[GNUTLS_EXTENSION_SUPPORTED_VERSIONS] = &ext_mod_supported_versions,
69 	[GNUTLS_EXTENSION_POST_HANDSHAKE] = &ext_mod_post_handshake,
70 	[GNUTLS_EXTENSION_ETM] = &ext_mod_etm,
71 #ifdef ENABLE_OCSP
72 	[GNUTLS_EXTENSION_STATUS_REQUEST] = &ext_mod_status_request,
73 #endif
74 	[GNUTLS_EXTENSION_SERVER_NAME] = &ext_mod_server_name,
75 	[GNUTLS_EXTENSION_SAFE_RENEGOTIATION] = &ext_mod_sr,
76 #ifdef ENABLE_SRP
77 	[GNUTLS_EXTENSION_SRP] = &ext_mod_srp,
78 #endif
79 #ifdef ENABLE_HEARTBEAT
80 	[GNUTLS_EXTENSION_HEARTBEAT] = &ext_mod_heartbeat,
81 #endif
82 	[GNUTLS_EXTENSION_SESSION_TICKET] = &ext_mod_session_ticket,
83 	[GNUTLS_EXTENSION_CLIENT_CERT_TYPE] = &ext_mod_client_cert_type,
84 	[GNUTLS_EXTENSION_SERVER_CERT_TYPE] = &ext_mod_server_cert_type,
85 	[GNUTLS_EXTENSION_SUPPORTED_GROUPS] = &ext_mod_supported_groups,
86 	[GNUTLS_EXTENSION_SUPPORTED_EC_POINT_FORMATS] = &ext_mod_supported_ec_point_formats,
87 	[GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS] = &ext_mod_sig,
88 	[GNUTLS_EXTENSION_KEY_SHARE] = &ext_mod_key_share,
89 	[GNUTLS_EXTENSION_COOKIE] = &ext_mod_cookie,
90 	[GNUTLS_EXTENSION_EARLY_DATA] = &ext_mod_early_data,
91 #ifdef ENABLE_DTLS_SRTP
92 	[GNUTLS_EXTENSION_SRTP] = &ext_mod_srtp,
93 #endif
94 #ifdef ENABLE_ALPN
95 	[GNUTLS_EXTENSION_ALPN] = &ext_mod_alpn,
96 #endif
97 	[GNUTLS_EXTENSION_RECORD_SIZE_LIMIT] = &ext_mod_record_size_limit,
98 	[GNUTLS_EXTENSION_MAX_RECORD_SIZE] = &ext_mod_max_record_size,
99 	[GNUTLS_EXTENSION_PSK_KE_MODES] = &ext_mod_psk_ke_modes,
100 	[GNUTLS_EXTENSION_PRE_SHARED_KEY] = &ext_mod_pre_shared_key,
101 	/* This must be the last extension registered.
102 	 */
103 	[GNUTLS_EXTENSION_DUMBFW] = &ext_mod_dumbfw,
104 };
105 
106 static const hello_ext_entry_st *
gid_to_ext_entry(gnutls_session_t session,extensions_t id)107 gid_to_ext_entry(gnutls_session_t session, extensions_t id)
108 {
109 	unsigned i;
110 
111 	assert(id < MAX_EXT_TYPES);
112 
113 	for (i=0;i<session->internals.rexts_size;i++) {
114 		if (session->internals.rexts[i].gid == id) {
115 			return &session->internals.rexts[i];
116 		}
117 	}
118 
119 	return extfunc[id];
120 }
121 
122 static const hello_ext_entry_st *
tls_id_to_ext_entry(gnutls_session_t session,uint16_t tls_id,gnutls_ext_parse_type_t parse_point)123 tls_id_to_ext_entry(gnutls_session_t session, uint16_t tls_id, gnutls_ext_parse_type_t parse_point)
124 {
125 	unsigned i;
126 	const hello_ext_entry_st *e;
127 
128 	for (i=0;i<session->internals.rexts_size;i++) {
129 		if (session->internals.rexts[i].tls_id == tls_id) {
130 			e = &session->internals.rexts[i];
131 			goto done;
132 		}
133 	}
134 
135 	for (i = 0; i < MAX_EXT_TYPES; i++) {
136 		if (!extfunc[i])
137 			continue;
138 
139 		if (extfunc[i]->tls_id == tls_id) {
140 			e = extfunc[i];
141 			goto done;
142 		}
143 	}
144 
145 	return NULL;
146 done:
147 	if (parse_point == GNUTLS_EXT_ANY || (IS_SERVER(session) && e->server_parse_point == parse_point) ||
148 	    (!IS_SERVER(session) && e->client_parse_point == parse_point)) {
149 		return e;
150 	} else {
151 		return NULL;
152 	}
153 }
154 
155 
156 /**
157  * gnutls_ext_get_name:
158  * @ext: is a TLS extension numeric ID
159  *
160  * Convert a TLS extension numeric ID to a printable string.
161  *
162  * Returns: a pointer to a string that contains the name of the
163  *   specified cipher, or %NULL.
164  **/
gnutls_ext_get_name(unsigned int ext)165 const char *gnutls_ext_get_name(unsigned int ext)
166 {
167 	size_t i;
168 
169 	for (i = 0; i < MAX_EXT_TYPES; i++) {
170 		if (!extfunc[i])
171 			continue;
172 
173 		if (extfunc[i]->tls_id == ext)
174 			return extfunc[i]->name;
175 	}
176 
177 	return NULL;
178 }
179 
180 /* Returns %GNUTLS_EXTENSION_INVALID on error
181  */
tls_id_to_gid(gnutls_session_t session,unsigned tls_id)182 static unsigned tls_id_to_gid(gnutls_session_t session, unsigned tls_id)
183 {
184 	unsigned i;
185 
186 	for (i=0; i < session->internals.rexts_size; i++) {
187 		if (session->internals.rexts[i].tls_id == tls_id)
188 			return session->internals.rexts[i].gid;
189 	}
190 
191 	for (i = 0; i < MAX_EXT_TYPES; i++) {
192 		if (!extfunc[i])
193 			continue;
194 
195 		if (extfunc[i]->tls_id == tls_id)
196 			return extfunc[i]->gid;
197 	}
198 
199 	return GNUTLS_EXTENSION_INVALID;
200 }
201 
202 typedef struct hello_ext_ctx_st {
203 	gnutls_session_t session;
204 	gnutls_ext_flags_t msg;
205 	gnutls_ext_parse_type_t parse_point;
206 	const hello_ext_entry_st *ext; /* used during send */
207 	unsigned seen_pre_shared_key;
208 } hello_ext_ctx_st;
209 
210 static
hello_ext_parse(void * _ctx,unsigned tls_id,const uint8_t * data,unsigned data_size)211 int hello_ext_parse(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned data_size)
212 {
213 	hello_ext_ctx_st *ctx = _ctx;
214 	gnutls_session_t session = ctx->session;
215 	const hello_ext_entry_st *ext;
216 	int ret;
217 
218 	if (tls_id == PRE_SHARED_KEY_TLS_ID) {
219 		ctx->seen_pre_shared_key = 1;
220 	} else if (ctx->seen_pre_shared_key && session->security_parameters.entity == GNUTLS_SERVER) {
221 		/* the pre-shared key extension must always be the last one,
222 		 * draft-ietf-tls-tls13-28: 4.2.11 */
223 		return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
224 	}
225 
226 	ext = tls_id_to_ext_entry(session, tls_id, ctx->parse_point);
227 	if (ext == NULL || ext->recv_func == NULL) {
228 		goto ignore;
229 	}
230 
231 	/* we do not hard fail when extensions defined for TLS are used for
232 	 * DTLS and vice-versa. They may extend their role in the future. */
233 	if (IS_DTLS(session)) {
234 		if (!(ext->validity & GNUTLS_EXT_FLAG_DTLS)) {
235 			gnutls_assert();
236 			goto ignore;
237 		}
238 	} else {
239 		if (!(ext->validity & GNUTLS_EXT_FLAG_TLS)) {
240 			gnutls_assert();
241 			goto ignore;
242 		}
243 	}
244 
245 	if (session->security_parameters.entity == GNUTLS_CLIENT) {
246 		if (!(ext->validity & GNUTLS_EXT_FLAG_IGNORE_CLIENT_REQUEST) &&
247 		    !_gnutls_hello_ext_is_present(session, ext->gid)) {
248 			_gnutls_debug_log("EXT[%p]: Received unexpected extension '%s/%d'\n", session,
249 					ext->name, (int)tls_id);
250 			return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
251 		}
252 	}
253 
254 	if ((ext->validity & ctx->msg) == 0) {
255 		_gnutls_debug_log("EXT[%p]: Received unexpected extension (%s/%d) for '%s'\n", session,
256 				  ext->name, (int)tls_id,
257 				  ext_msg_validity_to_str(ctx->msg));
258 		return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
259 	}
260 
261 	if (session->security_parameters.entity == GNUTLS_SERVER) {
262 		ret = _gnutls_hello_ext_save(session, ext->gid, 1);
263 		if (ret == 0)
264 			return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
265 	}
266 
267 	_gnutls_handshake_log
268 	    ("EXT[%p]: Parsing extension '%s/%d' (%d bytes)\n",
269 	     session, ext->name, (int)tls_id,
270 	     data_size);
271 
272 	_gnutls_ext_set_msg(session, ctx->msg);
273 	if ((ret = ext->recv_func(session, data, data_size)) < 0) {
274 		gnutls_assert();
275 		return ret;
276 	}
277 
278 	return 0;
279 
280  ignore:
281 	if (ext) {
282 		_gnutls_handshake_log
283 		    ("EXT[%p]: Ignoring extension '%s/%d'\n", session,
284 		     ext->name, (int)tls_id);
285 	}
286 	return 0;
287 }
288 
289 int
_gnutls_parse_hello_extensions(gnutls_session_t session,gnutls_ext_flags_t msg,gnutls_ext_parse_type_t parse_point,const uint8_t * data,int data_size)290 _gnutls_parse_hello_extensions(gnutls_session_t session,
291 			       gnutls_ext_flags_t msg,
292 			       gnutls_ext_parse_type_t parse_point,
293 			       const uint8_t * data, int data_size)
294 {
295 	int ret;
296 	hello_ext_ctx_st ctx;
297 
298 	msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
299 
300 	ctx.session = session;
301 	ctx.msg = msg;
302 	ctx.parse_point = parse_point;
303 	ctx.seen_pre_shared_key = 0;
304 
305 	ret = _gnutls_extv_parse(&ctx, hello_ext_parse, data, data_size);
306 	if (ret < 0)
307 		return gnutls_assert_val(ret);
308 
309 	return 0;
310 }
311 
312 static
hello_ext_send(void * _ctx,gnutls_buffer_st * buf)313 int hello_ext_send(void *_ctx, gnutls_buffer_st *buf)
314 {
315 	hello_ext_ctx_st *ctx = _ctx;
316 	int ret;
317 	const hello_ext_entry_st *p = ctx->ext;
318 	gnutls_session_t session = ctx->session;
319 	int appended;
320 	size_t size_prev;
321 
322 	if (unlikely(p->send_func == NULL))
323 		return 0;
324 
325 	if (ctx->parse_point != GNUTLS_EXT_ANY &&
326 	    ((IS_SERVER(session) && p->server_parse_point != ctx->parse_point) ||
327 	     (!IS_SERVER(session) && p->client_parse_point != ctx->parse_point))) {
328 		return 0;
329 	}
330 
331 	if (IS_DTLS(session)) {
332 		if (!(p->validity & GNUTLS_EXT_FLAG_DTLS)) {
333 			gnutls_assert();
334 			goto skip;
335 		}
336 	} else {
337 		if (!(p->validity & GNUTLS_EXT_FLAG_TLS)) {
338 			gnutls_assert();
339 			goto skip;
340 		}
341 	}
342 
343 	if ((ctx->msg & p->validity) == 0) {
344 		goto skip;
345 	} else {
346 		_gnutls_handshake_log("EXT[%p]: Preparing extension (%s/%d) for '%s'\n", session,
347 				  p->name, (int)p->tls_id,
348 				  ext_msg_validity_to_str(ctx->msg));
349 	}
350 
351 	/* ensure we don't send something twice (i.e, overridden extensions in
352 	 * client), and ensure we are sending only what we received in server. */
353 	ret = _gnutls_hello_ext_is_present(session, p->gid);
354 
355 	if (session->security_parameters.entity == GNUTLS_SERVER) {
356 		/* if client didn't advertise and the override flag is not present */
357 		if (!(p->validity & GNUTLS_EXT_FLAG_IGNORE_CLIENT_REQUEST) && ret == 0)
358 			return 0;
359 	} else {
360 		if (ret != 0) /* already sent */
361 			return 0;
362 	}
363 
364 
365 	size_prev = buf->length;
366 
367 	_gnutls_ext_set_msg(session, ctx->msg);
368 	ret = p->send_func(session, buf);
369 	if (ret < 0 && ret != GNUTLS_E_INT_RET_0) {
370 		return gnutls_assert_val(ret);
371 	}
372 
373 	appended = buf->length - size_prev;
374 
375 	/* add this extension to the extension list, to know which extensions
376 	 * to expect.
377 	 */
378 	if ((appended > 0 || ret == GNUTLS_E_INT_RET_0) &&
379 	    session->security_parameters.entity == GNUTLS_CLIENT) {
380 
381 		_gnutls_hello_ext_save(session, p->gid, 0);
382 	}
383 
384 	return ret;
385 
386  skip:
387 	_gnutls_handshake_log("EXT[%p]: Not sending extension (%s/%d) for '%s'\n", session,
388 			  p->name, (int)p->tls_id,
389 			  ext_msg_validity_to_str(ctx->msg));
390 	return 0;
391 }
392 
393 int
_gnutls_gen_hello_extensions(gnutls_session_t session,gnutls_buffer_st * buf,gnutls_ext_flags_t msg,gnutls_ext_parse_type_t parse_point)394 _gnutls_gen_hello_extensions(gnutls_session_t session,
395 			     gnutls_buffer_st * buf,
396 			     gnutls_ext_flags_t msg,
397 			     gnutls_ext_parse_type_t parse_point)
398 {
399 	int pos, ret;
400 	size_t i;
401 	hello_ext_ctx_st ctx;
402 
403 	msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
404 
405 	ctx.session = session;
406 	ctx.msg = msg;
407 	ctx.parse_point = parse_point;
408 
409 	ret = _gnutls_extv_append_init(buf);
410 	if (ret < 0)
411 		return gnutls_assert_val(ret);
412 
413 	pos = ret;
414 	_gnutls_ext_set_extensions_offset(session, pos);
415 
416 	for (i=0; i < session->internals.rexts_size; i++) {
417 		ctx.ext = &session->internals.rexts[i];
418 		ret = _gnutls_extv_append(buf, session->internals.rexts[i].tls_id,
419 					  &ctx, hello_ext_send);
420 		if (ret < 0)
421 			return gnutls_assert_val(ret);
422 
423 		if (ret > 0)
424 			_gnutls_handshake_log
425 				    ("EXT[%p]: Sending extension %s/%d (%d bytes)\n",
426 				     session, ctx.ext->name, (int)ctx.ext->tls_id, ret-4);
427 	}
428 
429 	/* hello_ext_send() ensures we don't send duplicates, in case
430 	 * of overridden extensions */
431 	for (i = 0; i < MAX_EXT_TYPES; i++) {
432 		if (!extfunc[i])
433 			continue;
434 
435 		ctx.ext = extfunc[i];
436 		ret = _gnutls_extv_append(buf, extfunc[i]->tls_id,
437 					  &ctx, hello_ext_send);
438 		if (ret < 0)
439 			return gnutls_assert_val(ret);
440 
441 		if (ret > 0)
442 			_gnutls_handshake_log
443 				    ("EXT[%p]: Sending extension %s/%d (%d bytes)\n",
444 				     session, ctx.ext->name, (int)ctx.ext->tls_id, ret-4);
445 	}
446 
447 	ret = _gnutls_extv_append_final(buf, pos, !(msg & GNUTLS_EXT_FLAG_EE));
448 	if (ret < 0)
449 		return gnutls_assert_val(ret);
450 
451 	return 0;
452 }
453 
454 /* Global deinit and init of global extensions */
_gnutls_hello_ext_init(void)455 int _gnutls_hello_ext_init(void)
456 {
457 	return GNUTLS_E_SUCCESS;
458 }
459 
_gnutls_hello_ext_deinit(void)460 void _gnutls_hello_ext_deinit(void)
461 {
462 	unsigned i;
463 
464 	for (i = 0; i < MAX_EXT_TYPES; i++) {
465 		if (!extfunc[i])
466 			continue;
467 
468 		if (extfunc[i]->free_struct != 0) {
469 			gnutls_free(((hello_ext_entry_st *)extfunc[i])->name);
470 			gnutls_free(extfunc[i]);
471 		}
472 	}
473 }
474 
475 /* Packing of extension data (for use in resumption) */
pack_extension(gnutls_session_t session,const hello_ext_entry_st * extp,gnutls_buffer_st * packed)476 static int pack_extension(gnutls_session_t session, const hello_ext_entry_st *extp,
477 			  gnutls_buffer_st *packed)
478 {
479 	int ret;
480 	int size_offset;
481 	int cur_size;
482 	gnutls_ext_priv_data_t data;
483 	int rval = 0;
484 
485 	ret =
486 	    _gnutls_hello_ext_get_priv(session, extp->gid,
487 					 &data);
488 	if (ret >= 0 && extp->pack_func != NULL) {
489 		BUFFER_APPEND_NUM(packed, extp->gid);
490 
491 		size_offset = packed->length;
492 		BUFFER_APPEND_NUM(packed, 0);
493 
494 		cur_size = packed->length;
495 
496 		ret = extp->pack_func(data, packed);
497 		if (ret < 0) {
498 			gnutls_assert();
499 			return ret;
500 		}
501 
502 		rval = 1;
503 		/* write the actual size */
504 		_gnutls_write_uint32(packed->length - cur_size,
505 				     packed->data + size_offset);
506 	}
507 
508 	return rval;
509 }
510 
_gnutls_hello_ext_pack(gnutls_session_t session,gnutls_buffer_st * packed)511 int _gnutls_hello_ext_pack(gnutls_session_t session, gnutls_buffer_st *packed)
512 {
513 	unsigned int i;
514 	int ret;
515 	int total_exts_pos;
516 	int n_exts = 0;
517 	const struct hello_ext_entry_st *ext;
518 
519 	total_exts_pos = packed->length;
520 	BUFFER_APPEND_NUM(packed, 0);
521 
522 	for (i = 0; i <= GNUTLS_EXTENSION_MAX_VALUE; i++) {
523 		if (session->internals.used_exts & ((ext_track_t)1 << i)) {
524 
525 			ext = gid_to_ext_entry(session, i);
526 			if (ext == NULL)
527 				continue;
528 
529 			ret = pack_extension(session, ext, packed);
530 			if (ret < 0)
531 				return gnutls_assert_val(ret);
532 
533 			if (ret > 0)
534 				n_exts++;
535 		}
536 	}
537 
538 	_gnutls_write_uint32(n_exts, packed->data + total_exts_pos);
539 
540 	return 0;
541 }
542 
_gnutls_ext_set_full_client_hello(gnutls_session_t session,handshake_buffer_st * recv_buf)543 int _gnutls_ext_set_full_client_hello(gnutls_session_t session,
544 				      handshake_buffer_st *recv_buf)
545 {
546 	int ret;
547 	gnutls_buffer_st *buf = &session->internals.full_client_hello;
548 
549 	_gnutls_buffer_clear(buf);
550 
551 	if ((ret = _gnutls_buffer_append_prefix(buf, 8, recv_buf->htype)) < 0)
552 		return gnutls_assert_val(ret);
553 	if ((ret = _gnutls_buffer_append_prefix(buf, 24, recv_buf->data.length)) < 0)
554 		return gnutls_assert_val(ret);
555 	if ((ret = _gnutls_buffer_append_data(buf, recv_buf->data.data, recv_buf->data.length)) < 0)
556 		return gnutls_assert_val(ret);
557 
558 	return 0;
559 }
560 
_gnutls_ext_get_full_client_hello(gnutls_session_t session,gnutls_datum_t * d)561 unsigned _gnutls_ext_get_full_client_hello(gnutls_session_t session,
562 				           gnutls_datum_t *d)
563 {
564 	gnutls_buffer_st *buf = &session->internals.full_client_hello;
565 
566 	if (!buf->length)
567 		return 0;
568 
569 	d->data = buf->data;
570 	d->size = buf->length;
571 
572 	return 1;
573 }
574 
575 static void
_gnutls_ext_set_resumed_session_data(gnutls_session_t session,extensions_t id,gnutls_ext_priv_data_t data)576 _gnutls_ext_set_resumed_session_data(gnutls_session_t session,
577 				     extensions_t id,
578 				     gnutls_ext_priv_data_t data)
579 {
580 	const struct hello_ext_entry_st *ext;
581 
582 	/* If this happens we need to increase the max */
583 	assert(id < MAX_EXT_TYPES);
584 
585 	ext = gid_to_ext_entry(session, id);
586 	assert(ext != NULL);
587 
588 	if (session->internals.ext_data[id].resumed_set != 0)
589 		unset_resumed_ext_data(session, ext, id);
590 
591 	session->internals.ext_data[id].resumed_priv = data;
592 	session->internals.ext_data[id].resumed_set = 1;
593 	return;
594 }
595 
_gnutls_hello_ext_unpack(gnutls_session_t session,gnutls_buffer_st * packed)596 int _gnutls_hello_ext_unpack(gnutls_session_t session, gnutls_buffer_st * packed)
597 {
598 	int i, ret;
599 	gnutls_ext_priv_data_t data;
600 	int max_exts = 0;
601 	extensions_t id;
602 	int size_for_id, cur_pos;
603 	const struct hello_ext_entry_st *ext;
604 
605 	BUFFER_POP_NUM(packed, max_exts);
606 	for (i = 0; i < max_exts; i++) {
607 		BUFFER_POP_NUM(packed, id);
608 		BUFFER_POP_NUM(packed, size_for_id);
609 
610 		cur_pos = packed->length;
611 
612 		ext = gid_to_ext_entry(session, id);
613 		if (ext == NULL || ext->unpack_func == NULL) {
614 			gnutls_assert();
615 			return GNUTLS_E_PARSING_ERROR;
616 		}
617 
618 		ret = ext->unpack_func(packed, &data);
619 		if (ret < 0) {
620 			gnutls_assert();
621 			return ret;
622 		}
623 
624 		/* verify that unpack read the correct bytes */
625 		cur_pos = cur_pos - packed->length;
626 		if (cur_pos /* read length */  != size_for_id) {
627 			gnutls_assert();
628 			return GNUTLS_E_PARSING_ERROR;
629 		}
630 
631 		_gnutls_ext_set_resumed_session_data(session, id, data);
632 	}
633 
634 	return 0;
635 
636       error:
637 	return ret;
638 }
639 
640 static void
unset_ext_data(gnutls_session_t session,const struct hello_ext_entry_st * ext,unsigned idx)641 unset_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *ext, unsigned idx)
642 {
643 	if (session->internals.ext_data[idx].set == 0)
644 		return;
645 
646 	if (ext && ext->deinit_func && session->internals.ext_data[idx].priv != NULL)
647 		ext->deinit_func(session->internals.ext_data[idx].priv);
648 	session->internals.ext_data[idx].set = 0;
649 }
650 
651 void
_gnutls_hello_ext_unset_priv(gnutls_session_t session,extensions_t id)652 _gnutls_hello_ext_unset_priv(gnutls_session_t session,
653 			      extensions_t id)
654 {
655 	const struct hello_ext_entry_st *ext;
656 
657 	ext = gid_to_ext_entry(session, id);
658 	if (ext)
659 		unset_ext_data(session, ext, id);
660 }
661 
unset_resumed_ext_data(gnutls_session_t session,const struct hello_ext_entry_st * ext,unsigned idx)662 static void unset_resumed_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *ext, unsigned idx)
663 {
664 	if (session->internals.ext_data[idx].resumed_set == 0)
665 		return;
666 
667 	if (ext && ext->deinit_func && session->internals.ext_data[idx].resumed_priv) {
668 		ext->deinit_func(session->internals.ext_data[idx].resumed_priv);
669 	}
670 	session->internals.ext_data[idx].resumed_set = 0;
671 }
672 
673 /* Deinitializes all data that are associated with TLS extensions.
674  */
_gnutls_hello_ext_priv_deinit(gnutls_session_t session)675 void _gnutls_hello_ext_priv_deinit(gnutls_session_t session)
676 {
677 	unsigned int i;
678 	const struct hello_ext_entry_st *ext;
679 
680 	for (i = 0; i < MAX_EXT_TYPES; i++) {
681 		if (!session->internals.ext_data[i].set && !session->internals.ext_data[i].resumed_set)
682 			continue;
683 
684 		ext = gid_to_ext_entry(session, i);
685 		if (ext) {
686 			unset_ext_data(session, ext, i);
687 			unset_resumed_ext_data(session, ext, i);
688 		}
689 	}
690 }
691 
692 /* This function allows an extension to store data in the current session
693  * and retrieve them later on. We use functions instead of a pointer to a
694  * private pointer, to allow API additions by individual extensions.
695  */
696 void
_gnutls_hello_ext_set_priv(gnutls_session_t session,extensions_t id,gnutls_ext_priv_data_t data)697 _gnutls_hello_ext_set_priv(gnutls_session_t session, extensions_t id,
698 			     gnutls_ext_priv_data_t data)
699 {
700 	const struct hello_ext_entry_st *ext;
701 
702 	assert(id < MAX_EXT_TYPES);
703 
704 	ext = gid_to_ext_entry(session, id);
705 	assert(ext != NULL);
706 
707 	if (session->internals.ext_data[id].set != 0) {
708 		unset_ext_data(session, ext, id);
709 	}
710 	session->internals.ext_data[id].priv = data;
711 	session->internals.ext_data[id].set = 1;
712 
713 	return;
714 }
715 
716 int
_gnutls_hello_ext_get_priv(gnutls_session_t session,extensions_t id,gnutls_ext_priv_data_t * data)717 _gnutls_hello_ext_get_priv(gnutls_session_t session,
718 			    extensions_t id, gnutls_ext_priv_data_t * data)
719 {
720 	if (session->internals.ext_data[id].set != 0) {
721 		*data =
722 		    session->internals.ext_data[id].priv;
723 		return 0;
724 	}
725 
726 	return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
727 }
728 
729 int
_gnutls_hello_ext_get_resumed_priv(gnutls_session_t session,extensions_t id,gnutls_ext_priv_data_t * data)730 _gnutls_hello_ext_get_resumed_priv(gnutls_session_t session,
731 				    extensions_t id,
732 				    gnutls_ext_priv_data_t * data)
733 {
734 	if (session->internals.ext_data[id].resumed_set != 0) {
735 		*data =
736 		    session->internals.ext_data[id].resumed_priv;
737 		return 0;
738 	}
739 
740 	return GNUTLS_E_INVALID_REQUEST;
741 }
742 
743 /**
744  * gnutls_ext_register:
745  * @name: the name of the extension to register
746  * @id: the numeric TLS id of the extension
747  * @parse_point: the parse type of the extension (see gnutls_ext_parse_type_t)
748  * @recv_func: a function to receive the data
749  * @send_func: a function to send the data
750  * @deinit_func: a function deinitialize any private data
751  * @pack_func: a function which serializes the extension's private data (used on session packing for resumption)
752  * @unpack_func: a function which will deserialize the extension's private data
753  *
754  * This function will register a new extension type. The extension will remain
755  * registered until gnutls_global_deinit() is called. If the extension type
756  * is already registered then %GNUTLS_E_ALREADY_REGISTERED will be returned.
757  *
758  * Each registered extension can store temporary data into the gnutls_session_t
759  * structure using gnutls_ext_set_data(), and they can be retrieved using
760  * gnutls_ext_get_data().
761  *
762  * Any extensions registered with this function are valid for the client
763  * and TLS1.2 server hello (or encrypted extensions for TLS1.3).
764  *
765  * This function is not thread safe.
766  *
767  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
768  *
769  * Since: 3.4.0
770  **/
771 int
gnutls_ext_register(const char * name,int id,gnutls_ext_parse_type_t parse_point,gnutls_ext_recv_func recv_func,gnutls_ext_send_func send_func,gnutls_ext_deinit_data_func deinit_func,gnutls_ext_pack_func pack_func,gnutls_ext_unpack_func unpack_func)772 gnutls_ext_register(const char *name, int id, gnutls_ext_parse_type_t parse_point,
773 		    gnutls_ext_recv_func recv_func, gnutls_ext_send_func send_func,
774 		    gnutls_ext_deinit_data_func deinit_func, gnutls_ext_pack_func pack_func,
775 		    gnutls_ext_unpack_func unpack_func)
776 {
777 	hello_ext_entry_st *tmp_mod;
778 	unsigned i;
779 	unsigned gid = GNUTLS_EXTENSION_MAX+1;
780 
781 	for (i = 0; i < MAX_EXT_TYPES; i++) {
782 		if (!extfunc[i])
783 			continue;
784 
785 		if (extfunc[i]->tls_id == id)
786 			return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
787 
788 		if (extfunc[i]->gid >= gid)
789 			gid = extfunc[i]->gid + 1;
790 	}
791 
792 	if (gid > GNUTLS_EXTENSION_MAX_VALUE || gid >= sizeof(extfunc)/sizeof(extfunc[0]))
793 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
794 
795 	tmp_mod = gnutls_calloc(1, sizeof(*tmp_mod));
796 	if (tmp_mod == NULL)
797 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
798 
799 	tmp_mod->name = gnutls_strdup(name);
800 	tmp_mod->free_struct = 1;
801 	tmp_mod->tls_id = id;
802 	tmp_mod->gid = gid;
803 	tmp_mod->client_parse_point = parse_point;
804 	tmp_mod->server_parse_point = parse_point;
805 	tmp_mod->recv_func = recv_func;
806 	tmp_mod->send_func = send_func;
807 	tmp_mod->deinit_func = deinit_func;
808 	tmp_mod->pack_func = pack_func;
809 	tmp_mod->unpack_func = unpack_func;
810 	tmp_mod->validity = GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO |
811 			    GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS;
812 
813 	assert(extfunc[gid] == NULL);
814 	extfunc[gid] = tmp_mod;
815 
816 	return 0;
817 }
818 
819 #define VALIDITY_MASK (GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO | \
820 			GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO | \
821 			GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_HRR)
822 
823 /**
824  * gnutls_session_ext_register:
825  * @session: the session for which this extension will be set
826  * @name: the name of the extension to register
827  * @id: the numeric id of the extension
828  * @parse_point: the parse type of the extension (see gnutls_ext_parse_type_t)
829  * @recv_func: a function to receive the data
830  * @send_func: a function to send the data
831  * @deinit_func: a function deinitialize any private data
832  * @pack_func: a function which serializes the extension's private data (used on session packing for resumption)
833  * @unpack_func: a function which will deserialize the extension's private data
834  * @flags: must be zero or flags from %gnutls_ext_flags_t
835  *
836  * This function will register a new extension type. The extension will be
837  * only usable within the registered session. If the extension type
838  * is already registered then %GNUTLS_E_ALREADY_REGISTERED will be returned,
839  * unless the flag %GNUTLS_EXT_FLAG_OVERRIDE_INTERNAL is specified. The latter
840  * flag when specified can be used to override certain extensions introduced
841  * after 3.6.0. It is expected to be used by applications which handle
842  * custom extensions that are not currently supported in GnuTLS, but direct
843  * support for them may be added in the future.
844  *
845  * Each registered extension can store temporary data into the gnutls_session_t
846  * structure using gnutls_ext_set_data(), and they can be retrieved using
847  * gnutls_ext_get_data().
848  *
849  * The validity of the extension registered can be given by the appropriate flags
850  * of %gnutls_ext_flags_t. If no validity is given, then the registered extension
851  * will be valid for client and TLS1.2 server hello (or encrypted extensions for TLS1.3).
852  *
853  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
854  *
855  * Since: 3.5.5
856  **/
857 int
gnutls_session_ext_register(gnutls_session_t session,const char * name,int id,gnutls_ext_parse_type_t parse_point,gnutls_ext_recv_func recv_func,gnutls_ext_send_func send_func,gnutls_ext_deinit_data_func deinit_func,gnutls_ext_pack_func pack_func,gnutls_ext_unpack_func unpack_func,unsigned flags)858 gnutls_session_ext_register(gnutls_session_t session,
859 			    const char *name, int id, gnutls_ext_parse_type_t parse_point,
860 			    gnutls_ext_recv_func recv_func, gnutls_ext_send_func send_func,
861 			    gnutls_ext_deinit_data_func deinit_func, gnutls_ext_pack_func pack_func,
862 			    gnutls_ext_unpack_func unpack_func, unsigned flags)
863 {
864 	hello_ext_entry_st tmp_mod;
865 	hello_ext_entry_st *exts;
866 	unsigned i;
867 	unsigned gid = GNUTLS_EXTENSION_MAX+1;
868 
869 	/* reject handling any extensions which modify the TLS handshake
870 	 * in any way, or are mapped to an exported API. */
871 	for (i = 0; i < GNUTLS_EXTENSION_MAX; i++) {
872 		if (!extfunc[i])
873 			continue;
874 
875 		if (extfunc[i]->tls_id == id) {
876 			if (!(flags & GNUTLS_EXT_FLAG_OVERRIDE_INTERNAL)) {
877 				return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
878 			} else if (extfunc[i]->cannot_be_overriden) {
879 				return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
880 			}
881 			break;
882 		}
883 
884 		if (extfunc[i]->gid >= gid)
885 			gid = extfunc[i]->gid + 1;
886 	}
887 
888 	for (i=0;i<session->internals.rexts_size;i++) {
889 		if (session->internals.rexts[i].tls_id == id) {
890 			return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
891 		}
892 
893 		if (session->internals.rexts[i].gid >= gid)
894 			gid = session->internals.rexts[i].gid + 1;
895 	}
896 
897 	if (gid > GNUTLS_EXTENSION_MAX_VALUE)
898 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
899 
900 	memset(&tmp_mod, 0, sizeof(hello_ext_entry_st));
901 	tmp_mod.name = gnutls_strdup(name);
902 	tmp_mod.free_struct = 1;
903 	tmp_mod.tls_id = id;
904 	tmp_mod.gid = gid;
905 	tmp_mod.client_parse_point = parse_point;
906 	tmp_mod.server_parse_point = parse_point;
907 	tmp_mod.recv_func = recv_func;
908 	tmp_mod.send_func = send_func;
909 	tmp_mod.deinit_func = deinit_func;
910 	tmp_mod.pack_func = pack_func;
911 	tmp_mod.unpack_func = unpack_func;
912 	tmp_mod.validity = flags;
913 
914 	if ((tmp_mod.validity & VALIDITY_MASK) == 0) {
915 		tmp_mod.validity = GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO |
916 				   GNUTLS_EXT_FLAG_EE;
917 	}
918 
919 	if ((tmp_mod.validity & (GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS)) == 0) {
920 		if (IS_DTLS(session))
921 			tmp_mod.validity |= GNUTLS_EXT_FLAG_DTLS;
922 		else
923 			tmp_mod.validity |= GNUTLS_EXT_FLAG_TLS;
924 	}
925 
926 	exts = gnutls_realloc(session->internals.rexts, (session->internals.rexts_size+1)*sizeof(*exts));
927 	if (exts == NULL) {
928 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
929 	}
930 
931 	session->internals.rexts = exts;
932 
933 	memcpy(&session->internals.rexts[session->internals.rexts_size], &tmp_mod, sizeof(hello_ext_entry_st));
934 	session->internals.rexts_size++;
935 
936 	return 0;
937 }
938 
939 /**
940  * gnutls_ext_set_data:
941  * @session: a #gnutls_session_t opaque pointer
942  * @tls_id: the numeric id of the extension
943  * @data: the private data to set
944  *
945  * This function allows an extension handler to store data in the current session
946  * and retrieve them later on. The set data will be deallocated using
947  * the gnutls_ext_deinit_data_func.
948  *
949  * Since: 3.4.0
950  **/
951 void
gnutls_ext_set_data(gnutls_session_t session,unsigned tls_id,gnutls_ext_priv_data_t data)952 gnutls_ext_set_data(gnutls_session_t session, unsigned tls_id,
953 		    gnutls_ext_priv_data_t data)
954 {
955 	unsigned id = tls_id_to_gid(session, tls_id);
956 	if (id == GNUTLS_EXTENSION_INVALID)
957 		return;
958 
959 	_gnutls_hello_ext_set_priv(session, id, data);
960 }
961 
962 /**
963  * gnutls_ext_get_data:
964  * @session: a #gnutls_session_t opaque pointer
965  * @tls_id: the numeric id of the extension
966  * @data: a pointer to the private data to retrieve
967  *
968  * This function retrieves any data previously stored with gnutls_ext_set_data().
969  *
970  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
971  *
972  * Since: 3.4.0
973  **/
974 int
gnutls_ext_get_data(gnutls_session_t session,unsigned tls_id,gnutls_ext_priv_data_t * data)975 gnutls_ext_get_data(gnutls_session_t session,
976 		    unsigned tls_id, gnutls_ext_priv_data_t *data)
977 {
978 	unsigned id = tls_id_to_gid(session, tls_id);
979 	if (id == GNUTLS_EXTENSION_INVALID)
980 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
981 
982 	return _gnutls_hello_ext_get_priv(session, id, data);
983 }
984 
985 /**
986  * gnutls_ext_get_current_msg:
987  * @session: a #gnutls_session_t opaque pointer
988  *
989  * This function allows an extension handler to obtain the message
990  * this extension is being called from. The returned value is a single
991  * entry of the %gnutls_ext_flags_t enumeration. That is, if an
992  * extension was registered with the %GNUTLS_EXT_FLAG_HRR and
993  * %GNUTLS_EXT_FLAG_EE flags, the value when called during parsing of the
994  * encrypted extensions message will be %GNUTLS_EXT_FLAG_EE.
995  *
996  * If not called under an extension handler, its value is undefined.
997  *
998  * Since: 3.6.3
999  **/
gnutls_ext_get_current_msg(gnutls_session_t session)1000 unsigned gnutls_ext_get_current_msg(gnutls_session_t session)
1001 {
1002 	return _gnutls_ext_get_msg(session);
1003 }
1004 
1005 /**
1006  * gnutls_ext_get_name2:
1007  * @session: a #gnutls_session_t opaque pointer
1008  * @tls_id: is a TLS extension numeric ID
1009  * @parse_point: the parse type of the extension
1010  *
1011  * Convert a TLS extension numeric ID to a printable string.
1012  *
1013  * Returns: a pointer to a string that contains the name of the
1014  *   specified cipher, or %NULL.
1015  **/
gnutls_ext_get_name2(gnutls_session_t session,unsigned int tls_id,gnutls_ext_parse_type_t parse_point)1016 const char *gnutls_ext_get_name2(gnutls_session_t session, unsigned int tls_id,
1017 				 gnutls_ext_parse_type_t parse_point)
1018 {
1019 	const struct hello_ext_entry_st *ext;
1020 
1021 	ext = tls_id_to_ext_entry(session, tls_id, parse_point);
1022 	if (ext)
1023 		return ext->name;
1024 
1025 	return NULL;
1026 }
1027 
1028