mirror of
https://github.com/openssl/openssl.git
synced 2025-02-23 14:42:15 +08:00
Use the configured max_send_fragment value in the write record layer
Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19343)
This commit is contained in:
parent
4bf610bdce
commit
435d88d708
@ -253,7 +253,7 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
|
||||
* Check if the received packet overflows the current Max Fragment
|
||||
* Length setting.
|
||||
*/
|
||||
if (rl->max_frag_len > 0 && rr->length > rl->max_frag_len) {
|
||||
if (rr->length > rl->max_frag_len) {
|
||||
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
|
||||
goto end;
|
||||
}
|
||||
@ -482,8 +482,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
|
||||
* If received packet overflows maximum possible fragment length then
|
||||
* silently discard it
|
||||
*/
|
||||
if (rl->max_frag_len > 0
|
||||
&& rr->length > rl->max_frag_len + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) {
|
||||
if (rr->length > rl->max_frag_len + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) {
|
||||
/* record too long, silently discard it */
|
||||
rr->length = 0;
|
||||
rl->packet_length = 0;
|
||||
@ -713,5 +712,6 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = {
|
||||
dtls_set_in_init,
|
||||
tls_get_state,
|
||||
tls_set_options,
|
||||
tls_get_compression
|
||||
tls_get_compression,
|
||||
tls_set_max_frag_len
|
||||
};
|
||||
|
@ -307,16 +307,8 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
/* ktls supports only the maximum fragment size */
|
||||
if (rl->max_frag_len > 0 && rl->max_frag_len != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
if (rl->max_frag_len != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
#if 0
|
||||
/*
|
||||
* TODO(RECLAYER): We will need to reintroduce the check of the send
|
||||
* fragment for KTLS once we do the record write side implementation
|
||||
*/
|
||||
if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
#endif
|
||||
|
||||
/* check that cipher is supported */
|
||||
if (!ktls_int_check_supported_cipher(rl, ciph, md, taglen))
|
||||
@ -476,5 +468,6 @@ const OSSL_RECORD_METHOD ossl_ktls_record_method = {
|
||||
NULL,
|
||||
tls_get_state,
|
||||
tls_set_options,
|
||||
tls_get_compression
|
||||
tls_get_compression,
|
||||
tls_set_max_frag_len
|
||||
};
|
||||
|
@ -173,7 +173,10 @@ struct ossl_record_layer_st
|
||||
/* Set to 1 if this is the first handshake. 0 otherwise */
|
||||
int is_first_handshake;
|
||||
|
||||
/* The negotiated maximum fragment length */
|
||||
/*
|
||||
* The smaller of the configured and negotiated maximum fragment length
|
||||
* or SSL3_RT_MAX_PLAIN_LENGTH if none
|
||||
*/
|
||||
unsigned int max_frag_len;
|
||||
|
||||
/* The maxium amount of early data we can receive/send */
|
||||
@ -329,6 +332,7 @@ void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr,
|
||||
const char **longstr);
|
||||
int tls_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options);
|
||||
const COMP_METHOD *tls_get_compression(OSSL_RECORD_LAYER *rl);
|
||||
void tls_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len);
|
||||
int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl);
|
||||
int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
|
||||
size_t firstlen, size_t nextlen);
|
||||
|
@ -144,8 +144,6 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
|
||||
size_t align = 0, headerlen;
|
||||
SSL3_BUFFER *wb;
|
||||
size_t currpipe;
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s = (SSL_CONNECTION *)rl->cbarg;
|
||||
size_t defltlen = 0;
|
||||
|
||||
if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) {
|
||||
@ -158,8 +156,8 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
|
||||
align = SSL3_ALIGN_PAYLOAD - 1;
|
||||
#endif
|
||||
|
||||
defltlen = ssl_get_max_send_fragment(s)
|
||||
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
defltlen = rl->max_frag_len + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
|
||||
+ headerlen + align;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (tls_allow_compression(rl))
|
||||
defltlen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
@ -237,8 +235,8 @@ int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl)
|
||||
#endif
|
||||
|
||||
if (b->buf == NULL) {
|
||||
len = SSL3_RT_MAX_PLAIN_LENGTH
|
||||
+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
len = rl->max_frag_len
|
||||
+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (tls_allow_compression(rl))
|
||||
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
@ -905,7 +903,7 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
|
||||
* Max Fragment Length setting.
|
||||
* Note: rl->max_frag_len > 0 and KTLS are mutually exclusive.
|
||||
*/
|
||||
if (rl->max_frag_len > 0 && thisrr->length > rl->max_frag_len) {
|
||||
if (thisrr->length > rl->max_frag_len) {
|
||||
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
|
||||
goto end;
|
||||
}
|
||||
@ -1214,6 +1212,12 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
if (rl == NULL)
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
|
||||
/*
|
||||
* Default the value for max_frag_len. This may be overridden by the
|
||||
* settings
|
||||
*/
|
||||
rl->max_frag_len = SSL3_RT_MAX_PLAIN_LENGTH;
|
||||
|
||||
/* Loop through all the settings since they must all be understood */
|
||||
if (settings != NULL) {
|
||||
for (p = settings; p->key != NULL; p++) {
|
||||
@ -1512,8 +1516,6 @@ int tls_write_records_default(OSSL_RECORD_LAYER *rl,
|
||||
size_t len, wpinited = 0;
|
||||
size_t j, prefix = 0;
|
||||
int using_ktls;
|
||||
/* TODO(RECLAYER): REMOVE ME */
|
||||
SSL_CONNECTION *s = rl->cbarg;
|
||||
OSSL_RECORD_TEMPLATE prefixtempl;
|
||||
OSSL_RECORD_TEMPLATE *thistempl;
|
||||
|
||||
@ -1688,7 +1690,7 @@ int tls_write_records_default(OSSL_RECORD_LAYER *rl,
|
||||
&& rl->enc_ctx != NULL
|
||||
&& (!rl->allow_plain_alerts
|
||||
|| thistempl->type != SSL3_RT_ALERT)) {
|
||||
size_t rlen, max_send_fragment;
|
||||
size_t rlen;
|
||||
|
||||
if (!WPACKET_put_bytes_u8(thispkt, thistempl->type)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
@ -1697,11 +1699,10 @@ int tls_write_records_default(OSSL_RECORD_LAYER *rl,
|
||||
SSL3_RECORD_add_length(thiswr, 1);
|
||||
|
||||
/* Add TLS1.3 padding */
|
||||
max_send_fragment = ssl_get_max_send_fragment(s);
|
||||
rlen = SSL3_RECORD_get_length(thiswr);
|
||||
if (rlen < max_send_fragment) {
|
||||
if (rlen < rl->max_frag_len) {
|
||||
size_t padding = 0;
|
||||
size_t max_padding = max_send_fragment - rlen;
|
||||
size_t max_padding = rl->max_frag_len - rlen;
|
||||
|
||||
if (rl->padding != NULL) {
|
||||
padding = rl->padding(rl->cbarg, thistempl->type, rlen);
|
||||
@ -2063,6 +2064,18 @@ const COMP_METHOD *tls_get_compression(OSSL_RECORD_LAYER *rl)
|
||||
#endif
|
||||
}
|
||||
|
||||
void tls_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len)
|
||||
{
|
||||
rl->max_frag_len = max_frag_len;
|
||||
/*
|
||||
* We don't need to adjust buffer sizes. Write buffer sizes are
|
||||
* automatically checked anyway. We should only be changing the read buffer
|
||||
* size during the handshake, so we will create a new buffer when we create
|
||||
* the new record layer. We can't change the existing buffer because it may
|
||||
* already have data in it.
|
||||
*/
|
||||
}
|
||||
|
||||
const OSSL_RECORD_METHOD ossl_tls_record_method = {
|
||||
tls_new_record_layer,
|
||||
tls_free,
|
||||
@ -2086,5 +2099,6 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
|
||||
NULL,
|
||||
tls_get_state,
|
||||
tls_set_options,
|
||||
tls_get_compression
|
||||
tls_get_compression,
|
||||
tls_set_max_frag_len
|
||||
};
|
||||
|
@ -1135,7 +1135,9 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
|
||||
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
|
||||
const OSSL_RECORD_METHOD *meth;
|
||||
int use_etm, stream_mac = 0, tlstree = 0;
|
||||
unsigned int maxfrag = SSL3_RT_MAX_PLAIN_LENGTH;
|
||||
unsigned int maxfrag = (direction == OSSL_RECORD_DIRECTION_WRITE)
|
||||
? ssl_get_max_send_fragment(s)
|
||||
: SSL3_RT_MAX_PLAIN_LENGTH;
|
||||
int use_early_data = 0;
|
||||
uint32_t max_early_data;
|
||||
COMP_METHOD *compm = (comp == NULL) ? NULL : comp->method;
|
||||
@ -1205,9 +1207,16 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
|
||||
*set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE,
|
||||
&tlstree);
|
||||
|
||||
if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session))
|
||||
/*
|
||||
* We only need to do this for the read side. The write side should already
|
||||
* have the correct value due to the ssl_get_max_send_fragment() call above
|
||||
*/
|
||||
if (direction == OSSL_RECORD_DIRECTION_READ
|
||||
&& s->session != NULL
|
||||
&& USE_MAX_FRAGMENT_LENGTH_EXT(s->session))
|
||||
maxfrag = GET_MAX_FRAGMENT_LENGTH(s->session);
|
||||
|
||||
|
||||
if (maxfrag != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
*set++ = OSSL_PARAM_construct_uint(OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN,
|
||||
&maxfrag);
|
||||
|
@ -302,6 +302,13 @@ struct ossl_record_method_st {
|
||||
int (*set_options)(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options);
|
||||
|
||||
const COMP_METHOD *(*get_compression)(OSSL_RECORD_LAYER *rl);
|
||||
|
||||
/*
|
||||
* Set the maximum fragment length to be used for the record layer. This
|
||||
* will override any previous value supplied for the "max_frag_len"
|
||||
* setting during construction of the record layer.
|
||||
*/
|
||||
void (*set_max_frag_len)(OSSL_RECORD_LAYER *rl, size_t max_frag_len);
|
||||
};
|
||||
|
||||
|
||||
|
@ -2789,6 +2789,7 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
sc->max_send_fragment = larg;
|
||||
if (sc->max_send_fragment < sc->split_send_fragment)
|
||||
sc->split_send_fragment = sc->max_send_fragment;
|
||||
sc->rlayer.wrlmethod->set_max_frag_len(sc->rlayer.wrl, larg);
|
||||
return 1;
|
||||
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
|
||||
if ((size_t)larg > sc->max_send_fragment || larg == 0)
|
||||
|
@ -1707,14 +1707,18 @@ static int final_maxfragmentlen(SSL_CONNECTION *s, unsigned int context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Current SSL buffer is lower than requested MFL */
|
||||
if (s->session && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)
|
||||
&& s->max_send_fragment < GET_MAX_FRAGMENT_LENGTH(s->session))
|
||||
if (s->session && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) {
|
||||
s->rlayer.rrlmethod->set_max_frag_len(s->rlayer.rrl,
|
||||
GET_MAX_FRAGMENT_LENGTH(s->session));
|
||||
s->rlayer.wrlmethod->set_max_frag_len(s->rlayer.wrl,
|
||||
ssl_get_max_send_fragment(s));
|
||||
/* trigger a larger buffer reallocation */
|
||||
if (!ssl3_setup_buffers(s)) {
|
||||
/* TODO(RECLAYER): Remove me when DTLS moved to write record layer */
|
||||
if (SSL_CONNECTION_IS_DTLS(s) && !ssl3_setup_buffers(s)) {
|
||||
/* SSLfatal() already called */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user