return WRITE_TRAN_FINISHED;
case TLS_ST_CR_SRVR_HELLO:
- /* We only get here in TLSv1.3 */
- st->hand_state = TLS_ST_CW_CLNT_HELLO;
+ /*
+ * We only get here in TLSv1.3. We just received an HRR, so issue a
+ * CCS unless middlebox compat mode is off, or we already issued one
+ * because we did early data.
+ */
+ if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
+ && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING)
+ st->hand_state = TLS_ST_CW_CHANGE;
+ else
+ st->hand_state = TLS_ST_CW_CLNT_HELLO;
return WRITE_TRAN_CONTINUE;
case TLS_ST_EARLY_DATA:
return WRITE_TRAN_CONTINUE;
case TLS_ST_CW_CHANGE:
- if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) {
+ if (s->hello_retry_request == SSL_HRR_PENDING) {
+ st->hand_state = TLS_ST_CW_CLNT_HELLO;
+ } else if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) {
st->hand_state = TLS_ST_EARLY_DATA;
} else {
#if defined(OPENSSL_NO_NEXTPROTONEG)
break;
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
- && s->max_early_data > 0
- && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) {
+ && s->max_early_data > 0) {
/*
* We haven't selected TLSv1.3 yet so we don't call the change
* cipher state function associated with the SSL_METHOD. Instead
* we call tls13_change_cipher_state() directly.
*/
- if (!tls13_change_cipher_state(s,
- SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
- /* SSLfatal() already called */
- return WORK_ERROR;
+ if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) {
+ if (!statem_flush(s))
+ return WORK_MORE_A;
+ 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;
case TLS_ST_CW_CHANGE:
- if (SSL_IS_TLS13(s))
+ if (SSL_IS_TLS13(s) || s->hello_retry_request == SSL_HRR_PENDING)
break;
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
&& 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
* cipher state function associated with the SSL_METHOD. Instead