diff options
-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); |