diff options
author | beck <> | 2019-01-24 02:56:41 +0000 |
---|---|---|
committer | beck <> | 2019-01-24 02:56:41 +0000 |
commit | 10e3b663a1750bc234861ed33ad78e8088b5cb47 (patch) | |
tree | eaf3f613ad96dff5f56e2d992bfb0ad1b7457dac /src/lib/libssl/ssl_tlsext.c | |
parent | 354172b127820c0f48cb417d4d46746e2122f87b (diff) | |
download | openbsd-10e3b663a1750bc234861ed33ad78e8088b5cb47.tar.gz openbsd-10e3b663a1750bc234861ed33ad78e8088b5cb47.tar.bz2 openbsd-10e3b663a1750bc234861ed33ad78e8088b5cb47.zip |
Add server side of versions, keyshare, and client and server of cookie
extensions for tls1.3.
versions is currently defanged to ignore its result until tls13 server
side wired in full, so that server side code still works today when
we only support tls 1.2
ok bcook@ tb@ jsing@
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 308 |
1 files changed, 289 insertions, 19 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 35c764f646..20acb43ccf 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.35 2019/01/24 01:50:41 beck Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.36 2019/01/24 02:56:41 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -1273,7 +1273,7 @@ tlsext_keyshare_client_build(SSL *s, CBB *cbb) | |||
1273 | 1273 | ||
1274 | return 1; | 1274 | return 1; |
1275 | 1275 | ||
1276 | err: | 1276 | err: |
1277 | freezero(public_key, X25519_KEY_LENGTH); | 1277 | freezero(public_key, X25519_KEY_LENGTH); |
1278 | freezero(private_key, X25519_KEY_LENGTH); | 1278 | freezero(private_key, X25519_KEY_LENGTH); |
1279 | 1279 | ||
@@ -1283,24 +1283,105 @@ err: | |||
1283 | int | 1283 | int |
1284 | tlsext_keyshare_server_parse(SSL *s, CBS *cbs, int *alert) | 1284 | tlsext_keyshare_server_parse(SSL *s, CBS *cbs, int *alert) |
1285 | { | 1285 | { |
1286 | /* XXX we accept this but currently ignore it */ | 1286 | CBS client_shares; |
1287 | if (!CBS_skip(cbs, CBS_len(cbs))) { | 1287 | CBS key_exchange; |
1288 | *alert = TLS1_AD_INTERNAL_ERROR; | 1288 | uint16_t group; |
1289 | return 0; | 1289 | size_t out_len; |
1290 | int ret = 0; | ||
1291 | |||
1292 | if (!CBS_get_u16_length_prefixed(cbs, &client_shares)) | ||
1293 | goto err; | ||
1294 | |||
1295 | if (CBS_len(cbs) != 0) | ||
1296 | goto err; | ||
1297 | |||
1298 | while (CBS_len(&client_shares) > 0) { | ||
1299 | |||
1300 | /* Unpack client share. */ | ||
1301 | if (!CBS_get_u16(&client_shares, &group)) | ||
1302 | goto err; | ||
1303 | |||
1304 | if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange)) | ||
1305 | goto err; | ||
1306 | |||
1307 | /* | ||
1308 | * Skip this client share if not X25519 | ||
1309 | * XXX support other groups later. | ||
1310 | * XXX enforce group can only appear once. | ||
1311 | */ | ||
1312 | if (S3I(s)->hs_tls13.x25519_peer_public != NULL || | ||
1313 | group != tls1_ec_nid2curve_id(NID_X25519)) | ||
1314 | continue; | ||
1315 | |||
1316 | if (CBS_len(&key_exchange) != X25519_KEY_LENGTH) | ||
1317 | goto err; | ||
1318 | |||
1319 | if (!CBS_stow(&key_exchange, &S3I(s)->hs_tls13.x25519_peer_public, | ||
1320 | &out_len)) | ||
1321 | goto err; | ||
1322 | |||
1323 | ret = 1; | ||
1290 | } | 1324 | } |
1291 | 1325 | ||
1292 | return 1; | 1326 | return ret; |
1327 | |||
1328 | err: | ||
1329 | *alert = SSL_AD_DECODE_ERROR; | ||
1330 | return 0; | ||
1293 | } | 1331 | } |
1294 | 1332 | ||
1295 | int | 1333 | int |
1296 | tlsext_keyshare_server_needs(SSL *s) | 1334 | tlsext_keyshare_server_needs(SSL *s) |
1297 | { | 1335 | { |
1298 | return (!SSL_IS_DTLS(s) && s->version >= TLS1_3_VERSION); | 1336 | size_t idx; |
1337 | |||
1338 | if (SSL_IS_DTLS(s) || s->version < TLS1_3_VERSION) | ||
1339 | return 0; | ||
1340 | if (tls_extension_find(TLSEXT_TYPE_key_share, &idx) == NULL) | ||
1341 | return 0; | ||
1342 | /* XXX move seen check to a function */ | ||
1343 | return ((S3I(s)->hs.extensions_seen & (1 << idx)) != 0); | ||
1299 | } | 1344 | } |
1300 | 1345 | ||
1301 | int | 1346 | int |
1302 | tlsext_keyshare_server_build(SSL *s, CBB *cbb) | 1347 | tlsext_keyshare_server_build(SSL *s, CBB *cbb) |
1303 | { | 1348 | { |
1349 | uint8_t *public_key = NULL, *private_key = NULL; | ||
1350 | CBB key_exchange; | ||
1351 | |||
1352 | /* XXX deduplicate with client code */ | ||
1353 | |||
1354 | /* X25519 */ | ||
1355 | if (S3I(s)->hs_tls13.x25519_peer_public == NULL) | ||
1356 | return 0; | ||
1357 | |||
1358 | /* Generate X25519 key pair. */ | ||
1359 | if ((public_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
1360 | goto err; | ||
1361 | if ((private_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
1362 | goto err; | ||
1363 | X25519_keypair(public_key, private_key); | ||
1364 | |||
1365 | /* Add the group and serialize the public key. */ | ||
1366 | if (!CBB_add_u16(cbb, tls1_ec_nid2curve_id(NID_X25519))) | ||
1367 | goto err; | ||
1368 | if (!CBB_add_u16_length_prefixed(cbb, &key_exchange)) | ||
1369 | goto err; | ||
1370 | if (!CBB_add_bytes(&key_exchange, public_key, X25519_KEY_LENGTH)) | ||
1371 | goto err; | ||
1372 | |||
1373 | if (!CBB_flush(cbb)) | ||
1374 | goto err; | ||
1375 | |||
1376 | S3I(s)->hs_tls13.x25519_public = public_key; | ||
1377 | S3I(s)->hs_tls13.x25519_private = private_key; | ||
1378 | |||
1379 | return 1; | ||
1380 | |||
1381 | err: | ||
1382 | freezero(public_key, X25519_KEY_LENGTH); | ||
1383 | freezero(private_key, X25519_KEY_LENGTH); | ||
1384 | |||
1304 | return 0; | 1385 | return 0; |
1305 | } | 1386 | } |
1306 | 1387 | ||
@@ -1321,8 +1402,10 @@ tlsext_keyshare_client_parse(SSL *s, CBS *cbs, int *alert) | |||
1321 | 1402 | ||
1322 | if (!CBS_get_u16_length_prefixed(cbs, &key_exchange)) | 1403 | if (!CBS_get_u16_length_prefixed(cbs, &key_exchange)) |
1323 | goto err; | 1404 | goto err; |
1405 | |||
1324 | if (CBS_len(&key_exchange) != X25519_KEY_LENGTH) | 1406 | if (CBS_len(&key_exchange) != X25519_KEY_LENGTH) |
1325 | goto err; | 1407 | goto err; |
1408 | |||
1326 | if (!CBS_stow(&key_exchange, &S3I(s)->hs_tls13.x25519_peer_public, | 1409 | if (!CBS_stow(&key_exchange, &S3I(s)->hs_tls13.x25519_peer_public, |
1327 | &out_len)) | 1410 | &out_len)) |
1328 | goto err; | 1411 | goto err; |
@@ -1340,11 +1423,9 @@ tlsext_keyshare_client_parse(SSL *s, CBS *cbs, int *alert) | |||
1340 | int | 1423 | int |
1341 | tlsext_versions_client_needs(SSL *s) | 1424 | tlsext_versions_client_needs(SSL *s) |
1342 | { | 1425 | { |
1343 | /* XXX once this gets initialized when we get tls13_client.c */ | 1426 | if (SSL_IS_DTLS(s)) |
1344 | if (S3I(s)->hs_tls13.max_version == 0) | ||
1345 | return 0; | 1427 | return 0; |
1346 | return (!SSL_IS_DTLS(s) && S3I(s)->hs_tls13.max_version >= | 1428 | return (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION); |
1347 | TLS1_3_VERSION); | ||
1348 | } | 1429 | } |
1349 | 1430 | ||
1350 | int | 1431 | int |
@@ -1378,13 +1459,48 @@ tlsext_versions_client_build(SSL *s, CBB *cbb) | |||
1378 | int | 1459 | int |
1379 | tlsext_versions_server_parse(SSL *s, CBS *cbs, int *alert) | 1460 | tlsext_versions_server_parse(SSL *s, CBS *cbs, int *alert) |
1380 | { | 1461 | { |
1381 | /* XXX we accept this but currently ignore it */ | 1462 | CBS versions; |
1382 | if (!CBS_skip(cbs, CBS_len(cbs))) { | 1463 | uint16_t version; |
1383 | *alert = TLS1_AD_INTERNAL_ERROR; | 1464 | uint16_t max, min; |
1384 | return 0; | 1465 | uint16_t matched_version = 0; |
1466 | |||
1467 | max = S3I(s)->hs_tls13.max_version; | ||
1468 | min = S3I(s)->hs_tls13.min_version; | ||
1469 | |||
1470 | if (!CBS_get_u8_length_prefixed(cbs, &versions)) | ||
1471 | goto err; | ||
1472 | |||
1473 | while (CBS_len(&versions) > 0) { | ||
1474 | if (!CBS_get_u16(&versions, &version)) | ||
1475 | goto err; | ||
1476 | /* | ||
1477 | * XXX What is below implements client preference, and | ||
1478 | * ignores any server preference entirely. | ||
1479 | */ | ||
1480 | if (matched_version == 0 && version >= min && version <= max) | ||
1481 | matched_version = version; | ||
1385 | } | 1482 | } |
1386 | 1483 | ||
1387 | return 1; | 1484 | /* |
1485 | * XXX if we haven't mached a version we should | ||
1486 | * fail - but we currently need to succeed to | ||
1487 | * ignore this before the server code for 1.3 | ||
1488 | * is set up and initialized. | ||
1489 | */ | ||
1490 | if (max == 0) | ||
1491 | return 1; /* XXX */ | ||
1492 | |||
1493 | if (matched_version != 0) { | ||
1494 | s->version = matched_version; | ||
1495 | return 1; | ||
1496 | } | ||
1497 | |||
1498 | *alert = SSL_AD_PROTOCOL_VERSION; | ||
1499 | return 0; | ||
1500 | |||
1501 | err: | ||
1502 | *alert = SSL_AD_DECODE_ERROR; | ||
1503 | return 0; | ||
1388 | } | 1504 | } |
1389 | 1505 | ||
1390 | int | 1506 | int |
@@ -1396,7 +1512,11 @@ tlsext_versions_server_needs(SSL *s) | |||
1396 | int | 1512 | int |
1397 | tlsext_versions_server_build(SSL *s, CBB *cbb) | 1513 | tlsext_versions_server_build(SSL *s, CBB *cbb) |
1398 | { | 1514 | { |
1399 | return 0; | 1515 | if (!CBB_add_u16(cbb, TLS1_3_VERSION)) |
1516 | return 0; | ||
1517 | /* XXX set 1.2 in legacy version? */ | ||
1518 | |||
1519 | return 1; | ||
1400 | } | 1520 | } |
1401 | 1521 | ||
1402 | int | 1522 | int |
@@ -1409,12 +1529,147 @@ tlsext_versions_client_parse(SSL *s, CBS *cbs, int *alert) | |||
1409 | return 0; | 1529 | return 0; |
1410 | } | 1530 | } |
1411 | 1531 | ||
1532 | if (selected_version < TLS1_3_VERSION) { | ||
1533 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
1534 | return 0; | ||
1535 | } | ||
1536 | |||
1412 | /* XXX test between min and max once initialization code goes in */ | 1537 | /* XXX test between min and max once initialization code goes in */ |
1413 | S3I(s)->hs_tls13.server_version = selected_version; | 1538 | S3I(s)->hs_tls13.server_version = selected_version; |
1414 | 1539 | ||
1415 | return 1; | 1540 | return 1; |
1416 | } | 1541 | } |
1417 | 1542 | ||
1543 | |||
1544 | /* | ||
1545 | * Cookie - RFC 8446 section 4.2.2. | ||
1546 | */ | ||
1547 | |||
1548 | int | ||
1549 | tlsext_cookie_client_needs(SSL *s) | ||
1550 | { | ||
1551 | if (SSL_IS_DTLS(s)) | ||
1552 | return 0; | ||
1553 | if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION) | ||
1554 | return 0; | ||
1555 | return (S3I(s)->hs_tls13.cookie_len > 0 && | ||
1556 | S3I(s)->hs_tls13.cookie != NULL); | ||
1557 | } | ||
1558 | |||
1559 | int | ||
1560 | tlsext_cookie_client_build(SSL *s, CBB *cbb) | ||
1561 | { | ||
1562 | CBB cookie; | ||
1563 | |||
1564 | if (!CBB_add_u16_length_prefixed(cbb, &cookie)) | ||
1565 | return 0; | ||
1566 | |||
1567 | if (!CBB_add_bytes(&cookie, S3I(s)->hs_tls13.cookie, | ||
1568 | S3I(s)->hs_tls13.cookie_len)) | ||
1569 | return 0; | ||
1570 | |||
1571 | if (!CBB_flush(cbb)) | ||
1572 | return 0; | ||
1573 | |||
1574 | return 1; | ||
1575 | } | ||
1576 | |||
1577 | int | ||
1578 | tlsext_cookie_server_parse(SSL *s, CBS *cbs, int *alert) | ||
1579 | { | ||
1580 | CBS cookie; | ||
1581 | |||
1582 | if (!CBS_get_u16_length_prefixed(cbs, &cookie)) | ||
1583 | goto err; | ||
1584 | |||
1585 | if (CBS_len(&cookie) != S3I(s)->hs_tls13.cookie_len) | ||
1586 | goto err; | ||
1587 | |||
1588 | /* | ||
1589 | * Check provided cookie value against what server previously | ||
1590 | * sent - client *MUST* send the same cookie with new CR after | ||
1591 | * a cookie is sent by the server with an HRR. | ||
1592 | */ | ||
1593 | if (!CBS_mem_equal(&cookie, S3I(s)->hs_tls13.cookie, | ||
1594 | S3I(s)->hs_tls13.cookie_len)) { | ||
1595 | /* XXX special cookie mismatch alert? */ | ||
1596 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
1597 | return 0; | ||
1598 | } | ||
1599 | |||
1600 | return 1; | ||
1601 | |||
1602 | err: | ||
1603 | *alert = SSL_AD_DECODE_ERROR; | ||
1604 | return 0; | ||
1605 | } | ||
1606 | |||
1607 | int | ||
1608 | tlsext_cookie_server_needs(SSL *s) | ||
1609 | { | ||
1610 | |||
1611 | if (SSL_IS_DTLS(s)) | ||
1612 | return 0; | ||
1613 | if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION) | ||
1614 | return 0; | ||
1615 | /* | ||
1616 | * Server needs to set cookie value in tls13 handshake | ||
1617 | * in order to send one, should only be sent with HRR. | ||
1618 | */ | ||
1619 | return (S3I(s)->hs_tls13.cookie_len > 0 && | ||
1620 | S3I(s)->hs_tls13.cookie != NULL); | ||
1621 | } | ||
1622 | |||
1623 | int | ||
1624 | tlsext_cookie_server_build(SSL *s, CBB *cbb) | ||
1625 | { | ||
1626 | CBB cookie; | ||
1627 | |||
1628 | /* XXX deduplicate with client code */ | ||
1629 | |||
1630 | if (!CBB_add_u16_length_prefixed(cbb, &cookie)) | ||
1631 | return 0; | ||
1632 | |||
1633 | if (!CBB_add_bytes(&cookie, S3I(s)->hs_tls13.cookie, | ||
1634 | S3I(s)->hs_tls13.cookie_len)) | ||
1635 | return 0; | ||
1636 | |||
1637 | if (!CBB_flush(cbb)) | ||
1638 | return 0; | ||
1639 | |||
1640 | return 1; | ||
1641 | } | ||
1642 | |||
1643 | int | ||
1644 | tlsext_cookie_client_parse(SSL *s, CBS *cbs, int *alert) | ||
1645 | { | ||
1646 | CBS cookie; | ||
1647 | |||
1648 | /* | ||
1649 | * XXX This currently assumes we will not get a second | ||
1650 | * HRR from a server with a cookie to process after accepting | ||
1651 | * one from the server in the same handshake | ||
1652 | */ | ||
1653 | if (S3I(s)->hs_tls13.cookie != NULL || | ||
1654 | S3I(s)->hs_tls13.cookie_len != 0) { | ||
1655 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
1656 | return 0; | ||
1657 | } | ||
1658 | |||
1659 | if (!CBS_get_u16_length_prefixed(cbs, &cookie)) | ||
1660 | goto err; | ||
1661 | |||
1662 | if (!CBS_stow(&cookie, &S3I(s)->hs_tls13.cookie, | ||
1663 | &S3I(s)->hs_tls13.cookie_len)) | ||
1664 | goto err; | ||
1665 | |||
1666 | return 1; | ||
1667 | |||
1668 | err: | ||
1669 | *alert = SSL_AD_DECODE_ERROR; | ||
1670 | return 0; | ||
1671 | } | ||
1672 | |||
1418 | struct tls_extension_funcs { | 1673 | struct tls_extension_funcs { |
1419 | int (*needs)(SSL *s); | 1674 | int (*needs)(SSL *s); |
1420 | int (*build)(SSL *s, CBB *cbb); | 1675 | int (*build)(SSL *s, CBB *cbb); |
@@ -1572,6 +1827,20 @@ static struct tls_extension tls_extensions[] = { | |||
1572 | .parse = tlsext_alpn_client_parse, | 1827 | .parse = tlsext_alpn_client_parse, |
1573 | }, | 1828 | }, |
1574 | }, | 1829 | }, |
1830 | { | ||
1831 | .type = TLSEXT_TYPE_cookie, | ||
1832 | .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_HRR, | ||
1833 | .client = { | ||
1834 | .needs = tlsext_cookie_client_needs, | ||
1835 | .build = tlsext_cookie_client_build, | ||
1836 | .parse = tlsext_cookie_server_parse, | ||
1837 | }, | ||
1838 | .server = { | ||
1839 | .needs = tlsext_cookie_server_needs, | ||
1840 | .build = tlsext_cookie_server_build, | ||
1841 | .parse = tlsext_cookie_client_parse, | ||
1842 | }, | ||
1843 | }, | ||
1575 | #ifndef OPENSSL_NO_SRTP | 1844 | #ifndef OPENSSL_NO_SRTP |
1576 | { | 1845 | { |
1577 | .type = TLSEXT_TYPE_use_srtp, | 1846 | .type = TLSEXT_TYPE_use_srtp, |
@@ -1595,7 +1864,7 @@ static struct tls_extension tls_extensions[] = { | |||
1595 | /* Ensure that extensions fit in a uint32_t bitmask. */ | 1864 | /* Ensure that extensions fit in a uint32_t bitmask. */ |
1596 | CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8)); | 1865 | CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8)); |
1597 | 1866 | ||
1598 | static struct tls_extension * | 1867 | struct tls_extension * |
1599 | tls_extension_find(uint16_t type, size_t *tls_extensions_idx) | 1868 | tls_extension_find(uint16_t type, size_t *tls_extensions_idx) |
1600 | { | 1869 | { |
1601 | size_t i; | 1870 | size_t i; |
@@ -1719,6 +1988,7 @@ tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) | |||
1719 | } | 1988 | } |
1720 | 1989 | ||
1721 | /* Check for duplicate known extensions. */ | 1990 | /* Check for duplicate known extensions. */ |
1991 | /* XXX move seen check to a function */ | ||
1722 | if ((S3I(s)->hs.extensions_seen & (1 << idx)) != 0) | 1992 | if ((S3I(s)->hs.extensions_seen & (1 << idx)) != 0) |
1723 | return 0; | 1993 | return 0; |
1724 | S3I(s)->hs.extensions_seen |= (1 << idx); | 1994 | S3I(s)->hs.extensions_seen |= (1 << idx); |