summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2016-12-18 13:52:53 +0000
committerjsing <>2016-12-18 13:52:53 +0000
commit8119207eb552e369038e8f9265f53d902e305a76 (patch)
tree507706df51532397cd6425a60b7f4505c7008ca4
parent95575415e5d3451b6de7a260d4093e491797faad (diff)
downloadopenbsd-8119207eb552e369038e8f9265f53d902e305a76.tar.gz
openbsd-8119207eb552e369038e8f9265f53d902e305a76.tar.bz2
openbsd-8119207eb552e369038e8f9265f53d902e305a76.zip
Convert ssl3_get_server_hello() to CBS.
ok doug@
-rw-r--r--src/lib/libssl/s3_clnt.c114
-rw-r--r--src/lib/libssl/ssl_locl.h4
-rw-r--r--src/lib/libssl/t1_lib.c9
3 files changed, 67 insertions, 60 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index 6c9639bbdd..be6e461a1e 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_clnt.c,v 1.155 2016/12/13 16:10:21 jsing Exp $ */ 1/* $OpenBSD: s3_clnt.c,v 1.156 2016/12/18 13:52:53 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 *
@@ -718,14 +718,16 @@ err:
718int 718int
719ssl3_get_server_hello(SSL *s) 719ssl3_get_server_hello(SSL *s)
720{ 720{
721 STACK_OF(SSL_CIPHER) *sk; 721 CBS cbs, server_random, session_id;
722 const SSL_CIPHER *c; 722 uint16_t server_version, cipher_suite;
723 unsigned char *p, *q, *d; 723 uint8_t compression_method;
724 int i, al, ok; 724 STACK_OF(SSL_CIPHER) *sk;
725 unsigned int j; 725 const SSL_CIPHER *cipher;
726 uint16_t cipher_value; 726 unsigned char *p;
727 long n; 727 unsigned long alg_k;
728 unsigned long alg_k; 728 size_t outlen;
729 int i, al, ok;
730 long n;
729 731
730 n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, 732 n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A,
731 SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, /* ?? */ &ok); 733 SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, /* ?? */ &ok);
@@ -733,6 +735,11 @@ ssl3_get_server_hello(SSL *s)
733 if (!ok) 735 if (!ok)
734 return ((int)n); 736 return ((int)n);
735 737
738 if (n < 0)
739 goto truncated;
740
741 CBS_init(&cbs, s->init_msg, n);
742
736 if (SSL_IS_DTLS(s)) { 743 if (SSL_IS_DTLS(s)) {
737 if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { 744 if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) {
738 if (s->d1->send_cookie == 0) { 745 if (s->d1->send_cookie == 0) {
@@ -755,48 +762,42 @@ ssl3_get_server_hello(SSL *s)
755 goto f_err; 762 goto f_err;
756 } 763 }
757 764
758 d = p = (unsigned char *)s->init_msg; 765 if (!CBS_get_u16(&cbs, &server_version))
759
760 if (2 > n)
761 goto truncated; 766 goto truncated;
762 if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { 767
768 if (s->version != server_version) {
763 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); 769 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION);
764 s->version = (s->version&0xff00) | p[1]; 770 s->version = (s->version & 0xff00) | (server_version & 0xff);
765 al = SSL_AD_PROTOCOL_VERSION; 771 al = SSL_AD_PROTOCOL_VERSION;
766 goto f_err; 772 goto f_err;
767 } 773 }
768 p += 2;
769
770 /* load the server hello data */
771 774
772 if (p + SSL3_RANDOM_SIZE + 1 - d > n) 775 /* Server random. */
776 if (!CBS_get_bytes(&cbs, &server_random, SSL3_RANDOM_SIZE))
773 goto truncated; 777 goto truncated;
778 if (!CBS_write_bytes(&server_random, s->s3->server_random,
779 sizeof(s->s3->server_random), NULL))
780 goto err;
774 781
775 /* load the server random */ 782 /* Session ID. */
776 memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); 783 if (!CBS_get_u8_length_prefixed(&cbs, &session_id))
777 p += SSL3_RANDOM_SIZE; 784 goto truncated;
778
779 /* get the session-id */
780 j = *(p++);
781 785
782 if ((j > sizeof s->session->session_id) || 786 if ((CBS_len(&session_id) > sizeof(s->session->session_id)) ||
783 (j > SSL3_SESSION_ID_SIZE)) { 787 (CBS_len(&session_id) > SSL3_SESSION_ID_SIZE)) {
784 al = SSL_AD_ILLEGAL_PARAMETER; 788 al = SSL_AD_ILLEGAL_PARAMETER;
785 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 789 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
786 SSL_R_SSL3_SESSION_ID_TOO_LONG); 790 SSL_R_SSL3_SESSION_ID_TOO_LONG);
787 goto f_err; 791 goto f_err;
788 } 792 }
789 793
790 if (p + j + 2 - d > n) 794 /* Cipher suite. */
795 if (!CBS_get_u16(&cbs, &cipher_suite))
791 goto truncated; 796 goto truncated;
792 797
793 /* Get the cipher value. */
794 q = p + j;
795 n2s(q, cipher_value);
796
797 /* 798 /*
798 * Check if we want to resume the session based on external 799 * Check if we want to resume the session based on external
799 * pre-shared secret 800 * pre-shared secret.
800 */ 801 */
801 if (s->tls_session_secret_cb) { 802 if (s->tls_session_secret_cb) {
802 SSL_CIPHER *pref_cipher = NULL; 803 SSL_CIPHER *pref_cipher = NULL;
@@ -805,13 +806,14 @@ ssl3_get_server_hello(SSL *s)
805 &s->session->master_key_length, NULL, &pref_cipher, 806 &s->session->master_key_length, NULL, &pref_cipher,
806 s->tls_session_secret_cb_arg)) { 807 s->tls_session_secret_cb_arg)) {
807 s->session->cipher = pref_cipher ? pref_cipher : 808 s->session->cipher = pref_cipher ? pref_cipher :
808 ssl3_get_cipher_by_value(cipher_value); 809 ssl3_get_cipher_by_value(cipher_suite);
809 s->s3->flags |= SSL3_FLAGS_CCS_OK; 810 s->s3->flags |= SSL3_FLAGS_CCS_OK;
810 } 811 }
811 } 812 }
812 813
813 if (j != 0 && j == s->session->session_id_length && 814 if (s->session->session_id_length != 0 &&
814 timingsafe_memcmp(p, s->session->session_id, j) == 0) { 815 CBS_mem_equal(&session_id, s->session->session_id,
816 s->session->session_id_length)) {
815 if (s->sid_ctx_length != s->session->sid_ctx_length || 817 if (s->sid_ctx_length != s->session->sid_ctx_length ||
816 timingsafe_memcmp(s->session->sid_ctx, 818 timingsafe_memcmp(s->session->sid_ctx,
817 s->sid_ctx, s->sid_ctx_length) != 0) { 819 s->sid_ctx, s->sid_ctx_length) != 0) {
@@ -835,31 +837,34 @@ ssl3_get_server_hello(SSL *s)
835 goto f_err; 837 goto f_err;
836 } 838 }
837 } 839 }
838 s->session->session_id_length = j; 840 /*
839 memcpy(s->session->session_id, p, j); /* j could be 0 */ 841 * XXX - improve the handling for the case where there is a
842 * zero length session identifier.
843 */
844 if (!CBS_write_bytes(&session_id, s->session->session_id,
845 sizeof(s->session->session_id), &outlen))
846 goto err;
847 s->session->session_id_length = outlen;
840 } 848 }
841 p += j;
842 849
843 if ((c = ssl3_get_cipher_by_value(cipher_value)) == NULL) { 850 if ((cipher = ssl3_get_cipher_by_value(cipher_suite)) == NULL) {
844 /* unknown cipher */
845 al = SSL_AD_ILLEGAL_PARAMETER; 851 al = SSL_AD_ILLEGAL_PARAMETER;
846 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 852 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
847 SSL_R_UNKNOWN_CIPHER_RETURNED); 853 SSL_R_UNKNOWN_CIPHER_RETURNED);
848 goto f_err; 854 goto f_err;
849 } 855 }
850 856
851 /* TLS v1.2 only ciphersuites require v1.2 or later */ 857 /* TLS v1.2 only ciphersuites require v1.2 or later. */
852 if ((c->algorithm_ssl & SSL_TLSV1_2) && 858 if ((cipher->algorithm_ssl & SSL_TLSV1_2) &&
853 (TLS1_get_version(s) < TLS1_2_VERSION)) { 859 (TLS1_get_version(s) < TLS1_2_VERSION)) {
854 al = SSL_AD_ILLEGAL_PARAMETER; 860 al = SSL_AD_ILLEGAL_PARAMETER;
855 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 861 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
856 SSL_R_WRONG_CIPHER_RETURNED); 862 SSL_R_WRONG_CIPHER_RETURNED);
857 goto f_err; 863 goto f_err;
858 } 864 }
859 p += SSL3_CIPHER_VALUE_SIZE;
860 865
861 sk = ssl_get_ciphers_by_id(s); 866 sk = ssl_get_ciphers_by_id(s);
862 i = sk_SSL_CIPHER_find(sk, c); 867 i = sk_SSL_CIPHER_find(sk, cipher);
863 if (i < 0) { 868 if (i < 0) {
864 /* we did not say we would use this cipher */ 869 /* we did not say we would use this cipher */
865 al = SSL_AD_ILLEGAL_PARAMETER; 870 al = SSL_AD_ILLEGAL_PARAMETER;
@@ -875,13 +880,14 @@ ssl3_get_server_hello(SSL *s)
875 */ 880 */
876 if (s->session->cipher) 881 if (s->session->cipher)
877 s->session->cipher_id = s->session->cipher->id; 882 s->session->cipher_id = s->session->cipher->id;
878 if (s->hit && (s->session->cipher_id != c->id)) { 883 if (s->hit && (s->session->cipher_id != cipher->id)) {
879 al = SSL_AD_ILLEGAL_PARAMETER; 884 al = SSL_AD_ILLEGAL_PARAMETER;
880 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 885 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
881 SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); 886 SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
882 goto f_err; 887 goto f_err;
883 } 888 }
884 s->s3->tmp.new_cipher = c; 889 s->s3->tmp.new_cipher = cipher;
890
885 /* 891 /*
886 * Don't digest cached records if no sigalgs: we may need them for 892 * Don't digest cached records if no sigalgs: we may need them for
887 * client authentication. 893 * client authentication.
@@ -892,19 +898,20 @@ ssl3_get_server_hello(SSL *s)
892 al = SSL_AD_INTERNAL_ERROR; 898 al = SSL_AD_INTERNAL_ERROR;
893 goto f_err; 899 goto f_err;
894 } 900 }
895 /* lets get the compression algorithm */ 901
896 /* COMPRESSION */ 902 if (!CBS_get_u8(&cbs, &compression_method))
897 if (p + 1 - d > n)
898 goto truncated; 903 goto truncated;
899 if (*(p++) != 0) { 904
905 if (compression_method != 0) {
900 al = SSL_AD_ILLEGAL_PARAMETER; 906 al = SSL_AD_ILLEGAL_PARAMETER;
901 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 907 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
902 SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 908 SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
903 goto f_err; 909 goto f_err;
904 } 910 }
905 911
906 /* TLS extensions*/ 912 /* TLS extensions. */
907 if (!ssl_parse_serverhello_tlsext(s, &p, d, n, &al)) { 913 p = (unsigned char *)CBS_data(&cbs);
914 if (!ssl_parse_serverhello_tlsext(s, &p, CBS_len(&cbs), &al)) {
908 /* 'al' set by ssl_parse_serverhello_tlsext */ 915 /* 'al' set by ssl_parse_serverhello_tlsext */
909 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); 916 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT);
910 goto f_err; 917 goto f_err;
@@ -914,7 +921,8 @@ ssl3_get_server_hello(SSL *s)
914 goto err; 921 goto err;
915 } 922 }
916 923
917 if (p != d + n) 924 /* See if any data remains... */
925 if (p - CBS_data(&cbs) != CBS_len(&cbs))
918 goto truncated; 926 goto truncated;
919 927
920 return (1); 928 return (1);
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 3de5571985..d7484dd7a0 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.139 2016/12/06 13:38:11 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.140 2016/12/18 13:52:53 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 *
@@ -787,7 +787,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p,
787int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, 787int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
788 unsigned char *d, int n, int *al); 788 unsigned char *d, int n, int *al);
789int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, 789int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
790 unsigned char *d, int n, int *al); 790 size_t n, int *al);
791int ssl_check_clienthello_tlsext_early(SSL *s); 791int ssl_check_clienthello_tlsext_early(SSL *s);
792int ssl_check_clienthello_tlsext_late(SSL *s); 792int ssl_check_clienthello_tlsext_late(SSL *s);
793int ssl_check_serverhello_tlsext(SSL *s); 793int ssl_check_serverhello_tlsext(SSL *s);
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 090259cf1f..0a5958341b 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.94 2016/11/05 08:26:37 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.95 2016/12/18 13:52:53 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 *
@@ -1607,14 +1607,13 @@ ssl_next_proto_validate(const unsigned char *d, unsigned int len)
1607} 1607}
1608 1608
1609int 1609int
1610ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, 1610ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al)
1611 int n, int *al)
1612{ 1611{
1613 unsigned short type; 1612 unsigned short type;
1614 unsigned short size; 1613 unsigned short size;
1615 unsigned short len; 1614 unsigned short len;
1616 unsigned char *data = *p; 1615 unsigned char *data = *p;
1617 unsigned char *end = d + n; 1616 unsigned char *end = *p + n;
1618 int tlsext_servername = 0; 1617 int tlsext_servername = 0;
1619 int renegotiate_seen = 0; 1618 int renegotiate_seen = 0;
1620 1619
@@ -1790,7 +1789,7 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1790 1789
1791 } 1790 }
1792 1791
1793 if (data != d + n) { 1792 if (data != end) {
1794 *al = SSL_AD_DECODE_ERROR; 1793 *al = SSL_AD_DECODE_ERROR;
1795 return 0; 1794 return 0;
1796 } 1795 }