X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_srvr.c;h=919469faa09c486b4c79a0a99182e219cd541e29;hb=bd79bcb42bab120575fc398692b7b61b1c5e6ed2;hp=259be22106f155e67e99bdc644c65c0bfb9703bb;hpb=ef6c191bceb7f09918cfd39e780759c32afb2396;p=openssl.git diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 259be22106..919469faa0 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -659,7 +659,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) case TLS_ST_SW_SRVR_HELLO: if (SSL_IS_DTLS(s)) { /* - * Messages we write from now on should be bufferred and + * Messages we write from now on should be buffered and * retransmitted if necessary, so we need to use the timer now */ st->use_timer = 1; @@ -1106,24 +1106,6 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) case TLS_ST_SR_KEY_EXCH: return tls_post_process_client_key_exchange(s, wst); - - case TLS_ST_SR_CERT_VRFY: -#ifndef OPENSSL_NO_SCTP - if ( /* Is this SCTP? */ - BIO_dgram_is_sctp(SSL_get_wbio(s)) - /* Are we renegotiating? */ - && s->renegotiate && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ossl_statem_set_sctp_read_sock(s, 1); - return WORK_MORE_A; - } else { - ossl_statem_set_sctp_read_sock(s, 0); - } -#endif - return WORK_FINISHED_CONTINUE; } return WORK_FINISHED_CONTINUE; } @@ -1442,7 +1424,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) /* Preserve the raw extensions PACKET for later use */ extensions = clienthello->extensions; - if (!tls_collect_extensions(s, &extensions, EXT_CLIENT_HELLO, + if (!tls_collect_extensions(s, &extensions, SSL_EXT_CLIENT_HELLO, &clienthello->pre_proc_exts, &al, &clienthello->pre_proc_exts_len)) { /* SSLerr already been called */ @@ -1476,6 +1458,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) STACK_OF(SSL_CIPHER) *ciphers = NULL; STACK_OF(SSL_CIPHER) *scsvs = NULL; CLIENTHELLO_MSG *clienthello = s->clienthello; + DOWNGRADE dgrd = DOWNGRADE_NONE; *al = SSL_AD_INTERNAL_ERROR; /* Finished parsing the ClientHello, now we can start processing it */ @@ -1516,7 +1499,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) * versions are potentially compatible. Version negotiation comes later. */ if (!SSL_IS_DTLS(s)) { - protverr = ssl_choose_server_version(s, clienthello); + protverr = ssl_choose_server_version(s, clienthello, &dgrd); } else if (s->method->version != DTLS_ANY_VERSION && DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) { protverr = SSL_R_VERSION_TOO_LOW; @@ -1534,6 +1517,14 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) goto err; } + /* TLSv1.3 specifies that a ClientHello must end on a record boundary */ + if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { + *al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, + SSL_R_NOT_ON_RECORD_BOUNDARY); + goto err; + } + if (SSL_IS_DTLS(s)) { /* Empty cookie was already handled above by returning early. */ if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { @@ -1557,7 +1548,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) s->d1->cookie_verified = 1; } if (s->method->version == DTLS_ANY_VERSION) { - protverr = ssl_choose_server_version(s, clienthello); + protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr != 0) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr); s->version = s->client_version; @@ -1571,7 +1562,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) /* We need to do this before getting the session */ if (!tls_parse_extension(s, TLSEXT_IDX_extended_master_secret, - EXT_CLIENT_HELLO, + SSL_EXT_CLIENT_HELLO, clienthello->pre_proc_exts, NULL, 0, al)) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); goto err; @@ -1699,7 +1690,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) #endif /* !OPENSSL_NO_EC */ /* TLS extensions */ - if (!tls_parse_all_extensions(s, EXT_CLIENT_HELLO, + if (!tls_parse_all_extensions(s, SSL_EXT_CLIENT_HELLO, clienthello->pre_proc_exts, NULL, 0, al)) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); goto err; @@ -1714,7 +1705,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) { unsigned char *pos; pos = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { + if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE, dgrd) <= 0) { goto err; } } @@ -1841,12 +1832,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher */ - if (!s->hit) { -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - s->session->compress_meth = (comp == NULL) ? 0 : comp->id; -#endif + if (!s->hit || s->hello_retry_request) { sk_SSL_CIPHER_free(s->session->ciphers); s->session->ciphers = ciphers; if (ciphers == NULL) { @@ -1855,6 +1841,14 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) goto err; } ciphers = NULL; + } + + if (!s->hit) { +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + s->session->compress_meth = (comp == NULL) ? 0 : comp->id; +#endif if (!tls1_set_server_sigalgs(s)) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); goto err; @@ -1943,7 +1937,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) wst = WORK_MORE_B; } if (wst == WORK_MORE_B) { - if (!s->hit) { + if (!s->hit || s->hello_retry_request) { /* Let cert callback update server certificates if required */ if (s->cert->cert_cb) { int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); @@ -1967,18 +1961,30 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) SSL_R_NO_SHARED_CIPHER); goto f_err; } - s->s3->tmp.new_cipher = cipher; - if (!tls_choose_sigalg(s, &al)) + if (SSL_IS_TLS13(s) && s->s3->tmp.new_cipher != NULL + && s->s3->tmp.new_cipher->id != cipher->id) { + /* + * A previous HRR picked a different ciphersuite to the one we + * just selected. Something must have changed. + */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_BAD_CIPHER); goto f_err; - /* check whether we should disable session resumption */ - if (s->not_resumable_session_cb != NULL) - s->session->not_resumable = - s->not_resumable_session_cb(s, ((cipher->algorithm_mkey - & (SSL_kDHE | SSL_kECDHE)) - != 0)); - if (s->session->not_resumable) - /* do not send a session ticket */ - s->ext.ticket_expected = 0; + } + s->s3->tmp.new_cipher = cipher; + if (!s->hit) { + if (!tls_choose_sigalg(s, &al)) + goto f_err; + /* check whether we should disable session resumption */ + if (s->not_resumable_session_cb != NULL) + s->session->not_resumable = + s->not_resumable_session_cb(s, ((cipher->algorithm_mkey + & (SSL_kDHE | SSL_kECDHE)) + != 0)); + if (s->session->not_resumable) + /* do not send a session ticket */ + s->ext.ticket_expected = 0; + } } else { /* Session-id reuse */ s->s3->tmp.new_cipher = s->session->cipher; @@ -2103,8 +2109,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) && !WPACKET_put_bytes_u8(pkt, compm)) || !tls_construct_extensions(s, pkt, SSL_IS_TLS13(s) - ? EXT_TLS1_3_SERVER_HELLO - : EXT_TLS1_2_SERVER_HELLO, + ? SSL_EXT_TLS1_3_SERVER_HELLO + : SSL_EXT_TLS1_2_SERVER_HELLO, NULL, 0, &al)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); goto err; @@ -2476,8 +2482,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) int tls_construct_certificate_request(SSL *s, WPACKET *pkt) { - int i; - STACK_OF(X509_NAME) *sk = NULL; + int al = SSL_AD_INTERNAL_ERROR; if (SSL_IS_TLS13(s)) { /* TODO(TLS1.3) for now send empty request context */ @@ -2486,14 +2491,22 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) ERR_R_INTERNAL_ERROR); goto err; } - } else { - /* get the list of acceptable cert types */ - if (!WPACKET_start_sub_packet_u8(pkt) - || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) { + + if (!tls_construct_extensions(s, pkt, + SSL_EXT_TLS1_3_CERTIFICATE_REQUEST, NULL, + 0, &al)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } + goto done; + } + + /* get the list of acceptable cert types */ + if (!WPACKET_start_sub_packet_u8(pkt) + || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); + goto err; } if (SSL_USE_SIGALGS(s)) { @@ -2510,49 +2523,16 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) } } - /* Start sub-packet for client CA list */ - if (!WPACKET_start_sub_packet_u16(pkt)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); - goto err; - } - - sk = SSL_get_client_CA_list(s); - if (sk != NULL) { - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - unsigned char *namebytes; - X509_NAME *name = sk_X509_NAME_value(sk, i); - int namelen; - - if (name == NULL - || (namelen = i2d_X509_NAME(name, NULL)) < 0 - || !WPACKET_sub_allocate_bytes_u16(pkt, namelen, - &namebytes) - || i2d_X509_NAME(name, &namebytes) != namelen) { - SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); - goto err; - } - } - } - /* else no CA names */ - if (!WPACKET_close(pkt)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); - goto err; - } - /* - * TODO(TLS1.3) implement configurable certificate_extensions - * For now just send zero length extensions. - */ - if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u16(pkt, 0)) { + if (!construct_ca_names(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } + done: s->s3->tmp.cert_request = 1; - return 1; err: - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, al); return 0; } @@ -3146,25 +3126,6 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); } - wst = WORK_MORE_B; - } - - if ((wst == WORK_MORE_B) - /* Is this SCTP? */ - && BIO_dgram_is_sctp(SSL_get_wbio(s)) - /* Are we renegotiating? */ - && s->renegotiate - /* Are we going to skip the CertificateVerify? */ - && (s->session->peer == NULL || s->statem.no_cert_verify) - && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ossl_statem_set_sctp_read_sock(s, 1); - return WORK_MORE_B; - } else { - ossl_statem_set_sctp_read_sock(s, 0); } #endif @@ -3254,9 +3215,10 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_BAD_LENGTH); goto f_err; } - if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE, - &rawexts, &al, NULL) - || !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE, + if (!tls_collect_extensions(s, &extensions, + SSL_EXT_TLS1_3_CERTIFICATE, &rawexts, + &al, NULL) + || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_CERTIFICATE, rawexts, x, chainidx, &al)) { OPENSSL_free(rawexts); goto f_err; @@ -3553,7 +3515,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) || !WPACKET_close(pkt) || (SSL_IS_TLS13(s) && !tls_construct_extensions(s, pkt, - EXT_TLS1_3_NEW_SESSION_TICKET, + SSL_EXT_TLS1_3_NEW_SESSION_TICKET, NULL, 0, &al))) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; @@ -3640,7 +3602,7 @@ static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt) { int al; - if (!tls_construct_extensions(s, pkt, EXT_TLS1_3_ENCRYPTED_EXTENSIONS, + if (!tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, NULL, 0, &al)) { ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS, ERR_R_INTERNAL_ERROR); @@ -3654,17 +3616,19 @@ static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt) static int tls_construct_hello_retry_request(SSL *s, WPACKET *pkt) { int al = SSL_AD_INTERNAL_ERROR; + size_t len = 0; /* * TODO(TLS1.3): Remove the DRAFT version before release * (should be s->version) */ if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT) - || !tls_construct_extensions(s, pkt, EXT_TLS1_3_HELLO_RETRY_REQUEST, + || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len) + || !tls_construct_extensions(s, pkt, + SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, NULL, 0, &al)) { SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST, ERR_R_INTERNAL_ERROR); - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; + goto err; } /* Ditch the session. We'll create a new one next time around */ @@ -3672,7 +3636,17 @@ static int tls_construct_hello_retry_request(SSL *s, WPACKET *pkt) s->session = NULL; s->hit = 0; + /* + * Re-initialise the Transcript Hash. We're going to prepopulate it with + * a synthetic message_hash in place of ClientHello1. + */ + if (!create_synthetic_message_hash(s)) + goto err; + return 1; + err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; } MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt)