From 73999b62a27d9ac7c10ff27d79fd2bab97f97670 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 10 Sep 2015 10:22:30 +0100 Subject: [PATCH] Move PACKET creation into the state machine Previously each message specific process function would create its own PACKET structure. Rather than duplicate all of this code lots of times we should create it in the state machine itself. Reviewed-by: Tim Hudson Reviewed-by: Richard Levitte --- include/openssl/ssl.h | 2 + ssl/d1_clnt.c | 21 ++++-- ssl/s3_both.c | 21 +++--- ssl/s3_clnt.c | 156 ++++++++++++++++------------------------- ssl/s3_srvr.c | 157 +++++++++++++++++------------------------- ssl/ssl_err.c | 2 + ssl/ssl_locl.h | 34 ++++----- ssl/statem.c | 54 ++++++++------- 8 files changed, 199 insertions(+), 248 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index ed1b59af5e..de858f6006 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1985,6 +1985,7 @@ void ERR_load_SSL_strings(void); # define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC 371 # define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385 # define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370 +# define SSL_F_DTLS_PROCESS_HELLO_VERIFY 386 # define SSL_F_READ_STATE_MACHINE 352 # define SSL_F_SSL3_ACCEPT 128 # define SSL_F_SSL3_ADD_CERT_TO_BUF 296 @@ -2300,6 +2301,7 @@ void ERR_load_SSL_strings(void); # define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 # define SSL_R_INVALID_TRUST 279 # define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_LONG 102 # define SSL_R_LENGTH_TOO_SHORT 160 # define SSL_R_LIBRARY_BUG 274 # define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index 47b1f252de..d26e39cab5 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -156,22 +156,31 @@ IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, dtls1_get_client_method, DTLSv1_2_enc_data) -enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt) { int al; - unsigned char *data; unsigned int cookie_len; + PACKET cookiepkt; - data = (unsigned char *)s->init_msg; - data += 2; + if (!PACKET_forward(pkt, 2) + || !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH); + goto f_err; + } - cookie_len = *(data++); + cookie_len = PACKET_remaining(&cookiepkt); if (cookie_len > sizeof(s->d1->cookie)) { al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_TOO_LONG); goto f_err; } - memcpy(s->d1->cookie, data, cookie_len); + if (!PACKET_copy_bytes(&cookiepkt, s->d1->cookie, cookie_len)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH); + goto f_err; + } s->d1->cookie_len = cookie_len; return MSG_PROCESS_FINISHED_READING; diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 6c5147421e..47f02dbf3a 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -224,26 +224,29 @@ static void ssl3_take_mac(SSL *s) } #endif -enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) { int al; - + long remain; + + remain = PACKET_remaining(pkt); /* * 'Change Cipher Spec' is just a single byte, which should already have * been consumed by ssl_get_message() so there should be no bytes left, * unless we're using DTLS1_BAD_VER, which has an extra 2 bytes */ if (SSL_IS_DTLS(s)) { - if ((s->version == DTLS1_BAD_VER && n != DTLS1_CCS_HEADER_LENGTH + 1) + if ((s->version == DTLS1_BAD_VER + && remain != DTLS1_CCS_HEADER_LENGTH + 1) || (s->version != DTLS1_BAD_VER - && n != DTLS1_CCS_HEADER_LENGTH - 1)) { + && remain != DTLS1_CCS_HEADER_LENGTH - 1)) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, SSL_R_BAD_CHANGE_CIPHER_SPEC); goto f_err; } } else { - if (n != 0) { + if (remain != 0) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, SSL_R_BAD_CHANGE_CIPHER_SPEC); @@ -288,10 +291,9 @@ enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n) return MSG_PROCESS_ERROR; } -enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) { int al, i; - unsigned char *p; /* If this occurs, we have missed a message */ if (!s->s3->change_cipher_spec) { @@ -301,16 +303,15 @@ enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n) } s->s3->change_cipher_spec = 0; - p = (unsigned char *)s->init_msg; i = s->s3->tmp.peer_finish_md_len; - if (i < 0 || (unsigned long)i != n) { + if (i < 0 || (unsigned long)i != PACKET_remaining(pkt)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_BAD_DIGEST_LENGTH); goto f_err; } - if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { + if (CRYPTO_memcmp(PACKET_data(pkt), s->s3->tmp.peer_finish_md, i) != 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_DIGEST_CHECK_FAILED); goto f_err; diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9e5165c53b..49a9f60259 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -448,11 +448,11 @@ int tls_construct_client_hello(SSL *s) return 0; } -enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) { STACK_OF(SSL_CIPHER) *sk; const SSL_CIPHER *c; - PACKET pkt, session_id; + PACKET session_id; size_t session_id_len; unsigned char *cipherchars; int i, al = SSL_AD_INTERNAL_ERROR; @@ -461,16 +461,10 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) SSL_COMP *comp; #endif - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if (s->method->version == TLS_ANY_VERSION) { unsigned int sversion; - if (!PACKET_get_net_2(&pkt, &sversion)) { + if (!PACKET_get_net_2(pkt, &sversion)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -515,7 +509,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) unsigned int hversion; int options; - if (!PACKET_get_net_2(&pkt, &hversion)) { + if (!PACKET_get_net_2(pkt, &hversion)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -542,7 +536,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) } else { unsigned char *vers; - if (!PACKET_get_bytes(&pkt, &vers, 2)) { + if (!PACKET_get_bytes(pkt, &vers, 2)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -558,7 +552,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) /* load the server hello data */ /* load the server random */ - if (!PACKET_copy_bytes(&pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { + if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -567,7 +561,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) s->hit = 0; /* Get the session-id. */ - if (!PACKET_get_length_prefixed_1(&pkt, &session_id)) { + if (!PACKET_get_length_prefixed_1(pkt, &session_id)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -580,7 +574,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) goto f_err; } - if (!PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) { + if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -700,7 +694,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) goto f_err; /* lets get the compression algorithm */ /* COMPRESSION */ - if (!PACKET_get_1(&pkt, &compression)) { + if (!PACKET_get_1(pkt, &compression)) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -748,12 +742,12 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) #endif /* TLS extensions */ - if (!ssl_parse_serverhello_tlsext(s, &pkt)) { + if (!ssl_parse_serverhello_tlsext(s, pkt)) { SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_PARSE_TLSEXT); goto err; } - if (PACKET_remaining(&pkt) != 0) { + if (PACKET_remaining(pkt) != 0) { /* wrong packet length */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); @@ -794,7 +788,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n) return MSG_PROCESS_ERROR; } -enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) { int al, i, ret = MSG_PROCESS_ERROR, exp_idx; unsigned long cert_list_len, cert_len; @@ -802,28 +796,21 @@ enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n) unsigned char *certstart, *certbytes; STACK_OF(X509) *sk = NULL; EVP_PKEY *pkey = NULL; - PACKET pkt; - - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - goto f_err; - } if ((sk = sk_X509_new_null()) == NULL) { SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto err; } - if (!PACKET_get_net_3(&pkt, &cert_list_len) - || PACKET_remaining(&pkt) != cert_list_len) { + if (!PACKET_get_net_3(pkt, &cert_list_len) + || PACKET_remaining(pkt) != cert_list_len) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); goto f_err; } - while (PACKET_remaining(&pkt)) { - if (!PACKET_get_net_3(&pkt, &cert_len) - || !PACKET_get_bytes(&pkt, &certbytes, cert_len)) { + while (PACKET_remaining(pkt)) { + if (!PACKET_get_net_3(pkt, &cert_len) + || !PACKET_get_bytes(pkt, &certbytes, cert_len)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_CERT_LENGTH_MISMATCH); @@ -924,7 +911,7 @@ enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n) return ret; } -enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) { #ifndef OPENSSL_NO_RSA unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2]; @@ -946,18 +933,13 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) EC_POINT *srvr_ecpoint = NULL; int curve_nid = 0; #endif - PACKET pkt, save_param_start, signature; + PACKET save_param_start, signature; EVP_MD_CTX_init(&md_ctx); alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - save_param_start = pkt; + save_param_start = *pkt; #ifndef OPENSSL_NO_RSA RSA_free(s->s3->peer_rsa_tmp); @@ -980,7 +962,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) /* PSK ciphersuites are preceded by an identity hint */ if (alg_k & SSL_PSK) { PACKET psk_identity_hint; - if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity_hint)) { + if (!PACKET_get_length_prefixed_2(pkt, &psk_identity_hint)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1011,10 +993,10 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { PACKET prime, generator, salt, server_pub; - if (!PACKET_get_length_prefixed_2(&pkt, &prime) - || !PACKET_get_length_prefixed_2(&pkt, &generator) - || !PACKET_get_length_prefixed_1(&pkt, &salt) - || !PACKET_get_length_prefixed_2(&pkt, &server_pub)) { + if (!PACKET_get_length_prefixed_2(pkt, &prime) + || !PACKET_get_length_prefixed_2(pkt, &generator) + || !PACKET_get_length_prefixed_1(pkt, &salt) + || !PACKET_get_length_prefixed_2(pkt, &server_pub)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1055,8 +1037,8 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) goto f_err; } - if (!PACKET_get_length_prefixed_2(&pkt, &mod) - || !PACKET_get_length_prefixed_2(&pkt, &exp)) { + if (!PACKET_get_length_prefixed_2(pkt, &mod) + || !PACKET_get_length_prefixed_2(pkt, &exp)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1098,9 +1080,9 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { PACKET prime, generator, pub_key; - if (!PACKET_get_length_prefixed_2(&pkt, &prime) - || !PACKET_get_length_prefixed_2(&pkt, &generator) - || !PACKET_get_length_prefixed_2(&pkt, &pub_key)) { + if (!PACKET_get_length_prefixed_2(pkt, &prime) + || !PACKET_get_length_prefixed_2(pkt, &generator) + || !PACKET_get_length_prefixed_2(pkt, &pub_key)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1157,7 +1139,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) * public key. For now we only support named (not generic) curves and * ECParameters in this case is just three bytes. */ - if (!PACKET_get_bytes(&pkt, &ecparams, 3)) { + if (!PACKET_get_bytes(pkt, &ecparams, 3)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; } @@ -1205,7 +1187,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) goto err; } - if (!PACKET_get_length_prefixed_1(&pkt, &encoded_pt)) { + if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1254,7 +1236,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) */ if (!PACKET_get_sub_packet(&save_param_start, ¶ms, PACKET_remaining(&save_param_start) - - PACKET_remaining(&pkt))) { + PACKET_remaining(pkt))) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -1263,7 +1245,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) if (SSL_USE_SIGALGS(s)) { unsigned char *sigalgs; int rv; - if (!PACKET_get_bytes(&pkt, &sigalgs, 2)) { + if (!PACKET_get_bytes(pkt, &sigalgs, 2)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; } @@ -1280,8 +1262,8 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) md = EVP_sha1(); } - if (!PACKET_get_length_prefixed_2(&pkt, &signature) - || PACKET_remaining(&pkt) != 0) { + if (!PACKET_get_length_prefixed_2(pkt, &signature) + || PACKET_remaining(pkt) != 0) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1362,7 +1344,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) goto err; } /* still data left over */ - if (PACKET_remaining(&pkt) != 0) { + if (PACKET_remaining(pkt) != 0) { SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE); goto f_err; } @@ -1390,7 +1372,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n) return MSG_PROCESS_ERROR; } -enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) { int ret = MSG_PROCESS_ERROR; unsigned int list_len, ctype_num, i, name_len; @@ -1398,13 +1380,6 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n) unsigned char *data; unsigned char *namestart, *namebytes; STACK_OF(X509_NAME) *ca_sk = NULL; - PACKET pkt; - - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); - goto err; - } if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); @@ -1412,8 +1387,8 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n) } /* get the certificate types */ - if (!PACKET_get_1(&pkt, &ctype_num) - || !PACKET_get_bytes(&pkt, &data, ctype_num)) { + if (!PACKET_get_1(pkt, &ctype_num) + || !PACKET_get_bytes(pkt, &data, ctype_num)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); goto err; @@ -1435,8 +1410,8 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n) s->s3->tmp.ctype[i] = data[i]; if (SSL_USE_SIGALGS(s)) { - if (!PACKET_get_net_2(&pkt, &list_len) - || !PACKET_get_bytes(&pkt, &data, list_len)) { + if (!PACKET_get_net_2(pkt, &list_len) + || !PACKET_get_bytes(pkt, &data, list_len)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); @@ -1462,16 +1437,16 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n) } /* get the CA RDNs */ - if (!PACKET_get_net_2(&pkt, &list_len) - || PACKET_remaining(&pkt) != list_len) { + if (!PACKET_get_net_2(pkt, &list_len) + || PACKET_remaining(pkt) != list_len) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); goto err; } - while (PACKET_remaining(&pkt)) { - if (!PACKET_get_net_2(&pkt, &name_len) - || !PACKET_get_bytes(&pkt, &namebytes, name_len)) { + while (PACKET_remaining(pkt)) { + if (!PACKET_get_net_2(pkt, &name_len) + || !PACKET_get_bytes(pkt, &namebytes, name_len)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); @@ -1520,22 +1495,15 @@ static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) return (X509_NAME_cmp(*a, *b)); } -enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) { int al; unsigned int ticklen; unsigned long ticket_lifetime_hint; - PACKET pkt; - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); - goto f_err; - } - - if (!PACKET_get_net_4(&pkt, &ticket_lifetime_hint) - || !PACKET_get_net_2(&pkt, &ticklen) - || PACKET_remaining(&pkt) != ticklen) { + if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint) + || !PACKET_get_net_2(pkt, &ticklen) + || PACKET_remaining(pkt) != ticklen) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1584,7 +1552,7 @@ enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n) SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); goto err; } - if (!PACKET_copy_bytes(&pkt, s->session->tlsext_tick, ticklen)) { + if (!PACKET_copy_bytes(pkt, s->session->tlsext_tick, ticklen)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1614,26 +1582,20 @@ enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n) return MSG_PROCESS_ERROR; } -enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) { int al; unsigned long resplen; unsigned int type; - PACKET pkt; - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if (!PACKET_get_1(&pkt, &type) + if (!PACKET_get_1(pkt, &type) || type != TLSEXT_STATUSTYPE_ocsp) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); goto f_err; } - if (!PACKET_get_net_3(&pkt, &resplen) - || PACKET_remaining(&pkt) != resplen) { + if (!PACKET_get_net_3(pkt, &resplen) + || PACKET_remaining(pkt) != resplen) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1645,7 +1607,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n) SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_MALLOC_FAILURE); goto f_err; } - if (!PACKET_copy_bytes(&pkt, s->tlsext_ocsp_resp, resplen)) { + if (!PACKET_copy_bytes(pkt, s->tlsext_ocsp_resp, resplen)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1672,9 +1634,9 @@ enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n) return MSG_PROCESS_ERROR; } -enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, unsigned long n) +enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) { - if (n > 0) { + if (PACKET_remaining(pkt) > 0) { /* should contain no data */ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, SSL_R_LENGTH_MISMATCH); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 85601b09f6..4442223282 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -204,7 +204,7 @@ int tls_construct_hello_request(SSL *s) return 1; } -enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) { int i, al = SSL_AD_INTERNAL_ERROR; unsigned int j, complen = 0; @@ -216,15 +216,9 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) STACK_OF(SSL_CIPHER) *ciphers = NULL; int protverr = 1; /* |cookie| will only be initialized for DTLS. */ - PACKET pkt, session_id, cipher_suites, compression, extensions, cookie; + PACKET session_id, cipher_suites, compression, extensions, cookie; int is_v2_record; - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - is_v2_record = RECORD_LAYER_is_sslv2_record(&s->rlayer); PACKET_null_init(&cookie); @@ -247,7 +241,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) * ... ... */ - if (!PACKET_get_1(&pkt, &mt) + if (!PACKET_get_1(pkt, &mt) || mt != SSL2_MT_CLIENT_HELLO) { /* * Should never happen. We should have tested this in the record @@ -258,7 +252,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) goto err; } - if (!PACKET_get_net_2(&pkt, &version)) { + if (!PACKET_get_net_2(pkt, &version)) { /* No protocol version supplied! */ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); goto err; @@ -280,7 +274,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) * use version from inside client hello, not from record header (may * differ: see RFC 2246, Appendix E, second paragraph) */ - if(!PACKET_get_net_2(&pkt, (unsigned int *)&s->client_version)) { + if(!PACKET_get_net_2(pkt, (unsigned int *)&s->client_version)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -365,20 +359,20 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) unsigned int cipher_len, session_id_len, challenge_len; PACKET challenge; - if (!PACKET_get_net_2(&pkt, &cipher_len) - || !PACKET_get_net_2(&pkt, &session_id_len) - || !PACKET_get_net_2(&pkt, &challenge_len)) { + if (!PACKET_get_net_2(pkt, &cipher_len) + || !PACKET_get_net_2(pkt, &session_id_len) + || !PACKET_get_net_2(pkt, &challenge_len)) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; } - if (!PACKET_get_sub_packet(&pkt, &cipher_suites, cipher_len) - || !PACKET_get_sub_packet(&pkt, &session_id, session_id_len) - || !PACKET_get_sub_packet(&pkt, &challenge, challenge_len) + if (!PACKET_get_sub_packet(pkt, &cipher_suites, cipher_len) + || !PACKET_get_sub_packet(pkt, &session_id, session_id_len) + || !PACKET_get_sub_packet(pkt, &challenge, challenge_len) /* No extensions. */ - || PACKET_remaining(&pkt) != 0) { + || PACKET_remaining(pkt) != 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -400,15 +394,15 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) PACKET_null_init(&extensions); } else { /* Regular ClientHello. */ - if (!PACKET_copy_bytes(&pkt, s->s3->client_random, SSL3_RANDOM_SIZE) - || !PACKET_get_length_prefixed_1(&pkt, &session_id)) { + if (!PACKET_copy_bytes(pkt, s->s3->client_random, SSL3_RANDOM_SIZE) + || !PACKET_get_length_prefixed_1(pkt, &session_id)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; } if (SSL_IS_DTLS(s)) { - if (!PACKET_get_length_prefixed_1(&pkt, &cookie)) { + if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -424,14 +418,14 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n) } } - if (!PACKET_get_length_prefixed_2(&pkt, &cipher_suites) - || !PACKET_get_length_prefixed_1(&pkt, &compression)) { + if (!PACKET_get_length_prefixed_2(pkt, &cipher_suites) + || !PACKET_get_length_prefixed_1(pkt, &compression)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; } /* Could be empty. */ - extensions = pkt; + extensions = *pkt; } s->hit = 0; @@ -1497,7 +1491,7 @@ int tls_construct_certificate_request(SSL *s) return 0; } -enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { int al; unsigned int i; @@ -1516,15 +1510,9 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) EC_POINT *clnt_ecpoint = NULL; BN_CTX *bn_ctx = NULL; #endif - PACKET pkt, enc_premaster; + PACKET enc_premaster; unsigned char *data, *rsa_decrypt = NULL; - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto f_err; - } - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; #ifndef OPENSSL_NO_PSK @@ -1532,9 +1520,9 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) if (alg_k & SSL_PSK) { unsigned char psk[PSK_MAX_PSK_LEN]; size_t psklen; - PACKET psk_identity; + PACKET psk_identity; - if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity)) { + if (!PACKET_get_length_prefixed_2(pkt, &psk_identity)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1589,7 +1577,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) } if (alg_k & SSL_kPSK) { /* Identity extracted earlier: should be nothing left */ - if (PACKET_remaining(&pkt) != 0) { + if (PACKET_remaining(pkt) != 0) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1637,11 +1625,11 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) /* SSLv3 and pre-standard DTLS omit the length bytes. */ if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) { - enc_premaster = pkt; + enc_premaster = *pkt; } else { - PACKET orig = pkt; - if (!PACKET_get_length_prefixed_2(&pkt, &enc_premaster) - || PACKET_remaining(&pkt) != 0) { + PACKET orig = *pkt; + if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster) + || PACKET_remaining(pkt) != 0) { /* Try SSLv3 behaviour for TLS. */ if (s->options & SSL_OP_TLS_D5_BUG) { enc_premaster = orig; @@ -1764,10 +1752,10 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) { int idx = -1; EVP_PKEY *skey = NULL; - PACKET bookmark = pkt; + PACKET bookmark = *pkt; unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8]; - if (!PACKET_get_net_2(&pkt, &i)) { + if (!PACKET_get_net_2(pkt, &i)) { if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, @@ -1776,14 +1764,14 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) } i = 0; } - if (PACKET_remaining(&pkt) != i) { + if (PACKET_remaining(pkt) != i) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); goto err; } else { - pkt = bookmark; - i = PACKET_remaining(&pkt); + *pkt = bookmark; + i = PACKET_remaining(pkt); } } if (alg_k & SSL_kDHr) @@ -1808,7 +1796,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) } else dh_srvr = s->s3->tmp.dh; - if (n == 0L) { + if (PACKET_remaining(pkt) == 0L) { /* Get pubkey from cert */ EVP_PKEY *clkey = X509_get_pubkey(s->session->peer); if (clkey) { @@ -1824,7 +1812,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) EVP_PKEY_free(clkey); pub = dh_clnt->pub_key; } else { - if (!PACKET_get_bytes(&pkt, &data, i)) { + if (!PACKET_get_bytes(pkt, &data, i)) { /* We already checked we have enough data */ al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, @@ -1906,7 +1894,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) goto err; } - if (n == 0L) { + if (PACKET_remaining(pkt) == 0L) { /* Client Publickey was in Client Certificate */ if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { @@ -1950,14 +1938,14 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) } /* Get encoded point length */ - if (!PACKET_get_1(&pkt, &i)) { + if (!PACKET_get_1(pkt, &i)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if (!PACKET_get_bytes(&pkt, &data, i) - || PACKET_remaining(&pkt) != 0) { + if (!PACKET_get_bytes(pkt, &data, i) + || PACKET_remaining(pkt) != 0) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } @@ -2003,8 +1991,8 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) #endif #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { - if (!PACKET_get_net_2(&pkt, &i) - || !PACKET_get_bytes(&pkt, &data, i)) { + if (!PACKET_get_net_2(pkt, &i) + || !PACKET_get_bytes(pkt, &data, i)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BAD_SRP_A_LENGTH); goto f_err; @@ -2041,6 +2029,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) unsigned long alg_a; int Ttag, Tclass; long Tlen; + long sess_key_len; /* Get our certificate private key */ alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -2061,14 +2050,15 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n) ERR_clear_error(); } /* Decrypt session key */ - if (!PACKET_get_bytes(&pkt, &data, n)) { + sess_key_len = PACKET_remaining(pkt); + if (!PACKET_get_bytes(pkt, &data, sess_key_len)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; } - if (ASN1_get_object - ((const unsigned char **)&data, &Tlen, &Ttag, &Tclass, - n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE + if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag, + &Tclass, sess_key_len) != V_ASN1_CONSTRUCTED + || Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); @@ -2239,7 +2229,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, return WORK_FINISHED_CONTINUE; } -enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) { EVP_PKEY *pkey = NULL; unsigned char *sig, *data; @@ -2249,7 +2239,6 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n) X509 *peer; const EVP_MD *md = NULL; EVP_MD_CTX mctx; - PACKET pkt; EVP_MD_CTX_init(&mctx); peer = s->session->peer; @@ -2263,24 +2252,18 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n) goto f_err; } - /* we now have a signature that we need to verify */ - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } /* Check for broken implementations of GOST ciphersuites */ /* * If key is GOST and n is exactly 64, it is bare signature without * length field */ - if (n == 64 && pkey->type == NID_id_GostR3410_2001) { + if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) { len = 64; } else { if (SSL_USE_SIGALGS(s)) { int rv; - if (!PACKET_get_bytes(&pkt, &sig, 2)) { + if (!PACKET_get_bytes(pkt, &sig, 2)) { al = SSL_AD_DECODE_ERROR; goto f_err; } @@ -2296,19 +2279,20 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n) fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif } - if (!PACKET_get_net_2(&pkt, &len)) { + if (!PACKET_get_net_2(pkt, &len)) { SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; } } j = EVP_PKEY_size(pkey); - if (((int)len > j) || ((int)PACKET_remaining(&pkt) > j) || (n <= 0)) { + if (((int)len > j) || ((int)PACKET_remaining(pkt) > j) + || (PACKET_remaining(pkt) == 0)) { SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); al = SSL_AD_DECODE_ERROR; goto f_err; } - if (!PACKET_get_bytes(&pkt, &data, len)) { + if (!PACKET_get_bytes(pkt, &data, len)) { SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -2421,7 +2405,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n) return ret; } -enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) { int i, al, ret = MSG_PROCESS_ERROR; X509 *x = NULL; @@ -2429,22 +2413,16 @@ enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n) const unsigned char *certstart; unsigned char *certbytes; STACK_OF(X509) *sk = NULL; - PACKET pkt, spkt; - - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); - goto f_err; - } + PACKET spkt; if ((sk = sk_X509_new_null()) == NULL) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto f_err; } - if (!PACKET_get_net_3(&pkt, &llen) - || !PACKET_get_sub_packet(&pkt, &spkt, llen) - || PACKET_remaining(&pkt) != 0) { + if (!PACKET_get_net_3(pkt, &llen) + || !PACKET_get_sub_packet(pkt, &spkt, llen) + || PACKET_remaining(pkt) != 0) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -2748,20 +2726,11 @@ int tls_construct_cert_status(SSL *s) * tls_process_next_proto reads a Next Protocol Negotiation handshake message. * It sets the next_proto member in s if found */ -enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n) +enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) { - PACKET pkt, next_proto, padding; + PACKET next_proto, padding; size_t next_proto_len; - if (n < 2) { - goto err; /* The body must be > 1 bytes long */ - } - - if (!PACKET_buf_init(&pkt, s->init_msg, n)) { - SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, ERR_R_INTERNAL_ERROR); - goto err; - } - /*- * The payload looks like: * uint8 proto_len; @@ -2769,9 +2738,9 @@ enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n) * uint8 padding_len; * uint8 padding[padding_len]; */ - if (!PACKET_get_length_prefixed_1(&pkt, &next_proto) - || !PACKET_get_length_prefixed_1(&pkt, &padding) - || PACKET_remaining(&pkt) > 0) { + if (!PACKET_get_length_prefixed_1(pkt, &next_proto) + || !PACKET_get_length_prefixed_1(pkt, &padding) + || PACKET_remaining(pkt) > 0) { SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, SSL_R_LENGTH_MISMATCH); goto err; } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index faee32fa5f..cbc4f598d3 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -118,6 +118,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { "dtls_construct_hello_verify_request"}, {ERR_FUNC(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE), "DTLS_GET_REASSEMBLED_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS_PROCESS_HELLO_VERIFY), "dtls_process_hello_verify"}, {ERR_FUNC(SSL_F_READ_STATE_MACHINE), "READ_STATE_MACHINE"}, {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"}, {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, @@ -524,6 +525,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { "invalid ticket keys length"}, {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"}, {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"}, + {ERR_REASON(SSL_R_LENGTH_TOO_LONG), "length too long"}, {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"}, {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"}, {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 4c51b0e92c..0833ed2475 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2003,8 +2003,9 @@ void ssl3_init_finished_mac(SSL *s); __owur int tls_construct_server_certificate(SSL *s); __owur int tls_construct_new_session_ticket(SSL *s); __owur int tls_construct_cert_status(SSL *s); -__owur enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n); -__owur enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n); +__owur enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, + PACKET *pkt); +__owur enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt); __owur int ssl3_setup_key_block(SSL *s); __owur int tls_construct_change_cipher_spec(SSL *s); __owur int dtls_construct_change_cipher_spec(SSL *s); @@ -2106,13 +2107,13 @@ void dtls1_hm_fragment_free(hm_fragment *frag); /* some client-only functions */ __owur int tls_construct_client_hello(SSL *s); __owur enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, - unsigned long n); + PACKET *pkt); __owur enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, - unsigned long n); + PACKET *pkt); __owur enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, - unsigned long n); -__owur enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n); -__owur enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, unsigned long n); + PACKET *pkt); +__owur enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt); +__owur enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt); __owur int tls_construct_client_verify(SSL *s); __owur enum WORK_STATE tls_prepare_client_certificate(SSL *s, enum WORK_STATE wst); @@ -2121,18 +2122,17 @@ __owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); __owur int tls_construct_client_key_exchange(SSL *s); __owur int tls_client_key_exchange_post_work(SSL *s); __owur enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, - unsigned long n); + PACKET *pkt); __owur enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, - unsigned long n); + PACKET *pkt); __owur int ssl3_check_cert_and_algorithm(SSL *s); # ifndef OPENSSL_NO_NEXTPROTONEG __owur int tls_construct_next_proto(SSL *s); # endif -__owur enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, - unsigned long n); +__owur enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt); /* some server-only functions */ -__owur enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n); +__owur enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt); __owur enum WORK_STATE tls_post_process_client_hello(SSL *s, enum WORK_STATE wst); __owur int tls_construct_server_hello(SSL *s); @@ -2141,13 +2141,15 @@ __owur int dtls_construct_hello_verify_request(SSL *s); __owur int tls_construct_server_key_exchange(SSL *s); __owur int tls_construct_certificate_request(SSL *s); __owur int tls_construct_server_done(SSL *s); -__owur enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n); -__owur enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n); +__owur enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, + PACKET *pkt); +__owur enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, + PACKET *pkt); __owur enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, enum WORK_STATE wst); -__owur enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n); +__owur enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt); # ifndef OPENSSL_NO_NEXTPROTONEG -__owur enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n); +__owur enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); # endif __owur int tls1_new(SSL *s); diff --git a/ssl/statem.c b/ssl/statem.c index ad44c5f86d..81af75c4d5 100644 --- a/ssl/statem.c +++ b/ssl/statem.c @@ -116,8 +116,7 @@ static enum WORK_STATE client_pre_work(SSL *s, enum WORK_STATE wst); static enum WORK_STATE client_post_work(SSL *s, enum WORK_STATE wst); static int client_construct_message(SSL *s); static unsigned long client_max_message_size(SSL *s); -static enum MSG_PROCESS_RETURN client_process_message(SSL *s, - unsigned long len); +static enum MSG_PROCESS_RETURN client_process_message(SSL *s, PACKET *pkt); static enum WORK_STATE client_post_process_message(SSL *s, enum WORK_STATE wst); static int server_read_transition(SSL *s, int mt); static inline int send_server_key_exchange(SSL *s); @@ -127,7 +126,7 @@ static enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst); static enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst); static int server_construct_message(SSL *s); static unsigned long server_max_message_size(SSL *s); -static enum MSG_PROCESS_RETURN server_process_message(SSL *s, unsigned long len); +static enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt); static enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst); @@ -529,7 +528,8 @@ static enum SUB_STATE_RETURN read_state_machine(SSL *s) { int ret, mt; unsigned long len; int (*transition)(SSL *s, int mt); - enum MSG_PROCESS_RETURN (*process_message)(SSL *s, unsigned long n); + PACKET pkt; + enum MSG_PROCESS_RETURN (*process_message)(SSL *s, PACKET *pkt); enum WORK_STATE (*post_process_message)(SSL *s, enum WORK_STATE wst); unsigned long (*max_message_size)(SSL *s); void (*cb) (const SSL *ssl, int type, int val) = NULL; @@ -612,7 +612,12 @@ static enum SUB_STATE_RETURN read_state_machine(SSL *s) { } s->first_packet = 0; - ret = process_message(s, len); + if (!PACKET_buf_init(&pkt, s->init_msg, len)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_INTERNAL_ERROR); + return SUB_STATE_ERROR; + } + ret = process_message(s, &pkt); if (ret == MSG_PROCESS_ERROR) { return SUB_STATE_ERROR; } @@ -1444,40 +1449,40 @@ static unsigned long client_max_message_size(SSL *s) /* * Process a message that the client has been received from the server. */ -static enum MSG_PROCESS_RETURN client_process_message(SSL *s, unsigned long len) +static enum MSG_PROCESS_RETURN client_process_message(SSL *s, PACKET *pkt) { STATEM *st = &s->statem; switch(st->hand_state) { case TLS_ST_CR_SRVR_HELLO: - return tls_process_server_hello(s, len); + return tls_process_server_hello(s, pkt); case DTLS_ST_CR_HELLO_VERIFY_REQUEST: - return dtls_process_hello_verify(s, len); + return dtls_process_hello_verify(s, pkt); case TLS_ST_CR_CERT: - return tls_process_server_certificate(s, len); + return tls_process_server_certificate(s, pkt); case TLS_ST_CR_CERT_STATUS: - return tls_process_cert_status(s, len); + return tls_process_cert_status(s, pkt); case TLS_ST_CR_KEY_EXCH: - return tls_process_key_exchange(s, len); + return tls_process_key_exchange(s, pkt); case TLS_ST_CR_CERT_REQ: - return tls_process_certificate_request(s, len); + return tls_process_certificate_request(s, pkt); case TLS_ST_CR_SRVR_DONE: - return tls_process_server_done(s, len); + return tls_process_server_done(s, pkt); case TLS_ST_CR_CHANGE: - return tls_process_change_cipher_spec(s, len); + return tls_process_change_cipher_spec(s, pkt); case TLS_ST_CR_SESSION_TICKET: - return tls_process_new_session_ticket(s, len); + return tls_process_new_session_ticket(s, pkt); case TLS_ST_CR_FINISHED: - return tls_process_finished(s, len); + return tls_process_finished(s, pkt); default: /* Shouldn't happen */ @@ -2161,34 +2166,33 @@ static unsigned long server_max_message_size(SSL *s) /* * Process a message that the server has received from the client. */ -static enum MSG_PROCESS_RETURN server_process_message(SSL *s, - unsigned long len) +static enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt) { STATEM *st = &s->statem; switch(st->hand_state) { case TLS_ST_SR_CLNT_HELLO: - return tls_process_client_hello(s, len); + return tls_process_client_hello(s, pkt); case TLS_ST_SR_CERT: - return tls_process_client_certificate(s, len); + return tls_process_client_certificate(s, pkt); case TLS_ST_SR_KEY_EXCH: - return tls_process_client_key_exchange(s, len); + return tls_process_client_key_exchange(s, pkt); case TLS_ST_SR_CERT_VRFY: - return tls_process_cert_verify(s, len); + return tls_process_cert_verify(s, pkt); #ifndef OPENSSL_NO_NEXTPROTONEG case TLS_ST_SR_NEXT_PROTO: - return tls_process_next_proto(s, len); + return tls_process_next_proto(s, pkt); #endif case TLS_ST_SR_CHANGE: - return tls_process_change_cipher_spec(s, len); + return tls_process_change_cipher_spec(s, pkt); case TLS_ST_SR_FINISHED: - return tls_process_finished(s, len); + return tls_process_finished(s, pkt); default: /* Shouldn't happen */ -- 2.40.0