提交 564547e4 编写于 作者: M Matt Caswell

Enable the client to call SSL_read() without stopping the ability to call SSL_write_early()

Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)
上级 4004ce5f
......@@ -900,7 +900,8 @@ typedef enum {
TLS_ST_CW_KEY_UPDATE,
TLS_ST_SR_KEY_UPDATE,
TLS_ST_CR_KEY_UPDATE,
TLS_ST_CW_EARLY_DATA
TLS_ST_CW_EARLY_DATA,
TLS_ST_CW_PENDING_EARLY_DATA_END
} OSSL_HANDSHAKE_STATE;
/*
......
......@@ -1545,13 +1545,16 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
return 0;
}
if (s->early_data_state != SSL_EARLY_DATA_NONE
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
&& s->early_data_state != SSL_EARLY_DATA_READING) {
if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
|| s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) {
SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
/*
* If we are a client and haven't received the ServerHello etc then we
* better do that
*/
ossl_statem_check_finish_init(s, 0);
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
......@@ -1745,13 +1748,20 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
return -1;
}
if (s->early_data_state != SSL_EARLY_DATA_NONE
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
&& s->early_data_state != SSL_EARLY_DATA_WRITING) {
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
/*
* We're still writing early data. We need to stop that so we can write
* normal data
*/
if (!SSL_write_early_finish(s))
return 0;
} else if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
|| s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) {
SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
/* If we are a client and haven't sent the Finished we better do that */
ossl_statem_check_finish_init(s, 1);
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
int ret;
......
......@@ -168,6 +168,13 @@ int ossl_statem_skip_early_data(SSL *s)
return 1;
}
void ossl_statem_check_finish_init(SSL *s, int send)
{
if ((send && s->statem.hand_state == TLS_ST_CW_PENDING_EARLY_DATA_END)
|| (!send && s->statem.hand_state == TLS_ST_CW_EARLY_DATA))
ossl_statem_set_in_init(s, 1);
}
void ossl_statem_set_hello_verify_done(SSL *s)
{
s->statem.state = MSG_FLOW_UNINITED;
......
......@@ -123,6 +123,7 @@ void ossl_statem_set_in_init(SSL *s, int init);
int ossl_statem_get_in_handshake(SSL *s);
void ossl_statem_set_in_handshake(SSL *s, int inhand);
__owur int ossl_statem_skip_early_data(SSL *s);
void ossl_statem_check_finish_init(SSL *s, int send);
void ossl_statem_set_hello_verify_done(SSL *s);
__owur int ossl_statem_app_data_allowed(SSL *s);
#ifndef OPENSSL_NO_SCTP
......
......@@ -435,6 +435,14 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
return WRITE_TRAN_CONTINUE;
case TLS_ST_CR_FINISHED:
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY)
st->hand_state = TLS_ST_CW_PENDING_EARLY_DATA_END;
else
st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
: TLS_ST_CW_FINISHED;
return WRITE_TRAN_CONTINUE;
case TLS_ST_CW_PENDING_EARLY_DATA_END:
st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
: TLS_ST_CW_FINISHED;
return WRITE_TRAN_CONTINUE;
......@@ -659,6 +667,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
break;
case TLS_ST_CW_EARLY_DATA:
case TLS_ST_CW_PENDING_EARLY_DATA_END:
case TLS_ST_OK:
return tls_finish_handshake(s, wst, 1);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册