diff options
author | jsing <> | 2016-12-18 13:52:53 +0000 |
---|---|---|
committer | jsing <> | 2016-12-18 13:52:53 +0000 |
commit | 8119207eb552e369038e8f9265f53d902e305a76 (patch) | |
tree | 507706df51532397cd6425a60b7f4505c7008ca4 /src/lib | |
parent | 95575415e5d3451b6de7a260d4093e491797faad (diff) | |
download | openbsd-8119207eb552e369038e8f9265f53d902e305a76.tar.gz openbsd-8119207eb552e369038e8f9265f53d902e305a76.tar.bz2 openbsd-8119207eb552e369038e8f9265f53d902e305a76.zip |
Convert ssl3_get_server_hello() to CBS.
ok doug@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/s3_clnt.c | 114 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 4 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 9 |
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: | |||
718 | int | 718 | int |
719 | ssl3_get_server_hello(SSL *s) | 719 | ssl3_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, | |||
787 | int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, | 787 | int 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); |
789 | int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, | 789 | int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, |
790 | unsigned char *d, int n, int *al); | 790 | size_t n, int *al); |
791 | int ssl_check_clienthello_tlsext_early(SSL *s); | 791 | int ssl_check_clienthello_tlsext_early(SSL *s); |
792 | int ssl_check_clienthello_tlsext_late(SSL *s); | 792 | int ssl_check_clienthello_tlsext_late(SSL *s); |
793 | int ssl_check_serverhello_tlsext(SSL *s); | 793 | int 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 | ||
1609 | int | 1609 | int |
1610 | ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | 1610 | ssl_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 | } |