summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_tlsext.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r--src/lib/libssl/ssl_tlsext.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index d0764af3c0..0e3ef7da15 100644
--- a/src/lib/libssl/ssl_tlsext.c
+++ b/src/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_tlsext.c,v 1.19 2018/01/27 15:17:13 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.20 2018/01/27 15:30:05 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -1292,6 +1292,35 @@ static struct tls_extension tls_extensions[] = {
1292 1292
1293#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) 1293#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions))
1294 1294
1295/* Ensure that extensions fit in a uint32_t bitmask. */
1296CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8));
1297
1298static struct tls_extension *
1299tls_extension_find(uint16_t type, size_t *tls_extensions_idx)
1300{
1301 size_t i;
1302
1303 for (i = 0; i < N_TLS_EXTENSIONS; i++) {
1304 if (tls_extensions[i].type == type) {
1305 *tls_extensions_idx = i;
1306 return &tls_extensions[i];
1307 }
1308 }
1309
1310 return NULL;
1311}
1312
1313static void
1314tlsext_clienthello_reset_state(SSL *s)
1315{
1316 s->internal->servername_done = 0;
1317 s->tlsext_status_type = -1;
1318 S3I(s)->renegotiate_seen = 0;
1319 free(S3I(s)->alpn_selected);
1320 S3I(s)->alpn_selected = NULL;
1321 s->internal->srtp_profile = NULL;
1322}
1323
1295int 1324int
1296tlsext_clienthello_build(SSL *s, CBB *cbb) 1325tlsext_clienthello_build(SSL *s, CBB *cbb)
1297{ 1326{
@@ -1329,28 +1358,55 @@ tlsext_clienthello_build(SSL *s, CBB *cbb)
1329} 1358}
1330 1359
1331int 1360int
1332tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) 1361tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1333{ 1362{
1363 CBS extensions, extension_data;
1334 struct tls_extension *tlsext; 1364 struct tls_extension *tlsext;
1335 size_t i; 1365 uint32_t extensions_seen = 0;
1366 uint16_t type;
1367 size_t idx;
1336 1368
1337 for (i = 0; i < N_TLS_EXTENSIONS; i++) { 1369 /* XXX - this possibly should be done by the caller... */
1338 tlsext = &tls_extensions[i]; 1370 tlsext_clienthello_reset_state(s);
1339 1371
1340 if (tlsext->type != type) 1372 /* An empty extensions block is valid. */
1373 if (CBS_len(cbs) == 0)
1374 return 1;
1375
1376 *alert = SSL_AD_DECODE_ERROR;
1377
1378 if (!CBS_get_u16_length_prefixed(cbs, &extensions))
1379 return 0;
1380
1381 while (CBS_len(&extensions) > 0) {
1382 if (!CBS_get_u16(&extensions, &type))
1383 return 0;
1384 if (!CBS_get_u16_length_prefixed(&extensions, &extension_data))
1385 return 0;
1386
1387 if (s->internal->tlsext_debug_cb != NULL)
1388 s->internal->tlsext_debug_cb(s, 0, type,
1389 (unsigned char *)CBS_data(&extension_data),
1390 CBS_len(&extension_data),
1391 s->internal->tlsext_debug_arg);
1392
1393 /* Unknown extensions are ignored. */
1394 if ((tlsext = tls_extension_find(type, &idx)) == NULL)
1341 continue; 1395 continue;
1342 if (!tlsext->clienthello_parse(s, cbs, alert)) 1396
1397 /* Check for duplicate extensions. */
1398 if ((extensions_seen & (1 << idx)) != 0)
1343 return 0; 1399 return 0;
1344 if (CBS_len(cbs) != 0) { 1400 extensions_seen |= (1 << idx);
1345 *alert = SSL_AD_DECODE_ERROR; 1401
1402 if (!tlsext->clienthello_parse(s, &extension_data, alert))
1346 return 0; 1403 return 0;
1347 }
1348 1404
1349 return 1; 1405 if (CBS_len(&extension_data) != 0)
1406 return 0;
1350 } 1407 }
1351 1408
1352 /* Not found. */ 1409 return 1;
1353 return 2;
1354} 1410}
1355 1411
1356int 1412int