diff options
| author | doug <> | 2017-08-26 20:23:46 +0000 |
|---|---|---|
| committer | doug <> | 2017-08-26 20:23:46 +0000 |
| commit | a07b08be0fe616280531694efcd12be53e09a432 (patch) | |
| tree | d42347fee889bfbea6b518ea0c0bc8a2f6c60bc0 /src/lib/libssl/t1_lib.c | |
| parent | 00cc6ad838cddc51f549767256bec3a613fb6ae0 (diff) | |
| download | openbsd-a07b08be0fe616280531694efcd12be53e09a432.tar.gz openbsd-a07b08be0fe616280531694efcd12be53e09a432.tar.bz2 openbsd-a07b08be0fe616280531694efcd12be53e09a432.zip | |
Rewrite ALPN extension using CBB/CBS and the new extension framework.
ok bcook@ beck@
input + ok jsing@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 140 |
1 files changed, 1 insertions, 139 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index d71067d73c..eb1d96cc11 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: t1_lib.c,v 1.134 2017/08/13 21:10:42 bcook Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.135 2017/08/26 20:23:46 doug Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -687,19 +687,6 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 687 | return NULL; | 687 | return NULL; |
| 688 | ret += len; | 688 | ret += len; |
| 689 | 689 | ||
| 690 | if (s->internal->alpn_client_proto_list != NULL && | ||
| 691 | S3I(s)->tmp.finish_md_len == 0) { | ||
| 692 | if ((size_t)(limit - ret) < | ||
| 693 | 6 + s->internal->alpn_client_proto_list_len) | ||
| 694 | return (NULL); | ||
| 695 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
| 696 | s2n(2 + s->internal->alpn_client_proto_list_len, ret); | ||
| 697 | s2n(s->internal->alpn_client_proto_list_len, ret); | ||
| 698 | memcpy(ret, s->internal->alpn_client_proto_list, | ||
| 699 | s->internal->alpn_client_proto_list_len); | ||
| 700 | ret += s->internal->alpn_client_proto_list_len; | ||
| 701 | } | ||
| 702 | |||
| 703 | #ifndef OPENSSL_NO_SRTP | 690 | #ifndef OPENSSL_NO_SRTP |
| 704 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { | 691 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { |
| 705 | int el; | 692 | int el; |
| @@ -778,20 +765,6 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 778 | } | 765 | } |
| 779 | #endif | 766 | #endif |
| 780 | 767 | ||
| 781 | if (S3I(s)->alpn_selected != NULL) { | ||
| 782 | const unsigned char *selected = S3I(s)->alpn_selected; | ||
| 783 | unsigned int len = S3I(s)->alpn_selected_len; | ||
| 784 | |||
| 785 | if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) | ||
| 786 | return (NULL); | ||
| 787 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
| 788 | s2n(3 + len, ret); | ||
| 789 | s2n(1 + len, ret); | ||
| 790 | *ret++ = len; | ||
| 791 | memcpy(ret, selected, len); | ||
| 792 | ret += len; | ||
| 793 | } | ||
| 794 | |||
| 795 | if ((extdatalen = ret - p - 2) == 0) | 768 | if ((extdatalen = ret - p - 2) == 0) |
| 796 | return p; | 769 | return p; |
| 797 | 770 | ||
| @@ -799,71 +772,6 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 799 | return ret; | 772 | return ret; |
| 800 | } | 773 | } |
| 801 | 774 | ||
| 802 | /* | ||
| 803 | * tls1_alpn_handle_client_hello is called to process the ALPN extension in a | ||
| 804 | * ClientHello. | ||
| 805 | * data: the contents of the extension, not including the type and length. | ||
| 806 | * data_len: the number of bytes in data. | ||
| 807 | * al: a pointer to the alert value to send in the event of a non-zero | ||
| 808 | * return. | ||
| 809 | * returns: 1 on success. | ||
| 810 | */ | ||
| 811 | static int | ||
| 812 | tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, | ||
| 813 | unsigned int data_len, int *al) | ||
| 814 | { | ||
| 815 | CBS cbs, proto_name_list, alpn; | ||
| 816 | const unsigned char *selected; | ||
| 817 | unsigned char selected_len; | ||
| 818 | int r; | ||
| 819 | |||
| 820 | if (s->ctx->internal->alpn_select_cb == NULL) | ||
| 821 | return (1); | ||
| 822 | |||
| 823 | if (data_len < 2) | ||
| 824 | goto parse_error; | ||
| 825 | |||
| 826 | CBS_init(&cbs, data, data_len); | ||
| 827 | |||
| 828 | /* | ||
| 829 | * data should contain a uint16 length followed by a series of 8-bit, | ||
| 830 | * length-prefixed strings. | ||
| 831 | */ | ||
| 832 | if (!CBS_get_u16_length_prefixed(&cbs, &alpn) || | ||
| 833 | CBS_len(&alpn) < 2 || | ||
| 834 | CBS_len(&cbs) != 0) | ||
| 835 | goto parse_error; | ||
| 836 | |||
| 837 | /* Validate data before sending to callback. */ | ||
| 838 | CBS_dup(&alpn, &proto_name_list); | ||
| 839 | while (CBS_len(&proto_name_list) > 0) { | ||
| 840 | CBS proto_name; | ||
| 841 | |||
| 842 | if (!CBS_get_u8_length_prefixed(&proto_name_list, &proto_name) || | ||
| 843 | CBS_len(&proto_name) == 0) | ||
| 844 | goto parse_error; | ||
| 845 | } | ||
| 846 | |||
| 847 | r = s->ctx->internal->alpn_select_cb(s, &selected, &selected_len, | ||
| 848 | CBS_data(&alpn), CBS_len(&alpn), | ||
| 849 | s->ctx->internal->alpn_select_cb_arg); | ||
| 850 | if (r == SSL_TLSEXT_ERR_OK) { | ||
| 851 | free(S3I(s)->alpn_selected); | ||
| 852 | if ((S3I(s)->alpn_selected = malloc(selected_len)) == NULL) { | ||
| 853 | *al = SSL_AD_INTERNAL_ERROR; | ||
| 854 | return (-1); | ||
| 855 | } | ||
| 856 | memcpy(S3I(s)->alpn_selected, selected, selected_len); | ||
| 857 | S3I(s)->alpn_selected_len = selected_len; | ||
| 858 | } | ||
| 859 | |||
| 860 | return (1); | ||
| 861 | |||
| 862 | parse_error: | ||
| 863 | *al = SSL_AD_DECODE_ERROR; | ||
| 864 | return (0); | ||
| 865 | } | ||
| 866 | |||
| 867 | int | 775 | int |
| 868 | ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | 776 | ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, |
| 869 | int n, int *al) | 777 | int n, int *al) |
| @@ -907,14 +815,6 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 907 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) | 815 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
| 908 | return 0; | 816 | return 0; |
| 909 | 817 | ||
| 910 | if (type == | ||
| 911 | TLSEXT_TYPE_application_layer_protocol_negotiation && | ||
| 912 | s->ctx->internal->alpn_select_cb != NULL && | ||
| 913 | S3I(s)->tmp.finish_md_len == 0) { | ||
| 914 | if (tls1_alpn_handle_client_hello(s, data, | ||
| 915 | size, al) != 1) | ||
| 916 | return (0); | ||
| 917 | } | ||
| 918 | /* session ticket processed earlier */ | 818 | /* session ticket processed earlier */ |
| 919 | #ifndef OPENSSL_NO_SRTP | 819 | #ifndef OPENSSL_NO_SRTP |
| 920 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { | 820 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { |
| @@ -988,44 +888,6 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) | |||
| 988 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) | 888 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) |
| 989 | return 0; | 889 | return 0; |
| 990 | 890 | ||
| 991 | if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { | ||
| 992 | unsigned int len; | ||
| 993 | |||
| 994 | /* We must have requested it. */ | ||
| 995 | if (s->internal->alpn_client_proto_list == NULL) { | ||
| 996 | *al = TLS1_AD_UNSUPPORTED_EXTENSION; | ||
| 997 | return 0; | ||
| 998 | } | ||
| 999 | if (size < 4) { | ||
| 1000 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1001 | return (0); | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | /* The extension data consists of: | ||
| 1005 | * uint16 list_length | ||
| 1006 | * uint8 proto_length; | ||
| 1007 | * uint8 proto[proto_length]; */ | ||
| 1008 | len = ((unsigned int)data[0]) << 8 | | ||
| 1009 | ((unsigned int)data[1]); | ||
| 1010 | if (len != (unsigned int)size - 2) { | ||
| 1011 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1012 | return (0); | ||
| 1013 | } | ||
| 1014 | len = data[2]; | ||
| 1015 | if (len != (unsigned int)size - 3) { | ||
| 1016 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1017 | return (0); | ||
| 1018 | } | ||
| 1019 | free(S3I(s)->alpn_selected); | ||
| 1020 | S3I(s)->alpn_selected = malloc(len); | ||
| 1021 | if (S3I(s)->alpn_selected == NULL) { | ||
| 1022 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1023 | return (0); | ||
| 1024 | } | ||
| 1025 | memcpy(S3I(s)->alpn_selected, data + 3, len); | ||
| 1026 | S3I(s)->alpn_selected_len = len; | ||
| 1027 | |||
| 1028 | } | ||
| 1029 | #ifndef OPENSSL_NO_SRTP | 891 | #ifndef OPENSSL_NO_SRTP |
| 1030 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { | 892 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { |
| 1031 | if (ssl_parse_serverhello_use_srtp_ext(s, data, | 893 | if (ssl_parse_serverhello_use_srtp_ext(s, data, |
