OpenSSL CVS Repository
http://cvs.openssl.org/
____________________________________________________________
________________
Server: cvs.openssl.org Name: Dr.
Stephen Henson
Root: /v/openssl/cvs Email: steve openssl.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 <pdh utter.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-cvs openssl.org
Automated List Manager
majordomo openssl.org
|