提交 d781d247 编写于 作者: M Matt Caswell

Provide an SSL_read_early() function for reading early data

Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)
上级 6cb42265
......@@ -1611,6 +1611,12 @@ __owur int SSL_accept(SSL *ssl);
__owur int SSL_connect(SSL *ssl);
__owur int SSL_read(SSL *ssl, void *buf, int num);
__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
# define SSL_READ_EARLY_ERROR 0
# define SSL_READ_EARLY_SUCCESS 1
# define SSL_READ_EARLY_FINISH 2
__owur int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes);
__owur int SSL_peek(SSL *ssl, void *buf, int num);
__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
__owur int SSL_write(SSL *ssl, const void *buf, int num);
......@@ -2255,6 +2261,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_SSL_PEEK_EX 432
# define SSL_F_SSL_PEEK_INTERNAL 522
# define SSL_F_SSL_READ 223
# define SSL_F_SSL_READ_EARLY 529
# define SSL_F_SSL_READ_EX 434
# define SSL_F_SSL_READ_INTERNAL 523
# define SSL_F_SSL_RENEGOTIATE 516
......@@ -2330,7 +2337,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489
# define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466
# define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355
# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 521
# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530
# define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467
# define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468
# define SSL_F_TLS_CONSTRUCT_CTOS_ETM 469
......@@ -2669,6 +2676,7 @@ int ERR_load_SSL_strings(void);
# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239
# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242
# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243
# define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178
# define SSL_R_UNEXPECTED_MESSAGE 244
# define SSL_R_UNEXPECTED_RECORD 245
# define SSL_R_UNINITIALIZED 276
......
......@@ -1437,6 +1437,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION);
goto f_err;
} else if (alert_descr == SSL_AD_END_OF_EARLY_DATA) {
if (!ssl_end_of_early_data_seen(s)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_READ_BYTES,
SSL_R_UNEXPECTED_END_OF_EARLY_DATA);
goto f_err;
}
return 0;
}
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
......
......@@ -419,15 +419,15 @@ int ssl3_get_record(SSL *s)
/*-
* enc_err is:
* 0: (in non-constant time) if the record is publically invalid.
* 0: (in non-constant time) if the record is publicly invalid.
* 1: if the padding is valid
* -1: if the padding is invalid
*/
if (enc_err == 0) {
if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
/*
* We assume this is unreadable early_data - we treat it like an
* empty record
* Valid early_data that we cannot decrypt might fail here as
* publicly invalid. We treat it like an empty record.
*/
thisrr = &rr[0];
thisrr->length = 0;
......@@ -507,6 +507,17 @@ int ssl3_get_record(SSL *s)
}
if (enc_err < 0) {
if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
/*
* We assume this is unreadable early_data - we treat it like an
* empty record
*/
thisrr = &rr[0];
thisrr->length = 0;
thisrr->read = 1;
RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
return 1;
}
/*
* A separate 'decryption_failed' alert was introduced with TLS 1.0,
* SSL 3.0 only has 'bad_record_mac'. But unless a decryption
......
......@@ -205,6 +205,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_SSL_PEEK_EX), "SSL_peek_ex"},
{ERR_FUNC(SSL_F_SSL_PEEK_INTERNAL), "ssl_peek_internal"},
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
{ERR_FUNC(SSL_F_SSL_READ_EARLY), "SSL_read_early"},
{ERR_FUNC(SSL_F_SSL_READ_EX), "SSL_read_ex"},
{ERR_FUNC(SSL_F_SSL_READ_INTERNAL), "ssl_read_internal"},
{ERR_FUNC(SSL_F_SSL_RENEGOTIATE), "SSL_renegotiate"},
......@@ -793,6 +794,8 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
"unable to load ssl3 md5 routines"},
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),
"unable to load ssl3 sha1 routines"},
{ERR_REASON(SSL_R_UNEXPECTED_END_OF_EARLY_DATA),
"unexpected end of early data"},
{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
{ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"},
......
......@@ -1594,6 +1594,75 @@ int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
return ret;
}
int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes)
{
int ret;
if (!s->server) {
SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return SSL_READ_EARLY_ERROR;
}
/*
* TODO(TLS1.3): Somehow we need to check that we're not receiving too much
* data
*/
switch (s->early_data_state) {
case SSL_EARLY_DATA_NONE:
if (!SSL_in_before(s)) {
SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return SSL_READ_EARLY_ERROR;
}
/* fall through */
case SSL_EARLY_DATA_ACCEPT_RETRY:
s->early_data_state = SSL_EARLY_DATA_ACCEPTING;
ret = SSL_accept(s);
if (ret <= 0) {
/* NBIO or error */
s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY;
return SSL_READ_EARLY_ERROR;
}
/* fall through */
case SSL_EARLY_DATA_READ_RETRY:
if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
s->early_data_state = SSL_EARLY_DATA_READING;
ret = SSL_read_ex(s, buf, num, readbytes);
/*
* Record layer will call ssl_end_of_early_data_seen() if we see
* that alert - which updates the early_data_state to
* SSL_EARLY_DATA_FINISHED_READING
*/
if (ret > 0 || (ret <= 0 && s->early_data_state
!= SSL_EARLY_DATA_FINISHED_READING)) {
s->early_data_state = SSL_EARLY_DATA_READ_RETRY;
return ret > 0 ? SSL_READ_EARLY_SUCCESS : SSL_READ_EARLY_ERROR;
}
} else {
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
}
*readbytes = 0;
ossl_statem_set_in_init(s, 1);
return SSL_READ_EARLY_FINISH;
default:
SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return SSL_READ_EARLY_ERROR;
}
}
int ssl_end_of_early_data_seen(SSL *s)
{
if (s->early_data_state == SSL_EARLY_DATA_READING) {
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
return 1;
}
return 0;
}
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
if (s->handshake_func == NULL) {
......
......@@ -618,7 +618,12 @@ typedef enum {
SSL_EARLY_DATA_CONNECTING,
SSL_EARLY_DATA_WRITE_RETRY,
SSL_EARLY_DATA_WRITING,
SSL_EARLY_DATA_FINISHED_WRITING
SSL_EARLY_DATA_FINISHED_WRITING,
SSL_EARLY_DATA_ACCEPT_RETRY,
SSL_EARLY_DATA_ACCEPTING,
SSL_EARLY_DATA_READ_RETRY,
SSL_EARLY_DATA_READING,
SSL_EARLY_DATA_FINISHED_READING
} SSL_EARLY_DATA_STATE;
#define MAX_COMPRESSIONS_SIZE 255
......@@ -1987,6 +1992,7 @@ static ossl_inline int ssl_has_cert(const SSL *s, int idx)
# ifndef OPENSSL_UNIT_TEST
int ssl_end_of_early_data_seen(SSL *s);
__owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes);
__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written);
void ssl_clear_cipher_ctx(SSL *s);
......
......@@ -326,7 +326,8 @@ static int state_machine(SSL *s, int server)
}
if ((SSL_IS_FIRST_HANDSHAKE(s)
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING)
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING)
|| s->renegotiate) {
if (!tls_setup_handshake(s)) {
ossl_statem_set_error(s);
......
......@@ -1229,12 +1229,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
SSL_COMP *comp;
#endif
/*
* This is a real handshake so make sure we clean it up at the end. We set
* this here so that we are after any early_data
*/
s->statem.cleanuphand = 1;
if (!PACKET_get_net_2(pkt, &sversion)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
......
......@@ -654,6 +654,10 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
int al = SSL_AD_INTERNAL_ERROR;
size_t md_len;
/* This is a real handshake so make sure we clean it up at the end */
s->statem.cleanuphand = 1;
/* If this occurs, we have missed a message */
if (!SSL_IS_TLS13(s) && !s->s3->change_cipher_spec) {
al = SSL_AD_UNEXPECTED_MESSAGE;
......@@ -944,6 +948,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs)
s->d1->next_handshake_write_seq = 0;
dtls1_clear_received_buffer(s);
}
s->early_data_state = SSL_EARLY_DATA_NONE;
}
/*
......
......@@ -406,6 +406,10 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
return WRITE_TRAN_ERROR;
case TLS_ST_OK:
if (s->early_data_state == SSL_EARLY_DATA_FINISHED_READING) {
st->hand_state = TLS_ST_SW_FINISHED;
return WRITE_TRAN_FINISHED;
}
if (s->key_update != SSL_KEY_UPDATE_NONE) {
st->hand_state = TLS_ST_SW_KEY_UPDATE;
return WRITE_TRAN_CONTINUE;
......@@ -450,6 +454,11 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_FINISHED:
if (s->early_data_state == SSL_EARLY_DATA_ACCEPTING) {
st->hand_state = TLS_ST_OK;
ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
}
return WRITE_TRAN_FINISHED;
case TLS_ST_SR_FINISHED:
......@@ -1234,9 +1243,6 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
s->new_session = 1;
}
/* This is a real handshake so make sure we clean it up at the end */
s->statem.cleanuphand = 1;
/*
* First, parse the raw ClientHello data into the CLIENTHELLO_MSG structure.
*/
......
......@@ -430,3 +430,4 @@ SSL_get_max_early_data 430 1_1_1 EXIST::FUNCTION:
SSL_CTX_get_max_early_data 431 1_1_1 EXIST::FUNCTION:
SSL_write_early 432 1_1_1 EXIST::FUNCTION:
SSL_write_early_finish 433 1_1_1 EXIST::FUNCTION:
SSL_read_early 434 1_1_1 EXIST::FUNCTION:
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册