mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
Check max_early_data against the amount of early data we actually receive
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2737)
This commit is contained in:
parent
67f78eadd0
commit
70ef40a05e
@ -2154,6 +2154,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385
|
||||
# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370
|
||||
# define SSL_F_DTLS_PROCESS_HELLO_VERIFY 386
|
||||
# define SSL_F_EARLY_DATA_COUNT_OK 532
|
||||
# define SSL_F_FINAL_EC_PT_FORMATS 485
|
||||
# define SSL_F_FINAL_EMS 486
|
||||
# define SSL_F_FINAL_KEY_SHARE 503
|
||||
@ -2679,6 +2680,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
|
||||
# define SSL_R_TOO_MANY_KEY_UPDATES 132
|
||||
# define SSL_R_TOO_MANY_WARN_ALERTS 409
|
||||
# define SSL_R_TOO_MUCH_EARLY_DATA 164
|
||||
# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314
|
||||
# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239
|
||||
# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242
|
||||
|
@ -101,6 +101,36 @@ static int ssl3_record_app_data_waiting(SSL *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
|
||||
{
|
||||
uint32_t max_early_data = s->max_early_data;
|
||||
|
||||
/*
|
||||
* We go with the lowest out of the max early data set in the session
|
||||
* and the configured max_early_data
|
||||
*/
|
||||
if (s->session->ext.max_early_data < s->max_early_data)
|
||||
max_early_data = s->max_early_data;
|
||||
|
||||
if (max_early_data == 0) {
|
||||
*al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we are dealing with ciphertext we need to allow for the overhead */
|
||||
max_early_data += overhead;
|
||||
|
||||
s->early_data_count += length;
|
||||
if (s->early_data_count > max_early_data) {
|
||||
*al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
|
||||
* will be processed per call to ssl3_get_record. Without this limit an
|
||||
@ -139,6 +169,7 @@ int ssl3_get_record(SSL *s)
|
||||
int imac_size;
|
||||
size_t num_recs = 0, max_recs, j;
|
||||
PACKET pkt, sslv2pkt;
|
||||
size_t first_rec_len;
|
||||
|
||||
rr = RECORD_LAYER_get_rrec(&s->rlayer);
|
||||
rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
|
||||
@ -415,6 +446,8 @@ int ssl3_get_record(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
first_rec_len = rr[0].length;
|
||||
|
||||
enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
|
||||
|
||||
/*-
|
||||
@ -429,7 +462,13 @@ int ssl3_get_record(SSL *s)
|
||||
* Valid early_data that we cannot decrypt might fail here as
|
||||
* publicly invalid. We treat it like an empty record.
|
||||
*/
|
||||
|
||||
thisrr = &rr[0];
|
||||
|
||||
if (!early_data_count_ok(s, thisrr->length,
|
||||
EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
|
||||
goto f_err;
|
||||
|
||||
thisrr->length = 0;
|
||||
thisrr->read = 1;
|
||||
RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
|
||||
@ -513,6 +552,15 @@ int ssl3_get_record(SSL *s)
|
||||
* We assume this is unreadable early_data - we treat it like an
|
||||
* empty record
|
||||
*/
|
||||
|
||||
/*
|
||||
* The record length may have been modified by the mac check above
|
||||
* so we use the previously saved value
|
||||
*/
|
||||
if (!early_data_count_ok(s, first_rec_len,
|
||||
EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
|
||||
goto f_err;
|
||||
|
||||
thisrr = &rr[0];
|
||||
thisrr->length = 0;
|
||||
thisrr->read = 1;
|
||||
@ -604,6 +652,13 @@ int ssl3_get_record(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (s->early_data_state == SSL_EARLY_DATA_READING) {
|
||||
thisrr = &rr[0];
|
||||
if (thisrr->type == SSL3_RT_APPLICATION_DATA
|
||||
&& !early_data_count_ok(s, thisrr->length, 0, &al))
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs);
|
||||
return 1;
|
||||
|
||||
|
@ -52,6 +52,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_FUNC(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE),
|
||||
"dtls_get_reassembled_message"},
|
||||
{ERR_FUNC(SSL_F_DTLS_PROCESS_HELLO_VERIFY), "dtls_process_hello_verify"},
|
||||
{ERR_FUNC(SSL_F_EARLY_DATA_COUNT_OK), "early_data_count_ok"},
|
||||
{ERR_FUNC(SSL_F_FINAL_EC_PT_FORMATS), "final_ec_pt_formats"},
|
||||
{ERR_FUNC(SSL_F_FINAL_EMS), "final_ems"},
|
||||
{ERR_FUNC(SSL_F_FINAL_KEY_SHARE), "final_key_share"},
|
||||
@ -788,6 +789,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
"tls invalid ecpointformat list"},
|
||||
{ERR_REASON(SSL_R_TOO_MANY_KEY_UPDATES), "too many key updates"},
|
||||
{ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
|
||||
{ERR_REASON(SSL_R_TOO_MUCH_EARLY_DATA), "too much early data"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),
|
||||
"unable to find ecdh parameters"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS),
|
||||
|
@ -626,6 +626,18 @@ typedef enum {
|
||||
SSL_EARLY_DATA_FINISHED_READING
|
||||
} SSL_EARLY_DATA_STATE;
|
||||
|
||||
/*
|
||||
* We check that the amount of unreadable early data doesn't exceed
|
||||
* max_early_data. max_early_data is given in plaintext bytes. However if it is
|
||||
* unreadable then we only know the number of ciphertext bytes. We also don't
|
||||
* know how much the overhead should be because it depends on the ciphersuite.
|
||||
* We make a small allowance. We assume 5 records of actual data plus the end
|
||||
* of early data alert record. Each record has a tag and a content type byte.
|
||||
* The longest tag length we know of is EVP_GCM_TLS_TAG_LEN. We don't count the
|
||||
* content of the alert record either which is 2 bytes.
|
||||
*/
|
||||
# define EARLY_DATA_CIPHERTEXT_OVERHEAD ((6 * (EVP_GCM_TLS_TAG_LEN + 1)) + 2)
|
||||
|
||||
#define MAX_COMPRESSIONS_SIZE 255
|
||||
|
||||
struct ssl_comp_st {
|
||||
@ -1245,8 +1257,14 @@ struct ssl_st {
|
||||
ASYNC_WAIT_CTX *waitctx;
|
||||
size_t asyncrw;
|
||||
|
||||
/* The maximum number of bytes that can be sent as early data */
|
||||
/* The maximum number of plaintext bytes that can be sent as early data */
|
||||
uint32_t max_early_data;
|
||||
/*
|
||||
* The number of bytes of early data received so far. If we accepted early
|
||||
* data then this is a count of the plaintext bytes. If we rejected it then
|
||||
* this is a count of the ciphertext bytes.
|
||||
*/
|
||||
uint32_t early_data_count;
|
||||
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user