diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 59 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 4 |
2 files changed, 54 insertions, 9 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index d8143ce1be..3da8ebc46c 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.100 2021/10/25 10:01:46 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.101 2021/11/01 16:37:17 jsing 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> |
| @@ -17,6 +17,11 @@ | |||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <sys/socket.h> | ||
| 21 | |||
| 22 | #include <arpa/inet.h> | ||
| 23 | #include <netinet/in.h> | ||
| 24 | |||
| 20 | #include <ctype.h> | 25 | #include <ctype.h> |
| 21 | 26 | ||
| 22 | #include <openssl/ocsp.h> | 27 | #include <openssl/ocsp.h> |
| @@ -673,6 +678,29 @@ tlsext_sni_client_build(SSL *s, uint16_t msg_type, CBB *cbb) | |||
| 673 | return 1; | 678 | return 1; |
| 674 | } | 679 | } |
| 675 | 680 | ||
| 681 | static int | ||
| 682 | tlsext_sni_is_ip_literal(CBS *cbs, int *is_ip) | ||
| 683 | { | ||
| 684 | union { | ||
| 685 | struct in_addr ip4; | ||
| 686 | struct in6_addr ip6; | ||
| 687 | } addrbuf; | ||
| 688 | char *hostname = NULL; | ||
| 689 | |||
| 690 | *is_ip = 0; | ||
| 691 | |||
| 692 | if (!CBS_strdup(cbs, &hostname)) | ||
| 693 | return 0; | ||
| 694 | |||
| 695 | if (inet_pton(AF_INET, hostname, &addrbuf) == 1 || | ||
| 696 | inet_pton(AF_INET6, hostname, &addrbuf) == 1) | ||
| 697 | *is_ip = 1; | ||
| 698 | |||
| 699 | free(hostname); | ||
| 700 | |||
| 701 | return 1; | ||
| 702 | } | ||
| 703 | |||
| 676 | /* | 704 | /* |
| 677 | * Validate that the CBS contains only a hostname consisting of RFC 5890 | 705 | * Validate that the CBS contains only a hostname consisting of RFC 5890 |
| 678 | * compliant A-labels (see RFC 6066 section 3). Not a complete check | 706 | * compliant A-labels (see RFC 6066 section 3). Not a complete check |
| @@ -680,7 +708,7 @@ tlsext_sni_client_build(SSL *s, uint16_t msg_type, CBB *cbb) | |||
| 680 | * correct structure and character set. | 708 | * correct structure and character set. |
| 681 | */ | 709 | */ |
| 682 | int | 710 | int |
| 683 | tlsext_sni_is_valid_hostname(CBS *cbs) | 711 | tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip) |
| 684 | { | 712 | { |
| 685 | uint8_t prev, c = 0; | 713 | uint8_t prev, c = 0; |
| 686 | int component = 0; | 714 | int component = 0; |
| @@ -691,7 +719,13 @@ tlsext_sni_is_valid_hostname(CBS *cbs) | |||
| 691 | if (CBS_len(&hostname) > TLSEXT_MAXLEN_host_name) | 719 | if (CBS_len(&hostname) > TLSEXT_MAXLEN_host_name) |
| 692 | return 0; | 720 | return 0; |
| 693 | 721 | ||
| 694 | while(CBS_len(&hostname) > 0) { | 722 | /* An IP literal is invalid as a host name (RFC 6066 section 3). */ |
| 723 | if (!tlsext_sni_is_ip_literal(&hostname, is_ip)) | ||
| 724 | return 0; | ||
| 725 | if (*is_ip) | ||
| 726 | return 0; | ||
| 727 | |||
| 728 | while (CBS_len(&hostname) > 0) { | ||
| 695 | prev = c; | 729 | prev = c; |
| 696 | if (!CBS_get_u8(&hostname, &c)) | 730 | if (!CBS_get_u8(&hostname, &c)) |
| 697 | return 0; | 731 | return 0; |
| @@ -727,12 +761,14 @@ tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) | |||
| 727 | { | 761 | { |
| 728 | CBS server_name_list, host_name; | 762 | CBS server_name_list, host_name; |
| 729 | uint8_t name_type; | 763 | uint8_t name_type; |
| 764 | int is_ip; | ||
| 730 | 765 | ||
| 731 | if (!CBS_get_u16_length_prefixed(cbs, &server_name_list)) | 766 | if (!CBS_get_u16_length_prefixed(cbs, &server_name_list)) |
| 732 | goto err; | 767 | goto err; |
| 733 | 768 | ||
| 734 | if (!CBS_get_u8(&server_name_list, &name_type)) | 769 | if (!CBS_get_u8(&server_name_list, &name_type)) |
| 735 | goto err; | 770 | goto err; |
| 771 | |||
| 736 | /* | 772 | /* |
| 737 | * RFC 6066 section 3, only one type (host_name) is specified. | 773 | * RFC 6066 section 3, only one type (host_name) is specified. |
| 738 | * We do not tolerate unknown types, neither does BoringSSL. | 774 | * We do not tolerate unknown types, neither does BoringSSL. |
| @@ -743,17 +779,25 @@ tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) | |||
| 743 | goto err; | 779 | goto err; |
| 744 | } | 780 | } |
| 745 | 781 | ||
| 746 | |||
| 747 | if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name)) | ||
| 748 | goto err; | ||
| 749 | /* | 782 | /* |
| 750 | * RFC 6066 section 3 specifies a host name must be at least 1 byte | 783 | * RFC 6066 section 3 specifies a host name must be at least 1 byte |
| 751 | * so 0 length is a decode error. | 784 | * so 0 length is a decode error. |
| 752 | */ | 785 | */ |
| 786 | if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name)) | ||
| 787 | goto err; | ||
| 753 | if (CBS_len(&host_name) < 1) | 788 | if (CBS_len(&host_name) < 1) |
| 754 | goto err; | 789 | goto err; |
| 755 | 790 | ||
| 756 | if (!tlsext_sni_is_valid_hostname(&host_name)) { | 791 | if (!tlsext_sni_is_valid_hostname(&host_name, &is_ip)) { |
| 792 | /* | ||
| 793 | * Various pieces of software have been known to set the SNI | ||
| 794 | * host name to an IP address, even though that violates the | ||
| 795 | * RFC. If this is the case, pretend the SNI extension does | ||
| 796 | * not exist. | ||
| 797 | */ | ||
| 798 | if (is_ip) | ||
| 799 | goto done; | ||
| 800 | |||
| 757 | *alert = SSL_AD_ILLEGAL_PARAMETER; | 801 | *alert = SSL_AD_ILLEGAL_PARAMETER; |
| 758 | goto err; | 802 | goto err; |
| 759 | } | 803 | } |
| @@ -777,6 +821,7 @@ tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) | |||
| 777 | } | 821 | } |
| 778 | } | 822 | } |
| 779 | 823 | ||
| 824 | done: | ||
| 780 | /* | 825 | /* |
| 781 | * RFC 6066 section 3 forbids multiple host names with the same type, | 826 | * RFC 6066 section 3 forbids multiple host names with the same type, |
| 782 | * therefore we allow only one entry. | 827 | * therefore we allow only one entry. |
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h index 8e0742aa2c..b4c135fdf1 100644 --- a/src/lib/libssl/ssl_tlsext.h +++ b/src/lib/libssl/ssl_tlsext.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_tlsext.h,v 1.26 2020/10/11 01:13:04 guenther Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.h,v 1.27 2021/11/01 16:37:17 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> |
| @@ -60,7 +60,7 @@ int tlsext_sni_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); | |||
| 60 | int tlsext_sni_server_needs(SSL *s, uint16_t msg_type); | 60 | int tlsext_sni_server_needs(SSL *s, uint16_t msg_type); |
| 61 | int tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb); | 61 | int tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb); |
| 62 | int tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); | 62 | int tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); |
| 63 | int tlsext_sni_is_valid_hostname(CBS *cbs); | 63 | int tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip); |
| 64 | 64 | ||
| 65 | int tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type); | 65 | int tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type); |
| 66 | int tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb); | 66 | int tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb); |
