1--- openssl-1.0.0a.orig/ssl/d1_pkt.c 2010-04-14 00:09:55.000000000 +0000 2+++ openssl-1.0.0a/ssl/d1_pkt.c 2010-08-25 21:12:39.000000000 +0000 3@@ -608,6 +608,24 @@ again: 4 goto again; 5 } 6 7+ /* If we receive a valid record larger than the current buffer size, 8+ * allocate some memory for it. 9+ */ 10+ if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH) 11+ { 12+ unsigned char *pp; 13+ unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH; 14+ if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL) 15+ { 16+ SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE); 17+ return(-1); 18+ } 19+ p = pp + (p - s->s3->rbuf.buf); 20+ s->s3->rbuf.buf=pp; 21+ s->s3->rbuf.len=newlen; 22+ s->packet= &(s->s3->rbuf.buf[0]); 23+ } 24+ 25 /* now s->rstate == SSL_ST_READ_BODY */ 26 } 27 28@@ -1342,6 +1360,7 @@ int do_dtls1_write(SSL *s, int type, con 29 SSL3_BUFFER *wb; 30 SSL_SESSION *sess; 31 int bs; 32+ unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD; 33 34 /* first check if there is a SSL3_BUFFER still being written 35 * out. This will happen with non blocking IO */ 36@@ -1351,6 +1370,16 @@ int do_dtls1_write(SSL *s, int type, con 37 return(ssl3_write_pending(s,type,buf,len)); 38 } 39 40+ if (s->s3->wbuf.len < len_with_overhead) 41+ { 42+ if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) { 43+ SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE); 44+ goto err; 45+ } 46+ s->s3->wbuf.buf = p; 47+ s->s3->wbuf.len = len_with_overhead; 48+ } 49+ 50 /* If we have an alert to send, lets send it */ 51 if (s->s3->alert_dispatch) 52 { 53--- openssl-1.0.0a.orig/ssl/s23_srvr.c 2010-02-16 14:20:40.000000000 +0000 54+++ openssl-1.0.0a/ssl/s23_srvr.c 2010-08-25 21:12:39.000000000 +0000 55@@ -403,8 +403,13 @@ int ssl23_get_client_hello(SSL *s) 56 v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ 57 v[1] = p[4]; 58 59+/* The SSL2 protocol allows n to be larger, just pick 60+ * a reasonable buffer size. */ 61+#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD 62+#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small." 63+#endif 64 n=((p[0]&0x7f)<<8)|p[1]; 65- if (n > (1024*4)) 66+ if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2) 67 { 68 SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); 69 goto err; 70--- openssl-1.0.0a.orig/ssl/s3_both.c 2010-03-24 23:16:49.000000000 +0000 71+++ openssl-1.0.0a/ssl/s3_both.c 2010-08-25 21:12:39.000000000 +0000 72@@ -715,13 +722,20 @@ int ssl3_setup_read_buffer(SSL *s) 73 74 if (s->s3->rbuf.buf == NULL) 75 { 76- len = SSL3_RT_MAX_PLAIN_LENGTH 77- + SSL3_RT_MAX_ENCRYPTED_OVERHEAD 78- + headerlen + align; 79- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) 80+ if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) 81 { 82- s->s3->init_extra = 1; 83- len += SSL3_RT_MAX_EXTRA; 84+ len = SSL3_RT_DEFAULT_PACKET_SIZE; 85+ } 86+ else 87+ { 88+ len = SSL3_RT_MAX_PLAIN_LENGTH 89+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD 90+ + headerlen + align; 91+ if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) 92+ { 93+ s->s3->init_extra = 1; 94+ len += SSL3_RT_MAX_EXTRA; 95+ } 96 } 97 #ifndef OPENSSL_NO_COMP 98 if (!(s->options & SSL_OP_NO_COMPRESSION)) 99@@ -757,7 +771,15 @@ int ssl3_setup_write_buffer(SSL *s) 100 101 if (s->s3->wbuf.buf == NULL) 102 { 103- len = s->max_send_fragment 104+ if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) 105+ { 106+ len = SSL3_RT_DEFAULT_PACKET_SIZE; 107+ } 108+ else 109+ { 110+ len = s->max_send_fragment; 111+ } 112+ len += 0 113 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD 114 + headerlen + align; 115 #ifndef OPENSSL_NO_COMP 116@@ -767,7 +789,6 @@ int ssl3_setup_write_buffer(SSL *s) 117 if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) 118 len += headerlen + align 119 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; 120- 121 if ((p=freelist_extract(s->ctx, 0, len)) == NULL) 122 goto err; 123 s->s3->wbuf.buf = p; 124@@ -810,4 +831,3 @@ int ssl3_release_read_buffer(SSL *s) 125 } 126 return 1; 127 } 128- 129--- openssl-1.0.0a.orig/ssl/s3_pkt.c 2010-03-25 11:22:42.000000000 +0000 130+++ openssl-1.0.0a/ssl/s3_pkt.c 2010-08-25 21:12:39.000000000 +0000 131@@ -293,6 +293,11 @@ static int ssl3_get_record(SSL *s) 132 size_t extra; 133 int decryption_failed_or_bad_record_mac = 0; 134 unsigned char *mac = NULL; 135+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 136+ long align=SSL3_ALIGN_PAYLOAD; 137+#else 138+ long align=0; 139+#endif 140 141 rr= &(s->s3->rrec); 142 sess=s->session; 143@@ -301,7 +306,8 @@ static int ssl3_get_record(SSL *s) 144 extra=SSL3_RT_MAX_EXTRA; 145 else 146 extra=0; 147- if (extra && !s->s3->init_extra) 148+ if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) && 149+ extra && !s->s3->init_extra) 150 { 151 /* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER 152 * set after ssl3_setup_buffers() was done */ 153@@ -350,6 +356,21 @@ fprintf(stderr, "Record type=%d, Length= 154 goto err; 155 } 156 157+ /* If we receive a valid record larger than the current buffer size, 158+ * allocate some memory for it. 159+ */ 160+ if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align) 161+ { 162+ if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL) 163+ { 164+ SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE); 165+ goto err; 166+ } 167+ s->s3->rbuf.buf=p; 168+ s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align; 169+ s->packet= &(s->s3->rbuf.buf[0]); 170+ } 171+ 172 if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) 173 { 174 al=SSL_AD_RECORD_OVERFLOW; 175@@ -576,6 +597,7 @@ int ssl3_write_bytes(SSL *s, int type, c 176 const unsigned char *buf=buf_; 177 unsigned int tot,n,nw; 178 int i; 179+ unsigned int max_plain_length; 180 181 s->rwstate=SSL_NOTHING; 182 tot=s->s3->wnum; 183@@ -595,8 +617,13 @@ int ssl3_write_bytes(SSL *s, int type, c 184 n=(len-tot); 185 for (;;) 186 { 187- if (n > s->max_send_fragment) 188- nw=s->max_send_fragment; 189+ if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)) 190+ max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH; 191+ else 192+ max_plain_length = s->max_send_fragment; 193+ 194+ if (n > max_plain_length) 195+ nw = max_plain_length; 196 else 197 nw=n; 198 199@@ -727,6 +727,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 200 s->s3->empty_fragment_done = 1; 201 } 202 203+ /* resize if necessary to hold the data. */ 204+ if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len) 205+ { 206+ if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL) 207+ { 208+ SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE); 209+ goto err; 210+ } 211+ wb->buf = p; 212+ wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD; 213+ } 214+ 215 if (create_empty_fragment) 216 { 217 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 218--- openssl-1.0.0a.orig/ssl/ssl.h 2010-01-06 17:37:38.000000000 +0000 219+++ openssl-1.0.0a/ssl/ssl.h 2010-08-25 21:12:39.000000000 +0000 220@@ -602,6 +602,9 @@ typedef struct ssl_session_st 221 * TLS only.) "Released" buffers are put onto a free-list in the context 222 * or just freed (depending on the context's setting for freelist_max_len). */ 223 #define SSL_MODE_RELEASE_BUFFERS 0x00000010L 224+/* Use small read and write buffers: (a) lazy allocate read buffers for 225+ * large incoming records, and (b) limit the size of outgoing records. */ 226+#define SSL_MODE_SMALL_BUFFERS 0x00000020L 227 228 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, 229 * they cannot be used to clear bits. */ 230--- openssl-1.0.0a.orig/ssl/ssl3.h 2010-01-06 17:37:38.000000000 +0000 231+++ openssl-1.0.0a/ssl/ssl3.h 2010-08-25 21:12:39.000000000 +0000 232@@ -280,6 +280,9 @@ extern "C" { 233 234 #define SSL3_RT_MAX_EXTRA (16384) 235 236+/* Default buffer length used for writen records. Thus a generated record 237+ * will contain plaintext no larger than this value. */ 238+#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048 239 /* Maximum plaintext length: defined by SSL/TLS standards */ 240 #define SSL3_RT_MAX_PLAIN_LENGTH 16384 241 /* Maximum compression overhead: defined by SSL/TLS standards */ 242@@ -311,6 +314,13 @@ extern "C" { 243 #define SSL3_RT_MAX_PACKET_SIZE \ 244 (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) 245 246+/* Extra space for empty fragment, headers, MAC, and padding. */ 247+#define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256 248+#define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD 249+#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE 250+#error "Insufficient space allocated for write buffers." 251+#endif 252+ 253 #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" 254 #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" 255 256@@ -634,4 +645,3 @@ typedef struct ssl3_state_st 257 } 258 #endif 259 #endif 260- 261--- openssl-1.0.0a.orig/ssl/ssltest.c 2010-01-24 16:57:38.000000000 +0000 262+++ openssl-1.0.0a/ssl/ssltest.c 2010-08-25 21:12:39.000000000 +0000 263@@ -316,6 +316,8 @@ static void sv_usage(void) 264 " (default is sect163r2).\n"); 265 #endif 266 fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); 267+ fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n"); 268+ fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n"); 269 } 270 271 static void print_details(SSL *c_ssl, const char *prefix) 272@@ -444,6 +447,9 @@ int opaque_prf_input_cb(SSL *ssl, void * 273 return arg->ret; 274 } 275 #endif 276+ int ssl_mode = 0; 277+ int c_small_records=0; 278+ int s_small_records=0; 279 280 int main(int argc, char *argv[]) 281 { 282@@ -680,6 +687,14 @@ int main(int argc, char *argv[]) 283 { 284 test_cipherlist = 1; 285 } 286+ else if (strcmp(*argv, "-c_small_records") == 0) 287+ { 288+ c_small_records = 1; 289+ } 290+ else if (strcmp(*argv, "-s_small_records") == 0) 291+ { 292+ s_small_records = 1; 293+ } 294 else 295 { 296 fprintf(stderr,"unknown option %s\n",*argv); 297@@ -802,6 +821,21 @@ bad: 298 SSL_CTX_set_cipher_list(s_ctx,cipher); 299 } 300 301+ ssl_mode = 0; 302+ if (c_small_records) 303+ { 304+ ssl_mode = SSL_CTX_get_mode(c_ctx); 305+ ssl_mode |= SSL_MODE_SMALL_BUFFERS; 306+ SSL_CTX_set_mode(c_ctx, ssl_mode); 307+ } 308+ ssl_mode = 0; 309+ if (s_small_records) 310+ { 311+ ssl_mode = SSL_CTX_get_mode(s_ctx); 312+ ssl_mode |= SSL_MODE_SMALL_BUFFERS; 313+ SSL_CTX_set_mode(s_ctx, ssl_mode); 314+ } 315+ 316 #ifndef OPENSSL_NO_DH 317 if (!no_dhe) 318 { 319--- openssl-1.0.0.orig/test/testssl 2006-03-10 15:06:27.000000000 -0800 320+++ openssl-1.0.0/test/testssl 2010-04-26 10:24:55.000000000 -0700 321@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit 322 echo test sslv2/sslv3 with both client and server authentication 323 $ssltest -server_auth -client_auth $CA $extra || exit 1 324 325+echo test sslv2/sslv3 with both client and server authentication and small client buffers 326+$ssltest -server_auth -client_auth -c_small_records $CA $extra || exit 1 327+ 328+echo test sslv2/sslv3 with both client and server authentication and small server buffers 329+$ssltest -server_auth -client_auth -s_small_records $CA $extra || exit 1 330+ 331+echo test sslv2/sslv3 with both client and server authentication and small client and server buffers 332+$ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1 333+ 334+ 335 echo test sslv2 via BIO pair 336 $ssltest -bio_pair -ssl2 $extra || exit 1 337 338