提交 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 { ...@@ -900,7 +900,8 @@ typedef enum {
TLS_ST_CW_KEY_UPDATE, TLS_ST_CW_KEY_UPDATE,
TLS_ST_SR_KEY_UPDATE, TLS_ST_SR_KEY_UPDATE,
TLS_ST_CR_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; } OSSL_HANDSHAKE_STATE;
/* /*
......
...@@ -1545,13 +1545,16 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) ...@@ -1545,13 +1545,16 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
return 0; return 0;
} }
if (s->early_data_state != SSL_EARLY_DATA_NONE if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) {
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
&& s->early_data_state != SSL_EARLY_DATA_READING) {
SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0; 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) { if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args; struct ssl_async_args args;
...@@ -1745,13 +1748,20 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) ...@@ -1745,13 +1748,20 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
return -1; return -1;
} }
if (s->early_data_state != SSL_EARLY_DATA_NONE if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING /*
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING * We're still writing early data. We need to stop that so we can write
&& s->early_data_state != SSL_EARLY_DATA_WRITING) { * 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); SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0; 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) { if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
int ret; int ret;
......
...@@ -168,6 +168,13 @@ int ossl_statem_skip_early_data(SSL *s) ...@@ -168,6 +168,13 @@ int ossl_statem_skip_early_data(SSL *s)
return 1; 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) void ossl_statem_set_hello_verify_done(SSL *s)
{ {
s->statem.state = MSG_FLOW_UNINITED; s->statem.state = MSG_FLOW_UNINITED;
......
...@@ -123,6 +123,7 @@ void ossl_statem_set_in_init(SSL *s, int init); ...@@ -123,6 +123,7 @@ void ossl_statem_set_in_init(SSL *s, int init);
int ossl_statem_get_in_handshake(SSL *s); int ossl_statem_get_in_handshake(SSL *s);
void ossl_statem_set_in_handshake(SSL *s, int inhand); void ossl_statem_set_in_handshake(SSL *s, int inhand);
__owur int ossl_statem_skip_early_data(SSL *s); __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); void ossl_statem_set_hello_verify_done(SSL *s);
__owur int ossl_statem_app_data_allowed(SSL *s); __owur int ossl_statem_app_data_allowed(SSL *s);
#ifndef OPENSSL_NO_SCTP #ifndef OPENSSL_NO_SCTP
......
...@@ -435,6 +435,14 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) ...@@ -435,6 +435,14 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
return WRITE_TRAN_CONTINUE; return WRITE_TRAN_CONTINUE;
case TLS_ST_CR_FINISHED: 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 st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
: TLS_ST_CW_FINISHED; : TLS_ST_CW_FINISHED;
return WRITE_TRAN_CONTINUE; return WRITE_TRAN_CONTINUE;
...@@ -659,6 +667,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) ...@@ -659,6 +667,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
break; break;
case TLS_ST_CW_EARLY_DATA: case TLS_ST_CW_EARLY_DATA:
case TLS_ST_CW_PENDING_EARLY_DATA_END:
case TLS_ST_OK: case TLS_ST_OK:
return tls_finish_handshake(s, wst, 1); return tls_finish_handshake(s, wst, 1);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册