Add session saving/loading

For now, the header (version+format bytes) is duplicated. This might be
optimized later.
This commit is contained in:
Manuel Pégourié-Gonnard 2019-07-11 12:50:53 +02:00 committed by Jarno Lamsa
parent 4c90e858b5
commit 4b7e6b925f
2 changed files with 92 additions and 5 deletions

View file

@ -3912,7 +3912,11 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
* \note \p olen is updated to the correct value regardless of
* whether \p buf_len was large enough. This makes it possible
* to determine the necessary size by calling this function
* with \p buf set to \c NULL and \p buf_len to \c 0.
* with \p buf set to \c NULL and \p buf_len to \c 0. However,
* the value of \p olen is only guaranteed to be correct when
* the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or
* \c 0. If the return value is different, then the value of
* \p olen is undefined.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
@ -3977,6 +3981,11 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
* newly-configured value with the value that was active when
* the context was saved.
*
* \note When this function returns an error code, it calls
* mbedtls_ssl_free() on \p ssl. In this case, you need to
* prepare the context with the usual sequence starting with a
* call to mbedtls_ssl_init() if you want to use it again.
*
* \param ssl The SSL context structure to be populated. It must have
* been prepared as described in the note above.
* \param buf The buffer holding the serialized connection data. It must

View file

@ -11340,6 +11340,8 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
{
unsigned char *p = buf;
size_t used = 0;
size_t session_len;
int ret = 0;
/*
* Enforce current usage restrictions
@ -11380,6 +11382,29 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
p += sizeof( ssl_serialized_context_header );
}
/*
* Session (length + data)
*/
ret = mbedtls_ssl_session_save( ssl->session, NULL, 0, &session_len );
if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
return( ret );
used += 4 + session_len;
if( used <= buf_len )
{
*p++ = (unsigned char)( ( session_len >> 24 ) & 0xFF );
*p++ = (unsigned char)( ( session_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( session_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( session_len ) & 0xFF );
ret = mbedtls_ssl_session_save( ssl->session,
p, session_len, &session_len );
if( ret != 0 )
return( ret );
p += session_len;
}
/*
* Done
*/
@ -11388,18 +11413,25 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
if( used > buf_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
MBEDTLS_SSL_DEBUG_BUF( 4, "saved context", buf, used );
return( 0 );
}
/*
* Deserialize a full SSL context
* Unserialize context, see mbedtls_ssl_context_save() for format.
*
* This internal version is wrapped by a public function that cleans up in
* case of error.
*/
int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
static int ssl_context_load( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
const unsigned char *p = buf;
const unsigned char * const end = buf + len;
size_t session_len;
int ret;
/*
* The context should have been freshly setup or reset.
@ -11430,6 +11462,8 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
MBEDTLS_SSL_DEBUG_BUF( 4, "context to load", buf, len );
/*
* Check version identifier
*/
@ -11443,6 +11477,35 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
}
p += sizeof( ssl_serialized_context_header );
/*
* Session
*/
if( (size_t)( end - p ) < 4 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
session_len = ( (size_t) p[0] << 24 ) |
( (size_t) p[1] << 16 ) |
( (size_t) p[2] << 8 ) |
( (size_t) p[3] );
p += 4;
ssl->session = mbedtls_calloc( 1, sizeof( mbedtls_ssl_session ) );
if( ssl->session == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
mbedtls_ssl_session_init( ssl->session );
ssl->session_in = ssl->session;
ssl->session_out = ssl->session;
if( (size_t)( end - p ) < session_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
ret = mbedtls_ssl_session_load( ssl->session, p, session_len );
if( ret != 0 )
return( ret );
p += session_len;
/*
* Done - should have consumed entire buffer
*/
@ -11452,6 +11515,21 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
return( 0 );
}
/*
* Unserialize context: public wrapper for error cleaning
*/
int mbedtls_ssl_context_load( mbedtls_ssl_context *context,
const unsigned char *buf,
size_t len )
{
int ret = ssl_context_load( context, buf, len );
if( ret != 0 )
mbedtls_ssl_free( context );
return( ret );
}
/*
* Free an SSL context
*/