summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2017-01-26 12:28:00 +0000
committerjsing <>2017-01-26 12:28:00 +0000
commit777045738b3a89cbe3ccc2e2323fff80b2188cf4 (patch)
treeeec21d9939bafb73996cdd2c83332c32f0727630
parent5ae189b08474853c519a12e66db1c17cfc3c9c8f (diff)
downloadopenbsd-777045738b3a89cbe3ccc2e2323fff80b2188cf4.tar.gz
openbsd-777045738b3a89cbe3ccc2e2323fff80b2188cf4.tar.bz2
openbsd-777045738b3a89cbe3ccc2e2323fff80b2188cf4.zip
Convert ssl3_get_client_hello() to CBS.
ok beck@
-rw-r--r--src/lib/libssl/ssl_srvr.c147
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)
719int 719int
720ssl3_get_client_hello(SSL *s) 720ssl3_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 */