Delay flush until after CCS with early_data

Normally we flush immediately after writing the ClientHello. However if
we are going to write a CCS immediately because we've got early_data to
come, then we should move the flush until after the CCS.

Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/4701)
This commit is contained in:
Matt Caswell 2017-11-30 11:28:26 +00:00
parent 7b0a3ce0f9
commit 5cc807da25
2 changed files with 22 additions and 17 deletions

View File

@ -1664,9 +1664,9 @@ int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context,
* TLSv1.3, therefore we shouldn't be getting an HRR for anything else. * TLSv1.3, therefore we shouldn't be getting an HRR for anything else.
*/ */
if (version != TLS1_3_VERSION) { if (version != TLS1_3_VERSION) {
*al = SSL_AD_PROTOCOL_VERSION; SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
SSLerr(SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS, SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS,
SSL_R_BAD_HRR_VERSION); SSL_R_BAD_HRR_VERSION);
return 0; return 0;
} }
return 1; return 1;

View File

@ -679,27 +679,30 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
break; break;
case TLS_ST_CW_CLNT_HELLO: case TLS_ST_CW_CLNT_HELLO:
if (wst == WORK_MORE_A && statem_flush(s) != 1)
return WORK_MORE_A;
if (SSL_IS_DTLS(s)) {
/* Treat the next message as the first packet */
s->first_packet = 1;
}
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
&& s->max_early_data > 0 && s->max_early_data > 0) {
&& (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) {
/* /*
* We haven't selected TLSv1.3 yet so we don't call the change * We haven't selected TLSv1.3 yet so we don't call the change
* cipher state function associated with the SSL_METHOD. Instead * cipher state function associated with the SSL_METHOD. Instead
* we call tls13_change_cipher_state() directly. * we call tls13_change_cipher_state() directly.
*/ */
if (!tls13_change_cipher_state(s, if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) {
SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { if (!statem_flush(s))
/* SSLfatal() already called */ return WORK_MORE_A;
return WORK_ERROR; if (!tls13_change_cipher_state(s,
SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
/* SSLfatal() already called */
return WORK_ERROR;
}
} }
/* else we're in compat mode so we delay flushing until after CCS */
} else if (!statem_flush(s)) {
return WORK_MORE_A;
}
if (SSL_IS_DTLS(s)) {
/* Treat the next message as the first packet */
s->first_packet = 1;
} }
break; break;
@ -724,6 +727,8 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
break; break;
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
&& s->max_early_data > 0) { && s->max_early_data > 0) {
if (statem_flush(s) != 1)
return WORK_MORE_A;
/* /*
* We haven't selected TLSv1.3 yet so we don't call the change * We haven't selected TLSv1.3 yet so we don't call the change
* cipher state function associated with the SSL_METHOD. Instead * cipher state function associated with the SSL_METHOD. Instead