diff options
author | David Benjamin <davidben@google.com> | 2016-05-12 07:43:05 +0300 |
---|---|---|
committer | David Benjamin <davidben@google.com> | 2016-05-13 23:06:24 +0300 |
commit | 060cfb091194edf7341d91009764c64096a87157 (patch) | |
tree | 62573149cd380ddf3f0d8b6a2153ae36bfb69a97 /ssl/d1_both.c | |
parent | 4e7a1ff055b987c9f900a2279380290cb8d9e939 (diff) |
Simplify handshake message size limits.
A handshake message can go up to 2^24 bytes = 16MB which is a little large for
the peer to force us to buffer. Accordingly, we bound the size of a
handshake message.
Rather than have a global limit, the existing logic uses a different limit at
each state in the handshake state machine and, for certificates, allows
configuring the maximum certificate size. This is nice in that we engage larger
limits iff the relevant state is reachable from the handshake. Servers without
client auth get a tighter limit "for free".
However, this doesn't work for DTLS due to out-of-order messages and we use a
simpler scheme for DTLS. This scheme also is tricky on optional messages and
makes the handshake <-> message layer communication complex.
Apart from an ignored 20,000 byte limit on ServerHello, the largest
non-certificate limit is the common 16k limit on ClientHello. So this
complexity wasn't buying us anything. Unify everything on the DTLS scheme
except, so as not to regress bounds on client-auth-less servers, also correctly
check for whether client auth is configured. The value of 16k was chosen based
on this value.
(The 20,000 byte ServerHello limit makes no sense. We can easily bound the
ServerHello because servers may not send extensions we don't implement. But it
gets overshadowed by the certificate anyway.)
Change-Id: I00309b16d809a3c2a1543f99fd29c4163e3add81
Reviewed-on: https://boringssl-review.googlesource.com/7941
Reviewed-by: David Benjamin <davidben@google.com>
Diffstat (limited to 'ssl/d1_both.c')
-rw-r--r-- | ssl/d1_both.c | 24 |
1 files changed, 4 insertions, 20 deletions
diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 9f60db41..7a624126 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -483,17 +483,6 @@ static hm_fragment *dtls1_get_buffered_message( return frag; } -/* dtls1_max_handshake_message_len returns the maximum number of bytes - * permitted in a DTLS handshake message for |ssl|. The minimum is 16KB, but may - * be greater if the maximum certificate list size requires it. */ -static size_t dtls1_max_handshake_message_len(const SSL *ssl) { - size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; - if (max_len < ssl->max_cert_list) { - return ssl->max_cert_list; - } - return max_len; -} - /* dtls1_process_fragment reads a handshake fragment and processes it. It * returns one if a fragment was successfully processed and 0 or -1 on error. */ static int dtls1_process_fragment(SSL *ssl) { @@ -521,7 +510,7 @@ static int dtls1_process_fragment(SSL *ssl) { const size_t msg_len = msg_hdr.msg_len; if (frag_off > msg_len || frag_off + frag_len < frag_off || frag_off + frag_len > msg_len || - msg_len > dtls1_max_handshake_message_len(ssl) || + msg_len > ssl_max_handshake_message_len(ssl) || frag_len > ssl->s3->rrec.length) { OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); @@ -567,9 +556,9 @@ static int dtls1_process_fragment(SSL *ssl) { } /* dtls1_get_message reads a handshake message of message type |msg_type| (any - * if |msg_type| == -1), maximum acceptable body length |max|. Read an entire - * handshake message. Handshake messages arrive in fragments. */ -long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, long max, + * if |msg_type| == -1). Read an entire handshake message. Handshake messages + * arrive in fragments. */ +long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, enum ssl_hash_message_t hash_message, int *ok) { pitem *item = NULL; hm_fragment *frag = NULL; @@ -610,11 +599,6 @@ long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, long max, assert(ssl->d1->handshake_read_seq == frag->msg_header.seq); assert(frag->reassembly == NULL); - if (frag->msg_header.msg_len > (size_t)max) { - OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto err; - } - /* Reconstruct the assembled message. */ size_t len; CBB cbb; |