diff options
author | FdaSilvaYY <fdasilvayy@gmail.com> | 2017-11-05 17:46:48 +0100 |
---|---|---|
committer | Bernd Edlinger <bernd.edlinger@hotmail.de> | 2017-11-05 17:46:48 +0100 |
commit | cf72c7579201086cee303eadcb60bd28eff78dd9 (patch) | |
tree | 35c096098b2527a814c95cc674bb54747e3054a0 /ssl/record | |
parent | b82acc3c1a7f304c9df31841753a0fa76b5b3cda (diff) |
Implement Maximum Fragment Length TLS extension.
Based on patch from Tomasz Moń:
https://groups.google.com/forum/#!topic/mailing.openssl.dev/fQxXvCg1uQY
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/1008)
Diffstat (limited to 'ssl/record')
-rw-r--r-- | ssl/record/rec_layer_d1.c | 4 | ||||
-rw-r--r-- | ssl/record/rec_layer_s3.c | 28 | ||||
-rw-r--r-- | ssl/record/ssl3_buffer.c | 9 | ||||
-rw-r--r-- | ssl/record/ssl3_record.c | 19 |
4 files changed, 42 insertions, 18 deletions
diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 59285ed591..3eabf71cf6 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -774,7 +774,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (len == 0 && !create_empty_fragment) return 0; - if (len > s->max_send_fragment) { + if (len > ssl_get_max_send_fragment(s)) { SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); return 0; } diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 1225f9b4d8..980e5a4b8b 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -334,9 +334,9 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, { const unsigned char *buf = buf_; size_t tot; - size_t n, split_send_fragment, maxpipes; + size_t n, max_send_fragment, split_send_fragment, maxpipes; #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - size_t max_send_fragment, nw; + size_t nw; #endif SSL3_BUFFER *wb = &s->rlayer.wbuf[0]; int i; @@ -403,7 +403,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * compromise is considered worthy. */ if (type == SSL3_RT_APPLICATION_DATA && - len >= 4 * (max_send_fragment = s->max_send_fragment) && + len >= 4 * (max_send_fragment = ssl_get_max_send_fragment(s)) && s->compress == NULL && s->msg_callback == NULL && !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) & @@ -523,7 +523,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, tot += tmpwrit; } } else -#endif +#endif /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */ if (tot == len) { /* done? */ if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) ssl3_release_write_buffer(s); @@ -534,7 +534,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, n = (len - tot); - split_send_fragment = s->split_send_fragment; + max_send_fragment = ssl_get_max_send_fragment(s); + split_send_fragment = ssl_get_split_send_fragment(s); /* * If max_pipelines is 0 then this means "undefined" and we default to * 1 pipeline. Similarly if the cipher does not support pipelined @@ -556,10 +557,10 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, & EVP_CIPH_FLAG_PIPELINE) || !SSL_USE_EXPLICIT_IV(s)) maxpipes = 1; - if (s->max_send_fragment == 0 || split_send_fragment > s->max_send_fragment - || split_send_fragment == 0) { + if (max_send_fragment == 0 || split_send_fragment == 0 + || split_send_fragment > max_send_fragment) { /* - * We should have prevented this when we set the split and max send + * We should have prevented this when we set/get the split and max send * fragments so we shouldn't get here */ SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR); @@ -577,13 +578,13 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, if (numpipes > maxpipes) numpipes = maxpipes; - if (n / numpipes >= s->max_send_fragment) { + if (n / numpipes >= max_send_fragment) { /* * We have enough data to completely fill all available * pipelines */ for (j = 0; j < numpipes; j++) { - pipelens[j] = s->max_send_fragment; + pipelens[j] = max_send_fragment; } } else { /* We can partially fill all available pipelines */ @@ -854,7 +855,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) { - size_t rlen; + size_t rlen, max_send_fragment; if (!WPACKET_put_bytes_u8(thispkt, type)) { SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); @@ -863,10 +864,11 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 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 < SSL3_RT_MAX_PLAIN_LENGTH) { + if (rlen < max_send_fragment) { size_t padding = 0; - size_t max_padding = SSL3_RT_MAX_PLAIN_LENGTH - rlen; + size_t max_padding = max_send_fragment - rlen; if (s->record_padding_cb != NULL) { padding = s->record_padding_cb(s, type, rlen, s->record_padding_arg); } else if (s->block_padding > 0) { diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c index 8a6a922261..da23b36791 100644 --- a/ssl/record/ssl3_buffer.c +++ b/ssl/record/ssl3_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -93,7 +93,7 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); #endif - len = s->max_send_fragment + len = ssl_get_max_send_fragment(s) + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s)) @@ -107,6 +107,11 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) for (currpipe = 0; currpipe < numwpipes; currpipe++) { SSL3_BUFFER *thiswb = &wb[currpipe]; + if (thiswb->buf != NULL && thiswb->len != len) { + OPENSSL_free(thiswb->buf); + thiswb->buf = NULL; /* force reallocation */ + } + if (thiswb->buf == NULL) { p = OPENSSL_malloc(len); if (p == NULL) { diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 8d71cd3184..28a706f7ba 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -685,6 +685,14 @@ int ssl3_get_record(SSL *s) goto f_err; } + /* If received packet overflows current Max Fragment Length setting */ + if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) + && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + thisrr->off = 0; /*- * So at this point the following is true @@ -1823,6 +1831,15 @@ int dtls1_get_record(SSL *s) goto again; } + /* If received packet overflows own-client Max Fragment Length setting */ + if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) + && rr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { + /* record too long, silently discard it */ + rr->length = 0; + RECORD_LAYER_reset_packet_length(&s->rlayer); + goto again; + } + /* now s->rlayer.rstate == SSL_ST_READ_BODY */ } |