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.c141
1 files changed, 72 insertions, 69 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index 0e3ef7da15..3735b719db 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.20 2018/01/27 15:30:05 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.21 2018/02/08 11:30:30 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>
@@ -1310,19 +1310,34 @@ tls_extension_find(uint16_t type, size_t *tls_extensions_idx)
1310 return NULL; 1310 return NULL;
1311} 1311}
1312 1312
1313static void 1313static int
1314tlsext_clienthello_reset_state(SSL *s) 1314tls_extension_needs(struct tls_extension *tlsext, int is_serverhello, SSL *s)
1315{ 1315{
1316 s->internal->servername_done = 0; 1316 if (is_serverhello)
1317 s->tlsext_status_type = -1; 1317 return tlsext->serverhello_needs(s);
1318 S3I(s)->renegotiate_seen = 0; 1318 return tlsext->clienthello_needs(s);
1319 free(S3I(s)->alpn_selected);
1320 S3I(s)->alpn_selected = NULL;
1321 s->internal->srtp_profile = NULL;
1322} 1319}
1323 1320
1324int 1321static int
1325tlsext_clienthello_build(SSL *s, CBB *cbb) 1322tls_extension_build(struct tls_extension *tlsext, int is_serverhello, SSL *s,
1323 CBB *cbb)
1324{
1325 if (is_serverhello)
1326 return tlsext->serverhello_build(s, cbb);
1327 return tlsext->clienthello_build(s, cbb);
1328}
1329
1330static int
1331tls_extension_parse(struct tls_extension *tlsext, int is_serverhello, SSL *s,
1332 CBS *cbs, int *alert)
1333{
1334 if (is_serverhello)
1335 return tlsext->serverhello_parse(s, cbs, alert);
1336 return tlsext->clienthello_parse(s, cbs, alert);
1337}
1338
1339static int
1340tlsext_build(SSL *s, CBB *cbb, int is_serverhello)
1326{ 1341{
1327 CBB extensions, extension_data; 1342 CBB extensions, extension_data;
1328 struct tls_extension *tlsext; 1343 struct tls_extension *tlsext;
@@ -1335,14 +1350,16 @@ tlsext_clienthello_build(SSL *s, CBB *cbb)
1335 for (i = 0; i < N_TLS_EXTENSIONS; i++) { 1350 for (i = 0; i < N_TLS_EXTENSIONS; i++) {
1336 tlsext = &tls_extensions[i]; 1351 tlsext = &tls_extensions[i];
1337 1352
1338 if (!tlsext->clienthello_needs(s)) 1353 if (!tls_extension_needs(tlsext, is_serverhello, s))
1339 continue; 1354 continue;
1340 1355
1341 if (!CBB_add_u16(&extensions, tlsext->type)) 1356 if (!CBB_add_u16(&extensions, tlsext->type))
1342 return 0; 1357 return 0;
1343 if (!CBB_add_u16_length_prefixed(&extensions, &extension_data)) 1358 if (!CBB_add_u16_length_prefixed(&extensions, &extension_data))
1344 return 0; 1359 return 0;
1345 if (!tls_extensions[i].clienthello_build(s, &extension_data)) 1360
1361 if (!tls_extension_build(tlsext, is_serverhello, s,
1362 &extension_data))
1346 return 0; 1363 return 0;
1347 1364
1348 extensions_present = 1; 1365 extensions_present = 1;
@@ -1357,8 +1374,8 @@ tlsext_clienthello_build(SSL *s, CBB *cbb)
1357 return 1; 1374 return 1;
1358} 1375}
1359 1376
1360int 1377static int
1361tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert) 1378tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_serverhello)
1362{ 1379{
1363 CBS extensions, extension_data; 1380 CBS extensions, extension_data;
1364 struct tls_extension *tlsext; 1381 struct tls_extension *tlsext;
@@ -1366,9 +1383,6 @@ tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1366 uint16_t type; 1383 uint16_t type;
1367 size_t idx; 1384 size_t idx;
1368 1385
1369 /* XXX - this possibly should be done by the caller... */
1370 tlsext_clienthello_reset_state(s);
1371
1372 /* An empty extensions block is valid. */ 1386 /* An empty extensions block is valid. */
1373 if (CBS_len(cbs) == 0) 1387 if (CBS_len(cbs) == 0)
1374 return 1; 1388 return 1;
@@ -1385,7 +1399,7 @@ tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1385 return 0; 1399 return 0;
1386 1400
1387 if (s->internal->tlsext_debug_cb != NULL) 1401 if (s->internal->tlsext_debug_cb != NULL)
1388 s->internal->tlsext_debug_cb(s, 0, type, 1402 s->internal->tlsext_debug_cb(s, is_serverhello, type,
1389 (unsigned char *)CBS_data(&extension_data), 1403 (unsigned char *)CBS_data(&extension_data),
1390 CBS_len(&extension_data), 1404 CBS_len(&extension_data),
1391 s->internal->tlsext_debug_arg); 1405 s->internal->tlsext_debug_arg);
@@ -1394,12 +1408,13 @@ tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1394 if ((tlsext = tls_extension_find(type, &idx)) == NULL) 1408 if ((tlsext = tls_extension_find(type, &idx)) == NULL)
1395 continue; 1409 continue;
1396 1410
1397 /* Check for duplicate extensions. */ 1411 /* Check for duplicate known extensions. */
1398 if ((extensions_seen & (1 << idx)) != 0) 1412 if ((extensions_seen & (1 << idx)) != 0)
1399 return 0; 1413 return 0;
1400 extensions_seen |= (1 << idx); 1414 extensions_seen |= (1 << idx);
1401 1415
1402 if (!tlsext->clienthello_parse(s, &extension_data, alert)) 1416 if (!tls_extension_parse(tlsext, is_serverhello, s,
1417 &extension_data, alert))
1403 return 0; 1418 return 0;
1404 1419
1405 if (CBS_len(&extension_data) != 0) 1420 if (CBS_len(&extension_data) != 0)
@@ -1409,63 +1424,51 @@ tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1409 return 1; 1424 return 1;
1410} 1425}
1411 1426
1412int 1427static void
1413tlsext_serverhello_build(SSL *s, CBB *cbb) 1428tlsext_clienthello_reset_state(SSL *s)
1414{ 1429{
1415 CBB extensions, extension_data; 1430 s->internal->servername_done = 0;
1416 struct tls_extension *tlsext; 1431 s->tlsext_status_type = -1;
1417 int extensions_present = 0; 1432 S3I(s)->renegotiate_seen = 0;
1418 size_t i; 1433 free(S3I(s)->alpn_selected);
1419 1434 S3I(s)->alpn_selected = NULL;
1420 if (!CBB_add_u16_length_prefixed(cbb, &extensions)) 1435 s->internal->srtp_profile = NULL;
1421 return 0; 1436}
1422
1423 for (i = 0; i < N_TLS_EXTENSIONS; i++) {
1424 tlsext = &tls_extensions[i];
1425
1426 if (!tlsext->serverhello_needs(s))
1427 continue;
1428
1429 if (!CBB_add_u16(&extensions, tlsext->type))
1430 return 0;
1431 if (!CBB_add_u16_length_prefixed(&extensions, &extension_data))
1432 return 0;
1433 if (!tlsext->serverhello_build(s, &extension_data))
1434 return 0;
1435 1437
1436 extensions_present = 1; 1438int
1437 } 1439tlsext_clienthello_build(SSL *s, CBB *cbb)
1440{
1441 return tlsext_build(s, cbb, 0);
1442}
1438 1443
1439 if (!extensions_present) 1444int
1440 CBB_discard_child(cbb); 1445tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1446{
1447 /* XXX - this possibly should be done by the caller... */
1448 tlsext_clienthello_reset_state(s);
1441 1449
1442 if (!CBB_flush(cbb)) 1450 return tlsext_parse(s, cbs, alert, 0);
1443 return 0; 1451}
1444 1452
1445 return 1; 1453static void
1454tlsext_serverhello_reset_state(SSL *s)
1455{
1456 S3I(s)->renegotiate_seen = 0;
1457 free(S3I(s)->alpn_selected);
1458 S3I(s)->alpn_selected = NULL;
1446} 1459}
1447 1460
1448int 1461int
1449tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) 1462tlsext_serverhello_build(SSL *s, CBB *cbb)
1450{ 1463{
1451 struct tls_extension *tlsext; 1464 return tlsext_build(s, cbb, 1);
1452 size_t i; 1465}
1453
1454 for (i = 0; i < N_TLS_EXTENSIONS; i++) {
1455 tlsext = &tls_extensions[i];
1456
1457 if (tlsext->type != type)
1458 continue;
1459 if (!tlsext->serverhello_parse(s, cbs, alert))
1460 return 0;
1461 if (CBS_len(cbs) != 0) {
1462 *alert = SSL_AD_DECODE_ERROR;
1463 return 0;
1464 }
1465 1466
1466 return 1; 1467int
1467 } 1468tlsext_serverhello_parse(SSL *s, CBS *cbs, int *alert)
1469{
1470 /* XXX - this possibly should be done by the caller... */
1471 tlsext_serverhello_reset_state(s);
1468 1472
1469 /* Not found. */ 1473 return tlsext_parse(s, cbs, alert, 1);
1470 return 2;
1471} 1474}