Here is an up to date version of the patch for OpenSSL 1.0.1. This patch adds the new variable 'renegotiate' to the SSL struct. Until now the variable 'new_session' is used to indicate if a renegotiation is in progress AND if a new session has to be created, i.e. a full handshake has to be performed. This has the severe disadvantage that it is not possible to perform an abbreviated handshake and keep the current session. With this patch the new variable 'renegotiate' is used to determine whether a renegotiation is in progress and 'new_session' is set whether a new session should be negotiated or not. This allows to perform abbreviated handshakes and to do so, the function SSL_renegotiate_abbreviated(SSL *s) is added, while SSL_renegotiate(SSL *s) remains unchanged and still performs full handshakes.
--- ssl/d1_clnt.c 26 Jan 2010 19:46:29 -0000 1.16.2.15 +++ ssl/d1_clnt.c 17 Jun 2010 12:47:40 -0000 @@ -171,7 +171,7 @@ switch(s->state) { case SSL_ST_RENEGOTIATE: - s->new_session=1; + s->renegotiate=1; s->state=SSL_ST_CONNECT; s->ctx->stats.sess_connect_renegotiate++; /* break */ @@ -539,7 +539,7 @@ /* else do it later in ssl3_write */ s->init_num=0; - s->new_session=0; + s->renegotiate=0; ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); if (s->hit) s->ctx->stats.sess_hit++; --- ssl/d1_pkt.c 15 Jun 2010 17:25:13 -0000 1.27.2.25 +++ ssl/d1_pkt.c 17 Jun 2010 12:47:40 -0000 @@ -957,6 +957,7 @@ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && !s->s3->renegotiate) { + s->new_session = 1; ssl3_renegotiate(s); if (ssl3_renegotiate_check(s)) { @@ -1163,7 +1164,7 @@ #else s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; #endif - s->new_session=1; + s->renegotiate=1; } i=s->handshake_func(s); if (i < 0) return(i); --- ssl/d1_srvr.c 1 Feb 2010 16:49:42 -0000 1.20.2.16 +++ ssl/d1_srvr.c 17 Jun 2010 12:47:40 -0000 @@ -177,7 +177,7 @@ switch (s->state) { case SSL_ST_RENEGOTIATE: - s->new_session=1; + s->renegotiate=1; /* s->state=SSL_ST_ACCEPT; */ case SSL_ST_BEFORE: @@ -299,7 +299,7 @@ case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: - s->new_session = 2; + s->renegotiate = 2; dtls1_start_timer(s); ret=dtls1_send_server_hello(s); if (ret <= 0) goto end; @@ -620,12 +620,12 @@ s->init_num=0; - if (s->new_session == 2) /* skipped if we just sent a HelloRequest */ + if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */ { /* actually not necessarily a 'new' session unless * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ - s->new_session=0; + s->renegotiate=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); --- ssl/s3_clnt.c 28 Feb 2010 00:24:24 -0000 1.129.2.15 +++ ssl/s3_clnt.c 17 Jun 2010 12:47:40 -0000 @@ -207,7 +207,7 @@ switch(s->state) { case SSL_ST_RENEGOTIATE: - s->new_session=1; + s->renegotiate=1; s->state=SSL_ST_CONNECT; s->ctx->stats.sess_connect_renegotiate++; /* break */ @@ -546,7 +546,7 @@ /* else do it later in ssl3_write */ s->init_num=0; - s->new_session=0; + s->renegotiate=0; ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); if (s->hit) s->ctx->stats.sess_hit++; --- ssl/s3_pkt.c 25 Mar 2010 11:22:42 -0000 1.72.2.7 +++ ssl/s3_pkt.c 17 Jun 2010 12:47:41 -0000 @@ -1261,7 +1261,7 @@ #else s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; #endif - s->new_session=1; + s->renegotiate=1; } i=s->handshake_func(s); if (i < 0) return(i); --- ssl/s3_srvr.c 27 Feb 2010 23:04:10 -0000 1.171.2.21 +++ ssl/s3_srvr.c 17 Jun 2010 12:47:41 -0000 @@ -218,7 +218,7 @@ switch (s->state) { case SSL_ST_RENEGOTIATE: - s->new_session=1; + s->renegotiate=1; /* s->state=SSL_ST_ACCEPT; */ case SSL_ST_BEFORE: @@ -316,7 +316,7 @@ ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; - s->new_session = 2; + s->renegotiate = 2; s->state=SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; break; @@ -673,12 +673,12 @@ s->init_num=0; - if (s->new_session == 2) /* skipped if we just sent a HelloRequest */ + if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */ { /* actually not necessarily a 'new' session unless * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ - s->new_session=0; + s->renegotiate=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); --- ssl/ssl.h 6 Jan 2010 17:37:38 -0000 1.221.2.24 +++ ssl/ssl.h 17 Jun 2010 12:47:41 -0000 @@ -1005,12 +1005,14 @@ int server; /* are we the server side? - mostly used by SSL_clear*/ - int new_session;/* 1 if we are to use a new session. - * 2 if we are a server and are inside a handshake - * (i.e. not just sending a HelloRequest) - * NB: For servers, the 'new' session may actually be a previously - * cached session or even the previous session unless - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + int new_session;/* Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + int renegotiate;/* 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) */ + int quiet_shutdown;/* don't send shutdown packets */ int shutdown; /* we have shut things down, 0x01 sent, 0x02 * for received */ @@ -1655,6 +1657,7 @@ int SSL_do_handshake(SSL *s); int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); int SSL_renegotiate_pending(SSL *s); int SSL_shutdown(SSL *s); --- ssl/ssl_lib.c 15 Jun 2010 17:25:14 -0000 1.176.2.19 +++ ssl/ssl_lib.c 17 Jun 2010 12:47:41 -0000 @@ -202,9 +202,9 @@ * needed because SSL_clear is not called when doing renegotiation) */ /* This is set if we are doing dynamic renegotiation so keep * the old cipher. It is sort of a SSL_clear_lite :-) */ - if (s->new_session) return(1); + if (s->renegotiate) return(1); #else - if (s->new_session) + if (s->renegotiate) { SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR); return 0; @@ -1008,18 +1008,29 @@ int SSL_renegotiate(SSL *s) { - if (s->new_session == 0) - { - s->new_session=1; - } + if (s->renegotiate == 0) + s->renegotiate=1; + + s->new_session=1; + return(s->method->ssl_renegotiate(s)); } +int SSL_renegotiate_abbreviated(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate=1; + + s->new_session=0; + + return(s->method->ssl_renegotiate(s)); +} + int SSL_renegotiate_pending(SSL *s) { /* becomes true when negotiation is requested; * false again once a handshake has finished */ - return (s->new_session != 0); + return (s->renegotiate != 0); } long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) @@ -2517,6 +2528,7 @@ ret->in_handshake = s->in_handshake; ret->handshake_func = s->handshake_func; ret->server = s->server; + ret->renegotiate = s->renegotiate; ret->new_session = s->new_session; ret->quiet_shutdown = s->quiet_shutdown; ret->shutdown=s->shutdown;
abbreviated-renegotiation.patch
Description: Binary data