diff options
| author | jsing <> | 2017-01-26 12:28:00 +0000 |
|---|---|---|
| committer | jsing <> | 2017-01-26 12:28:00 +0000 |
| commit | b141c006bb6adfcae96ba102630b285a36c875aa (patch) | |
| tree | eec21d9939bafb73996cdd2c83332c32f0727630 | |
| parent | a141ed2bc17672028f4c648479f1cc3c598be1e9 (diff) | |
| download | openbsd-b141c006bb6adfcae96ba102630b285a36c875aa.tar.gz openbsd-b141c006bb6adfcae96ba102630b285a36c875aa.tar.bz2 openbsd-b141c006bb6adfcae96ba102630b285a36c875aa.zip | |
Convert ssl3_get_client_hello() to CBS.
ok beck@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_srvr.c | 147 |
1 files changed, 71 insertions, 76 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 0b110d6a72..217ecafeec 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_srvr.c,v 1.4 2017/01/26 12:16:13 beck Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.5 2017/01/26 12:28:00 jsing 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 | * |
| @@ -719,8 +719,12 @@ ssl3_send_hello_request(SSL *s) | |||
| 719 | int | 719 | int |
| 720 | ssl3_get_client_hello(SSL *s) | 720 | ssl3_get_client_hello(SSL *s) |
| 721 | { | 721 | { |
| 722 | CBS cbs, client_random, session_id, cookie, cipher_suites; | ||
| 723 | CBS compression_methods; | ||
| 724 | uint16_t client_version; | ||
| 725 | uint8_t comp_method; | ||
| 726 | int comp_null; | ||
| 722 | int i, j, ok, al, ret = -1; | 727 | int i, j, ok, al, ret = -1; |
| 723 | unsigned int cookie_len; | ||
| 724 | long n; | 728 | long n; |
| 725 | unsigned long id; | 729 | unsigned long id; |
| 726 | unsigned char *p, *d; | 730 | unsigned char *p, *d; |
| @@ -729,6 +733,7 @@ ssl3_get_client_hello(SSL *s) | |||
| 729 | unsigned long alg_k; | 733 | unsigned long alg_k; |
| 730 | const SSL_METHOD *method; | 734 | const SSL_METHOD *method; |
| 731 | uint16_t shared_version; | 735 | uint16_t shared_version; |
| 736 | unsigned char *end; | ||
| 732 | 737 | ||
| 733 | /* | 738 | /* |
| 734 | * We do this so that we will respond with our native type. | 739 | * We do this so that we will respond with our native type. |
| @@ -745,23 +750,26 @@ ssl3_get_client_hello(SSL *s) | |||
| 745 | n = s->method->internal->ssl_get_message(s, SSL3_ST_SR_CLNT_HELLO_B, | 750 | n = s->method->internal->ssl_get_message(s, SSL3_ST_SR_CLNT_HELLO_B, |
| 746 | SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO, | 751 | SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO, |
| 747 | SSL3_RT_MAX_PLAIN_LENGTH, &ok); | 752 | SSL3_RT_MAX_PLAIN_LENGTH, &ok); |
| 748 | |||
| 749 | if (!ok) | 753 | if (!ok) |
| 750 | return ((int)n); | 754 | return ((int)n); |
| 751 | s->internal->first_packet = 0; | 755 | s->internal->first_packet = 0; |
| 752 | 756 | ||
| 757 | if (n < 0) | ||
| 758 | goto err; | ||
| 759 | |||
| 753 | d = p = (unsigned char *)s->internal->init_msg; | 760 | d = p = (unsigned char *)s->internal->init_msg; |
| 761 | end = d + n; | ||
| 762 | |||
| 763 | CBS_init(&cbs, s->internal->init_msg, n); | ||
| 754 | 764 | ||
| 755 | if (2 > n) | ||
| 756 | goto truncated; | ||
| 757 | /* | 765 | /* |
| 758 | * Use version from inside client hello, not from record header. | 766 | * Use version from inside client hello, not from record header. |
| 759 | * (may differ: see RFC 2246, Appendix E, second paragraph) | 767 | * (may differ: see RFC 2246, Appendix E, second paragraph) |
| 760 | */ | 768 | */ |
| 761 | s->client_version = (((int)p[0]) << 8)|(int)p[1]; | 769 | if (!CBS_get_u16(&cbs, &client_version)) |
| 762 | p += 2; | 770 | goto truncated; |
| 763 | 771 | ||
| 764 | if (ssl_max_shared_version(s, s->client_version, &shared_version) != 1) { | 772 | if (ssl_max_shared_version(s, client_version, &shared_version) != 1) { |
| 765 | SSLerror(SSL_R_WRONG_VERSION_NUMBER); | 773 | SSLerror(SSL_R_WRONG_VERSION_NUMBER); |
| 766 | if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && | 774 | if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && |
| 767 | !s->internal->enc_write_ctx && !s->internal->write_hash) { | 775 | !s->internal->enc_write_ctx && !s->internal->write_hash) { |
| @@ -774,6 +782,7 @@ ssl3_get_client_hello(SSL *s) | |||
| 774 | al = SSL_AD_PROTOCOL_VERSION; | 782 | al = SSL_AD_PROTOCOL_VERSION; |
| 775 | goto f_err; | 783 | goto f_err; |
| 776 | } | 784 | } |
| 785 | s->client_version = client_version; | ||
| 777 | s->version = shared_version; | 786 | s->version = shared_version; |
| 778 | 787 | ||
| 779 | if ((method = tls1_get_server_method(shared_version)) == NULL) | 788 | if ((method = tls1_get_server_method(shared_version)) == NULL) |
| @@ -784,39 +793,31 @@ ssl3_get_client_hello(SSL *s) | |||
| 784 | } | 793 | } |
| 785 | s->method = method; | 794 | s->method = method; |
| 786 | 795 | ||
| 796 | if (!CBS_get_bytes(&cbs, &client_random, SSL3_RANDOM_SIZE)) | ||
| 797 | goto truncated; | ||
| 798 | if (!CBS_get_u8_length_prefixed(&cbs, &session_id)) | ||
| 799 | goto truncated; | ||
| 800 | |||
| 787 | /* | 801 | /* |
| 788 | * If we require cookies (DTLS) and this ClientHello doesn't | 802 | * If we require cookies (DTLS) and this ClientHello doesn't |
| 789 | * contain one, just return since we do not want to | 803 | * contain one, just return since we do not want to |
| 790 | * allocate any memory yet. So check cookie length... | 804 | * allocate any memory yet. So check cookie length... |
| 791 | */ | 805 | */ |
| 792 | if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { | 806 | if (SSL_IS_DTLS(s)) { |
| 793 | unsigned int session_length, cookie_length; | 807 | if (!CBS_get_u8_length_prefixed(&cbs, &cookie)) |
| 794 | |||
| 795 | if (p - d + SSL3_RANDOM_SIZE + 1 >= n) | ||
| 796 | goto truncated; | ||
| 797 | session_length = *(p + SSL3_RANDOM_SIZE); | ||
| 798 | |||
| 799 | if (p - d + SSL3_RANDOM_SIZE + session_length + 1 >= n) | ||
| 800 | goto truncated; | 808 | goto truncated; |
| 801 | cookie_length = p[SSL3_RANDOM_SIZE + session_length + 1]; | 809 | if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { |
| 802 | 810 | if (CBS_len(&cookie) == 0) | |
| 803 | if (cookie_length == 0) | 811 | return (1); |
| 804 | return (1); | 812 | } |
| 805 | } | 813 | } |
| 806 | 814 | ||
| 807 | if (p - d + SSL3_RANDOM_SIZE + 1 > n) | 815 | if (!CBS_write_bytes(&client_random, s->s3->client_random, |
| 808 | goto truncated; | 816 | sizeof(s->s3->client_random), NULL)) |
| 809 | 817 | goto err; | |
| 810 | /* load the client random */ | ||
| 811 | memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); | ||
| 812 | p += SSL3_RANDOM_SIZE; | ||
| 813 | |||
| 814 | /* get the session-id */ | ||
| 815 | j= *(p++); | ||
| 816 | if (p - d + j > n) | ||
| 817 | goto truncated; | ||
| 818 | 818 | ||
| 819 | s->internal->hit = 0; | 819 | s->internal->hit = 0; |
| 820 | |||
| 820 | /* | 821 | /* |
| 821 | * Versions before 0.9.7 always allow clients to resume sessions in | 822 | * Versions before 0.9.7 always allow clients to resume sessions in |
| 822 | * renegotiation. 0.9.7 and later allow this by default, but optionally | 823 | * renegotiation. 0.9.7 and later allow this by default, but optionally |
| @@ -837,7 +838,10 @@ ssl3_get_client_hello(SSL *s) | |||
| 837 | if (!ssl_get_new_session(s, 1)) | 838 | if (!ssl_get_new_session(s, 1)) |
| 838 | goto err; | 839 | goto err; |
| 839 | } else { | 840 | } else { |
| 840 | i = ssl_get_prev_session(s, p, j, d + n); | 841 | /* XXX - pass CBS through instead... */ |
| 842 | i = ssl_get_prev_session(s, | ||
| 843 | (unsigned char *)CBS_data(&session_id), | ||
| 844 | CBS_len(&session_id), end); | ||
| 841 | if (i == 1) { /* previous session */ | 845 | if (i == 1) { /* previous session */ |
| 842 | s->internal->hit = 1; | 846 | s->internal->hit = 1; |
| 843 | } else if (i == -1) | 847 | } else if (i == -1) |
| @@ -849,33 +853,27 @@ ssl3_get_client_hello(SSL *s) | |||
| 849 | } | 853 | } |
| 850 | } | 854 | } |
| 851 | 855 | ||
| 852 | p += j; | ||
| 853 | |||
| 854 | if (SSL_IS_DTLS(s)) { | 856 | if (SSL_IS_DTLS(s)) { |
| 855 | /* cookie stuff */ | ||
| 856 | if (p - d + 1 > n) | ||
| 857 | goto truncated; | ||
| 858 | cookie_len = *(p++); | ||
| 859 | |||
| 860 | /* | 857 | /* |
| 861 | * The ClientHello may contain a cookie even if the | 858 | * The ClientHello may contain a cookie even if the HelloVerify |
| 862 | * HelloVerify message has not been sent--make sure that it | 859 | * message has not been sent - make sure that it does not cause |
| 863 | * does not cause an overflow. | 860 | * an overflow. |
| 864 | */ | 861 | */ |
| 865 | if (cookie_len > sizeof(D1I(s)->rcvd_cookie)) { | 862 | if (CBS_len(&cookie) > sizeof(D1I(s)->rcvd_cookie)) { |
| 866 | /* too much data */ | ||
| 867 | al = SSL_AD_DECODE_ERROR; | 863 | al = SSL_AD_DECODE_ERROR; |
| 868 | SSLerror(SSL_R_COOKIE_MISMATCH); | 864 | SSLerror(SSL_R_COOKIE_MISMATCH); |
| 869 | goto f_err; | 865 | goto f_err; |
| 870 | } | 866 | } |
| 871 | 867 | ||
| 872 | if (p - d + cookie_len > n) | 868 | /* Verify the cookie if appropriate option is set. */ |
| 873 | goto truncated; | ||
| 874 | |||
| 875 | /* verify the cookie if appropriate option is set. */ | ||
| 876 | if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && | 869 | if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && |
| 877 | cookie_len > 0) { | 870 | CBS_len(&cookie) > 0) { |
| 878 | memcpy(D1I(s)->rcvd_cookie, p, cookie_len); | 871 | size_t cookie_len; |
| 872 | |||
| 873 | /* XXX - rcvd_cookie seems to only be used here... */ | ||
| 874 | if (!CBS_write_bytes(&cookie, D1I(s)->rcvd_cookie, | ||
| 875 | sizeof(D1I(s)->rcvd_cookie), &cookie_len)) | ||
| 876 | goto err; | ||
| 879 | 877 | ||
| 880 | if (s->ctx->internal->app_verify_cookie_cb != NULL) { | 878 | if (s->ctx->internal->app_verify_cookie_cb != NULL) { |
| 881 | if (s->ctx->internal->app_verify_cookie_cb(s, | 879 | if (s->ctx->internal->app_verify_cookie_cb(s, |
| @@ -885,39 +883,37 @@ ssl3_get_client_hello(SSL *s) | |||
| 885 | goto f_err; | 883 | goto f_err; |
| 886 | } | 884 | } |
| 887 | /* else cookie verification succeeded */ | 885 | /* else cookie verification succeeded */ |
| 888 | } else if (timingsafe_memcmp(D1I(s)->rcvd_cookie, D1I(s)->cookie, | 886 | /* XXX - can d1->cookie_len > sizeof(rcvd_cookie) ? */ |
| 889 | D1I(s)->cookie_len) != 0) { | 887 | } else if (timingsafe_memcmp(D1I(s)->rcvd_cookie, |
| 888 | D1I(s)->cookie, D1I(s)->cookie_len) != 0) { | ||
| 890 | /* default verification */ | 889 | /* default verification */ |
| 891 | al = SSL_AD_HANDSHAKE_FAILURE; | 890 | al = SSL_AD_HANDSHAKE_FAILURE; |
| 892 | SSLerror(SSL_R_COOKIE_MISMATCH); | 891 | SSLerror(SSL_R_COOKIE_MISMATCH); |
| 893 | goto f_err; | 892 | goto f_err; |
| 894 | } | 893 | } |
| 895 | |||
| 896 | ret = 2; | 894 | ret = 2; |
| 897 | } | 895 | } |
| 898 | |||
| 899 | p += cookie_len; | ||
| 900 | } | 896 | } |
| 901 | 897 | ||
| 902 | if (p - d + 2 > n) | 898 | if (!CBS_get_u16_length_prefixed(&cbs, &cipher_suites)) |
| 903 | goto truncated; | 899 | goto truncated; |
| 904 | n2s(p, i); | 900 | |
| 905 | if ((i == 0) && (j != 0)) { | 901 | /* XXX - This logic seems wrong... */ |
| 902 | if (CBS_len(&cipher_suites) == 0 && CBS_len(&session_id) != 0) { | ||
| 906 | /* we need a cipher if we are not resuming a session */ | 903 | /* we need a cipher if we are not resuming a session */ |
| 907 | al = SSL_AD_ILLEGAL_PARAMETER; | 904 | al = SSL_AD_ILLEGAL_PARAMETER; |
| 908 | SSLerror(SSL_R_NO_CIPHERS_SPECIFIED); | 905 | SSLerror(SSL_R_NO_CIPHERS_SPECIFIED); |
| 909 | goto f_err; | 906 | goto f_err; |
| 910 | } | 907 | } |
| 911 | if (p - d + i > n) | 908 | |
| 912 | goto truncated; | 909 | if (CBS_len(&cipher_suites) > 0) { |
| 913 | if (i > 0) { | 910 | if ((ciphers = ssl_bytes_to_cipher_list(s, |
| 914 | if ((ciphers = ssl_bytes_to_cipher_list(s, p, i)) == NULL) | 911 | CBS_data(&cipher_suites), CBS_len(&cipher_suites))) == NULL) |
| 915 | goto err; | 912 | goto err; |
| 916 | } | 913 | } |
| 917 | p += i; | ||
| 918 | 914 | ||
| 919 | /* If it is a hit, check that the cipher is in the list */ | 915 | /* If it is a hit, check that the cipher is in the list */ |
| 920 | if ((s->internal->hit) && (i > 0)) { | 916 | if (s->internal->hit && CBS_len(&cipher_suites) > 0) { |
| 921 | j = 0; | 917 | j = 0; |
| 922 | id = s->session->cipher->id; | 918 | id = s->session->cipher->id; |
| 923 | 919 | ||
| @@ -939,25 +935,24 @@ ssl3_get_client_hello(SSL *s) | |||
| 939 | } | 935 | } |
| 940 | } | 936 | } |
| 941 | 937 | ||
| 942 | /* compression */ | 938 | if (!CBS_get_u8_length_prefixed(&cbs, &compression_methods)) |
| 943 | if (p - d + 1 > n) | ||
| 944 | goto truncated; | ||
| 945 | i= *(p++); | ||
| 946 | if (p - d + i > n) | ||
| 947 | goto truncated; | 939 | goto truncated; |
| 948 | for (j = 0; j < i; j++) { | ||
| 949 | if (p[j] == 0) | ||
| 950 | break; | ||
| 951 | } | ||
| 952 | 940 | ||
| 953 | p += i; | 941 | comp_null = 0; |
| 954 | if (j >= i) { | 942 | while (CBS_len(&compression_methods) > 0) { |
| 955 | /* no compress */ | 943 | if (!CBS_get_u8(&compression_methods, &comp_method)) |
| 944 | goto truncated; | ||
| 945 | if (comp_method == 0) | ||
| 946 | comp_null = 1; | ||
| 947 | } | ||
| 948 | if (comp_null == 0) { | ||
| 956 | al = SSL_AD_DECODE_ERROR; | 949 | al = SSL_AD_DECODE_ERROR; |
| 957 | SSLerror(SSL_R_NO_COMPRESSION_SPECIFIED); | 950 | SSLerror(SSL_R_NO_COMPRESSION_SPECIFIED); |
| 958 | goto f_err; | 951 | goto f_err; |
| 959 | } | 952 | } |
| 960 | 953 | ||
| 954 | p = (unsigned char *)CBS_data(&cbs); | ||
| 955 | |||
| 961 | /* TLS extensions*/ | 956 | /* TLS extensions*/ |
| 962 | if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { | 957 | if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { |
| 963 | /* 'al' set by ssl_parse_clienthello_tlsext */ | 958 | /* 'al' set by ssl_parse_clienthello_tlsext */ |
