Parse NewSessionTicket message

This commit is contained in:
Manuel Pégourié-Gonnard 2013-07-31 12:58:16 +02:00 committed by Paul Bakker
parent 60182ef989
commit a5cc6025e7
5 changed files with 122 additions and 4 deletions

View file

@ -30,6 +30,13 @@
#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_MEMORY_C)
#include "polarssl/memory.h"
#else
#define polarssl_malloc malloc
#define polarssl_free free
#endif
#include <stdlib.h>
#include <stdio.h>
@ -627,7 +634,8 @@ static int ssl_parse_session_ticket_ext( ssl_context *ssl,
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
((void) buf);
((void) ssl);
ssl->handshake->new_session_ticket = 1;
return( 0 );
}
@ -1890,6 +1898,97 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
!POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
static int ssl_parse_new_session_ticket( ssl_context *ssl )
{
int ret;
uint32_t lifetime;
size_t ticket_len;
unsigned char *ticket;
SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
/*
* struct {
* uint32 ticket_lifetime_hint;
* opaque ticket<0..2^16-1>;
* } NewSessionTicket;
*
* 0 . 0 handshake message type
* 1 . 3 handshake message length
* 4 . 7 ticket_lifetime_hint
* 8 . 9 ticket_len (n)
* 10 . 9+n ticket content
*/
if( ssl->in_msg[0] != SSL_HS_NEW_SESSION_TICKET ||
ssl->in_hslen < 10 )
{
SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
}
lifetime = ( ssl->in_msg[4] << 24 ) | ( ssl->in_msg[5] << 16 ) |
( ssl->in_msg[6] << 8 ) | ( ssl->in_msg[7] );
ticket_len = ( ssl->in_msg[8] << 8 ) | ( ssl->in_msg[9] );
if( ticket_len + 10 != ssl->in_hslen )
{
SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
}
ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
/*
* Zero-length ticket means the server changed his mind and doesn't want
* to send a ticket after all, so just forget it
*/
if( ticket_len == 0)
return( 0 );
polarssl_free( ssl->session_negotiate->ticket );
ssl->session_negotiate->ticket = NULL;
ssl->session_negotiate->ticket_len = 0;
if( ( ticket = polarssl_malloc( ticket_len ) ) == NULL )
{
SSL_DEBUG_MSG( 1, ( "ticket malloc failed" ) );
return( POLARSSL_ERR_SSL_MALLOC_FAILED );
}
memcpy( ticket, ssl->in_msg + 10, ticket_len );
ssl->session_negotiate->ticket = ticket;
ssl->session_negotiate->ticket_len = ticket_len;
ssl->session_negotiate->ticket_lifetime = lifetime;
/*
* RFC 5077 section 3.4:
* "If the client receives a session ticket from the server, then it
* discards any Session ID that was sent in the ServerHello."
*/
SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
ssl->session_negotiate->length = 0;
SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
return( 0 );
}
/*
* SSL handshake -- client side -- single step
*/
@ -1973,9 +2072,14 @@ int ssl_handshake_client_step( ssl_context *ssl )
break;
/*
* <== ChangeCipherSpec
* <== ( NewSessionTicket )
* ChangeCipherSpec
* Finished
*/
case SSL_SERVER_NEW_SESSION_TICKET:
ret = ssl_parse_new_session_ticket( ssl );
break;
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;