| Index: patches/small_records.patch | 
| =================================================================== | 
| --- patches/small_records.patch	(revision 0) | 
| +++ patches/small_records.patch	(revision 0) | 
| @@ -0,0 +1,337 @@ | 
| +--- openssl-1.0.0a.orig/ssl/d1_pkt.c	2010-04-14 00:09:55.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/d1_pkt.c	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -608,6 +608,24 @@ again: | 
| + 			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 */ | 
| + 		} | 
| + | 
| +@@ -1342,6 +1360,7 @@ int do_dtls1_write(SSL *s, int type, con | 
| + 	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 will happen with non blocking IO */ | 
| +@@ -1351,6 +1370,16 @@ int do_dtls1_write(SSL *s, int type, con | 
| + 		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) | 
| + 		{ | 
| +--- openssl-1.0.0a.orig/ssl/s23_srvr.c	2010-02-16 14:20:40.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/s23_srvr.c	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -403,8 +403,13 @@ int ssl23_get_client_hello(SSL *s) | 
| + 		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ | 
| + 		v[1] = p[4]; | 
| + | 
| ++/* 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; | 
| +--- openssl-1.0.0a.orig/ssl/s3_both.c	2010-03-24 23:16:49.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/s3_both.c	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -715,13 +722,20 @@ int ssl3_setup_read_buffer(SSL *s) | 
| + | 
| + 	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) | 
| ++		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) | 
| + 			{ | 
| +-			s->s3->init_extra = 1; | 
| +-			len += SSL3_RT_MAX_EXTRA; | 
| ++			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)) | 
| +@@ -757,7 +771,15 @@ int ssl3_setup_write_buffer(SSL *s) | 
| + | 
| + 	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 | 
| +@@ -767,7 +789,6 @@ int ssl3_setup_write_buffer(SSL *s) | 
| + 		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) | 
| + 			len += headerlen + align | 
| + 				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; | 
| +- | 
| + 		if ((p=freelist_extract(s->ctx, 0, len)) == NULL) | 
| + 			goto err; | 
| + 		s->s3->wbuf.buf = p; | 
| +@@ -810,4 +831,3 @@ int ssl3_release_read_buffer(SSL *s) | 
| + 		} | 
| + 	return 1; | 
| + 	} | 
| +- | 
| +--- openssl-1.0.0a.orig/ssl/s3_pkt.c	2010-03-25 11:22:42.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/s3_pkt.c	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -293,6 +293,11 @@ static int ssl3_get_record(SSL *s) | 
| + 	size_t extra; | 
| + 	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; | 
| +@@ -301,7 +306,8 @@ static int ssl3_get_record(SSL *s) | 
| + 		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 */ | 
| +@@ -350,6 +356,21 @@ fprintf(stderr, "Record type=%d, Length= | 
| + 			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 - align) | 
| ++			{ | 
| ++			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; | 
| +@@ -576,6 +597,7 @@ int ssl3_write_bytes(SSL *s, int type, c | 
| + 	const unsigned char *buf=buf_; | 
| + 	unsigned int tot,n,nw; | 
| + 	int i; | 
| ++	unsigned int max_plain_length; | 
| + | 
| + 	s->rwstate=SSL_NOTHING; | 
| + 	tot=s->s3->wnum; | 
| +@@ -595,8 +617,13 @@ int ssl3_write_bytes(SSL *s, int type, c | 
| + 	n=(len-tot); | 
| + 	for (;;) | 
| + 		{ | 
| +-		if (n > s->max_send_fragment) | 
| +-			nw=s->max_send_fragment; | 
| ++		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; | 
| + | 
| +@@ -727,6 +727,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, | 
| + 		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 | 
| +--- openssl-1.0.0a.orig/ssl/ssl.h	2010-01-06 17:37:38.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/ssl.h	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -602,6 +602,9 @@ typedef struct ssl_session_st | 
| +  * TLS only.)  "Released" buffers are put onto a free-list in the context | 
| +  * or just freed (depending on the context's setting for freelist_max_len). */ | 
| + #define SSL_MODE_RELEASE_BUFFERS 0x00000010L | 
| ++/* 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 0x00000020L | 
| + | 
| + /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, | 
| +  * they cannot be used to clear bits. */ | 
| +--- openssl-1.0.0a.orig/ssl/ssl3.h	2010-01-06 17:37:38.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/ssl3.h	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -280,6 +280,9 @@ extern "C" { | 
| + | 
| + #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 */ | 
| +@@ -311,6 +314,13 @@ extern "C" { | 
| + #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" | 
| + | 
| +@@ -634,4 +645,3 @@ typedef struct ssl3_state_st | 
| + } | 
| + #endif | 
| + #endif | 
| +- | 
| +--- openssl-1.0.0a.orig/ssl/ssltest.c	2010-01-24 16:57:38.000000000 +0000 | 
| ++++ openssl-1.0.0a/ssl/ssltest.c	2010-08-25 21:12:39.000000000 +0000 | 
| +@@ -316,6 +316,8 @@ static void sv_usage(void) | 
| + 	               "                 (default is sect163r2).\n"); | 
| + #endif | 
| + 	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); | 
| ++	fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n"); | 
| ++	fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n"); | 
| + 	} | 
| + | 
| + static void print_details(SSL *c_ssl, const char *prefix) | 
| +@@ -444,6 +447,9 @@ int opaque_prf_input_cb(SSL *ssl, void * | 
| + 	return arg->ret; | 
| + 	} | 
| + #endif | 
| ++	int ssl_mode = 0; | 
| ++	int c_small_records=0; | 
| ++	int s_small_records=0; | 
| + | 
| + int main(int argc, char *argv[]) | 
| + 	{ | 
| +@@ -680,6 +687,14 @@ int main(int argc, char *argv[]) | 
| + 			{ | 
| + 			test_cipherlist = 1; | 
| + 			} | 
| ++		else if (strcmp(*argv, "-c_small_records") == 0) | 
| ++			{ | 
| ++			c_small_records = 1; | 
| ++			} | 
| ++		else if (strcmp(*argv, "-s_small_records") == 0) | 
| ++			{ | 
| ++			s_small_records = 1; | 
| ++			} | 
| + 		else | 
| + 			{ | 
| + 			fprintf(stderr,"unknown option %s\n",*argv); | 
| +@@ -802,6 +821,21 @@ bad: | 
| + 		SSL_CTX_set_cipher_list(s_ctx,cipher); | 
| + 		} | 
| + | 
| ++	ssl_mode = 0; | 
| ++	if (c_small_records) | 
| ++		{ | 
| ++		ssl_mode = SSL_CTX_get_mode(c_ctx); | 
| ++		ssl_mode |= SSL_MODE_SMALL_BUFFERS; | 
| ++		SSL_CTX_set_mode(c_ctx, ssl_mode); | 
| ++		} | 
| ++	ssl_mode = 0; | 
| ++	if (s_small_records) | 
| ++		{ | 
| ++		ssl_mode = SSL_CTX_get_mode(s_ctx); | 
| ++		ssl_mode |= SSL_MODE_SMALL_BUFFERS; | 
| ++		SSL_CTX_set_mode(s_ctx, ssl_mode); | 
| ++		} | 
| ++ | 
| + #ifndef OPENSSL_NO_DH | 
| + 	if (!no_dhe) | 
| + 		{ | 
| +--- openssl-1.0.0.orig/test/testssl	2006-03-10 15:06:27.000000000 -0800 | 
| ++++ openssl-1.0.0/test/testssl	2010-04-26 10:24:55.000000000 -0700 | 
| +@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit | 
| + echo test sslv2/sslv3 with both client and server authentication | 
| + $ssltest -server_auth -client_auth $CA $extra || exit 1 | 
| + | 
| ++echo test sslv2/sslv3 with both client and server authentication and small client buffers | 
| ++$ssltest -server_auth -client_auth -c_small_records $CA $extra || exit 1 | 
| ++ | 
| ++echo test sslv2/sslv3 with both client and server authentication and small server buffers | 
| ++$ssltest -server_auth -client_auth -s_small_records $CA $extra || exit 1 | 
| ++ | 
| ++echo test sslv2/sslv3 with both client and server authentication and small client and server buffers | 
| ++$ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1 | 
| ++ | 
| ++ | 
| + echo test sslv2 via BIO pair | 
| + $ssltest -bio_pair -ssl2 $extra || exit 1 | 
| + | 
|  |