Add support for serialisation session with ticket

On client side, this is required for the main use case where of serialising a
session for later resumption, in case tickets are used.

On server side, this doesn't change much as ticket_len will always be 0.

This unblocks testing the functions by using them in ssl_client2, which will
be done in the next commit.
This commit is contained in:
Manuel Pégourié-Gonnard 2019-05-16 11:11:08 +02:00 committed by Jarno Lamsa
parent a3e7c65101
commit 35eb802103

View file

@ -9836,16 +9836,17 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
/* /*
* Serialize a session in the following format: * Serialize a session in the following format:
* (in the presentation language of TLS, RFC 8446 section 3)
* *
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled: * opaque session_struct[n]; // n = sizeof(mbedtls_ssl_session)
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) * select (MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) {
* n . n+2 peer_cert length = m (0 if no certificate) * case enabled: opaque peer_cert<0..2^24-1>; // length 0 means no cert
* n+3 . n+2+m peer cert ASN.1 * case disabled: uint8_t peer_cert_digest_type;
* opaque peer_cert_digest<0..2^8-1>;
* }
* opaque ticket<0..2^24-1>; // 0 means no ticket
* *
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled: * Only the peer's certificate is saved, not the whole chain.
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
* n . n length of peer certificate digest = k (0 if no digest)
* n+1 . n+k peer certificate digest (digest type encoded in session)
*/ */
int mbedtls_ssl_session_save( const mbedtls_ssl_session *session, int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
unsigned char *buf, unsigned char *buf,
@ -9862,16 +9863,22 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Shallow copy of the session structure
*/
if( left < sizeof( mbedtls_ssl_session ) ) if( left < sizeof( mbedtls_ssl_session ) )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
left -= sizeof( mbedtls_ssl_session );
/* This also copies the values of pointer fields in the /* This also copies the values of pointer fields in the
* session to be serialized, but they'll be ignored when * session to be serialized, but they'll be ignored when
* loading the session through ssl_load_session(). */ * loading the session through ssl_load_session(). */
memcpy( p, session, sizeof( mbedtls_ssl_session ) ); memcpy( p, session, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session ); p += sizeof( mbedtls_ssl_session );
left -= sizeof( mbedtls_ssl_session );
/*
* Copy of the peer's end-entity certificate
*/
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( session->peer_cert == NULL ) if( session->peer_cert == NULL )
@ -9881,6 +9888,7 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
if( left < 3 + cert_len ) if( left < 3 + cert_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
left -= 3 + cert_len;
*p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF ); *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
@ -9888,7 +9896,10 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
left -= 3; left -= 3;
if( session->peer_cert != NULL ) if( session->peer_cert != NULL )
{
memcpy( p, session->peer_cert->raw.p, cert_len ); memcpy( p, session->peer_cert->raw.p, cert_len );
p += cert_len;
}
p += cert_len; p += cert_len;
left -= cert_len; left -= cert_len;
@ -9912,6 +9923,27 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Copy of the session ticket if any
*/
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if( left < 3 + session->ticket_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
left -= 3 + session->ticket_len;
*p++ = (unsigned char)( ( session->ticket_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( session->ticket_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( session->ticket_len ) & 0xFF );
if( session->ticket != NULL )
{
memcpy( p, session->ticket, session->ticket_len );
p += session->ticket_len;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
/* Done */
(void) left;
*olen = p - buf; *olen = p - buf;
return( 0 ); return( 0 );
@ -9934,6 +9966,9 @@ int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Shallow session structure
*/
if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) ) if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@ -9953,6 +9988,9 @@ int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
session->ticket = NULL; session->ticket = NULL;
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
/*
* Peer certificate
*/
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* Deserialize CRT from the end of the ticket. */ /* Deserialize CRT from the end of the ticket. */
@ -10013,6 +10051,31 @@ int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Session ticket
*/
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if( 3 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
p += 3;
if( session->ticket_len != 0 )
{
if( session->ticket_len > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
session->ticket = mbedtls_calloc( 1, session->ticket_len );
if( session->ticket == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
memcpy( session->ticket, p, session->ticket_len );
p += session->ticket_len;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
/* Done, should have consumed entire buffer */
if( p != end ) if( p != end )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );