List Info

Thread: OpenSSL: OpenSSL_0_9_8-stable: openssl/ CHANGES Configure openss...




OpenSSL: OpenSSL_0_9_8-stable: openssl/ CHANGES Configure openss...
country flaguser name
Germany
2007-08-12 13:59:05
  OpenSSL CVS Repository
  http://cvs.openssl.org/
 
____________________________________________________________
________________

  Server: cvs.openssl.org                  Name:   Dr.
Stephen Henson
  Root:   /v/openssl/cvs                   Email:  steveopenssl.org
  Module: openssl                          Date:  
12-Aug-2007 20:59:05
  Branch: OpenSSL_0_9_8-stable             Handle:
2007081219585706

  Modified files:           (Branch: OpenSSL_0_9_8-stable)
    openssl                 CHANGES Configure
    openssl/apps            s_apps.h s_cb.c s_client.c
s_server.c
    openssl/ssl             s23_clnt.c s2_srvr.c s3_clnt.c
s3_lib.c s3_srvr.c
                            ssl.h ssl3.h ssl_asn1.c
ssl_err.c ssl_lib.c
                            ssl_locl.h ssl_sess.c ssl_txt.c
t1_lib.c tls1.h

  Log:
    Backport of TLS extension code to OpenSSL 0.9.8.
    
    Include server name and RFC4507bis support.
    
    This is not compiled in by default and must be
explicitly enabled with
    the Configure option enable-tlsext

  Summary:
    Revision    Changes     Path
    1.1238.2.74 +52 -0      openssl/CHANGES
    1.488.2.41  +5  -0      openssl/Configure
    1.16.2.1    +3  -0      openssl/apps/s_apps.h
    1.17.2.2    +59 -0      openssl/apps/s_cb.c
    1.76.2.10   +121 -1     openssl/apps/s_client.c
    1.97.2.5    +283 -11    openssl/apps/s_server.c
    1.28.2.4    +7  -0      openssl/ssl/s23_clnt.c
    1.46.2.3    +1  -1      openssl/ssl/s2_srvr.c
    1.88.2.8    +154 -2     openssl/ssl/s3_clnt.c
    1.74.2.17   +50 -0      openssl/ssl/s3_lib.c
    1.126.2.13  +128 -4     openssl/ssl/s3_srvr.c
    1.161.2.12  +66 -0      openssl/ssl/ssl.h
    1.30.2.3    +5  -0      openssl/ssl/ssl3.h
    1.20.2.2    +100 -1     openssl/ssl/ssl_asn1.c
    1.53.2.5    +13 -0      openssl/ssl/ssl_err.c
    1.133.2.9   +63 -2      openssl/ssl/ssl_lib.c
    1.63.2.6    +17 -1      openssl/ssl/ssl_locl.h
    1.51.2.7    +51 -7      openssl/ssl/ssl_sess.c
    1.14.2.3    +15 -0      openssl/ssl/ssl_txt.c
    1.13.2.3    +511 -0     openssl/ssl/t1_lib.c
    1.17.2.5    +49 -0      openssl/ssl/tls1.h
 
____________________________________________________________
________________

  patch -p0 <<' .'
  Index: openssl/CHANGES
 
============================================================
================
  $ cvs diff -u -r1.1238.2.73 -r1.1238.2.74 CHANGES
  --- openssl/CHANGES	19 Jul 2007 17:39:05
-0000	1.1238.2.73
  +++ openssl/CHANGES	12 Aug 2007 18:58:57
-0000	1.1238.2.74
   -3,6 +3,58 
    _______________
   
    Changes between 0.9.8e and 0.9.8f  [xx XXX xxxx]
  +  
  +  *) Add RFC4507 support to OpenSSL. This includes the
corrections in
  +     RFC4507bis. The encrypted ticket format is an
encrypted encoded
  +     SSL_SESSION structure, that way new session features
are automatically
  +     supported.
  +
  +     If a client application caches session in an
SSL_SESSION support it
  +     should automatically be supported because an
extension includes the
  +     ticket in the structure. The SSL_CTX structure
automatically generates
  +     keys for ticket protection in servers so again
support should be possible
  +     with no application modification.
  +
  +     If a client or server wishes to disable RFC4507
support then the option
  +     SSL_OP_NO_TICKET can be set.
  +
  +     Add a TLS extension debugging callback to allow the
contents of any client
  +     or server extensions to be examined.
  +     [Steve Henson]
  +
  +  *) Add initial support for TLS extensions, specifically
for the server_name
  +     extension so far.  The SSL_SESSION, SSL_CTX, and SSL
data structures now
  +     have new members for a host name.  The SSL data
structure has an
  +     additional member SSL_CTX *initial_ctx so that new
sessions can be
  +     stored in that context to allow for session
resumption, even after the
  +     SSL has been switched to a new SSL_CTX in reaction
to a client's
  +     server_name extension.
  +
  +     New functions (subject to change):
  +
  +         SSL_get_servername()
  +         SSL_get_servername_type()
  +         SSL_set_SSL_CTX()
  +
  +     New CTRL codes and macros (subject to change):
  +
  +         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  +                                 -
SSL_CTX_set_tlsext_servername_callback()
  +         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
  +                                      -
SSL_CTX_set_tlsext_servername_arg()
  +         SSL_CTRL_SET_TLSEXT_HOSTNAME           -
SSL_set_tlsext_host_name()
  +
  +     openssl s_client has a new '-servername ...'
option.
  +
  +     openssl s_server has new options '-servername_host
...', '-cert2 ...',
  +     '-key2 ...', '-servername_fatal' (subject to
change).  This allows
  +     testing the HostName extension for a specific single
host name ('-cert'
  +     and '-key' remain fallbacks for handshakes without
HostName
  +     negotiation).  If the unrecogninzed_name alert has
to be sent, this by
  +     default is a warning; it becomes fatal with the
'-servername_fatal'
  +     option.
  +
  +     [Peter Sylvester,  Remy Allais, Christophe Renou,
Steve Henson]
   
     *) Add AES and SSE2 assembly language support to VC++
build.
        [Steve Henson]
   .
  patch -p0 <<' .'
  Index: openssl/Configure
 
============================================================
================
  $ cvs diff -u -r1.488.2.40 -r1.488.2.41 Configure
  --- openssl/Configure	31 Jul 2007 20:03:23
-0000	1.488.2.40
  +++ openssl/Configure	12 Aug 2007 18:58:58
-0000	1.488.2.41
   -607,6 +607,7 
                    "rfc3779"        =>
"default",
                    "seed"           =>
"default",
                    "shared"         =>
"default",
  +                 "tlsext"         =>
"default",
                    "zlib"           =>
"default",
                    "zlib-dynamic"   =>
"default"
                  );
   -838,6 +839,10 
   	$disabled{"tls1"} = "forced";
   	}
   
  +if (defined($disabled{"tls1"}))
  +	{
  +	$disabled{"tlsext"} = "forced";
  +	}
   
   if ($target eq "TABLE") {
   	foreach $target (sort keys %table) {
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_apps.h
 
============================================================
================
  $ cvs diff -u -r1.16 -r1.16.2.1 s_apps.h
  --- openssl/apps/s_apps.h	26 Apr 2005 17:43:52 -0000	1.16
  +++ openssl/apps/s_apps.h	12 Aug 2007 18:58:59
-0000	1.16.2.1
   -167,4 +167,7 
   #ifdef HEADER_SSL_H
   void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int
where, int ret);
   void MS_CALLBACK msg_cb(int write_p, int version, int
content_type, const void *buf, size_t len, SSL *ssl, void
*arg);
  +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int
type,
  +					unsigned char *data, int len,
  +					void *arg);
   #endif
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_cb.c
 
============================================================
================
  $ cvs diff -u -r1.17.2.1 -r1.17.2.2 s_cb.c
  --- openssl/apps/s_cb.c	4 Jul 2007 13:09:26
-0000	1.17.2.1
  +++ openssl/apps/s_cb.c	12 Aug 2007 18:58:59
-0000	1.17.2.2
   -575,3 +575,62 
   		}
   	(void)BIO_flush(bio);
   	}
  +
  +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int
type,
  +					unsigned char *data, int len,
  +					void *arg)
  +	{
  +	BIO *bio = arg;
  +	char *extname;
  +
  +	switch(type)
  +		{
  +		case TLSEXT_TYPE_server_name:
  +		extname = "server name";
  +		break;
  +
  +		case TLSEXT_TYPE_max_fragment_length:
  +		extname = "max fragment length";
  +		break;
  +
  +		case TLSEXT_TYPE_client_certificate_url:
  +		extname = "client certificate URL";
  +		break;
  +
  +		case TLSEXT_TYPE_trusted_ca_keys:
  +		extname = "trusted CA keys";
  +		break;
  +
  +		case TLSEXT_TYPE_truncated_hmac:
  +		extname = "truncated HMAC";
  +		break;
  +
  +		case TLSEXT_TYPE_status_request:
  +		extname = "status request";
  +		break;
  +
  +		case TLSEXT_TYPE_elliptic_curves:
  +		extname = "elliptic curves";
  +		break;
  +
  +		case TLSEXT_TYPE_ec_point_formats:
  +		extname = "EC point formats";
  +		break;
  +
  +		case TLSEXT_TYPE_session_ticket:
  +		extname = "server ticket";
  +		break;
  +
  +
  +		default:
  +		extname = "unknown";
  +		break;
  +
  +		}
  +	
  +	BIO_printf(bio, "TLS %s extension "%s"
(id=%d), len=%dn",
  +			client_server ? "server":
"client",
  +			extname, type, len);
  +	BIO_dump(bio, (char *)data, len);
  +	(void)BIO_flush(bio);
  +	}
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_client.c
 
============================================================
================
  $ cvs diff -u -r1.76.2.9 -r1.76.2.10 s_client.c
  --- openssl/apps/s_client.c	4 Jul 2007 13:09:26
-0000	1.76.2.9
  +++ openssl/apps/s_client.c	12 Aug 2007 18:58:59
-0000	1.76.2.10
   -171,6 +171,9 
   #endif
   static int c_Pause=0;
   static int c_debug=0;
  +#ifndef OPENSSL_NO_TLSEXT
  +static int c_tlsextdebug=0;
  +#endif
   static int c_msg=0;
   static int c_showcerts=0;
   
   -231,9 +234,32 
   	BIO_printf(bio_err," -engine id    - Initialise and
use the specified enginen");
   #endif
   	BIO_printf(bio_err," -rand file%cfile%c...n",
LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
  -
  +#ifndef OPENSSL_NO_TLSEXT
  +	BIO_printf(bio_err," -servername host  - Set TLS
extension servername in ClientHellon");
  +#endif
   	}
   
  +#ifndef OPENSSL_NO_TLSEXT
  +
  +/* This is a context that we pass to callbacks */
  +typedef struct tlsextctx_st {
  +   BIO * biodebug;
  +   int ack;
  +} tlsextctx;
  +
  +
  +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad,
void *arg)
  +	{
  +	tlsextctx * p = (tlsextctx *) arg;
  +	const char * hn= SSL_get_servername(s,
TLSEXT_NAMETYPE_host_name);
  +	if (SSL_get_servername_type(s) != -1) 
  + 	        p->ack = !SSL_session_reused(s) &&
hn != NULL;
  +	else 
  +		BIO_printf(bio_err,"Can't use
SSL_get_servernamen");
  +	
  +	return SSL_TLSEXT_ERR_OK;
  +	}
  +#endif
   enum
   {
   	PROTO_OFF	= 0,
   -287,6 +313,13 
   	struct timeval tv;
   #endif
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	char *servername = NULL; 
  +        tlsextctx tlsextcbp = 
  +        {NULL,0};
  +#endif
  +	char *sess_in = NULL;
  +	char *sess_out = NULL;
   	struct sockaddr peer;
   	int peerlen = sizeof(peer);
   	int enable_timeouts = 0 ;
   -361,6 +394,16 
   			if (--argc < 1) goto bad;
   			cert_file= *(++argv);
   			}
  +		else if	(strcmp(*argv,"-sess_out") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			sess_out = *(++argv);
  +			}
  +		else if	(strcmp(*argv,"-sess_in") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			sess_in = *(++argv);
  +			}
   		else if	(strcmp(*argv,"-certform") == 0)
   			{
   			if (--argc < 1) goto bad;
   -385,6 +428,10 
   			c_Pause=1;
   		else if	(strcmp(*argv,"-debug") == 0)
   			c_debug=1;
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if	(strcmp(*argv,"-tlsextdebug") == 0)
  +			c_tlsextdebug=1;
  +#endif
   #ifdef WATT32
   		else if (strcmp(*argv,"-wdebug") == 0)
   			dbug_init();
   -460,6 +507,10 
   			off|=SSL_OP_NO_SSLv3;
   		else if (strcmp(*argv,"-no_ssl2") == 0)
   			off|=SSL_OP_NO_SSLv2;
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if	(strcmp(*argv,"-no_ticket") == 0)
  +			{ off|=SSL_OP_NO_TICKET; }
  +#endif
   		else if (strcmp(*argv,"-serverpref") == 0)
   			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
   		else if	(strcmp(*argv,"-cipher") == 0)
   -498,6 +549,14 
   			if (--argc < 1) goto bad;
   			inrand= *(++argv);
   			}
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if (strcmp(*argv,"-servername") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			servername= *(++argv);
  +			/* meth=TLSv1_client_method(); */
  +			}
  +#endif
   		else
   			{
   			BIO_printf(bio_err,"unknown option
%sn",*argv);
   -621,8 +680,51 
   
   	store = SSL_CTX_get_cert_store(ctx);
   	X509_STORE_set_flags(store, vflags);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (servername != NULL)
  +		{
  +		tlsextcbp.biodebug = bio_err;
  +		SSL_CTX_set_tlsext_servername_callback(ctx,
ssl_servername_cb);
  +		SSL_CTX_set_tlsext_servername_arg(ctx,
&tlsextcbp);
  +		}
  +#endif
   
   	con=SSL_new(ctx);
  +	if (sess_in)
  +		{
  +		SSL_SESSION *sess;
  +		BIO *stmp = BIO_new_file(sess_in, "r");
  +		if (!stmp)
  +			{
  +			BIO_printf(bio_err, "Can't open session file
%sn",
  +						sess_in);
  +			ERR_print_errors(bio_err);
  +			goto end;
  +			}
  +		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
  +		BIO_free(stmp);
  +		if (!sess)
  +			{
  +			BIO_printf(bio_err, "Can't open session file
%sn",
  +						sess_in);
  +			ERR_print_errors(bio_err);
  +			goto end;
  +			}
  +		SSL_set_session(con, sess);
  +		SSL_SESSION_free(sess);
  +		}
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (servername != NULL)
  +		{
  +		if (!SSL_set_tlsext_host_name(con,servername))
  +			{
  +			BIO_printf(bio_err,"Unable to set TLS servername
extension.n");
  +			ERR_print_errors(bio_err);
  +			goto end;
  +			}
  +		}
  +#endif
  +
   #ifndef OPENSSL_NO_KRB5
   	if (con  &&  (con->kssl_ctx = kssl_ctx_new())
!= NULL)
                   {
   -714,6 +816,13 
   		SSL_set_msg_callback(con, msg_cb);
   		SSL_set_msg_callback_arg(con, bio_c_out);
   		}
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (c_tlsextdebug)
  +		{
  +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
  +		SSL_set_tlsext_debug_arg(con, bio_c_out);
  +		}
  +#endif
   
   	SSL_set_bio(con,sbio,sbio);
   	SSL_set_connect_state(con);
   -837,6 +946,17 
   			if (in_init)
   				{
   				in_init=0;
  +				if (sess_out)
  +					{
  +					BIO *stmp = BIO_new_file(sess_out, "w");
  +					if (stmp)
  +						{
  +						PEM_write_bio_SSL_SESSION(stmp,
SSL_get_session(con));
  +						BIO_free(stmp);
  +						}
  +					else 
  +						BIO_printf(bio_err, "Error writing session
file %sn", sess_out);
  +					}
   				print_stuff(bio_c_out,con,full_log);
   				if (full_log > 0) full_log--;
   
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_server.c
 
============================================================
================
  $ cvs diff -u -r1.97.2.4 -r1.97.2.5 s_server.c
  --- openssl/apps/s_server.c	29 Nov 2006 20:47:11
-0000	1.97.2.4
  +++ openssl/apps/s_server.c	12 Aug 2007 18:58:59
-0000	1.97.2.5
   -238,6 +238,9 
   static int accept_socket= -1;
   
   #define TEST_CERT	"server.pem"
  +#ifndef OPENSSL_NO_TLSEXT
  +#define TEST_CERT2	"server2.pem"
  +#endif
   #undef PROG
   #define PROG		s_server_main
   
   -247,6 +250,9 
   static int s_server_verify=SSL_VERIFY_NONE;
   static int s_server_session_id_context = 1; /* anything
will do */
   static const char
*s_cert_file=TEST_CERT,*s_key_file=NULL;
  +#ifndef OPENSSL_NO_TLSEXT
  +static const char
*s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
  +#endif
   static char *s_dcert_file=NULL,*s_dkey_file=NULL;
   #ifdef FIONBIO
   static int s_nbio=0;
   -254,10 +260,16 
   static int s_nbio_test=0;
   int s_crlf=0;
   static SSL_CTX *ctx=NULL;
  +#ifndef OPENSSL_NO_TLSEXT
  +static SSL_CTX *ctx2=NULL;
  +#endif
   static int www=0;
   
   static BIO *bio_s_out=NULL;
   static int s_debug=0;
  +#ifndef OPENSSL_NO_TLSEXT
  +static int s_tlsextdebug=0;
  +#endif
   static int s_msg=0;
   static int s_quiet=0;
   
   -285,6 +297,11 
   	s_dkey_file=NULL;
   	s_cert_file=TEST_CERT;
   	s_key_file=NULL;
  +#ifndef OPENSSL_NO_TLSEXT
  +	s_cert_file2=TEST_CERT2;
  +	s_key_file2=NULL;
  +	ctx2=NULL;
  +#endif
   #ifdef FIONBIO
   	s_nbio=0;
   #endif
   -371,6 +388,14 
   #endif
   	BIO_printf(bio_err," -id_prefix arg - Generate
SSL/TLS session IDs prefixed by 'arg'n");
   	BIO_printf(bio_err," -rand file%cfile%c...n",
LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
  +#ifndef OPENSSL_NO_TLSEXT
  +	BIO_printf(bio_err," -servername host - servername
for HostName TLS extensionn");
  +	BIO_printf(bio_err," -servername_fatal - on
mismatch send fatal alert (default warning alert)n");
  +	BIO_printf(bio_err," -cert2 arg    - certificate
file to use for servernamen");
  +	BIO_printf(bio_err,"                 (default is
%s)n",TEST_CERT2);
  +	BIO_printf(bio_err," -key2 arg     - Private Key
file to use for servername, in cert file ifn");
  +	BIO_printf(bio_err,"                 not specified
(default is %s)n",TEST_CERT2);
  +#endif
   	}
   
   static int local_argc=0;
   -526,6 +551,39 
   }
   #endif
   
  +#ifndef OPENSSL_NO_TLSEXT
  +
  +/* This is a context that we pass to callbacks */
  +typedef struct tlsextctx_st {
  +   char * servername;
  +   BIO * biodebug;
  +   int extension_error;
  +} tlsextctx;
  +
  +
  +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad,
void *arg)
  +	{
  +	tlsextctx * p = (tlsextctx *) arg;
  +	const char * servername = SSL_get_servername(s,
TLSEXT_NAMETYPE_host_name);
  +        if (servername && p->biodebug) 
  +		BIO_printf(p->biodebug,"Hostname in TLS
extension: "%s"n",servername);
  +        
  +	if (!p->servername)
  +		return SSL_TLSEXT_ERR_NOACK;
  +	
  +	if (servername)
  +		{
  +    		if (strcmp(servername,p->servername)) 
  +			return p->extension_error;
  +		if (ctx2)
  +			{
  +			BIO_printf(p->biodebug,"Swiching server
context.n");
  +			SSL_set_SSL_CTX(s,ctx2);
  +			}     
  +		}
  +	return SSL_TLSEXT_ERR_OK;
  +}
  +#endif
   int MAIN(int, char **);
   
   int MAIN(int argc, char *argv[])
   -545,10 +603,7 
   	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
   	int state=0;
   	SSL_METHOD *meth=NULL;
  -#ifdef sock_type
  -#undef sock_type
  -#endif
  -    int sock_type=SOCK_STREAM;
  +        int socket_type=SOCK_STREAM;
   #ifndef OPENSSL_NO_ENGINE
   	ENGINE *e=NULL;
   #endif
   -559,6 +614,14 
   	int s_dcert_format = FORMAT_PEM, s_dkey_format =
FORMAT_PEM;
   	X509 *s_cert = NULL, *s_dcert = NULL;
   	EVP_PKEY *s_key = NULL, *s_dkey = NULL;
  +#ifndef OPENSSL_NO_TLSEXT
  +	EVP_PKEY *s_key2 = NULL;
  +	X509 *s_cert2 = NULL;
  +#endif
  +
  +#ifndef OPENSSL_NO_TLSEXT
  +        tlsextctx tlsextcbp = {NULL, NULL,
SSL_TLSEXT_ERR_ALERT_WARNING};
  +#endif
   
   #if !defined(OPENSSL_NO_SSL2) &&
!defined(OPENSSL_NO_SSL3)
   	meth=SSLv23_server_method();
   -724,6 +787,10 
   			}
   		else if	(strcmp(*argv,"-debug") == 0)
   			{ s_debug=1; }
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if	(strcmp(*argv,"-tlsextdebug") == 0)
  +			s_tlsextdebug=1;
  +#endif
   		else if	(strcmp(*argv,"-msg") == 0)
   			{ s_msg=1; }
   		else if	(strcmp(*argv,"-hack") == 0)
   -754,6 +821,10 
   			{ off|=SSL_OP_NO_SSLv3; }
   		else if	(strcmp(*argv,"-no_tls1") == 0)
   			{ off|=SSL_OP_NO_TLSv1; }
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if	(strcmp(*argv,"-no_ticket") == 0)
  +			{ off|=SSL_OP_NO_TICKET; }
  +#endif
   #ifndef OPENSSL_NO_SSL2
   		else if	(strcmp(*argv,"-ssl2") == 0)
   			{ meth=SSLv2_server_method(); }
   -770,7 +841,7 
   		else if	(strcmp(*argv,"-dtls1") == 0)
   			{ 
   			meth=DTLSv1_server_method();
  -			sock_type = SOCK_DGRAM;
  +			socket_type = SOCK_DGRAM;
   			}
   		else if (strcmp(*argv,"-timeout") == 0)
   			enable_timeouts = 1;
   -799,6 +870,25 
   			if (--argc < 1) goto bad;
   			inrand= *(++argv);
   			}
  +#ifndef OPENSSL_NO_TLSEXT
  +		else if (strcmp(*argv,"-servername") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			tlsextcbp.servername= *(++argv);
  +			}
  +		else if (strcmp(*argv,"-servername_fatal") ==
0)
  +			{ tlsextcbp.extension_error =
SSL_TLSEXT_ERR_ALERT_FATAL; }
  +		else if	(strcmp(*argv,"-cert2") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			s_cert_file2= *(++argv);
  +			}
  +		else if	(strcmp(*argv,"-key2") == 0)
  +			{
  +			if (--argc < 1) goto bad;
  +			s_key_file2= *(++argv);
  +			}
  +#endif
   		else
   			{
   			BIO_printf(bio_err,"unknown option
%sn",*argv);
   -831,6 +921,10 
   
   	if (s_key_file == NULL)
   		s_key_file = s_cert_file;
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (s_key_file2 == NULL)
  +		s_key_file2 = s_cert_file2;
  +#endif
   
   	if (nocert == 0)
   		{
   -850,8 +944,29 
   			ERR_print_errors(bio_err);
   			goto end;
   			}
  -		}
   
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (tlsextcbp.servername) 
  +			{
  +			s_key2 = load_key(bio_err, s_key_file2, s_key_format,
0, pass, e,
  +				"second server certificate private key
file");
  +			if (!s_key2)
  +				{
  +				ERR_print_errors(bio_err);
  +				goto end;
  +				}
  +			
  +			s_cert2 =
load_cert(bio_err,s_cert_file2,s_cert_format,
  +				NULL, e, "second server certificate
file");
  +			
  +			if (!s_cert2)
  +				{
  +				ERR_print_errors(bio_err);
  +				goto end;
  +				}
  +			}
  +#endif
  +		}
   	if (s_dcert_file)
   		{
   
   -908,6 +1023,10 
   		s_key_file=NULL;
   		s_dcert_file=NULL;
   		s_dkey_file=NULL;
  +#ifndef OPENSSL_NO_TLSEXT
  +		s_cert_file2=NULL;
  +		s_key_file2=NULL;
  +#endif
   		}
   
   	ctx=SSL_CTX_new(meth);
   -939,7 +1058,7 
   	/* DTLS: partial reads end up discarding unread UDP
bytes :-( 
   	 * Setting read ahead solves this problem.
   	 */
  -	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx,
1);
  +	if (socket_type == SOCK_DGRAM)
SSL_CTX_set_read_ahead(ctx, 1);
   
   	if (state)
SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
   
   -966,6 +1085,62 
   		}
   	store = SSL_CTX_get_cert_store(ctx);
   	X509_STORE_set_flags(store, vflags);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (s_cert2)
  +		{
  +		ctx2=SSL_CTX_new(meth);
  +		if (ctx2 == NULL)
  +			{
  +			ERR_print_errors(bio_err);
  +			goto end;
  +			}
  +		}
  +	
  +	if (ctx2)
  +		{
  +		BIO_printf(bio_s_out,"Setting secondary ctx
parametersn");
  +
  +		if (session_id_prefix)
  +			{
  +			if(strlen(session_id_prefix) >= 32)
  +				BIO_printf(bio_err,
  +					"warning: id_prefix is too long, only one new
session will be possiblen");
  +			else if(strlen(session_id_prefix) >= 16)
  +				BIO_printf(bio_err,
  +					"warning: id_prefix is too long if you use
SSLv2n");
  +			if(!SSL_CTX_set_generate_session_id(ctx2,
generate_session_id))
  +				{
  +				BIO_printf(bio_err,"error setting
'id_prefix'n");
  +				ERR_print_errors(bio_err);
  +				goto end;
  +				}
  +			BIO_printf(bio_err,"id_prefix '%s' set.n",
session_id_prefix);
  +			}
  +		SSL_CTX_set_quiet_shutdown(ctx2,1);
  +		if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
  +		if (hack)
SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_
BUG);
  +		SSL_CTX_set_options(ctx2,off);
  +
  +		/* DTLS: partial reads end up discarding unread UDP
bytes :-( 
  +		 * Setting read ahead solves this problem.
  +		 */
  +		if (socket_type == SOCK_DGRAM)
SSL_CTX_set_read_ahead(ctx2, 1);
  +
  +
  +		if (state)
SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
  +
  +		SSL_CTX_sess_set_cache_size(ctx2,128);
  +
  +		if
((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
  +			(!SSL_CTX_set_default_verify_paths(ctx2)))
  +			{
  +			ERR_print_errors(bio_err);
  +			}
  +		store = SSL_CTX_get_cert_store(ctx2);
  +		X509_STORE_set_flags(store, vflags);
  +		}
  +#endif 
  +
   
   #ifndef OPENSSL_NO_DH
   	if (!no_dhe)
   -989,6 +1164,24 
   		(void)BIO_flush(bio_s_out);
   
   		SSL_CTX_set_tmp_dh(ctx,dh);
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (ctx2)
  +			{
  +			if (!dhfile)
  +				{ 
  +				DH *dh2=load_dh_param(s_cert_file2);
  +				if (dh2 != NULL)
  +					{
  +					BIO_printf(bio_s_out,"Setting temp DH
parametersn");
  +					(void)BIO_flush(bio_s_out);
  +
  +					DH_free(dh);
  +					dh = dh2;
  +					}
  +				}
  +			SSL_CTX_set_tmp_dh(ctx2,dh);
  +			}
  +#endif
   		DH_free(dh);
   		}
   #endif
   -1034,12 +1227,20 
   		(void)BIO_flush(bio_s_out);
   
   		SSL_CTX_set_tmp_ecdh(ctx,ecdh);
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (ctx2) 
  +			SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
  +#endif
   		EC_KEY_free(ecdh);
   		}
   #endif
   	
   	if (!set_cert_key_stuff(ctx,s_cert,s_key))
   		goto end;
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (ctx2 &&
!set_cert_key_stuff(ctx2,s_cert2,s_key2))
  +		goto end; 
  +#endif
   	if (s_dcert != NULL)
   		{
   		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
   -1049,7 +1250,13 
   #ifndef OPENSSL_NO_RSA
   #if 1
   	if (!no_tmp_rsa)
  +		{
   		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (ctx2) 
  +			SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
  +#endif	
  +		}
   #else
   	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
   		{
   -1065,6 +1272,16 
   			ERR_print_errors(bio_err);
   			goto end;
   			}
  +#ifndef OPENSSL_NO_TLSEXT
  +			if (ctx2)
  +				{
  +				if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
  +					{
  +					ERR_print_errors(bio_err);
  +					goto end;
  +					}
  +				}
  +#endif
   		RSA_free(rsa);
   		BIO_printf(bio_s_out,"n");
   		}
   -1076,19 +1293,46 
   		BIO_printf(bio_err,"error setting cipher
listn");
   		ERR_print_errors(bio_err);
   		goto end;
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (ctx2 &&
!SSL_CTX_set_cipher_list(ctx2,cipher))
  +			{
  +			BIO_printf(bio_err,"error setting cipher
listn");
  +			ERR_print_errors(bio_err);
  +			goto end;
  +			}
  +#endif
   	}
  
	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
  
	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_ses
sion_id_context,
   		sizeof s_server_session_id_context);
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (ctx2)
  +		{
 
+		SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);

 
+		SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_
session_id_context,
  +			sizeof s_server_session_id_context);
  +
  +		tlsextcbp.biodebug = bio_s_out;
  +		SSL_CTX_set_tlsext_servername_callback(ctx2,
ssl_servername_cb);
  +		SSL_CTX_set_tlsext_servername_arg(ctx2,
&tlsextcbp);
  +		SSL_CTX_set_tlsext_servername_callback(ctx,
ssl_servername_cb);
  +		SSL_CTX_set_tlsext_servername_arg(ctx,
&tlsextcbp);
  +		}
  +#endif
   	if (CAfile != NULL)
  -	   
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfil
e));
  -
  +		{
 
+		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CA
file));
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (ctx2) 
 
+			SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(
CAfile));
  +#endif
  +		}
   	BIO_printf(bio_s_out,"ACCEPTn");
   	if (www)
  -		do_server(port,sock_type,&accept_socket,www_body,
context);
  +		do_server(port,socket_type,&accept_socket,www_body,
context);
   	else
  -		do_server(port,sock_type,&accept_socket,sv_body,
context);
  +		do_server(port,socket_type,&accept_socket,sv_body,
context);
   	print_stats(bio_s_out,ctx);
   	ret=0;
   end:
   -1105,6 +1349,13 
   		OPENSSL_free(pass);
   	if (dpass)
   		OPENSSL_free(dpass);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (ctx2 != NULL) SSL_CTX_free(ctx2);
  +	if (s_cert2)
  +		X509_free(s_cert2);
  +	if (s_key2)
  +		EVP_PKEY_free(s_key2);
  +#endif
   	if (bio_s_out != NULL)
   		{
           BIO_free(bio_s_out);
   -1171,6 +1422,13 
   
   	if (con == NULL) {
   		con=SSL_new(ctx);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (s_tlsextdebug)
  +		{
  +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
  +		SSL_set_tlsext_debug_arg(con, bio_s_out);
  +		}
  +#endif
   #ifndef OPENSSL_NO_KRB5
   		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
                           {
   -1241,6 +1499,13 
   		SSL_set_msg_callback(con, msg_cb);
   		SSL_set_msg_callback_arg(con, bio_s_out);
   		}
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (s_tlsextdebug)
  +		{
  +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
  +		SSL_set_tlsext_debug_arg(con, bio_s_out);
  +		}
  +#endif
   
   	width=s+1;
   	for (;;)
   -1606,6 +1871,13 
   	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
   
   	if ((con=SSL_new(ctx)) == NULL) goto err;
  +#ifndef OPENSSL_NO_TLSEXT
  +		if (s_tlsextdebug)
  +			{
  +			SSL_set_tlsext_debug_callback(con, tlsext_cb);
  +			SSL_set_tlsext_debug_arg(con, bio_s_out);
  +			}
  +#endif
   #ifndef OPENSSL_NO_KRB5
   	if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
   		{
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s23_clnt.c
 
============================================================
================
  $ cvs diff -u -r1.28.2.3 -r1.28.2.4 s23_clnt.c
  --- openssl/ssl/s23_clnt.c	29 Nov 2006 14:45:13
-0000	1.28.2.3
  +++ openssl/ssl/s23_clnt.c	12 Aug 2007 18:59:01
-0000	1.28.2.4
   -360,6 +360,13 
   				*(p++)=comp->id;
   				}
   			*(p++)=0; /* Add the NULL method */
  +#ifndef OPENSSL_NO_TLSEXT
  +			if ((p = ssl_add_clienthello_tlsext(s, p,
buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
  +				{
 
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
  +				return -1;
  +				}
  +#endif
   			
   			l = p-d;
   			*p = 42;
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s2_srvr.c
 
============================================================
================
  $ cvs diff -u -r1.46.2.2 -r1.46.2.3 s2_srvr.c
  --- openssl/ssl/s2_srvr.c	5 Dec 2005 17:32:20
-0000	1.46.2.2
  +++ openssl/ssl/s2_srvr.c	12 Aug 2007 18:59:01
-0000	1.46.2.3
   -607,7 +607,7 
   	else
   		{
  
		i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_s
pec_length]),
  -			s->s2->tmp.session_id_length);
  +			s->s2->tmp.session_id_length, NULL);
   		if (i == 1)
   			{ /* previous session */
   			s->hit=1;
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s3_clnt.c
 
============================================================
================
  $ cvs diff -u -r1.88.2.7 -r1.88.2.8 s3_clnt.c
  --- openssl/ssl/s3_clnt.c	9 Mar 2007 14:06:34
-0000	1.88.2.7
  +++ openssl/ssl/s3_clnt.c	12 Aug 2007 18:59:01
-0000	1.88.2.8
   -137,6 +137,9 
   
   static SSL_METHOD *ssl3_get_client_method(int ver);
   static int ca_dn_cmp(const X509_NAME * const *a,const
X509_NAME * const *b);
  +#ifndef OPENSSL_NO_TLSEXT
  +static int ssl3_check_finished(SSL *s);
  +#endif
   
   #ifndef OPENSSL_NO_ECDH
   static int curve_id2nid(int curve_id);
   -264,6 +267,17 
   
   		case SSL3_ST_CR_CERT_A:
   		case SSL3_ST_CR_CERT_B:
  +#ifndef OPENSSL_NO_TLSEXT
  +			ret=ssl3_check_finished(s);
  +			if (ret <= 0) goto end;
  +			if (ret == 2)
  +				{
  +				s->hit = 1;
  +				s->state=SSL3_ST_CR_FINISHED_A;
  +				s->init_num=0;
  +				break;
  +				}
  +#endif
   			/* Check if it is anon DH/ECDH */
   			if (!(s->s3->tmp.new_cipher->algorithms &
SSL_aNULL))
   				{
   -416,11 +430,27 
   				}
   			else
   				{
  +#ifndef OPENSSL_NO_TLSEXT
  +				/* Allow NewSessionTicket if ticket expected */
  +				if (s->tlsext_ticket_expected)
 
+					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_
A;
  +				else
  +#endif
  +				
   				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
   				}
   			s->init_num=0;
   			break;
   
  +#ifndef OPENSSL_NO_TLSEXT
  +		case SSL3_ST_CR_SESSION_TICKET_A:
  +		case SSL3_ST_CR_SESSION_TICKET_B:
  +			ret=ssl3_get_new_session_ticket(s);
  +			s->state=SSL3_ST_CR_FINISHED_A;
  +			s->init_num=0;
  +		break;
  +#endif
  +
   		case SSL3_ST_CR_FINISHED_A:
   		case SSL3_ST_CR_FINISHED_B:
   
   -600,7 +630,13 
   			}
   #endif
   		*(p++)=0; /* Add the NULL method */
  -		
  +#ifndef OPENSSL_NO_TLSEXT
  +		if ((p = ssl_add_clienthello_tlsext(s, p,
buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
  +			{
  +			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
  +			goto err;
  +			}
  +#endif		
   		l=(p-d);
   		d=buf;
   		*(d++)=SSL3_MT_CLIENT_HELLO;
   -634,7 +670,7 
   		SSL3_ST_CR_SRVR_HELLO_A,
   		SSL3_ST_CR_SRVR_HELLO_B,
   		-1,
  -		300, /* ?? */
  +		20000, /* ?? */
   		&ok);
   
   	if (!ok) return((int)n);
   -784,6 +820,24 
   		s->s3->tmp.new_compression=comp;
   		}
   #endif
  +#ifndef OPENSSL_NO_TLSEXT
  +	/* TLS extensions*/
  +	if (s->version > SSL3_VERSION)
  +		{
  +		if (!ssl_parse_serverhello_tlsext(s,&p,d,n,
&al))
  +			{
  +			/* 'al' set by ssl_parse_serverhello_tlsext */
 
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT);
  +			goto f_err; 
  +			}
  +		if (ssl_check_serverhello_tlsext(s) <= 0)
  +			{
 
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SERVERHELLO_TLS
EXT);
  +				goto err;
  +			}
  +		}
  +#endif
  +
   
   	if (p != (d+n))
   		{
   -1590,6 +1644,74 
   	{
   	return(X509_NAME_cmp(*a,*b));
   	}
  +#ifndef OPENSSL_NO_TLSEXT
  +int ssl3_get_new_session_ticket(SSL *s)
  +	{
  +	int ok,al,ret=0, ticklen;
  +	long n;
  +	const unsigned char *p;
  +	unsigned char *d;
  +
  +	n=s->method->ssl_get_message(s,
  +		SSL3_ST_CR_SESSION_TICKET_A,
  +		SSL3_ST_CR_SESSION_TICKET_B,
  +		-1,
  +		16384,
  +		&ok);
  +
  +	if (!ok)
  +		return((int)n);
  +
  +	if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
  +		{
  +		s->s3->tmp.reuse_message=1;
  +		return(1);
  +		}
  +	if (s->s3->tmp.message_type !=
SSL3_MT_NEWSESSION_TICKET)
  +		{
  +		al=SSL_AD_UNEXPECTED_MESSAGE;
 
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAG
E_TYPE);
  +		goto f_err;
  +		}
  +	if (n < 6)
  +		{
  +		/* need at least ticket_lifetime_hint + ticket length
*/
  +		al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
 
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MIS
MATCH);
  +		goto f_err;
  +		}
  +	p=d=(unsigned char *)s->init_msg;
  +	n2l(p, s->session->tlsext_tick_lifetime_hint);
  +	n2s(p, ticklen);
  +	/* ticket_lifetime_hint + ticket_length + ticket */
  +	if (ticklen + 6 != n)
  +		{
  +		al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
 
+		SSLerr(SSL_F_SSL3_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATC
H);
  +		goto f_err;
  +		}
  +	if (s->session->tlsext_tick)
  +		{
  +		OPENSSL_free(s->session->tlsext_tick);
  +		s->session->tlsext_ticklen = 0;
  +		}
  +	s->session->tlsext_tick =
OPENSSL_malloc(ticklen);
  +	if (!s->session->tlsext_tick)
  +		{
 
+		SSLerr(SSL_F_SSL3_NEW_SESSION_TICKET,ERR_R_MALLOC_FAILURE
);
  +		goto err;
  +		}
  +	memcpy(s->session->tlsext_tick, p, ticklen);
  +	s->session->tlsext_ticklen = ticklen;
  +	
  +	ret=1;
  +	return(ret);
  +f_err:
  +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
  +err:
  +	return(-1);
  +	}
  +#endif
   
   int ssl3_get_server_done(SSL *s)
   	{
   -2458,3 +2580,33 
   	return nid_list[curve_id];
   }
   #endif
  +
  +/* Check to see if handshake is full or resumed. Usually
this is just a
  + * case of checking to see if a cache hit has occurred.
In the case of
  + * session tickets we have to check the next message to
be sure.
  + */
  +
  +#ifndef OPENSSL_NO_TLSEXT
  +static int ssl3_check_finished(SSL *s)
  +	{
  +	int ok;
  +	long n;
  +	if (!s->session->tlsext_tick)
  +		return 1;
  +	/* this function is called when we really expect a
Certificate
  +	 * message, so permit appropriate message length */
  +	n=s->method->ssl_get_message(s,
  +		SSL3_ST_CR_CERT_A,
  +		SSL3_ST_CR_CERT_B,
  +		-1,
  +		s->max_cert_list,
  +		&ok);
  +	if (!ok) return((int)n);
  +	s->s3->tmp.reuse_message = 1;
  +	if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
  +		|| (s->s3->tmp.message_type ==
SSL3_MT_NEWSESSION_TICKET))
  +		return 2;
  +
  +	return 1;
  +	}
  +#endif
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s3_lib.c
 
============================================================
================
  $ cvs diff -u -r1.74.2.16 -r1.74.2.17 s3_lib.c
  --- openssl/ssl/s3_lib.c	23 Apr 2007 23:50:20
-0000	1.74.2.16
  +++ openssl/ssl/s3_lib.c	12 Aug 2007 18:59:01
-0000	1.74.2.17
   -1904,6 +1904,39 
   		}
   		break;
   #endif /* !OPENSSL_NO_ECDH */
  +#ifndef OPENSSL_NO_TLSEXT
  +	case SSL_CTRL_SET_TLSEXT_HOSTNAME:
  + 		if (larg == TLSEXT_NAMETYPE_host_name)
  +			{
  +			if (s->tlsext_hostname != NULL) 
  +				OPENSSL_free(s->tlsext_hostname);
  +			s->tlsext_hostname = NULL;
  +
  +			ret = 1;
  +			if (parg == NULL) 
  +				break;
  +			if (strlen((char *)parg) >
TLSEXT_MAXLEN_host_name)
  +				{
  +				SSLerr(SSL_F_SSL3_CTRL,
SSL_R_SSL3_EXT_INVALID_SERVERNAME);
  +				return 0;
  +				}
  +			if ((s->tlsext_hostname = BUF_strdup((char *)parg))
== NULL)
  +				{
  +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
  +				return 0;
  +				}
  +			}
  +		else
  +			{
  +			SSLerr(SSL_F_SSL3_CTRL,
SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
  +			return 0;
  +			}
  +		s->options |= SSL_OP_NO_SSLv2; /* can't use
extension w/ SSL 2.0 format */
  + 		break;
  +	case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
  +		s->tlsext_debug_arg=parg;
  +		break;
  +#endif /* !OPENSSL_NO_TLSEXT */
   	default:
   		break;
   		}
   -1955,6 +1988,12 
   		}
   		break;
   #endif
  +#ifndef OPENSSL_NO_TLSEXT
  +	case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
  +		s->tlsext_debug_cb=(void (*)(SSL *,int ,int,
  +					unsigned char *, int, void *))fp;
  +		break;
  +#endif
   	default:
   		break;
   		}
   -2088,6 +2127,11 
   		}
   		break;
   #endif /* !OPENSSL_NO_ECDH */
  +#ifndef OPENSSL_NO_TLSEXT
  +	case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
  +		ctx->tlsext_servername_arg=parg;
  +		break;
  +#endif /* !OPENSSL_NO_TLSEXT */
   	/* A Thawte special  */
   	case SSL_CTRL_EXTRA_CHAIN_CERT:
   		if (ctx->extra_certs == NULL)
   -2133,6 +2177,11 
   		}
   		break;
   #endif
  +#ifndef OPENSSL_NO_TLSEXT
  +	case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
  +		ctx->tlsext_servername_callback=(int (*)(SSL *,int
*,void *))fp;
  +		break;
  +#endif
   	default:
   		return(0);
   		}
   -2178,6 +2227,7 
   	SSL_CIPHER *c,*ret=NULL;
   	STACK_OF(SSL_CIPHER) *prio, *allow;
   	int i,j,ok;
  +
   	CERT *cert;
   	unsigned long alg,mask,emask;
   
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s3_srvr.c
 
============================================================
================
  $ cvs diff -u -r1.126.2.12 -r1.126.2.13 s3_srvr.c
  --- openssl/ssl/s3_srvr.c	9 Mar 2007 14:06:34
-0000	1.126.2.12
  +++ openssl/ssl/s3_srvr.c	12 Aug 2007 18:59:01
-0000	1.126.2.13
   -132,6 +132,7 
   #include <openssl/rand.h>
   #include <openssl/objects.h>
   #include <openssl/evp.h>
  +#include <openssl/hmac.h>
   #include <openssl/x509.h>
   #ifndef OPENSSL_NO_DH
   #include <openssl/dh.h>
   -143,7 +144,6 
   #include <openssl/md5.h>
   
   static SSL_METHOD *ssl3_get_server_method(int ver);
  -
   #ifndef OPENSSL_NO_ECDH
   static int nid2curve_id(int nid);
   #endif
   -494,11 +494,26 
   			if (ret <= 0) goto end;
   			if (s->hit)
   				s->state=SSL_ST_OK;
  +#ifndef OPENSSL_NO_TLSEXT
  +			else if (s->tlsext_ticket_expected)
  +				s->state=SSL3_ST_SW_SESSION_TICKET_A;
  +#endif
   			else
   				s->state=SSL3_ST_SW_CHANGE_A;
   			s->init_num=0;
   			break;
   
  +#ifndef OPENSSL_NO_TLSEXT
  +		case SSL3_ST_SW_SESSION_TICKET_A:
  +		case SSL3_ST_SW_SESSION_TICKET_B:
  +			ret=ssl3_send_newsession_ticket(s);
  +			if (ret <= 0) goto end;
  +			s->state=SSL3_ST_SW_CHANGE_A;
  +			s->init_num=0;
  +			break;
  +
  +#endif
  +
   		case SSL3_ST_SW_CHANGE_A:
   		case SSL3_ST_SW_CHANGE_B:
   
   -727,14 +742,14 
   	 * might be written that become totally unsecure when
compiled with
   	 * an earlier library version)
   	 */
  -	if (j == 0 || (s->new_session &&
(s->options &
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
  +	if ((s->new_session && (s->options &
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
   		{
   		if (!ssl_get_new_session(s,1))
   			goto err;
   		}
   	else
   		{
  -		i=ssl_get_prev_session(s,p,j);
  +		i=ssl_get_prev_session(s, p, j, d + n);
   		if (i == 1)
   			{ /* previous session */
   			s->hit=1;
   -897,6 +912,22 
   		goto f_err;
   		}
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	/* TLS extensions*/
  +	if (s->version > SSL3_VERSION)
  +		{
  +		if (!ssl_parse_clienthello_tlsext(s,&p,d,n,
&al))
  +			{
  +			/* 'al' set by ssl_parse_clienthello_tlsext */
 
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
  +			goto f_err;
  +			}
  +		}
  +		if (ssl_check_clienthello_tlsext(s) <= 0) {
 
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLS
EXT);
  +			goto err;
  +		}
  +#endif
   	/* Worst case, we will use the NULL compression, but if
we have other
   	 * options, we will now look for them.  We have i-1
compression
   	 * algorithms from the client, starting at q. */
   -1088,7 +1119,13 
   		else
   			*(p++)=s->s3->tmp.new_compression->id;
   #endif
  -
  +#ifndef OPENSSL_NO_TLSEXT
  +		if ((p = ssl_add_serverhello_tlsext(s, p,
buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
  +			{
 
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR
);
  +			return -1;
  +			}
  +#endif
   		/* do the header */
   		l=(p-d);
   		d=buf;
   -2615,3 +2652,90 
   	}
   }
   #endif
  +#ifndef OPENSSL_NO_TLSEXT
  +int ssl3_send_newsession_ticket(SSL *s)
  +	{
  +	if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
  +		{
  +		unsigned char *p, *senc, *macstart;
  +		int len, slen;
  +		unsigned int hlen;
  +		EVP_CIPHER_CTX ctx;
  +		HMAC_CTX hctx;
  +
  +		/* get session encoding length */
  +		slen = i2d_SSL_SESSION(s->session, NULL);
  +		/* Some length values are 16 bits, so forget it if
session is
  + 		 * too long
  + 		 */
  +		if (slen > 0xFF00)
  +			return -1;
  +		/* Grow buffer if need be: the length calculation is
as
  + 		 * follows 1 (size of message name) + 3 (message
length
  + 		 * bytes) + 4 (ticket lifetime hint) + 2 (ticket
length) +
  + 		 * 16 (key name) + max_iv_len (iv length) +
  + 		 * session_length + max_enc_block_size (max encrypted
session
  + 		 * length) + max_md_size (HMAC).
  + 		 */
  +		if (!BUF_MEM_grow(s->init_buf,
  +			26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
  +			EVP_MAX_MD_SIZE + slen))
  +			return -1;
  +		senc = OPENSSL_malloc(slen);
  +		if (!senc)
  +			return -1;
  +		p = senc;
  +		i2d_SSL_SESSION(s->session, &p);
  +
  +		p=(unsigned char *)s->init_buf->data;
  +		/* do the header */
  +		*(p++)=SSL3_MT_NEWSESSION_TICKET;
  +		/* Skip message length for now */
  +		p += 3;
  +		l2n(s->session->tlsext_tick_lifetime_hint, p);
  +		/* Skip ticket length for now */
  +		p += 2;
  +		/* Output key name */
  +		macstart = p;
  +		memcpy(p, s->ctx->tlsext_tick_key_name, 16);
  +		p += 16;
  +		/* Generate and output IV */
  +		RAND_pseudo_bytes(p, 16);
  +		EVP_CIPHER_CTX_init(&ctx);
  +		/* Encrypt session data */
  +		EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
  +					s->ctx->tlsext_tick_aes_key, p);
  +		p += 16;
  +		EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
  +		p += len;
  +		EVP_EncryptFinal(&ctx, p, &len);
  +		p += len;
  +		EVP_CIPHER_CTX_cleanup(&ctx);
  +
  +		HMAC_CTX_init(&hctx);
  +		HMAC_Init_ex(&hctx,
s->ctx->tlsext_tick_hmac_key, 16,
  +				EVP_sha1(), NULL);
  +		HMAC_Update(&hctx, macstart, p - macstart);
  +		HMAC_Final(&hctx, p, &hlen);
  +		HMAC_CTX_cleanup(&hctx);
  +
  +		p += hlen;
  +		/* Now write out lengths: p points to end of data
written */
  +		/* Total length */
  +		len = p - (unsigned char *)s->init_buf->data;
  +		p=(unsigned char *)s->init_buf->data + 1;
  +		l2n3(len - 4, p); /* Message length */
  +		p += 4;
  +		s2n(len - 10, p);  /* Ticket length */
  +
  +		/* number of bytes to write */
  +		s->init_num= len;
  +		s->state=SSL3_ST_SW_SESSION_TICKET_B;
  +		s->init_off=0;
  +		OPENSSL_free(senc);
  +		}
  +
  +	/* SSL3_ST_SW_SESSION_TICKET_B */
  +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
  +	}
  +#endif
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl.h
 
============================================================
================
  $ cvs diff -u -r1.161.2.11 -r1.161.2.12 ssl.h
  --- openssl/ssl/ssl.h	25 Apr 2007 07:58:32
-0000	1.161.2.11
  +++ openssl/ssl/ssl.h	12 Aug 2007 18:59:02
-0000	1.161.2.12
   -474,6 +474,13 
   	/* These are used to make removal of session-ids more
   	 * efficient and to implement a maximum cache size. */
   	struct ssl_session_st *prev,*next;
  +#ifndef OPENSSL_NO_TLSEXT
  +	char *tlsext_hostname;
  +	/* RFC4507 info */
  +	unsigned char *tlsext_tick;	/* Session ticket */
  +	size_t	tlsext_ticklen;		/* Session ticket length */	
  +	long tlsext_tick_lifetime_hint;	/* Session lifetime hint
in seconds */
  +#endif
   	} SSL_SESSION;
   
   
   -502,6 +509,8 
   #define SSL_OP_NO_QUERY_MTU                 0x00001000L
   /* Turn on Cookie Exchange (on relevant for servers) */
   #define SSL_OP_COOKIE_EXCHANGE              0x00002000L
  +/* Don't use RFC4507 ticket extension */
  +#define SSL_OP_NO_TICKET	            0x00004000L
   
   /* As server, disallow session resumption on
renegotiation */
   #define
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
   -749,6 +758,17 
   #endif
   
   	int quiet_shutdown;
  +
  +#ifndef OPENSSL_NO_TLSEXT
  +	/* TLS extensions servername callback */
  +	int (*tlsext_servername_callback)(SSL*, int *, void *);
  +	void *tlsext_servername_arg;
  +	/* RFC 4507 session ticket keys */
  +	unsigned char tlsext_tick_key_name[16];
  +	unsigned char tlsext_tick_hmac_key[16];
  +	unsigned char tlsext_tick_aes_key[16];
  +#endif
  +
   	};
   
   #define SSL_SESS_CACHE_OFF			0x0000
   -970,6 +990,26 
   	int first_packet;
   	int client_version;	/* what was passed, used for
   				 * SSLv3/TLS rollback check */
  +	unsigned int max_send_fragment;
  +#ifndef OPENSSL_NO_TLSEXT
  +	/* TLS extension debug callback */
  +	void (*tlsext_debug_cb)(SSL *s, int client_server, int
type,
  +					unsigned char *data, int len,
  +					void *arg);
  +	void *tlsext_debug_arg;
  +	char *tlsext_hostname;
  +	int servername_done;   /* no further mod of servername 
  +	                          0 : call the servername
extension callback.
  +	                          1 : prepare 2, allow last ack
just after in server callback.
  +	                          2 : don't call servername
callback, no ack in server hello
  +	                       */
  +	/* RFC4507 session ticket expected to be received or
sent */
  +	int tlsext_ticket_expected;
  +	SSL_CTX * initial_ctx; /* initial ctx, used to store
sessions */
  +#define session_ctx initial_ctx
  +#else
  +#define session_ctx ctx
  +#endif
   	};
   
   #ifdef __cplusplus
   -1115,6 +1155,9 
   #define SSL_AD_INTERNAL_ERROR		TLS1_AD_INTERNAL_ERROR	/*
fatal */
   #define SSL_AD_USER_CANCELLED		TLS1_AD_USER_CANCELLED
   #define
SSL_AD_NO_RENEGOTIATION		TLS1_AD_NO_RENEGOTIATION
  +#define
SSL_AD_UNSUPPORTED_EXTENSION	TLS1_AD_UNSUPPORTED_EXTENSION
  +#define SSL_AD_CERTIFICATE_UNOBTAINABLE
TLS1_AD_CERTIFICATE_UNOBTAINABLE
  +#define
SSL_AD_UNRECOGNIZED_NAME	TLS1_AD_UNRECOGNIZED_NAME
   
   #define SSL_ERROR_NONE			0
   #define SSL_ERROR_SSL			1
   -1173,6 +1216,15 
   #define SSL_CTRL_GET_MAX_CERT_LIST		50
   #define SSL_CTRL_SET_MAX_CERT_LIST		51
   
  +/* see tls1.h for macros based on these */
  +#ifndef OPENSSL_NO_TLSEXT
  +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB	53
  +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG	54
  +#define SSL_CTRL_SET_TLSEXT_HOSTNAME		55
  +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB		56
  +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG		57
  +#endif
  +
   #define SSL_session_reused(ssl) 
   	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
   #define SSL_num_renegotiations(ssl) 
   -1445,6 +1497,7 
   SSL_SESSION *SSL_get_session(const SSL *ssl);
   SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a
reference count */
   SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
  +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx);
   void SSL_set_info_callback(SSL *ssl,
   			   void (*cb)(const SSL *ssl,int type,int val));
   void (*SSL_get_info_callback(const SSL *ssl))(const SSL
*ssl,int type,int val);
   -1621,10 +1674,12 
   #define SSL_F_SSL3_GET_FINISHED				 140
   #define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
   #define SSL_F_SSL3_GET_MESSAGE				 142
  +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET		 283
   #define SSL_F_SSL3_GET_RECORD				 143
   #define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
   #define SSL_F_SSL3_GET_SERVER_DONE			 145
   #define SSL_F_SSL3_GET_SERVER_HELLO			 146
  +#define SSL_F_SSL3_NEW_SESSION_TICKET			 284
   #define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
   #define SSL_F_SSL3_PEEK					 235
   #define SSL_F_SSL3_READ_BYTES				 148
   -1640,8 +1695,10 
   #define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
   #define SSL_F_SSL3_WRITE_BYTES				 158
   #define SSL_F_SSL3_WRITE_PENDING			 159
  +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 272
   #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
   #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
  +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 273
   #define SSL_F_SSL_BAD_METHOD				 160
   #define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
   #define SSL_F_SSL_CERT_DUP				 221
   -1649,6 +1706,7 
   #define SSL_F_SSL_CERT_INSTANTIATE			 214
   #define SSL_F_SSL_CERT_NEW				 162
   #define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
  +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 274
   #define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
   #define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
   #define SSL_F_SSL_CLEAR					 164
   -1681,6 +1739,8 
   #define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
   #define SSL_F_SSL_NEW					 186
   #define SSL_F_SSL_PEEK					 270
  +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 275
  +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 276
   #define SSL_F_SSL_READ					 223
   #define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
   #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
   -1763,6 +1823,7 
   #define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
   #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
   #define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
  +#define SSL_R_CLIENTHELLO_TLSEXT			 157
   #define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
   #define SSL_R_COMPRESSION_FAILURE			 141
   #define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	
307
   -1847,6 +1908,7 
   #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
   #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
   #define SSL_R_PACKET_LENGTH_TOO_LONG			 198
  +#define SSL_R_PARSE_TLSEXT				 223
   #define SSL_R_PATH_TOO_LONG				 270
   #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
   #define SSL_R_PEER_ERROR				 200
   -1870,11 +1932,14 
   #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
   #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
   #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
  +#define SSL_R_SERVERHELLO_TLSEXT			 224
   #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
   #define SSL_R_SHORT_READ				 219
   #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
   #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
   #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
  +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 225
  +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 226
   #define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
   #define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
   #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
   -1909,6 +1974,7 
   #define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
   #define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
   #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
  +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 227
   #define
SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
   #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	
234
   #define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl3.h
 
============================================================
================
  $ cvs diff -u -r1.30.2.2 -r1.30.2.3 ssl3.h
  --- openssl/ssl/ssl3.h	30 Sep 2005 23:38:20
-0000	1.30.2.2
  +++ openssl/ssl/ssl3.h	12 Aug 2007 18:59:02
-0000	1.30.2.3
   -481,6 +481,8 
   #define SSL3_ST_CR_CHANGE_B		(0x1C1|SSL_ST_CONNECT)
   #define SSL3_ST_CR_FINISHED_A		(0x1D0|SSL_ST_CONNECT)
   #define SSL3_ST_CR_FINISHED_B		(0x1D1|SSL_ST_CONNECT)
  +#define
SSL3_ST_CR_SESSION_TICKET_A	(0x1E0|SSL_ST_CONNECT)
  +#define
SSL3_ST_CR_SESSION_TICKET_B	(0x1E1|SSL_ST_CONNECT)
   
   /* server */
   /* extra state */
   -522,10 +524,13 
   #define SSL3_ST_SW_CHANGE_B		(0x1D1|SSL_ST_ACCEPT)
   #define SSL3_ST_SW_FINISHED_A		(0x1E0|SSL_ST_ACCEPT)
   #define SSL3_ST_SW_FINISHED_B		(0x1E1|SSL_ST_ACCEPT)
  +#define
SSL3_ST_SW_SESSION_TICKET_A	(0x1F0|SSL_ST_CONNECT)
  +#define
SSL3_ST_SW_SESSION_TICKET_B	(0x1F1|SSL_ST_CONNECT)
   
   #define SSL3_MT_HELLO_REQUEST			0
   #define SSL3_MT_CLIENT_HELLO			1
   #define SSL3_MT_SERVER_HELLO			2
  +#define	SSL3_MT_NEWSESSION_TICKET		4
   #define SSL3_MT_CERTIFICATE			11
   #define SSL3_MT_SERVER_KEY_EXCHANGE		12
   #define SSL3_MT_CERTIFICATE_REQUEST		13
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_asn1.c
 
============================================================
================
  $ cvs diff -u -r1.20.2.1 -r1.20.2.2 ssl_asn1.c
  --- openssl/ssl/ssl_asn1.c	5 Dec 2005 17:32:21
-0000	1.20.2.1
  +++ openssl/ssl/ssl_asn1.c	12 Aug 2007 18:59:02
-0000	1.20.2.2
   -78,6 +78,11 
   	ASN1_INTEGER time;
   	ASN1_INTEGER timeout;
   	ASN1_INTEGER verify_result;
  +#ifndef OPENSSL_NO_TLSEXT
  +	ASN1_OCTET_STRING tlsext_hostname;
  +	ASN1_INTEGER tlsext_tick_lifetime;
  +	ASN1_OCTET_STRING tlsext_tick;
  +#endif /* OPENSSL_NO_TLSEXT */
   	} SSL_SESSION_ASN1;
   
   int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
   -86,6 +91,10 
   	int v1=0,v2=0,v3=0,v4=0,v5=0;
   	unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
   	unsigned char
ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
  +#ifndef OPENSSL_NO_TLSEXT
  +	int v6=0,v9=0,v10=0;
  +	unsigned char ibuf6[LSIZE2];
  +#endif
   	long l;
   	SSL_SESSION_ASN1 a;
   	M_ASN1_I2D_vars(in);
   -178,7 +187,32 
  
		ASN1_INTEGER_set(&a.verify_result,in->verify_result
);
   		}
   
  -
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (in->tlsext_hostname)
  +                {
  +               
a.tlsext_hostname.length=strlen(in->tlsext_hostname);
  +               
a.tlsext_hostname.type=V_ASN1_OCTET_STRING;
  +                a.tlsext_hostname.data=(unsigned char
*)in->tlsext_hostname;
  +                }
  +	if (in->tlsext_tick)
  +                {
  +                a.tlsext_tick.length=
in->tlsext_ticklen;
  +                a.tlsext_tick.type=V_ASN1_OCTET_STRING;
  +                a.tlsext_tick.data=(unsigned char
*)in->tlsext_tick;
  +		/* If we have a ticket set session ID to empty because
  +		 * it will be bogus. 
  +		 */
  +		if (in->tlsext_ticklen)
  +			a.session_id.length=0;
  +                }
  +	if (in->tlsext_tick_lifetime_hint != 0)
  +		{
  +		a.tlsext_tick_lifetime.length=LSIZE2;
  +		a.tlsext_tick_lifetime.type=V_ASN1_INTEGER;
  +		a.tlsext_tick_lifetime.data=ibuf6;
 
+		ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsex
t_tick_lifetime_hint);
  +		}
  +#endif /* OPENSSL_NO_TLSEXT */
   	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
   	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
  
	M_ASN1_I2D_len(&(a.cipher),		i2d_ASN1_OCTET_STRING);
   -200,6 +234,14 
   	if (in->verify_result != X509_V_OK)
  
		M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INT
EGER,5,v5);
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (in->tlsext_tick_lifetime_hint)
  +      	
	M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime,
i2d_ASN1_INTEGER,9,v9);
  +	if (in->tlsext_tick)
  +        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick),
i2d_ASN1_OCTET_STRING,10,v10);
  +	if (in->tlsext_hostname)
  +        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname),
i2d_ASN1_OCTET_STRING,6,v6);
  +#endif /* OPENSSL_NO_TLSEXT */
   	M_ASN1_I2D_seq_total();
   
   	M_ASN1_I2D_put(&(a.version),		i2d_ASN1_INTEGER);
   -223,6 +265,14 
   			       v4);
   	if (in->verify_result != X509_V_OK)
  
		M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEG
ER,5,v5);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (in->tlsext_hostname)
  +        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname),
i2d_ASN1_OCTET_STRING,6,v6);
  +	if (in->tlsext_tick_lifetime_hint)
  +      	
	M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime,
i2d_ASN1_INTEGER,9,v9);
  +	if (in->tlsext_tick)
  +        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick),
i2d_ASN1_OCTET_STRING,10,v10);
  +#endif /* OPENSSL_NO_TLSEXT */
   	M_ASN1_I2D_finish();
   	}
   
   -394,5 +444,54 
   	else
   		ret->verify_result=X509_V_OK;
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	os.length=0;
  +	os.data=NULL;
  +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6);
  +	if (os.data)
  +		{
  +		ret->tlsext_hostname = BUF_strndup((char *)os.data,
os.length);
  +		OPENSSL_free(os.data);
  +		os.data = NULL;
  +		os.length = 0;
  +		}
  +	else
  +		ret->tlsext_hostname=NULL;
  +	ai.length=0;
  +	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
  +	if (ai.data != NULL)
  +		{
 
+		ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip);
  +		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
  +		}
  +	else
  +		ret->tlsext_tick_lifetime_hint=0;
  + 	os.length=0;
  + 	os.data=NULL;
  +  	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
  + 	if (os.data)
  + 		{
  +		ret->tlsext_tick = os.data;
  +		ret->tlsext_ticklen = os.length;
  + 		os.data = NULL;
  + 		os.length = 0;
  +#if 0
  +		/* There are two ways to detect a resumed ticket
sesion.
  +		 * One is to set a random session ID and then the
server
  +		 * must return a match in ServerHello. This allows the
normal
  +		 * client session ID matching to work.
  +		 */ 
  +		if (ret->session_id_length == 0)
  +			{
 
+			ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH
;
  +			RAND_pseudo_bytes(ret->session_id,
  +						ret->session_id_length);
  +			}
  +#endif
  + 		}
  +	else
  +		ret->tlsext_tick=NULL;
  +#endif /* OPENSSL_NO_TLSEXT */
  +
  
	M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION)
;
   	}
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_err.c
 
============================================================
================
  $ cvs diff -u -r1.53.2.4 -r1.53.2.5 ssl_err.c
  --- openssl/ssl/ssl_err.c	21 Nov 2006 20:14:46
-0000	1.53.2.4
  +++ openssl/ssl/ssl_err.c	12 Aug 2007 18:59:02
-0000	1.53.2.5
   -147,10 +147,12 
  
{ERR_FUNC(SSL_F_SSL3_GET_FINISHED),	"SSL3_GET_FINISHED&
quot;},
  
{ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE),	"SSL3_GET_KEY_E
XCHANGE"},
  
{ERR_FUNC(SSL_F_SSL3_GET_MESSAGE),	"SSL3_GET_MESSAGE&qu
ot;},
 
+{ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET),	"SSL3_GE
T_NEW_SESSION_TICKET"},
  
{ERR_FUNC(SSL_F_SSL3_GET_RECORD),	"SSL3_GET_RECORD"
;},
  
{ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),	"SSL3_GET
_SERVER_CERTIFICATE"},
  
{ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE),	"SSL3_GET_SERVER
_DONE"},
  
{ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO),	"SSL3_GET_SERVE
R_HELLO"},
 
+{ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET),	"SSL3_NEW_SE
SSION_TICKET"},
  
{ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN),	"SSL3_OUTPUT_C
ERT_CHAIN"},
   {ERR_FUNC(SSL_F_SSL3_PEEK),	"SSL3_PEEK"},
  
{ERR_FUNC(SSL_F_SSL3_READ_BYTES),	"SSL3_READ_BYTES"
;},
   -166,8 +168,10 
  
{ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK),	"SSL3_SETUP_KEY_
BLOCK"},
  
{ERR_FUNC(SSL_F_SSL3_WRITE_BYTES),	"SSL3_WRITE_BYTES&qu
ot;},
  
{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),	"SSL3_WRITE_PENDIN
G"},
 
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),	"SSL_ADD_
CLIENTHELLO_TLSEXT"},
  
{ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),	"S
SL_add_dir_cert_subjects_to_stack"},
  
{ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),	"
SSL_add_file_cert_subjects_to_stack"},
 
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),	"SSL_ADD_
SERVERHELLO_TLSEXT"},
  
{ERR_FUNC(SSL_F_SSL_BAD_METHOD),	"SSL_BAD_METHOD"}
,
  
{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST),	"SSL_BYTES_T
O_CIPHER_LIST"},
  
{ERR_FUNC(SSL_F_SSL_CERT_DUP),	"SSL_CERT_DUP"},
   -175,6 +179,7 
  
{ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE),	"SSL_CERT_INSTAN
TIATE"},
  
{ERR_FUNC(SSL_F_SSL_CERT_NEW),	"SSL_CERT_NEW"},
  
{ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_priv
ate_key"},
 
+{ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CH
ECK_SERVERHELLO_TLSEXT"},
  
{ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),	"SSL_CIPHE
R_PROCESS_RULESTR"},
  
{ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT),	"SSL_CIPHER_
STRENGTH_SORT"},
   {ERR_FUNC(SSL_F_SSL_CLEAR),	"SSL_clear"},
   -207,6 +212,8 
  
{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE),	"SSL_load_cli
ent_CA_file"},
   {ERR_FUNC(SSL_F_SSL_NEW),	"SSL_new"},
   {ERR_FUNC(SSL_F_SSL_PEEK),	"SSL_peek"},
 
+{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT),	"SSL_
PREPARE_CLIENTHELLO_TLSEXT"},
 
+{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT),	"SSL_
PREPARE_SERVERHELLO_TLSEXT"},
   {ERR_FUNC(SSL_F_SSL_READ),	"SSL_read"},
  
{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT),	"SSL_RSA_PRIV
ATE_DECRYPT"},
  
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT),	"SSL_RSA_PUBLI
C_ENCRYPT"},
   -292,6 +299,7 
   {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher
code wrong length"},
  
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher
or hash unavailable"},
   {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher
table src error"},
  +{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT)   
,"clienthello tlsext"},
  
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compress
ed length too long"},
   {ERR_REASON(SSL_R_COMPRESSION_FAILURE)  
,"compression failure"},
  
{ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),&
quot;compression id not within private range"},
   -376,6 +384,7 
  
{ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old
session cipher not returned"},
  
{ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only
tls allowed in fips mode"},
   {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet
length too long"},
  +{ERR_REASON(SSL_R_PARSE_TLSEXT)          ,"parse
tlsext"},
   {ERR_REASON(SSL_R_PATH_TOO_LONG)         ,"path too
long"},
  
{ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"p
eer did not return a certificate"},
   {ERR_REASON(SSL_R_PEER_ERROR)            ,"peer
error"},
   -399,11 +408,14 
   {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse
cert length not zero"},
   {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse
cert type not zero"},
   {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse
cipher list not zero"},
  +{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT)   
,"serverhello tlsext"},
  
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"se
ssion id context uninitialized"},
   {ERR_REASON(SSL_R_SHORT_READ)            ,"short
read"},
  
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),&qu
ot;signature for non signing certificate"},
  
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23
doing session id reuse"},
   {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2
connection id too long"},
  +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3
ext invalid servername"},
 
+{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"s
sl3 ext invalid servername type"},
   {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3
session id too long"},
   {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT),"ssl3
session id too short"},
  
{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),"sslv3
alert bad certificate"},
   -438,6 +450,7 
   {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1
alert unknown ca"},
   {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1
alert user cancelled"},
  
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),&quo
t;tls client cert req with anon cipher"},
 
+{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls
invalid ecpointformat list"},
  
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_
LIST),"tls peer did not respond with certificate
list"},
  
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),&
quot;tls rsa encrypted value length is wrong"},
  
{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tri
ed to use unsupported cipher"},
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_lib.c
 
============================================================
================
  $ cvs diff -u -r1.133.2.8 -r1.133.2.9 ssl_lib.c
  --- openssl/ssl/ssl_lib.c	29 Nov 2006 20:47:15
-0000	1.133.2.8
  +++ openssl/ssl/ssl_lib.c	12 Aug 2007 18:59:02
-0000	1.133.2.9
   -125,6 +125,7 
   #include <openssl/objects.h>
   #include <openssl/lhash.h>
   #include <openssl/x509v3.h>
  +#include <openssl/rand.h>
   #ifndef OPENSSL_NO_DH
   #include <openssl/dh.h>
   #endif
   -306,7 +307,13 
   
  
	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
   	s->ctx=ctx;
  -
  +#ifndef OPENSSL_NO_TLSEXT
  +	s->tlsext_debug_cb = 0;
  +	s->tlsext_debug_arg = NULL;
  +	s->tlsext_ticket_expected = 0;
 
+	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);

  +	s->initial_ctx=ctx;
  +#endif
   	s->verify_result=X509_V_OK;
   
   	s->method=ctx->method;
   -492,7 +499,9 
   	/* Free up if allocated */
   
   	if (s->ctx) SSL_CTX_free(s->ctx);
  -
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
  +#endif
   	if (s->client_CA != NULL)
   		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
   
   -1304,6 +1313,29 
   	return(NULL);
   	}
   
  +#ifndef OPENSSL_NO_TLSEXT
  +/** return a servername extension value if provided in
Client Hello, or NULL.
  + * So far, only host_name types are defined (RFC 3546).
  + */
  +
  +const char *SSL_get_servername(const SSL *s, const int
type)
  +	{
  +	if (type != TLSEXT_NAMETYPE_host_name)
  +		return NULL;
  +
  +	return s->session && !s->tlsext_hostname
?
  +		s->session->tlsext_hostname :
  +		s->tlsext_hostname;
  +	}
  +
  +int SSL_get_servername_type(const SSL *s)
  +	{
  +	if (s->session && (!s->tlsext_hostname ?
s->session->tlsext_hostname : s->tlsext_hostname))
  +		return TLSEXT_NAMETYPE_host_name;
  +	return -1;
  +	}
  +#endif
  +
   unsigned long SSL_SESSION_hash(const SSL_SESSION *a)
   	{
   	unsigned long l;
   -1453,6 +1485,17 
   	ret->extra_certs=NULL;
  
	ret->comp_methods=SSL_COMP_get_compression_methods();
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	ret->tlsext_servername_callback = 0;
  +	ret->tlsext_servername_arg = NULL;
  +	/* Setup RFC4507 ticket keys */
  +	if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16)
<= 0)
  +		|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <=
0)
  +		|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <=
0))
  +		ret->options |= SSL_OP_NO_TICKET;
  +
  +#endif
  +
   	return(ret);
   err:
   	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
   -2402,6 +2445,24 
   	return(ssl->ctx);
   	}
   
  +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
  +	{
  +	if (ssl->ctx == ctx)
  +		return ssl->ctx;
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (ctx == NULL)
  +		ctx = ssl->initial_ctx;
  +#endif
  +	if (ssl->cert != NULL)
  +		ssl_cert_free(ssl->cert);
  +	ssl->cert = ssl_cert_dup(ctx->cert);
 
+	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);

  +	if (ssl->ctx != NULL)
  +		SSL_CTX_free(ssl->ctx); /* decrement reference count
*/
  +	ssl->ctx = ctx;
  +	return(ssl->ctx);
  +	}
  +
   #ifndef OPENSSL_NO_STDIO
   int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
   	{
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_locl.h
 
============================================================
================
  $ cvs diff -u -r1.63.2.5 -r1.63.2.6 ssl_locl.h
  --- openssl/ssl/ssl_locl.h	23 Apr 2007 23:50:22
-0000	1.63.2.5
  +++ openssl/ssl/ssl_locl.h	12 Aug 2007 18:59:02
-0000	1.63.2.6
   -716,7 +716,7 
   void ssl_sess_cert_free(SESS_CERT *sc);
   int ssl_set_peer_cert_type(SESS_CERT *c, int type);
   int ssl_get_new_session(SSL *s, int session);
  -int ssl_get_prev_session(SSL *s, unsigned char
*session,int len);
  +int ssl_get_prev_session(SSL *s, unsigned char
*session,int len, const unsigned char *limit);
   int ssl_cipher_id_cmp(const SSL_CIPHER *a,const
SSL_CIPHER *b);
   int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
   			const SSL_CIPHER * const *bp);
   -776,6 +776,7 
   int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned
char *p);
   void ssl3_init_finished_mac(SSL *s);
   int ssl3_send_server_certificate(SSL *s);
  +int ssl3_send_newsession_ticket(SSL *s);
   int ssl3_get_finished(SSL *s,int state_a,int state_b);
   int ssl3_setup_key_block(SSL *s);
   int ssl3_send_change_cipher_spec(SSL *s,int state_a,int
state_b);
   -866,6 +867,7 
   int ssl3_client_hello(SSL *s);
   int ssl3_get_server_hello(SSL *s);
   int ssl3_get_certificate_request(SSL *s);
  +int ssl3_get_new_session_ticket(SSL *s);
   int ssl3_get_server_done(SSL *s);
   int ssl3_send_client_verify(SSL *s);
   int ssl3_send_client_certificate(SSL *s);
   -947,5 +949,19 
   
   SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
   
  +#ifndef OPENSSL_NO_TLSEXT
  +unsigned char *ssl_add_clienthello_tlsext(SSL *s,
unsigned char *p, unsigned char *limit); 
  +unsigned char *ssl_add_serverhello_tlsext(SSL *s,
unsigned char *p, unsigned char *limit); 
  +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char
**data, unsigned char *d, int n, int *al);
  +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char
**data, unsigned char *d, int n, int *al);
  +int ssl_prepare_clienthello_tlsext(SSL *s);
  +int ssl_prepare_serverhello_tlsext(SSL *s);
  +int ssl_check_clienthello_tlsext(SSL *s);
  +int ssl_check_serverhello_tlsext(SSL *s);
  +int tls1_process_ticket(SSL *s, unsigned char
*session_id, int len,
  +				const unsigned char *limit, SSL_SESSION **ret);
  +EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const
EVP_MD *md) ;
  +void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
  +#endif
   
   #endif
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_sess.c
 
============================================================
================
  $ cvs diff -u -r1.51.2.6 -r1.51.2.7 ssl_sess.c
  --- openssl/ssl/ssl_sess.c	21 Mar 2007 14:33:01
-0000	1.51.2.6
  +++ openssl/ssl/ssl_sess.c	12 Aug 2007 18:59:03
-0000	1.51.2.7
   -122,6 +122,9 
   	ss->prev=NULL;
   	ss->next=NULL;
   	ss->compress_meth=0;
  +#ifndef OPENSSL_NO_TLSEXT
  +	ss->tlsext_hostname = NULL; 
  +#endif
   	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss,
&ss->ex_data);
   	return(ss);
   	}
   -216,6 +219,14 
   			SSL_SESSION_free(ss);
   			return(0);
   			}
  +#ifndef OPENSSL_NO_TLSEXT
  +		/* If RFC4507 ticket use empty session ID */
  +		if (s->tlsext_ticket_expected)
  +			{
  +			ss->session_id_length = 0;
  +			goto sess_id_done;
  +			}
  +#endif
   		/* Choose which callback will set the session ID */
   		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
   		if(s->generate_session_id)
   -257,6 +268,17 
   			SSL_SESSION_free(ss);
   			return(0);
   			}
  +#ifndef OPENSSL_NO_TLSEXT
  +		sess_id_done:
  +		if (s->tlsext_hostname) {
  +			ss->tlsext_hostname =
BUF_strdup(s->tlsext_hostname);
  +			if (ss->tlsext_hostname == NULL) {
  +				SSLerr(SSL_F_SSL_GET_NEW_SESSION,
ERR_R_INTERNAL_ERROR);
  +				SSL_SESSION_free(ss);
  +				return 0;
  +				}
  +			}
  +#endif
   		}
   	else
   		{
   -278,21 +300,39 
   	return(1);
   	}
   
  -int ssl_get_prev_session(SSL *s, unsigned char
*session_id, int len)
  +int ssl_get_prev_session(SSL *s, unsigned char
*session_id, int len,
  +			const unsigned char *limit)
   	{
   	/* This is used only by servers. */
   
  -	SSL_SESSION *ret=NULL,data;
  +	SSL_SESSION *ret=NULL;
   	int fatal = 0;
  -
  -	data.ssl_version=s->version;
  -	data.session_id_length=len;
  +#ifndef OPENSSL_NO_TLSEXT
  +	int r;
  +#endif
  +  
   	if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
   		goto err;
  -	memcpy(data.session_id,session_id,len);
  -
  +#ifndef OPENSSL_NO_TLSEXT
  + 	r = tls1_process_ticket(s, session_id, len, limit,
&ret);
  +	if (r == -1)
  +		{
  +		fatal = 1;
  + 		goto err;
  +		}
  +	else if (r == 0)
  +		goto err;
  +	else if (!ret &&
!(s->session_ctx->session_cache_mode &
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
  +#else
   	if (!(s->ctx->session_cache_mode &
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
  +#endif
   		{
  +		SSL_SESSION data;
  +		data.ssl_version=s->version;
  +		data.session_id_length=len;
  +		if (len == 0)
  +			return 0;
  + 		memcpy(data.session_id,session_id,len);
   		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
   		ret=(SSL_SESSION
*)lh_retrieve(s->ctx->sessions,&data);
   		if (ret != NULL)
   -548,6 +588,10 
   	if (ss->sess_cert != NULL)
ssl_sess_cert_free(ss->sess_cert);
   	if (ss->peer != NULL) X509_free(ss->peer);
   	if (ss->ciphers != NULL)
sk_SSL_CIPHER_free(ss->ciphers);
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (ss->tlsext_hostname != NULL)
OPENSSL_free(ss->tlsext_hostname);
  +	if (ss->tlsext_tick != NULL)
OPENSSL_free(ss->tlsext_tick);
  +#endif
   	OPENSSL_cleanse(ss,sizeof(*ss));
   	OPENSSL_free(ss);
   	}
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_txt.c
 
============================================================
================
  $ cvs diff -u -r1.14.2.2 -r1.14.2.3 ssl_txt.c
  --- openssl/ssl/ssl_txt.c	30 Sep 2005 23:38:20
-0000	1.14.2.2
  +++ openssl/ssl/ssl_txt.c	12 Aug 2007 18:59:03
-0000	1.14.2.3
   -151,6 +151,21 
   			if
(BIO_printf(bp,"%02X",x->krb5_client_princ[i])
<= 0) goto err;
   			}
   #endif /* OPENSSL_NO_KRB5 */
  +#ifndef OPENSSL_NO_TLSEXT
  +	if (x->tlsext_tick_lifetime_hint)
  +		{
  +		if (BIO_printf(bp,
  +			"n    TLS session ticket lifetime hint: %ld
(seconds)",
  +			x->tlsext_tick_lifetime_hint) <=0)
  +			goto err;
  +		}
  +	if (x->tlsext_tick)
  +		{
  +		if (BIO_puts(bp, "n    TLS session
ticket:n") <= 0) goto err;
  +		if (BIO_dump_indent(bp, (char *)x->tlsext_tick,
x->tlsext_ticklen, 4) <= 0)
  +			goto err;
  +		}
  +#endif
   #ifndef OPENSSL_NO_COMP
   	if (x->compress_meth != 0)
   		{
   .
  patch -p0 <<' .'
  Index: openssl/ssl/t1_lib.c
 
============================================================
================
  $ cvs diff -u -r1.13.2.2 -r1.13.2.3 t1_lib.c
  --- openssl/ssl/t1_lib.c	21 Jan 2007 16:07:25
-0000	1.13.2.2
  +++ openssl/ssl/t1_lib.c	12 Aug 2007 18:59:03
-0000	1.13.2.3
   -58,10 +58,18 
   
   #include <stdio.h>
   #include <openssl/objects.h>
  +#include <openssl/evp.h>
  +#include <openssl/hmac.h>
   #include "ssl_locl.h"
   
   const char tls1_version_str[]="TLSv1"
OPENSSL_VERSION_PTEXT;
   
  +#ifndef OPENSSL_NO_TLSEXT
  +static int tls_decrypt_ticket(SSL *s, const unsigned char
*tick, int ticklen,
  +				const unsigned char *sess_id, int sesslen,
  +				SSL_SESSION **psess);
  +#endif
  +
   SSL3_ENC_METHOD TLSv1_enc_data={
   	tls1_enc,
   	tls1_mac,
   -117,3 +125,506 
   	return(0);
   	}
   #endif
  +
  +#ifndef OPENSSL_NO_TLSEXT
  +unsigned char *ssl_add_clienthello_tlsext(SSL *s,
unsigned char *p, unsigned char *limit)
  +	{
  +	int extdatalen=0;
  +	unsigned char *ret = p;
  +
  +	ret+=2;
  +
  +	if (ret>=limit) return NULL; /* this really never
occurs, but ... */
  +
  + 	if (s->tlsext_hostname != NULL)
  +		{ 
  +		/* Add TLS extension servername to the Client Hello
message */
  +		unsigned long size_str;
  +		long lenmax; 
  +
  +		/* check for enough space.
  +		   4 for the servername type and entension length
  +		   2 for servernamelist length
  +		   1 for the hostname type
  +		   2 for hostname length
  +		   + hostname length 
  +		*/
  +		   
  +		if ((lenmax = limit - p - 9) < 0 
  +		|| (size_str = strlen(s->tlsext_hostname)) >
(unsigned long)lenmax) 
  +			return NULL;
  +			
  +		/* extension type and length */
  +		s2n(TLSEXT_TYPE_server_name,ret); 
  +		s2n(size_str+5,ret);
  +		
  +		/* length of servername list */
  +		s2n(size_str+3,ret);
  +	
  +		/* hostname type, length and hostname */
  +		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
  +		s2n(size_str,ret);
  +		memcpy(ret, s->tlsext_hostname, size_str);
  +		ret+=size_str;
  +
  +		}
  +
  +	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
  +		{
  +		int ticklen;
  +		if (s->session &&
s->session->tlsext_tick)
  +			ticklen = s->session->tlsext_ticklen;
  +		else
  +			ticklen = 0;
  +		/* Check for enough room 2 for extension type, 2 for
len
  + 		 * rest for ticket
  +  		 */
  +		if (limit - p - 4 - ticklen < 0)
  +			return NULL;
  +		s2n(TLSEXT_TYPE_session_ticket,ret); 
  +		s2n(ticklen,ret);
  +		if (ticklen)
  +			{
  +			memcpy(ret, s->session->tlsext_tick, ticklen);
  +			ret += ticklen;
  +			}
  +		}
  +
  +	if ((extdatalen = ret-p-2)== 0) 
  +		return p;
  +
  +	s2n(extdatalen,p);
  +	return ret;
  +	}
  +
  +unsigned char *ssl_add_serverhello_tlsext(SSL *s,
unsigned char *p, unsigned char *limit)
  +	{
  +	int extdatalen=0;
  +	unsigned char *ret = p;
  +
  +	ret+=2;
  +	if (ret>=limit) return NULL; /* this really never
occurs, but ... */
  +
  +	if (!s->hit && s->servername_done == 1
&& s->session->tlsext_hostname != NULL)
  +		{ 
  +		if (limit - p - 4 < 0) return NULL; 
  +
  +		s2n(TLSEXT_TYPE_server_name,ret);
  +		s2n(0,ret);
  +		}
  +	
  +	if (s->tlsext_ticket_expected
  +		&& !(SSL_get_options(s) &
SSL_OP_NO_TICKET)) 
  +		{ 
  +		if (limit - p - 4 < 0) return NULL; 
  +		s2n(TLSEXT_TYPE_session_ticket,ret);
  +		s2n(0,ret);
  +		}
  +		
  +	if ((extdatalen = ret-p-2)== 0) 
  +		return p;
  +
  +	s2n(extdatalen,p);
  +	return ret;
  +	}
  +
  +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char
**p, unsigned char *d, int n, int *al)
  +	{
  +	unsigned short type;
  +	unsigned short size;
  +	unsigned short len;
  +	unsigned char *data = *p;
  +	s->servername_done = 0;
  +
  +	if (data >= (d+n-2))
  +		return 1;
  +	n2s(data,len);
  +
  +	if (data > (d+n-len)) 
  +		return 1;
  +
  +	while (data <= (d+n-4))
  +		{
  +		n2s(data,type);
  +		n2s(data,size);
  +
  +		if (data+size > (d+n))
  +	   		return 1;
  +
  +		if (s->tlsext_debug_cb)
  +			s->tlsext_debug_cb(s, 0, type, data, size,
  +						s->tlsext_debug_arg);
  +/* The servername extension is treated as follows:
  +
  +   - Only the hostname type is supported with a maximum
length of 255.
  +   - The servername is rejected if too long or if it
contains zeros,
  +     in which case an fatal alert is generated.
  +   - The servername field is maintained together with the
session cache.
  +   - When a session is resumed, the servername call back
invoked in order
  +     to allow the application to position itself to the
right context. 
  +   - The servername is acknowledged if it is new for a
session or when 
  +     it is identical to a previously used for the same
session. 
  +     Applications can control the behaviour.  They can at
any time
  +     set a 'desirable' servername for a new SSL object.
This can be the
  +     case for example with HTTPS when a Host: header
field is received and
  +     a renegotiation is requested. In this case, a
possible servername
  +     presented in the new client hello is only
acknowledged if it matches
  +     the value of the Host: field. 
  +   - Applications must  use
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
  +     if they provide for changing an explicit servername
context for the session,
  +     i.e. when the session has been established with a
servername extension. 
  +   - On session reconnect, the servername extension may
be absent. 
  +
  +*/      
  +
  +		if (type == TLSEXT_TYPE_server_name)
  +			{
  +			unsigned char *sdata;
  +			int servname_type;
  +			int dsize; 
  +		
  +			if (size < 2) 
  +				{
  +				*al = SSL_AD_DECODE_ERROR;
  +				return 0;
  +				}
  +			n2s(data,dsize);  
  +			size -= 2;
  +			if (dsize > size  ) 
  +				{
  +				*al = SSL_AD_DECODE_ERROR;
  +				return 0;
  +				} 
  +
  +			sdata = data;
  +			while (dsize > 3) 
  +				{
  +	 			servname_type = *(sdata++); 
  +				n2s(sdata,len);
  +				dsize -= 3;
  +
  +				if (len > dsize) 
  +					{
  +					*al = SSL_AD_DECODE_ERROR;
  +					return 0;
  +					}
  +				if (s->servername_done == 0)
  +				switch (servname_type)
  +					{
  +				case TLSEXT_NAMETYPE_host_name:
  +					if (s->session->tlsext_hostname == NULL)
  +						{
  +						if (len > TLSEXT_MAXLEN_host_name || 
  +							((s->session->tlsext_hostname =
OPENSSL_malloc(len+1)) == NULL))
  +							{
  +							*al = TLS1_AD_UNRECOGNIZED_NAME;
  +							return 0;
  +							}
  +						memcpy(s->session->tlsext_hostname, sdata,
len);
  +						s->session->tlsext_hostname[len]='';
  +						if (strlen(s->session->tlsext_hostname) !=
len) {
  +							OPENSSL_free(s->session->tlsext_hostname);
  +							*al = TLS1_AD_UNRECOGNIZED_NAME;
  +							return 0;
  +						}
  +						s->servername_done = 1; 
  +
  +						}
  +					else 
  +						s->servername_done =
strlen(s->session->tlsext_hostname) == len 
  +							&&
strncmp(s->session->tlsext_hostname, (char *)sdata,
len) == 0;
  +					
  +					break;
  +
  +				default:
  +					break;
  +					}
  +				 
  +				dsize -= len;
  +				}
  +			if (dsize != 0) 
  +				{
  +				*al = SSL_AD_DECODE_ERROR;
  +				return 0;
  +				}
  +
  +			}
  +		/* session ticket processed earlier */
  +
  +		data+=size;		
  +		}
  +
  +	*p = data;
  +	return 1;
  +	}
  +
  +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char
**p, unsigned char *d, int n, int *al)
  +	{
  +	unsigned short type;
  +	unsigned short size;
  +	unsigned short len;  
  +	unsigned char *data = *p;
  +
  +	int tlsext_servername = 0;
  +
  +	if (data >= (d+n-2))
  +		return 1;
  +
  +	n2s(data,len);
  +
  +	while(data <= (d+n-4))
  +		{
  +		n2s(data,type);
  +		n2s(data,size);
  +
  +		if (data+size > (d+n))
  +	   		return 1;
  +
  +		if (s->tlsext_debug_cb)
  +			s->tlsext_debug_cb(s, 1, type, data, size,
  +						s->tlsext_debug_arg);
  +
  +		if (type == TLSEXT_TYPE_server_name)
  +			{
  +			if (s->tlsext_hostname == NULL || size > 0)
  +				{
  +				*al = TLS1_AD_UNRECOGNIZED_NAME;
  +				return 0;
  +				}
  +			tlsext_servername = 1;   
  +			}
  +		else if (type == TLSEXT_TYPE_session_ticket)
  +			{
  +			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
  +				|| (size > 0))
  +				{
  +				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
  +				return 0;
  +				}
  +			s->tlsext_ticket_expected = 1;
  +			}
  +
  +		data+=size;		
  +		}
  +
  +	if (data != d+n)
  +		{
  +		*al = SSL_AD_DECODE_ERROR;
  +		return 0;
  +		}
  +
  +	if (!s->hit && tlsext_servername == 1)
  +		{
  + 		if (s->tlsext_hostname)
  +			{
  +			if (s->session->tlsext_hostname == NULL)
  +				{
  +				s->session->tlsext_hostname =
BUF_strdup(s->tlsext_hostname);	
  +				if (!s->session->tlsext_hostname)
  +					{
  +					*al = SSL_AD_UNRECOGNIZED_NAME;
  +					return 0;
  +					}
  +				}
  +			else 
  +				{
  +				*al = SSL_AD_DECODE_ERROR;
  +				return 0;
  +				}
  +			}
  +		}
  +
  +	*p = data;
  +	return 1;
  +	}
  +
  +int ssl_check_clienthello_tlsext(SSL *s)
  +	{
  +	int ret=SSL_TLSEXT_ERR_NOACK;
  +	int al = SSL_AD_UNRECOGNIZED_NAME;
  +
  +	if (s->ctx != NULL &&
s->ctx->tlsext_servername_callback != 0) 
  +		ret = s->ctx->tlsext_servername_callback(s,
&al, s->ctx->tlsext_servername_arg);
  +	else if (s->initial_ctx != NULL &&
s->initial_ctx->tlsext_servername_callback != 0) 		
  +		ret =
s->initial_ctx->tlsext_servername_callback(s, &al,
s->initial_ctx->tlsext_servername_arg);
  +
  +	switch (ret)
  +		{
  +		case SSL_TLSEXT_ERR_ALERT_FATAL:
  +			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
  +			return -1;
  +
  +		case SSL_TLSEXT_ERR_ALERT_WARNING:
  +			ssl3_send_alert(s,SSL3_AL_WARNING,al);
  +			return 1; 
  +					
  +		case SSL_TLSEXT_ERR_NOACK:
  +			s->servername_done=0;
  +			default:
  +		return 1;
  +		}
  +	}
  +
  +int ssl_check_serverhello_tlsext(SSL *s)
  +	{
  +	int ret=SSL_TLSEXT_ERR_NOACK;
  +	int al = SSL_AD_UNRECOGNIZED_NAME;
  +
  +	if (s->ctx != NULL &&
s->ctx->tlsext_servername_callback != 0) 
  +		ret = s->ctx->tlsext_servername_callback(s,
&al, s->ctx->tlsext_servername_arg);
  +	else if (s->initial_ctx != NULL &&
s->initial_ctx->tlsext_servername_callback != 0) 		
  +		ret =
s->initial_ctx->tlsext_servername_callback(s, &al,
s->initial_ctx->tlsext_servername_arg);
  +
  +	switch (ret)
  +		{
  +		case SSL_TLSEXT_ERR_ALERT_FATAL:
  +			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
  +			return -1;
  +
  +		case SSL_TLSEXT_ERR_ALERT_WARNING:
  +			ssl3_send_alert(s,SSL3_AL_WARNING,al);
  +			return 1; 
  +					
  +		case SSL_TLSEXT_ERR_NOACK:
  +			s->servername_done=0;
  +			default:
  +		return 1;
  +		}
  +	}
  +
  +/* Since the server cache lookup is done early on in the
processing of client
  + * hello and other operations depend on the result we
need to handle any TLS
  + * session ticket extension at the same time.
  + */
  +
  +int tls1_process_ticket(SSL *s, unsigned char
*session_id, int len,
  +				const unsigned char *limit, SSL_SESSION **ret)
  +	{
  +	/* Point after session ID in client hello */
  +	const unsigned char *p = session_id + len;
  +	unsigned short i;
  +	if ((s->version <= SSL3_VERSION) || !limit)
  +		return 1;
  +	if (p >= limit)
  +		return -1;
  +	/* Skip past cipher list */
  +	n2s(p, i);
  +	p+= i;
  +	if (p >= limit)
  +		return -1;
  +	/* Skip past compression algorithm list */
  +	i = *(p++);
  +	p += i;
  +	if (p > limit)
  +		return -1;
  +	/* Now at start of extensions */
  +	if ((p + 2) >= limit)
  +		return 1;
  +	n2s(p, i);
  +	while ((p + 4) <= limit)
  +		{
  +		unsigned short type, size;
  +		n2s(p, type);
  +		n2s(p, size);
  +		if (p + size > limit)
  +			return 1;
  +		if (type == TLSEXT_TYPE_session_ticket)
  +			{
  +			/* If tickets disabled indicate cache miss which will
  + 			 * trigger a full handshake
  + 			 */
  +			if (SSL_get_options(s) & SSL_OP_NO_TICKET)
  +				return 0;
  +			/* If zero length not client will accept a ticket
  + 			 * and indicate cache miss to trigger full handshake
  + 			 */
  +			if (size == 0)
  +				{
  +				s->tlsext_ticket_expected = 1;
  +				return 0;	/* Cache miss */
  +				}
  +			return tls_decrypt_ticket(s, p, size, session_id,
len,
  +									ret);
  +			}
  +		p += size;
  +		}
  +	return 1;
  +	}
  +
  +static int tls_decrypt_ticket(SSL *s, const unsigned char
*etick, int eticklen,
  +				const unsigned char *sess_id, int sesslen,
  +				SSL_SESSION **psess)
  +	{
  +	SSL_SESSION *sess;
  +	unsigned char *sdec;
  +	const unsigned char *p;
  +	int slen, mlen;
  +	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
  +	HMAC_CTX hctx;
  +	EVP_CIPHER_CTX ctx;
  +	/* Attempt to process session ticket, first conduct
sanity and
  + 	 * integrity checks on ticket.
  + 	 */
  +	mlen = EVP_MD_size(EVP_sha1());
  +	eticklen -= mlen;
  +	/* Need at least keyname + iv + some encrypted data */
  +	if (eticklen < 48)
  +		goto tickerr;
  +	/* Check key name matches */
  +	if (memcmp(etick, s->ctx->tlsext_tick_key_name,
16))
  +		goto tickerr;
  +	/* Check HMAC of encrypted ticket */
  +	HMAC_CTX_init(&hctx);
  +	HMAC_Init_ex(&hctx,
s->ctx->tlsext_tick_hmac_key, 16,
  +				EVP_sha1(), NULL);
  +	HMAC_Update(&hctx, etick, eticklen);
  +	HMAC_Final(&hctx, tick_hmac, NULL);
  +	HMAC_CTX_cleanup(&hctx);
  +	if (memcmp(tick_hmac, etick + eticklen, mlen))
  +		goto tickerr;
  +	/* Set p to start of IV */
  +	p = etick + 16;
  +	EVP_CIPHER_CTX_init(&ctx);
  +	/* Attempt to decrypt session data */
  +	EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
  +					s->ctx->tlsext_tick_aes_key, p);
  +	/* Move p after IV to start of encrypted ticket, update
length */
  +	p += 16;
  +	eticklen -= 32;
  +	sdec = OPENSSL_malloc(eticklen);
  +	if (!sdec)
  +		{
  +		EVP_CIPHER_CTX_cleanup(&ctx);
  +		return -1;
  +		}
  +	EVP_DecryptUpdate(&ctx, sdec, &slen, p,
eticklen);
  +	if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen)
<= 0)
  +		goto tickerr;
  +	slen += mlen;
  +	EVP_CIPHER_CTX_cleanup(&ctx);
  +	p = sdec;
  +		
  +	sess = d2i_SSL_SESSION(NULL, &p, slen);
  +	OPENSSL_free(sdec);
  +	if (sess)
  +		{
  +		/* The session ID if non-empty is used by some clients
to
  + 		 * detect that the ticket has been accepted. So we
copy it to
  + 		 * the session structure. If it is empty set length to
zero
  + 		 * as required by standard.
  + 		 */
  +		if (sesslen)
  +			memcpy(sess->session_id, sess_id, sesslen);
  +		sess->session_id_length = sesslen;
  +		*psess = sess;
  +		return 1;
  +		}
  +	/* If session decrypt failure indicate a cache miss and
set state to
  + 	 * send a new ticket
  + 	 */
  +	tickerr:	
  +	s->tlsext_ticket_expected = 1;
  +	return 0;
  +	}
  +
  +#endif
   .
  patch -p0 <<' .'
  Index: openssl/ssl/tls1.h
 
============================================================
================
  $ cvs diff -u -r1.17.2.4 -r1.17.2.5 tls1.h
  --- openssl/ssl/tls1.h	23 Apr 2007 23:50:22
-0000	1.17.2.4
  +++ openssl/ssl/tls1.h	12 Aug 2007 18:59:03
-0000	1.17.2.5
   -96,6 +96,55 
   #define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
   #define TLS1_AD_USER_CANCELLED		90
   #define TLS1_AD_NO_RENEGOTIATION	100
  +/* codes 110-114 are from RFC3546 */
  +#define TLS1_AD_UNSUPPORTED_EXTENSION	110
  +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
  +#define TLS1_AD_UNRECOGNIZED_NAME 	112
  +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
  +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
  +#define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
  +
  +/* ExtensionType values from RFC 3546 */
  +#define TLSEXT_TYPE_server_name			0
  +#define TLSEXT_TYPE_max_fragment_length		1
  +#define TLSEXT_TYPE_client_certificate_url	2
  +#define TLSEXT_TYPE_trusted_ca_keys		3
  +#define TLSEXT_TYPE_truncated_hmac		4
  +#define TLSEXT_TYPE_status_request		5
  +#define TLSEXT_TYPE_elliptic_curves		10
  +#define TLSEXT_TYPE_ec_point_formats		11
  +#define TLSEXT_TYPE_session_ticket		35
  +
  +/* NameType value from RFC 3546 */
  +#define TLSEXT_NAMETYPE_host_name 0
  +
  +#ifndef OPENSSL_NO_TLSEXT
  +
  +#define TLSEXT_MAXLEN_host_name 255
  +
  +const char *SSL_get_servername(const SSL *s, const int
type) ;
  +int SSL_get_servername_type(const SSL *s) ;
  +
  +#define SSL_set_tlsext_host_name(s,name) 
 
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_hos
t_name,(char *)name)
  +
  +#define SSL_set_tlsext_debug_callback(ssl, cb) 
  +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void
(*)(void))cb)
  +
  +#define SSL_set_tlsext_debug_arg(ssl, arg) 
  +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void
*)arg)
  +
  +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb)

 
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
,(void (*)(void))cb)
  +
  +#define SSL_TLSEXT_ERR_OK 0    
  +#define SSL_TLSEXT_ERR_ALERT_WARNING 1  
  +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 
  +#define SSL_TLSEXT_ERR_NOACK 3
  +
  +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) 
  +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0,
(void *)arg)
  +#endif
   
   /* Additional TLS ciphersuites from
draft-ietf-tls-56-bit-ciphersuites-00.txt
    * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is
defined, see
   .
____________________________________________________________
__________
OpenSSL Project                                 http://www.openssl.org
CVS Repository Commit List                    
openssl-cvsopenssl.org
Automated List Manager                          
majordomoopenssl.org

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )