mirror of
https://github.com/openssl/openssl.git
synced 2024-12-02 14:33:41 +08:00
Update end of early data processing for draft-19
The end of early data is now indicated by a new handshake message rather than an alert. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2895)
This commit is contained in:
parent
bc993d30fc
commit
ef6c191bce
@ -901,7 +901,9 @@ typedef enum {
|
||||
TLS_ST_SR_KEY_UPDATE,
|
||||
TLS_ST_CR_KEY_UPDATE,
|
||||
TLS_ST_EARLY_DATA,
|
||||
TLS_ST_PENDING_EARLY_DATA_END
|
||||
TLS_ST_PENDING_EARLY_DATA_END,
|
||||
TLS_ST_CW_END_OF_EARLY_DATA,
|
||||
TLS_ST_SR_END_OF_EARLY_DATA
|
||||
} OSSL_HANDSHAKE_STATE;
|
||||
|
||||
/*
|
||||
@ -1027,7 +1029,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR
|
||||
# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
|
||||
# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
|
||||
# define SSL_AD_END_OF_EARLY_DATA TLS13_AD_END_OF_EARLY_DATA
|
||||
# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION
|
||||
# define SSL_AD_CERTIFICATE_REQUIRED TLS13_AD_CERTIFICATE_REQUIRED
|
||||
# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
|
||||
@ -2373,6 +2374,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP 482
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_VERIFY 358
|
||||
# define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS 443
|
||||
# define SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA 536
|
||||
# define SSL_F_TLS_CONSTRUCT_EXTENSIONS 447
|
||||
# define SSL_F_TLS_CONSTRUCT_FINISHED 359
|
||||
# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST 373
|
||||
@ -2434,6 +2436,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_TLS_PROCESS_CLIENT_HELLO 381
|
||||
# define SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE 382
|
||||
# define SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS 444
|
||||
# define SSL_F_TLS_PROCESS_END_OF_EARLY_DATA 537
|
||||
# define SSL_F_TLS_PROCESS_FINISHED 364
|
||||
# define SSL_F_TLS_PROCESS_HELLO_REQ 507
|
||||
# define SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST 511
|
||||
|
@ -280,6 +280,7 @@ extern "C" {
|
||||
# define SSL3_MT_CLIENT_HELLO 1
|
||||
# define SSL3_MT_SERVER_HELLO 2
|
||||
# define SSL3_MT_NEWSESSION_TICKET 4
|
||||
# define SSL3_MT_END_OF_EARLY_DATA 5
|
||||
# define SSL3_MT_HELLO_RETRY_REQUEST 6
|
||||
# define SSL3_MT_ENCRYPTED_EXTENSIONS 8
|
||||
# define SSL3_MT_CERTIFICATE 11
|
||||
|
@ -904,7 +904,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
SSL3_RECORD_set_length(thiswr, len);
|
||||
}
|
||||
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITING
|
||||
|| s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
|
||||
/*
|
||||
* We haven't actually negotiated the version yet, but we're trying to
|
||||
* send early data - so we need to use the the tls13enc function.
|
||||
@ -1367,17 +1368,16 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
n = SSL3_RECORD_get_length(rr); /* available bytes */
|
||||
|
||||
/* now move 'n' bytes: */
|
||||
while (n-- > 0) {
|
||||
dest[(*dest_len)++] =
|
||||
SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
|
||||
SSL3_RECORD_add_off(rr, 1);
|
||||
SSL3_RECORD_add_length(rr, -1);
|
||||
}
|
||||
|
||||
if (*dest_len < dest_maxlen) {
|
||||
memcpy(dest + *dest_len,
|
||||
SSL3_RECORD_get_data(rr) + SSL3_RECORD_get_off(rr), n);
|
||||
SSL3_RECORD_add_off(rr, n);
|
||||
SSL3_RECORD_add_length(rr, -n);
|
||||
*dest_len += n;
|
||||
if (SSL3_RECORD_get_length(rr) == 0)
|
||||
SSL3_RECORD_set_read(rr);
|
||||
|
||||
if (*dest_len < dest_maxlen)
|
||||
goto start; /* fragment was too small */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1454,14 +1454,6 @@ 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];
|
||||
@ -1504,19 +1496,6 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
*/
|
||||
if ((s->rlayer.handshake_fragment_len >= 4)
|
||||
&& !ossl_statem_get_in_handshake(s)) {
|
||||
/*
|
||||
* To get here we must be trying to read app data but found handshake
|
||||
* data. But if we're trying to read app data, and we're not in init
|
||||
* (which is tested for at the top of this function) then init must be
|
||||
* finished
|
||||
*/
|
||||
assert(SSL_is_init_finished(s));
|
||||
if (!SSL_is_init_finished(s)) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
/* We found handshake data, so we're going back into init */
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
|
||||
|
@ -56,7 +56,8 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send)
|
||||
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITING
|
||||
|| s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
|
||||
alg_enc = s->session->cipher->algorithm_enc;
|
||||
} else {
|
||||
/*
|
||||
|
@ -343,6 +343,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_VERIFY), "TLS_CONSTRUCT_CTOS_VERIFY"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS),
|
||||
"tls_construct_encrypted_extensions"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA),
|
||||
"tls_construct_end_of_early_data"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_EXTENSIONS), "tls_construct_extensions"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_FINISHED), "tls_construct_finished"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST),
|
||||
@ -438,6 +440,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"tls_process_client_key_exchange"},
|
||||
{ERR_FUNC(SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS),
|
||||
"tls_process_encrypted_extensions"},
|
||||
{ERR_FUNC(SSL_F_TLS_PROCESS_END_OF_EARLY_DATA),
|
||||
"tls_process_end_of_early_data"},
|
||||
{ERR_FUNC(SSL_F_TLS_PROCESS_FINISHED), "tls_process_finished"},
|
||||
{ERR_FUNC(SSL_F_TLS_PROCESS_HELLO_REQ), "tls_process_hello_req"},
|
||||
{ERR_FUNC(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST),
|
||||
|
@ -105,8 +105,6 @@ static const struct {
|
||||
},
|
||||
};
|
||||
|
||||
static int ssl_write_early_finish(SSL *s);
|
||||
|
||||
static int dane_ctx_enable(struct dane_ctx_st *dctx)
|
||||
{
|
||||
const EVP_MD **mdevp;
|
||||
@ -1641,9 +1639,9 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
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
|
||||
* State machine will update early_data_state to
|
||||
* SSL_EARLY_DATA_FINISHED_READING if we get an EndOfEarlyData
|
||||
* message
|
||||
*/
|
||||
if (ret > 0 || (ret <= 0 && s->early_data_state
|
||||
!= SSL_EARLY_DATA_FINISHED_READING)) {
|
||||
@ -1663,18 +1661,6 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
}
|
||||
}
|
||||
|
||||
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_READ_RETRY) {
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
|
||||
ossl_statem_finish_early_data(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SSL_get_early_data_status(const SSL *s)
|
||||
{
|
||||
return s->ext.early_data;
|
||||
@ -1753,14 +1739,7 @@ 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_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
|
||||
if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
|
||||
|| s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY
|
||||
|| s->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
|
||||
SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
@ -1863,32 +1842,6 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
}
|
||||
}
|
||||
|
||||
static int ssl_write_early_finish(SSL *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY) {
|
||||
SSLerr(SSL_F_SSL_WRITE_EARLY_FINISH, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->early_data_state = SSL_EARLY_DATA_WRITING;
|
||||
ret = ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_END_OF_EARLY_DATA);
|
||||
if (ret <= 0) {
|
||||
s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
|
||||
return 0;
|
||||
}
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
|
||||
/*
|
||||
* We set the enc_write_ctx back to NULL because we may end up writing
|
||||
* in cleartext again if we get a HelloRetryRequest from the server.
|
||||
*/
|
||||
EVP_CIPHER_CTX_free(s->enc_write_ctx);
|
||||
s->enc_write_ctx = NULL;
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_shutdown(SSL *s)
|
||||
{
|
||||
/*
|
||||
@ -3252,13 +3205,6 @@ int SSL_do_handshake(SSL *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
|
||||
int edfin;
|
||||
|
||||
edfin = ssl_write_early_finish(s);
|
||||
if (edfin <= 0)
|
||||
return edfin;
|
||||
}
|
||||
ossl_statem_check_finish_init(s, -1);
|
||||
|
||||
s->method->ssl_renegotiate_check(s, 0);
|
||||
|
@ -350,7 +350,8 @@
|
||||
&& (s)->method->version != TLS_ANY_VERSION)
|
||||
|
||||
# define SSL_TREAT_AS_TLS13(s) \
|
||||
(SSL_IS_TLS13(s) || (s)->early_data_state == SSL_EARLY_DATA_WRITING)
|
||||
(SSL_IS_TLS13(s) || (s)->early_data_state == SSL_EARLY_DATA_WRITING \
|
||||
|| (s)->early_data_state == SSL_EARLY_DATA_WRITE_RETRY)
|
||||
|
||||
# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3->tmp.finish_md_len == 0)
|
||||
|
||||
@ -2030,7 +2031,6 @@ 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);
|
||||
|
@ -180,13 +180,29 @@ void ossl_statem_check_finish_init(SSL *s, int send)
|
||||
{
|
||||
if (send == -1) {
|
||||
if (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END
|
||||
|| s->statem.hand_state == TLS_ST_EARLY_DATA)
|
||||
|| s->statem.hand_state == TLS_ST_EARLY_DATA) {
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
|
||||
/*
|
||||
* SSL_connect() or SSL_do_handshake() has been called directly.
|
||||
* We don't allow any more writing of early data.
|
||||
*/
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
|
||||
}
|
||||
}
|
||||
} else if (!s->server) {
|
||||
if ((send && s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END
|
||||
if ((send && (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END
|
||||
|| s->statem.hand_state == TLS_ST_EARLY_DATA)
|
||||
&& s->early_data_state != SSL_EARLY_DATA_WRITING)
|
||||
|| (!send && s->statem.hand_state == TLS_ST_EARLY_DATA))
|
||||
|| (!send && s->statem.hand_state == TLS_ST_EARLY_DATA)) {
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
/*
|
||||
* SSL_write() has been called directly. We don't allow any more
|
||||
* writing of early data.
|
||||
*/
|
||||
if (send && s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY)
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
|
||||
}
|
||||
} else {
|
||||
if (s->early_data_state == SSL_EARLY_DATA_FINISHED_READING
|
||||
&& s->statem.hand_state == TLS_ST_EARLY_DATA)
|
||||
|
@ -130,4 +130,3 @@ __owur int ossl_statem_app_data_allowed(SSL *s);
|
||||
void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock);
|
||||
__owur int ossl_statem_in_sctp_read_sock(SSL *s);
|
||||
#endif
|
||||
int ossl_statem_finish_early_data(SSL *s);
|
||||
|
@ -435,7 +435,8 @@ 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)
|
||||
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
|
||||
|| s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING)
|
||||
st->hand_state = TLS_ST_PENDING_EARLY_DATA_END;
|
||||
else
|
||||
st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
|
||||
@ -443,6 +444,13 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_PENDING_EARLY_DATA_END:
|
||||
if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
|
||||
st->hand_state = TLS_ST_CW_END_OF_EARLY_DATA;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case TLS_ST_CW_END_OF_EARLY_DATA:
|
||||
st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
|
||||
: TLS_ST_CW_FINISHED;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
@ -666,8 +674,18 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
|
||||
}
|
||||
break;
|
||||
|
||||
case TLS_ST_EARLY_DATA:
|
||||
case TLS_ST_PENDING_EARLY_DATA_END:
|
||||
/*
|
||||
* If we've been called by SSL_do_handshake()/SSL_write(), or we did not
|
||||
* attempt to write early data before calling SSL_read() then we press
|
||||
* on with the handshake. Otherwise we pause here.
|
||||
*/
|
||||
if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING
|
||||
|| s->early_data_state == SSL_EARLY_DATA_NONE)
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
/* Fall through */
|
||||
|
||||
case TLS_ST_EARLY_DATA:
|
||||
case TLS_ST_OK:
|
||||
return tls_finish_handshake(s, wst, 1);
|
||||
}
|
||||
@ -712,6 +730,15 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
|
||||
}
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_END_OF_EARLY_DATA:
|
||||
/*
|
||||
* We set the enc_write_ctx back to NULL because we may end up writing
|
||||
* in cleartext again if we get a HelloRetryRequest from the server.
|
||||
*/
|
||||
EVP_CIPHER_CTX_free(s->enc_write_ctx);
|
||||
s->enc_write_ctx = NULL;
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_KEY_EXCH:
|
||||
if (tls_client_key_exchange_post_work(s) == 0)
|
||||
return WORK_ERROR;
|
||||
@ -813,6 +840,16 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt,
|
||||
*mt = SSL3_MT_CLIENT_HELLO;
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_END_OF_EARLY_DATA:
|
||||
*confunc = tls_construct_end_of_early_data;
|
||||
*mt = SSL3_MT_END_OF_EARLY_DATA;
|
||||
break;
|
||||
|
||||
case TLS_ST_PENDING_EARLY_DATA_END:
|
||||
*confunc = NULL;
|
||||
*mt = SSL3_MT_DUMMY;
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_CERT:
|
||||
*confunc = tls_construct_client_certificate;
|
||||
*mt = SSL3_MT_CERTIFICATE;
|
||||
@ -3543,3 +3580,16 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY
|
||||
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
|
||||
return 1;
|
||||
}
|
||||
|
@ -986,7 +986,6 @@ 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
/* The spec allows for a longer length than this, but we limit it */
|
||||
#define HELLO_VERIFY_REQUEST_MAX_LENGTH 258
|
||||
#define END_OF_EARLY_DATA_MAX_LENGTH 0
|
||||
#define SERVER_HELLO_MAX_LENGTH 20000
|
||||
#define HELLO_RETRY_REQUEST_MAX_LENGTH 20000
|
||||
#define ENCRYPTED_EXTENSIONS_MAX_LENGTH 20000
|
||||
@ -147,6 +148,7 @@ __owur int tls_construct_next_proto(SSL *s, WPACKET *pkt);
|
||||
#endif
|
||||
__owur MSG_PROCESS_RETURN tls_process_hello_req(SSL *s, PACKET *pkt);
|
||||
__owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt);
|
||||
__owur int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt);
|
||||
|
||||
/* some server-only functions */
|
||||
__owur MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt);
|
||||
@ -165,6 +167,7 @@ __owur MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt);
|
||||
__owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt);
|
||||
#endif
|
||||
__owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt);
|
||||
MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt);
|
||||
|
||||
|
||||
/* Extension processing */
|
||||
|
@ -94,6 +94,16 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt)
|
||||
break;
|
||||
|
||||
case TLS_ST_EARLY_DATA:
|
||||
if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
|
||||
if (mt == SSL3_MT_END_OF_EARLY_DATA) {
|
||||
st->hand_state = TLS_ST_SR_END_OF_EARLY_DATA;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case TLS_ST_SR_END_OF_EARLY_DATA:
|
||||
case TLS_ST_SW_FINISHED:
|
||||
if (s->s3->tmp.cert_request) {
|
||||
if (mt == SSL3_MT_CERTIFICATE) {
|
||||
@ -144,9 +154,6 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt)
|
||||
}
|
||||
|
||||
/* No valid transition found */
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
|
||||
SSLerr(SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION,
|
||||
SSL_R_UNEXPECTED_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1009,6 +1016,9 @@ size_t ossl_statem_server_max_message_size(SSL *s)
|
||||
case TLS_ST_SR_CLNT_HELLO:
|
||||
return CLIENT_HELLO_MAX_LENGTH;
|
||||
|
||||
case TLS_ST_SR_END_OF_EARLY_DATA:
|
||||
return END_OF_EARLY_DATA_MAX_LENGTH;
|
||||
|
||||
case TLS_ST_SR_CERT:
|
||||
return s->max_cert_list;
|
||||
|
||||
@ -1049,6 +1059,9 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt)
|
||||
case TLS_ST_SR_CLNT_HELLO:
|
||||
return tls_process_client_hello(s, pkt);
|
||||
|
||||
case TLS_ST_SR_END_OF_EARLY_DATA:
|
||||
return tls_process_end_of_early_data(s, pkt);
|
||||
|
||||
case TLS_ST_SR_CERT:
|
||||
return tls_process_client_certificate(s, pkt);
|
||||
|
||||
@ -1115,15 +1128,6 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
}
|
||||
|
||||
int ossl_statem_finish_early_data(SSL *s)
|
||||
{
|
||||
if (!s->method->ssl3_enc->change_cipher_state(s,
|
||||
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
|
||||
{
|
||||
@ -3670,3 +3674,45 @@ static int tls_construct_hello_retry_request(SSL *s, WPACKET *pkt)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt)
|
||||
{
|
||||
int al = SSL_AD_INTERNAL_ERROR;
|
||||
|
||||
if (PACKET_remaining(pkt) != 0) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, SSL_R_LENGTH_MISMATCH);
|
||||
ossl_statem_set_error(s);
|
||||
return MSG_PROCESS_ERROR;
|
||||
}
|
||||
|
||||
if (s->early_data_state != SSL_EARLY_DATA_READING
|
||||
&& s->early_data_state != SSL_EARLY_DATA_READ_RETRY) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* EndOfEarlyData signals a key change so the end of the message must be on
|
||||
* a record boundary.
|
||||
*/
|
||||
if (RECORD_LAYER_processed_read_pending(&s->rlayer)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_TLS_PROCESS_END_OF_EARLY_DATA,
|
||||
SSL_R_NOT_ON_RECORD_BOUNDARY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
|
||||
if (!s->method->ssl3_enc->change_cipher_state(s,
|
||||
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return MSG_PROCESS_CONTINUE_READING;
|
||||
err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
ossl_statem_set_error(s);
|
||||
return MSG_PROCESS_ERROR;
|
||||
}
|
||||
|
@ -600,7 +600,7 @@ int tls13_update_key(SSL *s, int send)
|
||||
|
||||
int tls13_alert_code(int code)
|
||||
{
|
||||
if (code == SSL_AD_MISSING_EXTENSION || code == SSL_AD_END_OF_EARLY_DATA)
|
||||
if (code == SSL_AD_MISSING_EXTENSION)
|
||||
return code;
|
||||
|
||||
return tls1_alert_code(code);
|
||||
|
@ -1764,15 +1764,6 @@ static int test_early_data_read_write(void)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect SSL_accept() to initially block as it handles the end of early
|
||||
* data alert
|
||||
*/
|
||||
if (SSL_accept(serverssl) > 0) {
|
||||
printf("Unexpected success completing server handshake\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (SSL_accept(serverssl) <= 0) {
|
||||
printf("Unable to complete server handshake\n");
|
||||
goto end;
|
||||
|
Loading…
Reference in New Issue
Block a user