--- openssl-1.0.0.orig/ssl/ssl.h	2010-07-13 22:24:27.000000000 +0000
+++ openssl-1.0.0/ssl/ssl.h	2010-07-13 22:24:27.000000000 +0000
@@ -1090,6 +1090,9 @@ struct ssl_st
 	/* This can also be in the session once a session is established */
 	SSL_SESSION *session;
 
+        /* This can be disabled to prevent the use of uncached sessions */
+	int session_creation_enabled;
+
 	/* Default generate session ID callback. */
 	GEN_SESSION_CB generate_session_id;
 
@@ -1509,6 +1512,7 @@ BIO *	SSL_get_rbio(const SSL *s);
 BIO *	SSL_get_wbio(const SSL *s);
 #endif
 int	SSL_set_cipher_list(SSL *s, const char *str);
+int	SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
 void	SSL_set_read_ahead(SSL *s, int yes);
 int	SSL_get_verify_mode(const SSL *s);
 int	SSL_get_verify_depth(const SSL *s);
@@ -1524,6 +1528,8 @@ int	SSL_use_PrivateKey(SSL *ssl, EVP_PKE
 int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
 int	SSL_use_certificate(SSL *ssl, X509 *x);
 int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+int	SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
 
 #ifndef OPENSSL_NO_STDIO
 int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
@@ -1568,6 +1574,7 @@ int	SSL_SESSION_print(BIO *fp,const SSL_
 void	SSL_SESSION_free(SSL_SESSION *ses);
 int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
 int	SSL_set_session(SSL *to, SSL_SESSION *session);
+void	SSL_set_session_creation_enabled(SSL *, int);
 int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
 int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
 int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
@@ -2009,6 +2016,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
 #define SSL_F_SSL_USE_CERTIFICATE			 198
 #define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN			 2000
 #define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
 #define SSL_F_SSL_USE_PRIVATEKEY			 201
 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
@@ -2213,6 +2221,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
 #define SSL_R_SERVERHELLO_TLSEXT			 275
 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
+#define SSL_R_SESSION_MAY_NOT_BE_CREATED		 2000
 #define SSL_R_SHORT_READ				 219
 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
--- openssl-1.0.0.orig/ssl/d1_clnt.c	2010-01-26 19:46:29.000000000 +0000
+++ openssl-1.0.0/ssl/d1_clnt.c	2010-07-13 22:24:27.000000000 +0000
@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s)
 #endif
 			(s->session->not_resumable))
 			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
 			if (!ssl_get_new_session(s,0))
 				goto err;
 			}
--- openssl-1.0.0.orig/ssl/s23_clnt.c	2010-02-16 14:20:40.000000000 +0000
+++ openssl-1.0.0/ssl/s23_clnt.c	2010-07-13 22:24:27.000000000 +0000
@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s
 
 	/* Since, if we are sending a ssl23 client hello, we are not
 	 * reusing a session-id */
+        if (!s->session_creation_enabled)
+		{
+		if (!(s->client_version == SSL2_VERSION))
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+		goto err;
+		}
 	if (!ssl_get_new_session(s,0))
 		goto err;
 
--- openssl-1.0.0.orig/ssl/s3_both.c	2010-07-13 22:24:27.000000000 +0000
+++ openssl-1.0.0/ssl/s3_both.c	2010-07-13 22:24:27.000000000 +0000
@@ -322,8 +322,11 @@ unsigned long ssl3_output_cert_chain(SSL
 	unsigned long l=7;
 	BUF_MEM *buf;
 	int no_chain;
+	STACK_OF(X509) *cert_chain;
 
-	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
+	cert_chain = SSL_get_certificate_chain(s, x);
+
+	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
 		no_chain = 1;
 	else
 		no_chain = 0;
@@ -375,6 +378,10 @@ unsigned long ssl3_output_cert_chain(SSL
 			return(0);
 		}
 
+	for (i=0; i<sk_X509_num(cert_chain); i++)
+		if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
+			return(0);
+
 	l-=7;
 	p=(unsigned char *)&(buf->data[4]);
 	l2n3(l,p);
--- openssl-1.0.0.orig/ssl/s3_clnt.c	2010-07-13 22:24:27.000000000 +0000
+++ openssl-1.0.0/ssl/s3_clnt.c	2010-07-13 22:24:27.000000000 +0000
@@ -668,6 +668,12 @@ int ssl3_client_hello(SSL *s)
 #endif
 			(sess->not_resumable))
 			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
 			if (!ssl_get_new_session(s,0))
 				goto err;
 			}
@@ -876,6 +882,12 @@ int ssl3_get_server_hello(SSL *s)
 		s->hit=0;
 		if (s->session->session_id_length > 0)
 			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
 			if (!ssl_get_new_session(s,0))
 				{
 				al=SSL_AD_INTERNAL_ERROR;
--- openssl-1.0.0.orig/ssl/s3_srvr.c	2010-02-27 23:04:10.000000000 +0000
+++ openssl-1.0.0/ssl/s3_srvr.c	2010-07-13 22:24:27.000000000 +0000
@@ -869,6 +869,12 @@ int ssl3_get_client_hello(SSL *s)
 	 */
 	if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
 		{
+	        if (!s->session_creation_enabled)
+			{
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+			goto err;
+		}
 		if (!ssl_get_new_session(s,1))
 			goto err;
 		}
@@ -883,6 +889,12 @@ int ssl3_get_client_hello(SSL *s)
 			goto err;
 		else /* i == 0 */
 			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
 			if (!ssl_get_new_session(s,1))
 				goto err;
 			}
--- openssl-1.0.0.orig/ssl/ssl_err.c	2010-01-06 17:37:38.000000000 +0000
+++ openssl-1.0.0/ssl/ssl_err.c	2010-07-13 22:24:27.000000000 +0000
@@ -462,6 +462,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
 {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
 {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT)    ,"serverhello tlsext"},
 {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
+{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
 {ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
 {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
 {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
--- openssl-1.0.0.orig/ssl/ssl_lib.c	2010-07-13 22:24:27.000000000 +0000
+++ openssl-1.0.0/ssl/ssl_lib.c	2010-07-13 22:24:27.000000000 +0000
@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx)
 	OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
 	memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
 	s->verify_callback=ctx->default_verify_callback;
+	s->session_creation_enabled=1;
 	s->generate_session_id=ctx->generate_session_id;
 
 	s->param = X509_VERIFY_PARAM_new();
@@ -1303,6 +1304,32 @@ int SSL_set_cipher_list(SSL *s,const cha
 	return 1;
 	}
 
+/** specify the ciphers to be used by the SSL */
+int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
+	{
+	STACK_OF(SSL_CIPHER) *tmp_cipher_list;
+
+	if (sk == NULL)
+		return 0;
+
+        /* Based on end of ssl_create_cipher_list */
+	tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
+	if (tmp_cipher_list == NULL)
+		{
+		return 0;
+		}
+	if (s->cipher_list != NULL)
+		sk_SSL_CIPHER_free(s->cipher_list);
+	s->cipher_list = sk;
+	if (s->cipher_list_by_id != NULL)
+		sk_SSL_CIPHER_free(s->cipher_list_by_id);
+	s->cipher_list_by_id = tmp_cipher_list;
+	(void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
+
+	sk_SSL_CIPHER_sort(s->cipher_list_by_id);
+	return 1;
+	}
+
 /* works well for SSLv2, not so good for SSLv3 */
 char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
 	{
--- openssl-1.0.0.orig/ssl/ssl_locl.h	2009-12-08 11:38:18.000000000 +0000
+++ openssl-1.0.0/ssl/ssl_locl.h	2010-07-13 22:24:27.000000000 +0000
@@ -456,6 +456,7 @@
 typedef struct cert_pkey_st
 	{
 	X509 *x509;
+	STACK_OF(X509) *cert_chain;
 	EVP_PKEY *privatekey;
 	} CERT_PKEY;
 
--- openssl-1.0.0.orig/ssl/ssl_rsa.c	2009-09-12 23:09:26.000000000 +0000
+++ openssl-1.0.0/ssl/ssl_rsa.c	2010-07-13 22:24:27.000000000 +0000
@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type
 	}
 
 
+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
+	{
+	if (ssl == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (ssl->cert == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	if (ssl->cert->key == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	ssl->cert->key->cert_chain = cert_chain;
+	return(1);
+	}
+
+STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
+	{
+	int i;
+	if (x == NULL)
+		return NULL;
+	if (ssl == NULL)
+		return NULL;
+	if (ssl->cert == NULL)
+		return NULL;
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		if (ssl->cert->pkeys[i].x509 == x)
+			return ssl->cert->pkeys[i].cert_chain;
+	return NULL;
+	}
+
 #ifndef OPENSSL_NO_STDIO
 /* Read a file that contains our certificate in "PEM" format,
  * possibly followed by a sequence of CA certificates that should be
--- openssl-1.0.0.orig/ssl/ssl_sess.c	2010-02-01 16:49:42.000000000 +0000
+++ openssl-1.0.0/ssl/ssl_sess.c	2010-07-13 22:24:27.000000000 +0000
@@ -261,6 +261,11 @@ static int def_generate_session_id(const
 	return 0;
 }
 
+void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
+	{
+	s->session_creation_enabled = creation_enabled;
+	}
+
 int ssl_get_new_session(SSL *s, int session)
 	{
 	/* This gets used by clients and servers. */
@@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess
 	SSL_SESSION *ss=NULL;
 	GEN_SESSION_CB cb = def_generate_session_id;
 
+	/* caller should check this if they can do better error handling */
+        if (!s->session_creation_enabled) return(0);
 	if ((ss=SSL_SESSION_new()) == NULL) return(0);
 
 	/* If the context has a default timeout, use it */
