X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_clnt.c;h=abddc0ace375f7da3b69c3cc50785b28937d1ad4;hp=7053ef29baa22074d624864c79e1e8753f611452;hb=c19602b543562104b756aa6adec9bd5081207574;hpb=05b8486e47c50db658474f9a36eab91cd41d1a13;ds=sidebyside diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 7053ef29ba..abddc0ace3 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -60,6 +60,7 @@ #include #include +static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); static ossl_inline int cert_req_allowed(SSL *s); @@ -137,6 +138,17 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) default: break; + case TLS_ST_CW_CLNT_HELLO: + /* + * This must a ClientHello following a HelloRetryRequest, so the only + * thing we can get now is a ServerHello. + */ + if (mt == SSL3_MT_SERVER_HELLO) { + st->hand_state = TLS_ST_CR_SRVR_HELLO; + return 1; + } + break; + case TLS_ST_CR_SRVR_HELLO: if (mt == SSL3_MT_ENCRYPTED_EXTENSIONS) { st->hand_state = TLS_ST_CR_ENCRYPTED_EXTENSIONS; @@ -188,6 +200,10 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_SESSION_TICKET; return 1; } + if (mt == SSL3_MT_KEY_UPDATE) { + st->hand_state = TLS_ST_CR_KEY_UPDATE; + return 1; + } break; } @@ -210,8 +226,8 @@ int ossl_statem_client_read_transition(SSL *s, int mt) int ske_expected; /* - * Note that after a ClientHello we don't know what version we are going - * to negotiate yet, so we don't take this branch until later + * Note that after writing the first ClientHello we don't know what version + * we are going to negotiate yet, so we don't take this branch until later. */ if (SSL_IS_TLS13(s)) { if (!ossl_statem_client13_read_transition(s, mt)) @@ -234,6 +250,11 @@ int ossl_statem_client_read_transition(SSL *s, int mt) st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST; return 1; } + } else { + if (mt == SSL3_MT_HELLO_RETRY_REQUEST) { + st->hand_state = TLS_ST_CR_HELLO_RETRY_REQUEST; + return 1; + } } break; @@ -385,20 +406,23 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) OSSL_STATEM *st = &s->statem; /* - * TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time - * we will update this to look more like real TLSv1.3 - */ - - /* - * Note: There are no cases for TLS_ST_BEFORE or TLS_ST_CW_CLNT_HELLO, - * because we haven't negotiated TLSv1.3 yet at that point. They are - * handled by ossl_statem_client_write_transition(). + * Note: There are no cases for TLS_ST_BEFORE because we haven't negotiated + * TLSv1.3 yet at that point. They are handled by + * ossl_statem_client_write_transition(). */ switch (st->hand_state) { default: /* Shouldn't happen */ return WRITE_TRAN_ERROR; + case TLS_ST_CW_CLNT_HELLO: + /* We only hit this in the case of HelloRetryRequest */ + return WRITE_TRAN_FINISHED; + + case TLS_ST_CR_HELLO_RETRY_REQUEST: + st->hand_state = TLS_ST_CW_CLNT_HELLO; + return WRITE_TRAN_CONTINUE; + case TLS_ST_CR_FINISHED: st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT : TLS_ST_CW_FINISHED; @@ -414,6 +438,14 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) st->hand_state = TLS_ST_CW_FINISHED; return WRITE_TRAN_CONTINUE; + case TLS_ST_CR_KEY_UPDATE: + if (s->key_update != SSL_KEY_UPDATE_NONE) { + st->hand_state = TLS_ST_CW_KEY_UPDATE; + return WRITE_TRAN_CONTINUE; + } + /* Fall through */ + + case TLS_ST_CW_KEY_UPDATE: case TLS_ST_CR_SESSION_TICKET: case TLS_ST_CW_FINISHED: st->hand_state = TLS_ST_OK; @@ -421,7 +453,12 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_OK: - /* Just go straight to trying to read from the server */ + if (s->key_update != SSL_KEY_UPDATE_NONE) { + st->hand_state = TLS_ST_CW_KEY_UPDATE; + return WRITE_TRAN_CONTINUE; + } + + /* Try to read from the server instead */ return WRITE_TRAN_FINISHED; } } @@ -612,8 +649,6 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) /* * Perform any work that needs to be done after sending a message from the * client to the server. - case TLS_ST_SR_CERT_VRFY: - return SSL3_RT_MAX_PLAIN_LENGTH; */ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) { @@ -694,6 +729,13 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) return WORK_ERROR; } break; + + case TLS_ST_CW_KEY_UPDATE: + if (statem_flush(s) != 1) + return WORK_MORE_A; + if (!tls13_update_key(s, 1)) + return WORK_ERROR; + break; } return WORK_FINISHED_CONTINUE; @@ -755,6 +797,11 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, *confunc = tls_construct_finished; *mt = SSL3_MT_FINISHED; break; + + case TLS_ST_CW_KEY_UPDATE: + *confunc = tls_construct_key_update; + *mt = SSL3_MT_KEY_UPDATE; + break; } return 1; @@ -779,6 +826,9 @@ size_t ossl_statem_client_max_message_size(SSL *s) case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return HELLO_VERIFY_REQUEST_MAX_LENGTH; + case TLS_ST_CR_HELLO_RETRY_REQUEST: + return HELLO_RETRY_REQUEST_MAX_LENGTH; + case TLS_ST_CR_CERT: return s->max_cert_list; @@ -815,6 +865,9 @@ size_t ossl_statem_client_max_message_size(SSL *s) case TLS_ST_CR_ENCRYPTED_EXTENSIONS: return ENCRYPTED_EXTENSIONS_MAX_LENGTH; + + case TLS_ST_CR_KEY_UPDATE: + return KEY_UPDATE_MAX_LENGTH; } } @@ -836,6 +889,9 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return dtls_process_hello_verify(s, pkt); + case TLS_ST_CR_HELLO_RETRY_REQUEST: + return tls_process_hello_retry_request(s, pkt); + case TLS_ST_CR_CERT: return tls_process_server_certificate(s, pkt); @@ -868,6 +924,9 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) case TLS_ST_CR_ENCRYPTED_EXTENSIONS: return tls_process_encrypted_extensions(s, pkt); + + case TLS_ST_CR_KEY_UPDATE: + return tls_process_key_update(s, pkt); } } @@ -1046,7 +1105,9 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) return 0; } #ifndef OPENSSL_NO_COMP - if (ssl_allow_compression(s) && s->ctx->comp_methods) { + if (ssl_allow_compression(s) + && s->ctx->comp_methods + && (SSL_IS_DTLS(s) || s->s3->tmp.max_ver < TLS1_3_VERSION)) { int compnum = sk_SSL_COMP_num(s->ctx->comp_methods); for (i = 0; i < compnum; i++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); @@ -1193,7 +1254,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) context = SSL_IS_TLS13(s) ? EXT_TLS1_3_SERVER_HELLO : EXT_TLS1_2_SERVER_HELLO; - if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al)) + if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al, NULL)) goto f_err; s->hit = 0; @@ -1233,7 +1294,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) && master_key_length > 0) { s->session->master_key_length = master_key_length; s->session->cipher = pref_cipher ? - pref_cipher : ssl_get_cipher_by_char(s, cipherchars); + pref_cipher : ssl_get_cipher_by_char(s, cipherchars, 0); } else { SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR); al = SSL_AD_INTERNAL_ERROR; @@ -1292,7 +1353,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto f_err; } - c = ssl_get_cipher_by_char(s, cipherchars); + c = ssl_get_cipher_by_char(s, cipherchars, 0); if (c == NULL) { /* unknown cipher */ al = SSL_AD_ILLEGAL_PARAMETER; @@ -1432,6 +1493,52 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } +static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt) +{ + unsigned int sversion; + int errorcode; + RAW_EXTENSION *extensions = NULL; + int al; + PACKET extpkt; + + if (!PACKET_get_net_2(pkt, &sversion)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + s->hello_retry_request = 1; + + /* This will fail if it doesn't choose TLSv1.3+ */ + errorcode = ssl_choose_client_version(s, sversion); + if (errorcode != 0) { + al = SSL_AD_PROTOCOL_VERSION; + SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, errorcode); + goto f_err; + } + + if (!PACKET_as_length_prefixed_2(pkt, &extpkt)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_BAD_LENGTH); + goto f_err; + } + + if (!tls_collect_extensions(s, &extpkt, EXT_TLS1_3_HELLO_RETRY_REQUEST, + &extensions, &al, NULL) + || !tls_parse_all_extensions(s, EXT_TLS1_3_HELLO_RETRY_REQUEST, + extensions, NULL, 0, &al)) + goto f_err; + + OPENSSL_free(extensions); + + return MSG_PROCESS_FINISHED_READING; + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + ossl_statem_set_error(s); + OPENSSL_free(extensions); + return MSG_PROCESS_ERROR; +} + MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) { int al, i, ret = MSG_PROCESS_ERROR, exp_idx; @@ -1489,7 +1596,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) goto f_err; } if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE, - &rawexts, &al) + &rawexts, &al, NULL) || !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE, rawexts, x, chainidx, &al)) { OPENSSL_free(rawexts); @@ -1981,16 +2088,16 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) al = SSL_AD_DECODE_ERROR; goto err; } - md = s->s3->tmp.peer_md; #ifdef SSL_DEBUG fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif - } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { - md = EVP_md5_sha1(); - } else { - md = EVP_sha1(); + } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) { + al = SSL_AD_INTERNAL_ERROR; + goto err; } + md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx); + if (!PACKET_get_length_prefixed_2(pkt, &signature) || PACKET_remaining(pkt) != 0) { al = SSL_AD_DECODE_ERROR; @@ -2089,39 +2196,46 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) 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; + unsigned int i, name_len; X509_NAME *xn = NULL; - const unsigned char *data; const unsigned char *namestart, *namebytes; STACK_OF(X509_NAME) *ca_sk = NULL; + PACKET cadns; if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); goto err; } - /* get the certificate types */ - 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; - } - OPENSSL_free(s->cert->ctypes); - s->cert->ctypes = NULL; - if (ctype_num > SSL3_CT_NUMBER) { - /* If we exceed static buffer copy all to cert structure */ - s->cert->ctypes = OPENSSL_malloc(ctype_num); - if (s->cert->ctypes == NULL) { - SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + if (SSL_IS_TLS13(s)) { + PACKET reqctx; + + /* Free and zero certificate types: it is not present in TLS 1.3 */ + OPENSSL_free(s->s3->tmp.ctype); + s->s3->tmp.ctype = NULL; + s->s3->tmp.ctype_len = 0; + /* TODO(TLS1.3) need to process request context, for now ignore */ + if (!PACKET_get_length_prefixed_1(pkt, &reqctx)) { + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, + SSL_R_LENGTH_MISMATCH); + goto err; + } + } else { + PACKET ctypes; + + /* get the certificate types */ + if (!PACKET_get_length_prefixed_1(pkt, &ctypes)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, + SSL_R_LENGTH_MISMATCH); + goto err; + } + + if (!PACKET_memdup(&ctypes, &s->s3->tmp.ctype, &s->s3->tmp.ctype_len)) { + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } - memcpy(s->cert->ctypes, data, ctype_num); - s->cert->ctype_num = ctype_num; - ctype_num = SSL3_CT_NUMBER; } - for (i = 0; i < ctype_num; i++) - s->s3->tmp.ctype[i] = data[i]; if (SSL_USE_SIGALGS(s)) { PACKET sigalgs; @@ -2133,11 +2247,9 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) goto err; } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - s->s3->tmp.md[i] = NULL; + /* Clear certificate validity flags */ + for (i = 0; i < SSL_PKEY_NUM; i++) s->s3->tmp.valid_flags[i] = 0; - } if (!tls1_save_sigalgs(s, &sigalgs)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, @@ -2149,21 +2261,18 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); goto err; } - } else { - ssl_set_default_md(s); } /* get the CA RDNs */ - if (!PACKET_get_net_2(pkt, &list_len) - || PACKET_remaining(pkt) != list_len) { + if (!PACKET_get_length_prefixed_2(pkt, &cadns)) { 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(&cadns)) { + if (!PACKET_get_net_2(&cadns, &name_len) + || !PACKET_get_bytes(&cadns, &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); @@ -2191,10 +2300,26 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) } xn = NULL; } + /* TODO(TLS1.3) need to parse and process extensions, for now ignore */ + if (SSL_IS_TLS13(s)) { + PACKET reqexts; + + if (!PACKET_get_length_prefixed_2(pkt, &reqexts)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, + SSL_R_EXT_LENGTH_MISMATCH); + goto err; + } + } + + if (PACKET_remaining(pkt) != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); + goto err; + } /* we should setup a certificate to return.... */ s->s3->tmp.cert_req = 1; - s->s3->tmp.ctype_num = ctype_num; sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); s->s3->tmp.ca_names = ca_sk; ca_sk = NULL; @@ -2296,7 +2421,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) if (!PACKET_as_length_prefixed_2(pkt, &extpkt) || !tls_collect_extensions(s, &extpkt, EXT_TLS1_3_NEW_SESSION_TICKET, - &exts, &al) + &exts, &al, NULL) || !tls_parse_all_extensions(s, EXT_TLS1_3_NEW_SESSION_TICKET, exts, NULL, 0, &al)) { SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_BAD_EXTENSION); @@ -2629,12 +2754,6 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt, int *al) } EVP_PKEY_CTX_free(pctx); pctx = NULL; -# ifdef PKCS1_CHECK - if (s->options & SSL_OP_PKCS1_CHECK_1) - (*p)[1]++; - if (s->options & SSL_OP_PKCS1_CHECK_2) - tmp_buf[0] = 0x70; -# endif /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION && !WPACKET_close(pkt)) { @@ -3013,10 +3132,8 @@ int tls_client_key_exchange_post_work(SSL *s) */ static int ssl3_check_client_certificate(SSL *s) { - if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) - return 0; /* If no suitable signature algorithm can't use certificate */ - if (SSL_USE_SIGALGS(s) && !s->s3->tmp.md[s->cert->key - s->cert->pkeys]) + if (!tls_choose_sigalg(s, NULL) || s->s3->tmp.sigalg == NULL) return 0; /* * If strict mode check suitability of chain before using it. This also @@ -3261,7 +3378,7 @@ static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt) } if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS, - &rawexts, &al) + &rawexts, &al, NULL) || !tls_parse_all_extensions(s, EXT_TLS1_3_ENCRYPTED_EXTENSIONS, rawexts, NULL, 0, &al)) goto err;