summaryrefslogtreecommitdiffstats
path: root/ssl/record
diff options
context:
space:
mode:
authorFdaSilvaYY <fdasilvayy@gmail.com>2017-11-05 17:46:48 +0100
committerBernd Edlinger <bernd.edlinger@hotmail.de>2017-11-05 17:46:48 +0100
commitcf72c7579201086cee303eadcb60bd28eff78dd9 (patch)
tree35c096098b2527a814c95cc674bb54747e3054a0 /ssl/record
parentb82acc3c1a7f304c9df31841753a0fa76b5b3cda (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.c4
-rw-r--r--ssl/record/rec_layer_s3.c28
-rw-r--r--ssl/record/ssl3_buffer.c9
-rw-r--r--ssl/record/ssl3_record.c19
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 */
}