X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_srvr.c;h=6bd16b879b8c11cdb44340ba540c796e3e2b0302;hp=c7841ac48efdb841383386c9537d5827b6dfba23;hb=fba7b84ca30dc809652e9f35f65e1d55c5b3c6e4;hpb=4bfe1432c8d82ffaa99c01085da0520b6090567d diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index c7841ac48e..6bd16b879b 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -903,16 +903,15 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) CLIENTHELLO_MSG clienthello; /* - * First step is to parse the raw ClientHello data into the CLIENTHELLO_MSG - * structure. + * First, parse the raw ClientHello data into the CLIENTHELLO_MSG structure. */ - + memset(&clienthello, 0, sizeof(clienthello)); clienthello.isv2 = RECORD_LAYER_is_sslv2_record(&s->rlayer); - PACKET_null_init(&cookie); if (clienthello.isv2) { unsigned int mt; + /*- * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 * header is sent directly on the wire, not wrapped as a TLS @@ -940,7 +939,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } } - if (!PACKET_get_net_2(pkt, &clienthello.version)) { + if (!PACKET_get_net_2(pkt, &clienthello.legacy_version)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto err; @@ -951,7 +950,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) /* * Handle an SSLv2 backwards compatible ClientHello * Note, this is only for SSLv3+ using the backward compatible format. - * Real SSLv2 is not supported, and is rejected above. + * Real SSLv2 is not supported, and is rejected below. */ unsigned int ciphersuite_len, session_id_len, challenge_len; PACKET challenge; @@ -964,7 +963,6 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) al = SSL_AD_DECODE_ERROR; goto f_err; } - clienthello.session_id_len = session_id_len; if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { al = SSL_AD_DECODE_ERROR; @@ -974,8 +972,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (!PACKET_get_sub_packet(pkt, &clienthello.ciphersuites, ciphersuite_len) - || !PACKET_get_sub_packet(pkt, &session_id, - clienthello.session_id_len) + || !PACKET_copy_bytes(pkt, clienthello.session_id, session_id_len) || !PACKET_get_sub_packet(pkt, &challenge, challenge_len) /* No extensions. */ || PACKET_remaining(pkt) != 0) { @@ -984,10 +981,15 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) al = SSL_AD_DECODE_ERROR; goto f_err; } + clienthello.session_id_len = session_id_len; - /* Load the client random and compression list. */ - challenge_len = challenge_len > SSL3_RANDOM_SIZE ? SSL3_RANDOM_SIZE : - challenge_len; + /* Load the client random and compression list. We use SSL3_RANDOM_SIZE + * here rather than sizeof(clienthello.random) because that is the limit + * for SSLv3 and it is fixed. It won't change even if + * sizeof(clienthello.random) does. + */ + challenge_len = challenge_len > SSL3_RANDOM_SIZE + ? SSL3_RANDOM_SIZE : challenge_len; memset(clienthello.random, 0, SSL3_RANDOM_SIZE); if (!PACKET_copy_bytes(&challenge, clienthello.random + SSL3_RANDOM_SIZE - @@ -1003,7 +1005,10 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } else { /* Regular ClientHello. */ if (!PACKET_copy_bytes(pkt, clienthello.random, SSL3_RANDOM_SIZE) - || !PACKET_get_length_prefixed_1(pkt, &session_id)) { + || !PACKET_get_length_prefixed_1(pkt, &session_id) + || !PACKET_copy_all(&session_id, clienthello.session_id, + SSL_MAX_SSL_SESSION_ID_LENGTH, + &clienthello.session_id_len)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -1058,18 +1063,16 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } if (!PACKET_copy_all(&compression, clienthello.compressions, - MAX_COMPRESSIONS_SIZE, &clienthello.compressions_len) - || !PACKET_copy_all(&session_id, clienthello.session_id, - SSL_MAX_SSL_SESSION_ID_LENGTH, - &clienthello.session_id_len)) { + MAX_COMPRESSIONS_SIZE, + &clienthello.compressions_len)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); goto f_err; } - /* We preserve the raw extensions PACKET for later use */ + /* Preserve the raw extensions PACKET for later use */ extensions = clienthello.extensions; - if (!tls_parse_raw_extensions(&extensions, &clienthello.pre_proc_exts, + if (!tls_collect_extensions(&extensions, &clienthello.pre_proc_exts, &clienthello.num_extensions, &al)) { /* SSLerr already been called */ goto f_err; @@ -1083,18 +1086,18 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) /* Choose the version */ if (clienthello.isv2) { - if (clienthello.version == 0x0002) { - /* This is real SSLv2. We don't support it. */ - SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } else if ((clienthello.version & 0xff00) == (SSL3_VERSION_MAJOR << 8)) { - /* SSLv3/TLS */ - s->client_version = clienthello.version; - } else { - /* No idea what protocol this is */ + if (clienthello.legacy_version == SSL2_VERSION + || (clienthello.legacy_version & 0xff00) + != (SSL3_VERSION_MAJOR << 8)) { + /* + * This is real SSLv2 or something complete unknown. We don't + * support it. + */ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); goto err; } + /* SSLv3/TLS */ + s->client_version = clienthello.legacy_version; } /* * Do SSL/TLS version negotiation if applicable. For DTLS we just check @@ -1103,7 +1106,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (!SSL_IS_DTLS(s)) { protverr = ssl_choose_server_version(s, &clienthello); } else if (s->method->version != DTLS_ANY_VERSION && - DTLS_VERSION_LT((int)clienthello.version, s->version)) { + DTLS_VERSION_LT((int)clienthello.legacy_version, s->version)) { protverr = SSL_R_VERSION_TOO_LOW; } else { protverr = 0; @@ -1112,11 +1115,8 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (protverr) { SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr); if ((!s->enc_write_ctx && !s->write_hash)) { - /* - * similar to ssl3_get_record, send alert using remote version - * number - */ - s->version = s->client_version = clienthello.version; + /* like ssl3_get_record, send alert using remote version number */ + s->version = s->client_version = clienthello.legacy_version; } al = SSL_AD_PROTOCOL_VERSION; goto f_err; @@ -1158,8 +1158,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) s->hit = 0; /* We need to do this before getting the session */ - if (!tls_check_client_ems_support(s, &clienthello)) - { + if (!tls_check_client_ems_support(s, &clienthello)) { /* Only fails if the extension is malformed */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); @@ -1210,7 +1209,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } } - if (ssl_bytes_to_cipher_list(s, &clienthello.ciphersuites, &(ciphers), + if (ssl_bytes_to_cipher_list(s, &clienthello.ciphersuites, &ciphers, clienthello.isv2, &al) == NULL) { goto f_err; } @@ -1423,6 +1422,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } sk_SSL_CIPHER_free(ciphers); + OPENSSL_free(clienthello.pre_proc_exts); return MSG_PROCESS_CONTINUE_PROCESSING; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); @@ -1430,8 +1430,9 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) ossl_statem_set_error(s); sk_SSL_CIPHER_free(ciphers); - return MSG_PROCESS_ERROR; + OPENSSL_free(clienthello.pre_proc_exts); + return MSG_PROCESS_ERROR; } WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)