From cd32a50d67c0916f60915aa1954f2d383c419804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Sat, 20 Sep 2014 13:54:12 +0200 Subject: [PATCH] Fix NewSesssionTicket vs ChangeCipherSpec bug Since we were cheating on state, ssl_read_record() wasn't able to drop out-of-sequence ChangeCipherSpec messages. Cheat a bit less. --- library/ssl_cli.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index b5dae23a6b..a117647db4 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -2686,6 +2686,7 @@ static int ssl_parse_new_session_ticket( ssl_context *ssl ) /* We're not waiting for a NewSessionTicket message any more */ ssl->handshake->new_session_ticket = 0; + ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC; /* * Zero-length ticket means the server changed his mind and doesn't want @@ -2751,6 +2752,16 @@ int ssl_handshake_client_step( ssl_context *ssl ) } #endif + /* Change state now, so that it is right in ssl_read_record(), used + * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( ssl->state == SSL_SERVER_CHANGE_CIPHER_SPEC && + ssl->handshake->new_session_ticket != 0 ) + { + ssl->state = SSL_SERVER_NEW_SESSION_TICKET; + } +#endif + switch( ssl->state ) { case SSL_HELLO_REQUEST: @@ -2823,13 +2834,14 @@ int ssl_handshake_client_step( ssl_context *ssl ) * ChangeCipherSpec * Finished */ - case SSL_SERVER_CHANGE_CIPHER_SPEC: #if defined(POLARSSL_SSL_SESSION_TICKETS) - if( ssl->handshake->new_session_ticket != 0 ) - ret = ssl_parse_new_session_ticket( ssl ); - else + case SSL_SERVER_NEW_SESSION_TICKET: + ret = ssl_parse_new_session_ticket( ssl ); + break; #endif - ret = ssl_parse_change_cipher_spec( ssl ); + + case SSL_SERVER_CHANGE_CIPHER_SPEC: + ret = ssl_parse_change_cipher_spec( ssl ); break; case SSL_SERVER_FINISHED: