List Info

Thread: OpenSSL: openssl/ CHANGES openssl/apps/ s_apps.h s_cb.c s_client...




OpenSSL: openssl/ CHANGES openssl/apps/ s_apps.h s_cb.c s_client...
country flaguser name
Germany
2007-08-11 18:18:33
  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 01:18:32
  Branch: HEAD                             Handle:
2007081200180821

  Modified files:
    openssl                 CHANGES
    openssl/apps            s_apps.h s_cb.c s_client.c
s_server.c
    openssl/ssl             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:
    RFC4507 (including RFC4507bis) TLS stateless session
resumption support
    for OpenSSL.

  Summary:
    Revision    Changes     Path
    1.1388      +18 -0      openssl/CHANGES
    1.17        +3  -0      openssl/apps/s_apps.h
    1.20        +59 -0      openssl/apps/s_cb.c
    1.103       +64 -0      openssl/apps/s_client.c
    1.119       +32 -0      openssl/apps/s_server.c
    1.51        +1  -1      openssl/ssl/s2_srvr.c
    1.109       +129 -1     openssl/ssl/s3_clnt.c
    1.113       +9  -0      openssl/ssl/s3_lib.c
    1.152       +105 -2     openssl/ssl/s3_srvr.c
    1.195       +21 -0      openssl/ssl/ssl.h
    1.39        +5  -0      openssl/ssl/ssl3.h
    1.30        +62 -7      openssl/ssl/ssl_asn1.c
    1.63        +2  -0      openssl/ssl/ssl_err.c
    1.157       +10 -0      openssl/ssl/ssl_lib.c
    1.82        +5  -1      openssl/ssl/ssl_locl.h
    1.68        +34 -6      openssl/ssl/ssl_sess.c
    1.19        +16 -0      openssl/ssl/ssl_txt.c
    1.41        +198 -4     openssl/ssl/t1_lib.c
    1.34        +7  -0      openssl/ssl/tls1.h
 
____________________________________________________________
________________

  patch -p0 <<' .'
  Index: openssl/CHANGES
 
============================================================
================
  $ cvs diff -u -r1.1387 -r1.1388 CHANGES
  --- openssl/CHANGES	20 Jun 2007 17:46:43 -0000	1.1387
  +++ openssl/CHANGES	11 Aug 2007 23:18:08 -0000	1.1388
   -4,6 +4,24 
   
    Changes between 0.9.8f and 0.9.9  [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]
  +
     *) Final changes to avoid use of pointer pointer casts
in OpenSSL.
        OpenSSL should now compile cleanly on gcc 4.2
        [Peter Hartley <pdhutter.chaos.org.uk>,
Steve Henson]
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_apps.h
 
============================================================
================
  $ cvs diff -u -r1.16 -r1.17 s_apps.h
  --- openssl/apps/s_apps.h	26 Apr 2005 17:43:52 -0000	1.16
  +++ openssl/apps/s_apps.h	11 Aug 2007 23:18:13 -0000	1.17
   -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.19 -r1.20 s_cb.c
  --- openssl/apps/s_cb.c	17 Sep 2006 17:16:24 -0000	1.19
  +++ openssl/apps/s_cb.c	11 Aug 2007 23:18:13 -0000	1.20
   -592,3 +592,62 
   		}
   	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, data, len);
  +	BIO_flush(bio);
  +	}
   .
  patch -p0 <<' .'
  Index: openssl/apps/s_client.c
 
============================================================
================
  $ cvs diff -u -r1.102 -r1.103 s_client.c
  --- openssl/apps/s_client.c	22 Feb 2007 17:39:47
-0000	1.102
  +++ openssl/apps/s_client.c	11 Aug 2007 23:18:15
-0000	1.103
   -194,6 +194,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;
   
   -406,6 +409,8 
           tlsextctx tlsextcbp = 
           {NULL,0};
   #endif
  +	char *sess_in = NULL;
  +	char *sess_out = NULL;
   	struct sockaddr peer;
   	int peerlen = sizeof(peer);
   	int enable_timeouts = 0 ;
   -480,6 +485,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;
   -506,6 +521,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();
   -604,6 +623,10 
   			off|=SSL_OP_NO_SSLv2;
   		else if	(strcmp(*argv,"-no_comp") == 0)
   			{ off|=SSL_OP_NO_COMPRESSION; }
  +#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)
   -791,6 +814,29 
   #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)
   		{
   -893,6 +939,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);
   -1022,6 +1075,17 
   					BIO_printf(bio_c_out,"Server did %sacknowledge
servername
extension.n",tlsextcbp.ack?"":"not
");
   					}
   #endif
  +				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.118 -r1.119 s_server.c
  --- openssl/apps/s_server.c	21 May 2007 15:53:30
-0000	1.118
  +++ openssl/apps/s_server.c	11 Aug 2007 23:18:15
-0000	1.119
   -281,6 +281,9 
   
   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;
   
   -869,6 +872,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)
   -922,6 +929,10 
   			{ off|=SSL_OP_NO_TLSv1; }
   		else if	(strcmp(*argv,"-no_comp") == 0)
   			{ off|=SSL_OP_NO_COMPRESSION; }
  +#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(); }
   -1541,6 +1552,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)
                           {
   -1610,6 +1628,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 (;;)
   -1989,6 +2014,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/s2_srvr.c
 
============================================================
================
  $ cvs diff -u -r1.50 -r1.51 s2_srvr.c
  --- openssl/ssl/s2_srvr.c	4 Jun 2007 17:04:34 -0000	1.50
  +++ openssl/ssl/s2_srvr.c	11 Aug 2007 23:18:17 -0000	1.51
   -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.108 -r1.109 s3_clnt.c
  --- openssl/ssl/s3_clnt.c	24 Apr 2007 01:06:16
-0000	1.108
  +++ openssl/ssl/s3_clnt.c	11 Aug 2007 23:18:19
-0000	1.109
   -163,6 +163,9 
   
   static const 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
   
   static const SSL_METHOD *ssl3_get_client_method(int ver)
   	{
   -286,6 +289,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 */
   			/* or PSK */
   			if (!(s->s3->tmp.new_cipher->algorithm_auth
& SSL_aNULL) &&
   -439,11 +453,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:
   
   -671,7 +701,7 
   		SSL3_ST_CR_SRVR_HELLO_A,
   		SSL3_ST_CR_SRVR_HELLO_B,
   		-1,
  -		300, /* ?? */
  +		20000, /* ?? */
   		&ok);
   
   	if (!ok) return((int)n);
   -1693,6 +1723,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)
   	{
   -2600,3 +2698,33 
   err:
   	return(0);
   	}
  +
  +/* 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.112 -r1.113 s3_lib.c
  --- openssl/ssl/s3_lib.c	4 Jun 2007 17:04:35 -0000	1.112
  +++ openssl/ssl/s3_lib.c	11 Aug 2007 23:18:20 -0000	1.113
   -2338,6 +2338,9 
   			}
   		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;
   -2390,6 +2393,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;
   		}
   .
  patch -p0 <<' .'
  Index: openssl/ssl/s3_srvr.c
 
============================================================
================
  $ cvs diff -u -r1.151 -r1.152 s3_srvr.c
  --- openssl/ssl/s3_srvr.c	24 Apr 2007 01:06:17
-0000	1.151
  +++ openssl/ssl/s3_srvr.c	11 Aug 2007 23:18:21
-0000	1.152
   -158,6 +158,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>
   -529,11 +530,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:
   
   -762,14 +778,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;
   -2714,3 +2730,90 
   	/* SSL3_ST_SW_CERT_B */
   	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
   	}
  +#ifndef OPENSSLP_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.194 -r1.195 ssl.h
  --- openssl/ssl/ssl.h	7 Jun 2007 13:14:40 -0000	1.194
  +++ openssl/ssl/ssl.h	11 Aug 2007 23:18:22 -0000	1.195
   -500,6 +500,10 
   	size_t tlsext_ellipticcurvelist_length;
   	unsigned char *tlsext_ellipticcurvelist; /* peer's list
*/
   #endif /* OPENSSL_NO_EC */
  +	/* 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;
   
   -529,6 +533,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
   -789,6 +795,10 
   	/* 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
   #ifndef OPENSSL_NO_PSK
   	char *psk_identity_hint;
   -1057,12 +1067,19 
   				 * 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;
   #ifndef OPENSSL_NO_EC
   	size_t tlsext_ecpointformatlist_length;
   	unsigned char *tlsext_ecpointformatlist; /* our list */
   -1283,6 +1300,8 
   #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) 
   -1739,10 +1758,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
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl3.h
 
============================================================
================
  $ cvs diff -u -r1.38 -r1.39 ssl3.h
  --- openssl/ssl/ssl3.h	4 Jun 2007 17:04:36 -0000	1.38
  +++ openssl/ssl/ssl3.h	11 Aug 2007 23:18:23 -0000	1.39
   -533,6 +533,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 */
   -574,10 +576,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.29 -r1.30 ssl_asn1.c
  --- openssl/ssl/ssl_asn1.c	5 Apr 2006 17:11:19 -0000	1.29
  +++ openssl/ssl/ssl_asn1.c	11 Aug 2007 23:18:26
-0000	1.30
   -106,6 +106,8 
   	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 */
   #ifndef OPENSSL_NO_PSK
   	ASN1_OCTET_STRING psk_identity_hint;
   -116,9 +118,10 
   int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
   	{
   #define LSIZE2 (sizeof(long)*2)
  -	int v1=0,v2=0,v3=0,v4=0,v5=0,v6=0,v7=0,v8=0;
  +	int v1=0,v2=0,v3=0,v4=0,v5=0,v6=0,v7=0,v8=0,v9=0,v10=0;
   	unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
   	unsigned char
ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
  +	unsigned char ibuf6[LSIZE2];
   	long l;
   	SSL_SESSION_ASN1 a;
   	M_ASN1_I2D_vars(in);
   -217,7 +220,25 
                  
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 */
   #ifndef OPENSSL_NO_PSK
   	if (in->psk_identity_hint)
   -256,6 +277,10 
  
		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 */
   -299,6 +324,12 
   	if (in->psk_identity)
   		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity),
i2d_ASN1_OCTET_STRING,8,v8);
   #endif /* OPENSSL_NO_PSK */
  +#ifndef OPENSSL_NO_TLSEXT
  +	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();
   	}
   
   -488,7 +519,7 
   #ifndef OPENSSL_NO_PSK
   	os.length=0;
   	os.data=NULL;
  -	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,9);
  +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7);
   	if (os.data)
   		{
   		ret->psk_identity_hint = BUF_strndup((char
*)os.data, os.length);
   -498,20 +529,44 
   		}
   	else
   		ret->psk_identity_hint=NULL;
  +#endif /* OPENSSL_NO_PSK */
   
  +#ifndef OPENSSL_NO_TLSEXT
  +	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->psk_identity = BUF_strndup((char *)os.data,
os.length);
  -		OPENSSL_free(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->psk_identity=NULL;
  -#endif /* OPENSSL_NO_KRB5 */
  +		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.62 -r1.63 ssl_err.c
  --- openssl/ssl/ssl_err.c	24 Apr 2007 01:06:18 -0000	1.62
  +++ openssl/ssl/ssl_err.c	11 Aug 2007 23:18:26 -0000	1.63
   -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"
;},
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_lib.c
 
============================================================
================
  $ cvs diff -u -r1.156 -r1.157 ssl_lib.c
  --- openssl/ssl/ssl_lib.c	4 Jun 2007 17:04:37 -0000	1.156
  +++ openssl/ssl/ssl_lib.c	11 Aug 2007 23:18:26
-0000	1.157
   -151,6 +151,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
   -336,6 +337,9 
  
	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
   -1545,6 +1549,12 
   #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
   #ifndef OPENSSL_NO_PSK
   	ret->psk_identity_hint=NULL;
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_locl.h
 
============================================================
================
  $ cvs diff -u -r1.81 -r1.82 ssl_locl.h
  --- openssl/ssl/ssl_locl.h	4 Jun 2007 17:04:38 -0000	1.81
  +++ openssl/ssl/ssl_locl.h	11 Aug 2007 23:18:27
-0000	1.82
   -740,7 +740,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);
   -800,6 +800,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);
   -890,6 +891,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);
   -985,6 +987,8 
   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
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_sess.c
 
============================================================
================
  $ cvs diff -u -r1.67 -r1.68 ssl_sess.c
  --- openssl/ssl/ssl_sess.c	7 Jun 2007 13:14:42 -0000	1.67
  +++ openssl/ssl/ssl_sess.c	11 Aug 2007 23:18:28
-0000	1.68
   -308,6 +308,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)
   -350,6 +358,7 
   			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) {
   -406,21 +415,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;
  +#ifndef OPENSSL_NO_TLSEXT
  +	int r;
  +#endif
   
  -	data.ssl_version=s->version;
  -	data.session_id_length=len;
   	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->session_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->session_ctx->sessions,&data);
   		if (ret != NULL)
   -678,6 +705,7 
   	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);
   #ifndef OPENSSL_NO_EC
   	ss->tlsext_ecpointformatlist_length = 0;
   	if (ss->tlsext_ecpointformatlist != NULL)
OPENSSL_free(ss->tlsext_ecpointformatlist);
   .
  patch -p0 <<' .'
  Index: openssl/ssl/ssl_txt.c
 
============================================================
================
  $ cvs diff -u -r1.18 -r1.19 ssl_txt.c
  --- openssl/ssl/ssl_txt.c	4 Jun 2007 17:04:39 -0000	1.18
  +++ openssl/ssl/ssl_txt.c	11 Aug 2007 23:18:28 -0000	1.19
   -183,6 +183,22 
   	if (BIO_puts(bp,"n    PSK identity hint: ")
<= 0) goto err;
   	if (BIO_printf(bp, "%s",
x->psk_identity_hint ? x->psk_identity_hint :
"None") <= 0) goto err;
   #endif
  +#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.40 -r1.41 t1_lib.c
  --- openssl/ssl/t1_lib.c	24 Apr 2007 01:06:19 -0000	1.40
  +++ openssl/ssl/t1_lib.c	11 Aug 2007 23:18:29 -0000	1.41
   -111,10 +111,16 
   
   #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;
   
  +static int tls_decrypt_ticket(SSL *s, const unsigned char
*tick, int ticklen,
  +				const unsigned char *sess_id, int sesslen,
  +				SSL_SESSION **psess);
  +
   SSL3_ENC_METHOD TLSv1_enc_data={
   	tls1_enc,
   	tls1_mac,
   -164,6 +170,7 
   	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 */
   -243,6 +250,27 
   		}
   #endif /* OPENSSL_NO_EC */
   
  +	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;
   
   -289,6 +317,14 
   	/* Currently the server should not respond with a
SupportedCurves extension */
   #endif /* OPENSSL_NO_EC */
   	
  +	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;
   
   -318,7 +354,10 
   
   		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.
   -472,9 +511,10 
   #endif
   			}
   #endif /* OPENSSL_NO_EC */
  -		data+=size;		
  +		/* session ticket processed earlier */
  +		data+=size;
   		}
  -
  +				
   	*p = data;
   	return 1;
   	}
   -501,6 +541,10 
   		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)
   -540,6 +584,17 
   #endif
   			}
   #endif /* OPENSSL_NO_EC */
  +
  +		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;		
   		}
   
   -854,5 +909,144 
   		return 1;
   		}
   	}
  -#endif
   
  +/* 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;
  +fprintf(stderr, "Ticket match OKn");
  +	/* 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;
  +fprintf(stderr, "HMAC match OKn");
  +	/* 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;
  +fprintf(stderr, "Decrypt OKn");
  +	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.33 -r1.34 tls1.h
  --- openssl/ssl/tls1.h	4 Jun 2007 17:04:40 -0000	1.33
  +++ openssl/ssl/tls1.h	11 Aug 2007 23:18:29 -0000	1.34
   -192,6 +192,7 
   #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
   -213,6 +214,12 
   #define SSL_set_tlsext_host_name(s,name) 
  
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host
_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)
   
   .
____________________________________________________________
__________
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 )