diff options
| author | jsing <> | 2016-12-18 13:52:53 +0000 |
|---|---|---|
| committer | jsing <> | 2016-12-18 13:52:53 +0000 |
| commit | 4b3d6b86234b0d9d9129be2b2cbbad14aac5afdb (patch) | |
| tree | 507706df51532397cd6425a60b7f4505c7008ca4 | |
| parent | 8def53432c03f833e2f2c79b876710d1cf8d60ea (diff) | |
| download | openbsd-4b3d6b86234b0d9d9129be2b2cbbad14aac5afdb.tar.gz openbsd-4b3d6b86234b0d9d9129be2b2cbbad14aac5afdb.tar.bz2 openbsd-4b3d6b86234b0d9d9129be2b2cbbad14aac5afdb.zip | |
Convert ssl3_get_server_hello() to CBS.
ok doug@
Diffstat (limited to '')
| -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 | } |
