diff -ur openssl-1.0.1m.ori/ssl/d1_pkt.c openssl-1.0.1m/ssl/d1_pkt.c --- openssl-1.0.1m.ori/ssl/d1_pkt.c 2015-03-19 14:37:10.000000000 +0100 +++ openssl-1.0.1m/ssl/d1_pkt.c 2015-04-07 13:49:06.638445384 +0200 @@ -650,6 +650,22 @@ goto again; } + /* If we receive a valid record larger than the current buffer size, + * allocate some memory for it. + */ + if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH) { + unsigned char *pp; + unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH; + if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL) { + SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE); + return(-1); + } + p = pp + (p - s->s3->rbuf.buf); + s->s3->rbuf.buf=pp; + s->s3->rbuf.len=newlen; + s->packet= &(s->s3->rbuf.buf[0]); + } + /* now s->rstate == SSL_ST_READ_BODY */ } @@ -1492,6 +1508,7 @@ SSL3_BUFFER *wb; SSL_SESSION *sess; int bs; + unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD; /* * first check if there is a SSL3_BUFFER still being written out. This @@ -1502,6 +1519,15 @@ return (ssl3_write_pending(s, type, buf, len)); } + if (s->s3->wbuf.len < len_with_overhead) { + if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) { + SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE); + goto err; + } + s->s3->wbuf.buf = p; + s->s3->wbuf.len = len_with_overhead; + } + /* If we have an alert to send, lets send it */ if (s->s3->alert_dispatch) { i = s->method->ssl_dispatch_alert(s); diff -ur openssl-1.0.1m.ori/ssl/s23_srvr.c openssl-1.0.1m/ssl/s23_srvr.c --- openssl-1.0.1m.ori/ssl/s23_srvr.c 2015-04-07 13:29:08.474471605 +0200 +++ openssl-1.0.1m/ssl/s23_srvr.c 2015-04-07 13:51:07.946442730 +0200 @@ -437,8 +437,13 @@ * 9-10 challenge_length * ... ... */ +/* The SSL2 protocol allows n to be larger, just pick + * a reasonable buffer size. */ +#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD +#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small." +#endif n = ((p[0] & 0x7f) << 8) | p[1]; - if (n > (1024 * 4)) { + if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); goto err; } diff -ur openssl-1.0.1m.ori/ssl/s3_both.c openssl-1.0.1m/ssl/s3_both.c --- openssl-1.0.1m.ori/ssl/s3_both.c 2015-03-19 14:37:10.000000000 +0100 +++ openssl-1.0.1m/ssl/s3_both.c 2015-04-07 14:04:05.954425704 +0200 @@ -729,12 +729,18 @@ #endif if (s->s3->rbuf.buf == NULL) { - len = SSL3_RT_MAX_PLAIN_LENGTH - + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { - s->s3->init_extra = 1; - len += SSL3_RT_MAX_EXTRA; + if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) { + len = SSL3_RT_DEFAULT_PACKET_SIZE; } + else { + len = SSL3_RT_MAX_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { + s->s3->init_extra = 1; + len += SSL3_RT_MAX_EXTRA; + } + } + #ifndef OPENSSL_NO_COMP if (!(s->options & SSL_OP_NO_COMPRESSION)) len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; @@ -768,7 +774,13 @@ #endif if (s->s3->wbuf.buf == NULL) { - len = s->max_send_fragment + if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) { + len = SSL3_RT_DEFAULT_PACKET_SIZE; + } + else { + len = s->max_send_fragment; + } + len += 0 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; #ifndef OPENSSL_NO_COMP if (!(s->options & SSL_OP_NO_COMPRESSION)) diff -ur openssl-1.0.1m.ori/ssl/s3_pkt.c openssl-1.0.1m/ssl/s3_pkt.c --- openssl-1.0.1m.ori/ssl/s3_pkt.c 2015-03-19 14:37:10.000000000 +0100 +++ openssl-1.0.1m/ssl/s3_pkt.c 2015-04-07 14:12:35.242414559 +0200 @@ -304,6 +304,13 @@ unsigned mac_size, orig_len; size_t extra; unsigned empty_record_count = 0; + int decryption_failed_or_bad_record_mac = 0; + unsigned char *mac = NULL; +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + long align=SSL3_ALIGN_PAYLOAD; +#else + long align=0; +#endif rr = &(s->s3->rrec); sess = s->session; @@ -312,7 +319,8 @@ extra = SSL3_RT_MAX_EXTRA; else extra = 0; - if (extra && !s->s3->init_extra) { + if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) && + extra && !s->s3->init_extra) { /* * An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER set after * ssl3_setup_buffers() was done @@ -362,6 +370,19 @@ goto err; } + /* If we receive a valid record larger than the current buffer size, + * allocate some memory for it. + */ + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { + if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL) { + SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE); + goto err; + } + s->s3->rbuf.buf=p; + s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align; + s->packet= &(s->s3->rbuf.buf[0]); + } + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { al = SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); @@ -612,6 +633,7 @@ const unsigned char *buf = buf_; unsigned int n, nw; int i, tot; + unsigned int max_plain_length; s->rwstate = SSL_NOTHING; OPENSSL_assert(s->s3->wnum <= INT_MAX); @@ -644,10 +666,15 @@ n = (len - tot); for (;;) { - if (n > s->max_send_fragment) - nw = s->max_send_fragment; - else - nw = n; + if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)) + max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH; + else + max_plain_length = s->max_send_fragment; + + if (n > max_plain_length) + nw = max_plain_length; + else + nw=n; i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); if (i <= 0) { @@ -756,6 +783,16 @@ s->s3->empty_fragment_done = 1; } + /* resize if necessary to hold the data. */ + if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len) { + if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL) { + SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE); + goto err; + } + wb->buf = p; + wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD; + } + if (create_empty_fragment) { #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 /* diff -ur openssl-1.0.1m.ori/ssl/ssl3.h openssl-1.0.1m/ssl/ssl3.h --- openssl-1.0.1m.ori/ssl/ssl3.h 2015-03-19 14:37:10.000000000 +0100 +++ openssl-1.0.1m/ssl/ssl3.h 2015-04-07 14:14:38.894411853 +0200 @@ -296,6 +296,9 @@ # define SSL3_RT_MAX_EXTRA (16384) +/* Default buffer length used for writen records. Thus a generated record + * will contain plaintext no larger than this value. */ +#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048 /* Maximum plaintext length: defined by SSL/TLS standards */ # define SSL3_RT_MAX_PLAIN_LENGTH 16384 /* Maximum compression overhead: defined by SSL/TLS standards */ @@ -329,6 +332,13 @@ # define SSL3_RT_MAX_PACKET_SIZE \ (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) +/* Extra space for empty fragment, headers, MAC, and padding. */ +# define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256 +# define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD +# if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE +# error "Insufficient space allocated for write buffers." +# endif + # define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" # define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" diff -ur openssl-1.0.1m.ori/ssl/ssl.h openssl-1.0.1m/ssl/ssl.h --- openssl-1.0.1m.ori/ssl/ssl.h 2015-04-07 13:37:49.634460200 +0200 +++ openssl-1.0.1m/ssl/ssl.h 2015-04-07 14:13:36.066413228 +0200 @@ -684,6 +684,9 @@ * draft-ietf-tls-downgrade-scsv-00. */ # define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L +/* Use small read and write buffers: (a) lazy allocate read buffers for + * large incoming records, and (b) limit the size of outgoing records. */ +# define SSL_MODE_SMALL_BUFFERS 0x00000100L /* * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they