Merge remote-tracking branch 'origin/development' into development-restricted

* origin/development: (114 commits)
  Don't redefine calloc and free
  Add changelog entry to record checking
  Fix compiler warning
  Add debug messages
  Remove duplicate entries from ChangeLog
  Fix parameter name in doxygen
  Add missing guards for mac usage
  Improve reability and debugability of large if
  Fix a typo in a comment
  Fix MSVC warning
  Fix compile error in reduced configurations
  Avoid duplication of session format header
  Implement config-checking header to context s11n
  Provide serialisation API only if it's enabled
  Fix compiler warning: comparing signed to unsigned
  Actually reset the context on save as advertised
  Re-use buffer allocated by handshake_init()
  Enable serialisation tests in ssl-opt.sh
  Change requirements for setting timer callback
  Add setting of forced fields when deserializing
  ...
This commit is contained in:
Jaeden Amero 2019-08-27 10:09:10 +01:00
commit f1cdceae0d
18 changed files with 2907 additions and 513 deletions

View File

@ -38,6 +38,15 @@ Features
changed its IP or port. The feature is enabled at compile-time by setting
MBEDTLS_SSL_DTLS_CONNECTION_ID (disabled by default), and at run-time
through the new APIs mbedtls_ssl_conf_cid() and mbedtls_ssl_set_cid().
* Add new API functions mbedtls_ssl_session_save() and
mbedtls_ssl_session_load() to allow serializing a session, for example to
store it in non-volatile storage, and later using it for TLS session
resumption.
* Add a new API function mbedtls_ssl_check_record() to allow checking that
an incoming record is valid, authentic and has not been seen before. This
feature can be used alongside Connection ID and SSL context serialisation.
The feature is enabled at compile-time by MBEDTLS_SSL_RECORD_CHECKING
option.
API Changes
* Extend the MBEDTLS_SSL_EXPORT_KEYS to export the handshake randbytes,
@ -103,7 +112,6 @@ Bugfix
* Fix propagation of restart contexts in restartable EC operations.
This could previously lead to segmentation faults in builds using an
address-sanitizer and enabling but not using MBEDTLS_ECP_RESTARTABLE.
Changes
* Server's RSA certificate in certs.c was SHA-1 signed. In the default
mbedTLS configuration only SHA-2 signed certificates are accepted.

View File

@ -1403,6 +1403,33 @@
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/**
* \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
*
* Enable serialization of the TLS context structures, through use of the
* functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
*
* This pair of functions allows one side of a connection to serialize the
* context associated with the connection, then free or re-use that context
* while the serialized state is persisted elsewhere, and finally deserialize
* that state to a live context for resuming read/write operations on the
* connection. From a protocol perspective, the state of the connection is
* unaffected, in particular this is entirely transparent to the peer.
*
* Note: this is distinct from TLS session resumption, which is part of the
* protocol and fully visible by the peer. TLS session resumption enables
* establishing new connections associated to a saved session with shorter,
* lighter handshakes, while context serialization is a local optimization in
* handling a single, potentially long-lived connection.
*
* Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
* saved after the handshake to allow for more efficient serialization, so if
* you don't need this feature you'll save RAM by disabling it.
*
* Comment to disable the context serialization APIs.
*/
#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
/**
* \def MBEDTLS_SSL_DEBUG_ALL
*

View File

@ -100,6 +100,7 @@
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* SSL 5 1 (Started from 0x5F00)
* CIPHER 6 8 (Started from 0x6080)
* SSL 6 24 (Started from top, plus 0x6000)
* SSL 7 32

View File

@ -127,6 +127,7 @@
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */
#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 /**< An encrypted DTLS-frame with an unexpected CID was received. */
#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 /**< An operation failed due to an unexpected version or configuration. */
#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */
/*
@ -845,6 +846,14 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
/*
* This structure is used for storing current session data.
*
* Note: when changing this definition, we need to check and update:
* - in tests/suites/test_suite_ssl.function:
* ssl_populate_session() and ssl_serialize_session_save_load()
* - in library/ssl_tls.c:
* mbedtls_ssl_session_init() and mbedtls_ssl_session_free()
* mbedtls_ssl_session_save() and ssl_session_load()
* ssl_session_copy()
*/
struct mbedtls_ssl_session
{
@ -2348,6 +2357,90 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session );
#endif /* MBEDTLS_SSL_CLI_C */
/**
* \brief Load serialized session data into a session structure.
* On client, this can be used for loading saved sessions
* before resuming them with mbedstls_ssl_set_session().
* On server, this can be used for alternative implementations
* of session cache or session tickets.
*
* \warning If a peer certificate chain is associated with the session,
* the serialized state will only contain the peer's
* end-entity certificate and the result of the chain
* verification (unless verification was disabled), but not
* the rest of the chain.
*
* \see mbedtls_ssl_session_save()
* \see mbedtls_ssl_set_session()
*
* \param session The session structure to be populated. It must have been
* initialised with mbedtls_ssl_session_init() but not
* populated yet.
* \param buf The buffer holding the serialized session data. It must be a
* readable buffer of at least \p len bytes.
* \param len The size of the serialized data in bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
* \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
* was generated in a different version or configuration of
* Mbed TLS.
* \return Another negative value for other kinds of errors (for
* example, unsupported features in the embedded certificate).
*/
int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
const unsigned char *buf,
size_t len );
/**
* \brief Save session structure as serialized data in a buffer.
* On client, this can be used for saving session data,
* potentially in non-volatile storage, for resuming later.
* On server, this can be used for alternative implementations
* of session cache or session tickets.
*
* \see mbedtls_ssl_session_load()
* \see mbedtls_ssl_get_session_pointer()
*
* \param session The session structure to be saved.
* \param buf The buffer to write the serialized data to. It must be a
* writeable buffer of at least \p len bytes, or may be \c
* NULL if \p len is \c 0.
* \param buf_len The number of bytes available for writing in \p buf.
* \param olen The size in bytes of the data that has been or would have
* been written. It must point to a valid \c size_t.
*
* \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.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
*/
int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
unsigned char *buf,
size_t buf_len,
size_t *olen );
/**
* \brief Get a pointer to the current session structure, for example
* to serialize it.
*
* \warning Ownership of the session remains with the SSL context, and
* the returned pointer is only guaranteed to be valid until
* the next API call operating on the same \p ssl context.
*
* \see mbedtls_ssl_session_save()
*
* \param ssl The SSL context.
*
* \return A pointer to the current session if successful.
* \return \c NULL if no session is active.
*/
const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl );
/**
* \brief Set the list of allowed ciphersuites and the preference
* order. First in the list has the highest preference.
@ -3786,6 +3879,130 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
*/
void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/**
* \brief Save an active connection as serialized data in a buffer.
* This allows the freeing or re-using of the SSL context
* while still picking up the connection later in a way that
* it entirely transparent to the peer.
*
* \see mbedtls_ssl_context_load()
*
* \note This feature is currently only available under certain
* conditions, see the documentation of the return value
* #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details.
*
* \note When this function succeeds, it calls
* mbedtls_ssl_session_reset() on \p ssl which as a result is
* no longer associated with the connection that has been
* serialized. This avoids creating copies of the connection
* state. You're then free to either re-use the context
* structure for a different connection, or call
* mbedtls_ssl_free() on it. See the documentation of
* mbedtls_ssl_session_reset() for more details.
*
* \param ssl The SSL context to save. On success, it is no longer
* associated with the connection that has been serialized.
* \param buf The buffer to write the serialized data to. It must be a
* writeable buffer of at least \p buf_len bytes, or may be \c
* NULL if \p buf_len is \c 0.
* \param buf_len The number of bytes available for writing in \p buf.
* \param olen The size in bytes of the data that has been or would have
* been written. It must point to a valid \c size_t.
*
* \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. 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.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed
* while reseting the context.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
* progress, or there is pending data for reading or sending,
* or the connection does not use DTLS 1.2 with an AEAD
* ciphersuite, or renegotiation is enabled.
*/
int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t buf_len,
size_t *olen );
/**
* \brief Load serialized connection data to an SSL context.
*
* \see mbedtls_ssl_context_save()
*
* \warning The same serialized data must never be loaded into more
* that one context. In order to ensure that, after
* successfully loading serialized data to an SSL context, you
* should immediately destroy or invalidate all copies of the
* serialized data that was loaded. Loading the same data in
* more than one context would cause severe security failures
* including but not limited to loss of confidentiality.
*
* \note Before calling this function, the SSL context must be
* prepared in one of the two following ways. The first way is
* to take a context freshly initialised with
* mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with
* the same ::mbedtls_ssl_config structure that was used in
* the original connection. The second way is to
* call mbedtls_ssl_session_reset() on a context that was
* previously prepared as above but used in the meantime.
* Either way, you must not use the context to perform a
* handshake between calling mbedtls_ssl_setup() or
* mbedtls_ssl_session_reset() and calling this function. You
* may however call other setter functions in that time frame
* as indicated in the note below.
*
* \note Before or after calling this function successfully, you
* also need to configure some connection-specific callbacks
* and settings before you can use the connection again
* (unless they were already set before calling
* mbedtls_ssl_session_reset() and the values are suitable for
* the present connection). Specifically, you want to call
* at least mbedtls_ssl_set_bio() and
* mbedtls_ssl_set_timer_cb(). All other SSL setter functions
* are not necessary to call, either because they're only used
* in handshakes, or because the setting is already saved. You
* might choose to call them anyway, for example in order to
* share code between the cases of establishing a new
* connection and the case of loading an already-established
* connection.
*
* \note If you have new information about the path MTU, you want to
* call mbedtls_ssl_set_mtu() after calling this function, as
* otherwise this function would overwrite your
* 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
* be a readable buffer of at least \p len bytes.
* \param len The size of the serialized data in bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
* comes from a different Mbed TLS version or build.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
*/
int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len );
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/**
* \brief Initialize an SSL configuration context
* Just makes the context ready for

View File

@ -458,7 +458,7 @@ struct mbedtls_ssl_handshake_params
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf;
@ -642,8 +642,29 @@ struct mbedtls_ssl_transform
z_stream ctx_deflate; /*!< compression context */
z_stream ctx_inflate; /*!< decompression context */
#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/* We need the Hello random bytes in order to re-derive keys from the
* Master Secret and other session info, see ssl_populate_transform() */
unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
};
/*
* Return 1 if the transform uses an AEAD cipher, 0 otherwise.
* Equivalently, return 0 if a separate MAC is used, 1 otherwise.
*/
static inline int mbedtls_ssl_transform_uses_aead(
const mbedtls_ssl_transform *transform )
{
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
return( transform->maclen == 0 && transform->taglen != 0 );
#else
(void) transform;
return( 1 );
#endif
}
/*
* Internal representation of record frames
*

View File

@ -525,6 +525,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_CID) )
mbedtls_snprintf( buf, buflen, "SSL - An encrypted DTLS-frame with an unexpected CID was received" );
if( use_ret == -(MBEDTLS_ERR_SSL_VERSION_MISMATCH) )
mbedtls_snprintf( buf, buflen, "SSL - An operation failed due to an unexpected version or configuration" );
if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
#endif /* MBEDTLS_SSL_TLS_C */

View File

@ -3625,7 +3625,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
unsigned char hash[48];
unsigned char *hash_start = hash;
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
unsigned int hashlen;
size_t hashlen;
void *rs_ctx = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@ -3674,7 +3674,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
sign:
#endif
ssl->handshake->calc_verify( ssl, hash );
ssl->handshake->calc_verify( ssl, hash, &hashlen );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
@ -3692,7 +3692,6 @@ sign:
* sha_hash
* SHA(handshake_messages);
*/
hashlen = 36;
md_alg = MBEDTLS_MD_NONE;
/*

View File

@ -4361,7 +4361,10 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
}
/* Calculate hash and verify signature */
ssl->handshake->calc_verify( ssl, hash );
{
size_t dummy_hlen;
ssl->handshake->calc_verify( ssl, hash, &dummy_hlen );
}
if( ( ret = mbedtls_pk_verify( peer_pk,
md_alg, hash_start, hashlen,

View File

@ -185,189 +185,6 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
return( 0 );
}
/*
* Serialize a session in the following format:
*
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled:
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
* n . n+2 peer_cert length = m (0 if no certificate)
* n+3 . n+2+m peer cert ASN.1
*
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled:
* 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)
*/
static int ssl_save_session( const mbedtls_ssl_session *session,
unsigned char *buf, size_t buf_len,
size_t *olen )
{
unsigned char *p = buf;
size_t left = buf_len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
size_t cert_len;
#else
size_t cert_digest_len;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( left < sizeof( mbedtls_ssl_session ) )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
/* This also copies the values of pointer fields in the
* session to be serialized, but they'll be ignored when
* loading the session through ssl_load_session(). */
memcpy( p, session, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session );
left -= sizeof( mbedtls_ssl_session );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( session->peer_cert == NULL )
cert_len = 0;
else
cert_len = session->peer_cert->raw.len;
if( left < 3 + cert_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
*p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len ) & 0xFF );
left -= 3;
if( session->peer_cert != NULL )
memcpy( p, session->peer_cert->raw.p, cert_len );
p += cert_len;
left -= cert_len;
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( session->peer_cert_digest != NULL )
cert_digest_len = 0;
else
cert_digest_len = session->peer_cert_digest_len;
if( left < 1 + cert_digest_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
*p++ = (unsigned char) cert_digest_len;
left--;
if( session->peer_cert_digest != NULL )
memcpy( p, session->peer_cert_digest, cert_digest_len );
p += cert_digest_len;
left -= cert_digest_len;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
*olen = p - buf;
return( 0 );
}
/*
* Unserialise session, see ssl_save_session()
*/
static int ssl_load_session( mbedtls_ssl_session *session,
const unsigned char *buf, size_t len )
{
const unsigned char *p = buf;
const unsigned char * const end = buf + len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
size_t cert_len;
#else
size_t cert_digest_len;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
memcpy( session, p, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session );
/* Non-NULL pointer fields of `session` are meaningless
* and potentially harmful. Zeroize them for safety. */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
session->peer_cert = NULL;
#else
session->peer_cert_digest = NULL;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
session->ticket = NULL;
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* Deserialize CRT from the end of the ticket. */
if( 3 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
p += 3;
if( cert_len != 0 )
{
int ret;
if( cert_len > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
if( session->peer_cert == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
mbedtls_x509_crt_init( session->peer_cert );
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
p, cert_len ) ) != 0 )
{
mbedtls_x509_crt_free( session->peer_cert );
mbedtls_free( session->peer_cert );
session->peer_cert = NULL;
return( ret );
}
p += cert_len;
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Deserialize CRT digest from the end of the ticket. */
if( 1 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
cert_digest_len = (size_t) p[0];
p++;
if( cert_digest_len != 0 )
{
if( cert_digest_len > (size_t)( end - p ) ||
cert_digest_len != session->peer_cert_digest_len )
{
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
session->peer_cert_digest = mbedtls_calloc( 1, cert_digest_len );
if( session->peer_cert_digest == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
memcpy( session->peer_cert_digest, p, cert_digest_len );
p += cert_digest_len;
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( p != end )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
return( 0 );
}
/*
* Create session ticket, with the following structure:
*
@ -427,8 +244,9 @@ int mbedtls_ssl_ticket_write( void *p_ticket,
goto cleanup;
/* Dump session state */
if( ( ret = ssl_save_session( session,
state, end - state, &clear_len ) ) != 0 ||
if( ( ret = mbedtls_ssl_session_save( session,
state, end - state,
&clear_len ) ) != 0 ||
(unsigned long) clear_len > 65535 )
{
goto cleanup;
@ -551,7 +369,7 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
}
/* Actually load session */
if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 )
if( ( ret = mbedtls_ssl_session_load( session, ticket, clear_len ) ) != 0 )
goto cleanup;
#if defined(MBEDTLS_HAVE_TIME)

File diff suppressed because it is too large Load Diff

View File

@ -459,6 +459,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"MBEDTLS_SSL_ASYNC_PRIVATE",
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
"MBEDTLS_SSL_CONTEXT_SERIALIZATION",
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
#if defined(MBEDTLS_SSL_DEBUG_ALL)
"MBEDTLS_SSL_DEBUG_ALL",
#endif /* MBEDTLS_SSL_DEBUG_ALL */

View File

@ -1266,6 +1266,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( strcmp( "MBEDTLS_SSL_CONTEXT_SERIALIZATION", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONTEXT_SERIALIZATION );
return( 0 );
}
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
#if defined(MBEDTLS_SSL_DEBUG_ALL)
if( strcmp( "MBEDTLS_SSL_DEBUG_ALL", config ) == 0 )
{

View File

@ -113,6 +113,7 @@ int main( void )
#define DFL_DHMLEN -1
#define DFL_RECONNECT 0
#define DFL_RECO_DELAY 0
#define DFL_RECO_MODE 1
#define DFL_CID_ENABLED 0
#define DFL_CID_VALUE ""
#define DFL_CID_ENABLED_RENEGO -1
@ -129,6 +130,8 @@ int main( void )
#define DFL_FALLBACK -1
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
#define DFL_SERIALIZE 0
#define DFL_EXTENDED_MS_ENFORCE -1
#define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define DFL_REPRODUCIBLE 0
@ -339,6 +342,15 @@ int main( void )
#define USAGE_ECRESTART ""
#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
#define USAGE_SERIALIZATION \
" serialize=%%d default: 0 (do not serialize/deserialize)\n" \
" options: 1 (serialize)\n" \
" 2 (serialize with re-initialization)\n"
#else
#define USAGE_SERIALIZATION ""
#endif
#define USAGE \
"\n usage: ssl_client2 param=<>...\n" \
"\n acceptable parameters:\n" \
@ -376,8 +388,11 @@ int main( void )
" allow_legacy=%%d default: (library default: no)\n" \
USAGE_RENEGO \
" exchanges=%%d default: 1\n" \
" reconnect=%%d default: 0 (disabled)\n" \
" reconnect=%%d number of reconnections using session resumption\n" \
" default: 0 (disabled)\n" \
" reco_delay=%%d default: 0 seconds\n" \
" reco_mode=%%d 0: copy session, 1: serialize session\n" \
" default: 1\n" \
" reconnect_hard=%%d default: 0 (disabled)\n" \
USAGE_TICKETS \
USAGE_EAP_TLS \
@ -405,6 +420,7 @@ int main( void )
" configuration macro is defined and 1\n" \
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
" acceptable ciphersuite names:\n"
#define ALPN_LIST_SIZE 10
@ -458,6 +474,7 @@ struct options
int dhmlen; /* minimum DHM params len in bits */
int reconnect; /* attempt to resume session */
int reco_delay; /* delay in seconds before resuming session */
int reco_mode; /* how to keep the session around */
int reconnect_hard; /* unexpectedly reconnect from the same port */
int tickets; /* enable / disable session tickets */
const char *curves; /* list of supported elliptic curves */
@ -476,6 +493,7 @@ struct options
int cid_enabled_renego; /* whether to use the CID extension or not
* during renegotiation */
const char *cid_val; /* the CID to use for incoming messages */
int serialize; /* serialize/deserialize connection */
const char *cid_val_renego; /* the CID to use for incoming messages
* after renegotiation */
int reproducible; /* make communication reproducible */
@ -1047,6 +1065,8 @@ int main( int argc, char *argv[] )
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_ssl_session saved_session;
unsigned char *session_data = NULL;
size_t session_data_len = 0;
#if defined(MBEDTLS_TIMING_C)
mbedtls_timing_delay_context timer;
#endif
@ -1061,6 +1081,10 @@ int main( int argc, char *argv[] )
#endif
char *p, *q;
const int *list;
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
unsigned char *context_buf = NULL;
size_t context_buf_len;
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
unsigned char eap_tls_keymaterial[16];
unsigned char eap_tls_iv[8];
@ -1164,6 +1188,7 @@ int main( int argc, char *argv[] )
opt.dhmlen = DFL_DHMLEN;
opt.reconnect = DFL_RECONNECT;
opt.reco_delay = DFL_RECO_DELAY;
opt.reco_mode = DFL_RECO_MODE;
opt.reconnect_hard = DFL_RECONNECT_HARD;
opt.tickets = DFL_TICKETS;
opt.alpn_string = DFL_ALPN_STRING;
@ -1176,6 +1201,7 @@ int main( int argc, char *argv[] )
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
opt.dgram_packing = DFL_DGRAM_PACKING;
opt.serialize = DFL_SERIALIZE;
opt.eap_tls = DFL_EAP_TLS;
opt.reproducible = DFL_REPRODUCIBLE;
@ -1350,6 +1376,12 @@ int main( int argc, char *argv[] )
if( opt.reco_delay < 0 )
goto usage;
}
else if( strcmp( p, "reco_mode" ) == 0 )
{
opt.reco_mode = atoi( q );
if( opt.reco_mode < 0 )
goto usage;
}
else if( strcmp( p, "reconnect_hard" ) == 0 )
{
opt.reconnect_hard = atoi( q );
@ -1558,6 +1590,12 @@ int main( int argc, char *argv[] )
{
return query_config( q );
}
else if( strcmp( p, "serialize") == 0 )
{
opt.serialize = atoi( q );
if( opt.serialize < 0 || opt.serialize > 2)
goto usage;
}
else if( strcmp( p, "eap_tls" ) == 0 )
{
opt.eap_tls = atoi( q );
@ -2440,14 +2478,55 @@ int main( int argc, char *argv[] )
mbedtls_printf(" . Saving session for reuse..." );
fflush( stdout );
if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
if( opt.reco_mode == 1 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_get_session returned -0x%x\n\n",
-ret );
goto exit;
/* free any previously saved data */
if( session_data != NULL )
{
mbedtls_platform_zeroize( session_data, session_data_len );
mbedtls_free( session_data );
session_data = NULL;
}
/* get size of the buffer needed */
mbedtls_ssl_session_save( mbedtls_ssl_get_session_pointer( &ssl ),
NULL, 0, &session_data_len );
session_data = mbedtls_calloc( 1, session_data_len );
if( session_data == NULL )
{
mbedtls_printf( " failed\n ! alloc %u bytes for session data\n",
(unsigned) session_data_len );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto exit;
}
/* actually save session data */
if( ( ret = mbedtls_ssl_session_save( mbedtls_ssl_get_session_pointer( &ssl ),
session_data, session_data_len,
&session_data_len ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_session_saved returned -0x%04x\n\n",
-ret );
goto exit;
}
}
else
{
if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_get_session returned -0x%x\n\n",
-ret );
goto exit;
}
}
mbedtls_printf( " ok\n" );
if( opt.reco_mode == 1 )
{
mbedtls_printf( " [ Saved %u bytes of session data]\n",
(unsigned) session_data_len );
}
}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -2839,7 +2918,103 @@ send_request:
}
/*
* 7c. Continue doing data exchanges?
* 7c. Simulate serialize/deserialize and go back to data exchange
*/
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( opt.serialize != 0 )
{
size_t buf_len;
mbedtls_printf( " . Serializing live connection..." );
ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_context_save returned "
"-0x%x\n\n", -ret );
goto exit;
}
if( ( context_buf = mbedtls_calloc( 1, buf_len ) ) == NULL )
{
mbedtls_printf( " failed\n ! Couldn't allocate buffer for "
"serialized context" );
goto exit;
}
context_buf_len = buf_len;
if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
buf_len, &buf_len ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_context_save returned "
"-0x%x\n\n", -ret );
goto exit;
}
mbedtls_printf( " ok\n" );
if( opt.serialize == 1 )
{
/* nothing to do here, done by context_save() already */
mbedtls_printf( " . Context has been reset... ok" );
}
if( opt.serialize == 2 )
{
mbedtls_printf( " . Freeing and reinitializing context..." );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_init( &ssl );
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned "
"-0x%x\n\n", -ret );
goto exit;
}
if( opt.nbio == 2 )
mbedtls_ssl_set_bio( &ssl, &server_fd, delayed_send,
delayed_recv, NULL );
else
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send,
mbedtls_net_recv,
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb( &ssl, &timer,
mbedtls_timing_set_delay,
mbedtls_timing_get_delay );
#endif /* MBEDTLS_TIMING_C */
mbedtls_printf( " ok\n" );
}
mbedtls_printf( " . Deserializing connection..." );
if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
buf_len ) ) != 0 )
{
mbedtls_printf( "failed\n ! mbedtls_ssl_context_load returned "
"-0x%x\n\n", -ret );
goto exit;
}
mbedtls_free( context_buf );
context_buf = NULL;
context_buf_len = 0;
mbedtls_printf( " ok\n" );
}
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/*
* 7d. Continue doing data exchanges?
*/
if( --opt.exchanges > 0 )
goto send_request;
@ -2886,10 +3061,22 @@ reconnect:
goto exit;
}
if( opt.reco_mode == 1 )
{
if( ( ret = mbedtls_ssl_session_load( &saved_session,
session_data,
session_data_len ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_session_load returned -0x%x\n\n",
-ret );
goto exit;
}
}
if( ( ret = mbedtls_ssl_set_session( &ssl, &saved_session ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_session returned %d\n\n",
ret );
mbedtls_printf( " failed\n ! mbedtls_ssl_set_session returned -0x%x\n\n",
-ret );
goto exit;
}
@ -2959,6 +3146,14 @@ exit:
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
if( session_data != NULL )
mbedtls_platform_zeroize( session_data, session_data_len );
mbedtls_free( session_data );
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( context_buf != NULL )
mbedtls_platform_zeroize( context_buf, context_buf_len );
mbedtls_free( context_buf );
#endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)

View File

@ -171,6 +171,8 @@ int main( void )
#define DFL_DGRAM_PACKING 1
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
#define DFL_SERIALIZE 0
#define DFL_EXTENDED_MS_ENFORCE -1
#define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define DFL_REPRODUCIBLE 0
@ -435,6 +437,15 @@ int main( void )
#define USAGE_CURVES ""
#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
#define USAGE_SERIALIZATION \
" serialize=%%d default: 0 (do not serialize/deserialize)\n" \
" options: 1 (serialize)\n" \
" 2 (serialize with re-initialization)\n"
#else
#define USAGE_SERIALIZATION ""
#endif
#define USAGE \
"\n usage: ssl_server2 param=<>...\n" \
"\n acceptable parameters:\n" \
@ -499,6 +510,7 @@ int main( void )
" configuration macro is defined and 1\n" \
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
" acceptable ciphersuite names:\n"
#define ALPN_LIST_SIZE 10
@ -590,6 +602,7 @@ struct options
int cid_enabled_renego; /* whether to use the CID extension or not
* during renegotiation */
const char *cid_val; /* the CID to use for incoming messages */
int serialize; /* serialize/deserialize connection */
const char *cid_val_renego; /* the CID to use for incoming messages
* after renegotiation */
int reproducible; /* make communication reproducible */
@ -1714,6 +1727,10 @@ int main( int argc, char *argv[] )
size_t cid_len = 0;
size_t cid_renego_len = 0;
#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
unsigned char *context_buf = NULL;
size_t context_buf_len;
#endif
int i;
char *p, *q;
@ -1872,6 +1889,7 @@ int main( int argc, char *argv[] )
opt.badmac_limit = DFL_BADMAC_LIMIT;
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
opt.serialize = DFL_SERIALIZE;
opt.eap_tls = DFL_EAP_TLS;
opt.reproducible = DFL_REPRODUCIBLE;
@ -2286,6 +2304,12 @@ int main( int argc, char *argv[] )
{
return query_config( q );
}
else if( strcmp( p, "serialize") == 0 )
{
opt.serialize = atoi( q );
if( opt.serialize < 0 || opt.serialize > 2)
goto usage;
}
else if( strcmp( p, "eap_tls" ) == 0 )
{
opt.eap_tls = atoi( q );
@ -3907,7 +3931,124 @@ data_exchange:
ret = 0;
/*
* 7b. Continue doing data exchanges?
* 7b. Simulate serialize/deserialize and go back to data exchange
*/
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( opt.serialize != 0 )
{
size_t buf_len;
mbedtls_printf( " . Serializing live connection..." );
ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_context_save returned "
"-0x%x\n\n", -ret );
goto exit;
}
if( ( context_buf = mbedtls_calloc( 1, buf_len ) ) == NULL )
{
mbedtls_printf( " failed\n ! Couldn't allocate buffer for "
"serialized context" );
goto exit;
}
context_buf_len = buf_len;
if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
buf_len, &buf_len ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_context_save returned "
"-0x%x\n\n", -ret );
goto exit;
}
mbedtls_printf( " ok\n" );
/*
* This simulates a workflow where you have a long-lived server
* instance, potentially with a pool of ssl_context objects, and you
* just want to re-use one while the connection is inactive: in that
* case you can just reset() it, and then it's ready to receive
* serialized data from another connection (or the same here).
*/
if( opt.serialize == 1 )
{
/* nothing to do here, done by context_save() already */
mbedtls_printf( " . Context has been reset... ok" );
}
/*
* This simulates a workflow where you have one server instance per
* connection, and want to release it entire when the connection is
* inactive, and spawn it again when needed again - this would happen
* between ssl_free() and ssl_init() below, together with any other
* teardown/startup code needed - for example, preparing the
* ssl_config again (see section 3 "setup stuff" in this file).
*/
if( opt.serialize == 2 )
{
mbedtls_printf( " . Freeing and reinitializing context..." );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_init( &ssl );
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned "
"-0x%x\n\n", -ret );
goto exit;
}
/*
* This illustrates the minimum amount of things you need to set
* up, however you could set up much more if desired, for example
* if you want to share your set up code between the case of
* establishing a new connection and this case.
*/
if( opt.nbio == 2 )
mbedtls_ssl_set_bio( &ssl, &client_fd, delayed_send,
delayed_recv, NULL );
else
mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send,
mbedtls_net_recv,
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb( &ssl, &timer,
mbedtls_timing_set_delay,
mbedtls_timing_get_delay );
#endif /* MBEDTLS_TIMING_C */
mbedtls_printf( " ok\n" );
}
mbedtls_printf( " . Deserializing connection..." );
if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
buf_len ) ) != 0 )
{
mbedtls_printf( "failed\n ! mbedtls_ssl_context_load returned "
"-0x%x\n\n", -ret );
goto exit;
}
mbedtls_free( context_buf );
context_buf = NULL;
context_buf_len = 0;
mbedtls_printf( " ok\n" );
}
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/*
* 7c. Continue doing data exchanges?
*/
if( --exchanges_left > 0 )
goto data_exchange;
@ -4013,6 +4154,12 @@ exit:
mbedtls_free( buf );
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( context_buf != NULL )
mbedtls_platform_zeroize( context_buf, context_buf_len );
mbedtls_free( context_buf );
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_status();

View File

@ -760,7 +760,7 @@ component_test_small_ssl_dtls_max_buffering () {
component_test_small_mbedtls_ssl_dtls_max_buffering () {
msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1"
scripts/config.pl set MBEDTLS_SSL_DTLS_MAX_BUFFERING 240
scripts/config.pl set MBEDTLS_SSL_DTLS_MAX_BUFFERING 190
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make

View File

@ -1280,6 +1280,56 @@ run_test "Truncated HMAC, DTLS: client enabled, server enabled" \
-S "dumping 'expected mac' (20 bytes)" \
-s "dumping 'expected mac' (10 bytes)"
# Tests for Context serialization
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, client serializes" \
"$P_SRV dtls=1 serialize=0 exchanges=2" \
"$P_CLI dtls=1 serialize=1 exchanges=2" \
0 \
-c "Deserializing connection..." \
-S "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, server serializes" \
"$P_SRV dtls=1 serialize=1 exchanges=2" \
"$P_CLI dtls=1 serialize=0 exchanges=2" \
0 \
-C "Deserializing connection..." \
-s "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, both serialize" \
"$P_SRV dtls=1 serialize=1 exchanges=2" \
"$P_CLI dtls=1 serialize=1 exchanges=2" \
0 \
-c "Deserializing connection..." \
-s "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, re-init, client serializes" \
"$P_SRV dtls=1 serialize=0 exchanges=2" \
"$P_CLI dtls=1 serialize=2 exchanges=2" \
0 \
-c "Deserializing connection..." \
-S "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, re-init, server serializes" \
"$P_SRV dtls=1 serialize=2 exchanges=2" \
"$P_CLI dtls=1 serialize=0 exchanges=2" \
0 \
-C "Deserializing connection..." \
-s "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, re-init, both serialize" \
"$P_SRV dtls=1 serialize=2 exchanges=2" \
"$P_CLI dtls=1 serialize=2 exchanges=2" \
0 \
-c "Deserializing connection..." \
-s "Deserializing connection..."
# Tests for DTLS Connection ID extension
# So far, the CID API isn't implemented, so we can't
@ -1939,8 +1989,8 @@ run_test "Extended Master Secret: default" \
-s "found extended master secret extension" \
-s "server hello, adding extended master secret extension" \
-c "found extended_master_secret extension" \
-c "using extended master secret" \
-s "using extended master secret"
-c "session hash for extended master secret" \
-s "session hash for extended master secret"
run_test "Extended Master Secret: client enabled, server disabled" \
"$P_SRV debug_level=3 extended_ms=0" \
@ -1950,8 +2000,8 @@ run_test "Extended Master Secret: client enabled, server disabled" \
-s "found extended master secret extension" \
-S "server hello, adding extended master secret extension" \
-C "found extended_master_secret extension" \
-C "using extended master secret" \
-S "using extended master secret"
-C "session hash for extended master secret" \
-S "session hash for extended master secret"
run_test "Extended Master Secret: client disabled, server enabled" \
"$P_SRV debug_level=3 extended_ms=1" \
@ -1961,8 +2011,8 @@ run_test "Extended Master Secret: client disabled, server enabled" \
-S "found extended master secret extension" \
-S "server hello, adding extended master secret extension" \
-C "found extended_master_secret extension" \
-C "using extended master secret" \
-S "using extended master secret"
-C "session hash for extended master secret" \
-S "session hash for extended master secret"
requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
run_test "Extended Master Secret: client SSLv3, server enabled" \
@ -1973,8 +2023,8 @@ run_test "Extended Master Secret: client SSLv3, server enabled" \
-S "found extended master secret extension" \
-S "server hello, adding extended master secret extension" \
-C "found extended_master_secret extension" \
-C "using extended master secret" \
-S "using extended master secret"
-C "session hash for extended master secret" \
-S "session hash for extended master secret"
requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
run_test "Extended Master Secret: client enabled, server SSLv3" \
@ -1985,8 +2035,8 @@ run_test "Extended Master Secret: client enabled, server SSLv3" \
-S "found extended master secret extension" \
-S "server hello, adding extended master secret extension" \
-C "found extended_master_secret extension" \
-C "using extended master secret" \
-S "using extended master secret"
-C "session hash for extended master secret" \
-S "session hash for extended master secret"
# Tests for FALLBACK_SCSV
@ -2239,6 +2289,20 @@ run_test "Session resume using tickets: timeout" \
-S "a session has been resumed" \
-C "a session has been resumed"
run_test "Session resume using tickets: session copy" \
"$P_SRV debug_level=3 tickets=1 cache_max=0" \
"$P_CLI debug_level=3 tickets=1 reconnect=1 reco_mode=0" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
-s "server hello, adding session ticket extension" \
-c "found session_ticket extension" \
-c "parse new session ticket" \
-S "session successfully restored from cache" \
-s "session successfully restored from ticket" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using tickets: openssl server" \
"$O_SRV" \
"$P_CLI debug_level=3 tickets=1 reconnect=1" \
@ -2304,6 +2368,20 @@ run_test "Session resume using tickets, DTLS: timeout" \
-S "a session has been resumed" \
-C "a session has been resumed"
run_test "Session resume using tickets, DTLS: session copy" \
"$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_mode=0" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
-s "server hello, adding session ticket extension" \
-c "found session_ticket extension" \
-c "parse new session ticket" \
-S "session successfully restored from cache" \
-s "session successfully restored from ticket" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using tickets, DTLS: openssl server" \
"$O_SRV -dtls1" \
"$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
@ -2400,6 +2478,15 @@ run_test "Session resume using cache: no timeout" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using cache: session copy" \
"$P_SRV debug_level=3 tickets=0" \
"$P_CLI debug_level=3 tickets=0 reconnect=1 reco_mode=0" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using cache: openssl client" \
"$P_SRV debug_level=3 tickets=0" \
"( $O_CLI -sess_out $SESSION; \
@ -2495,6 +2582,15 @@ run_test "Session resume using cache, DTLS: no timeout" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using cache, DTLS: session copy" \
"$P_SRV dtls=1 debug_level=3 tickets=0" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_mode=0" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
-s "a session has been resumed" \
-c "a session has been resumed"
run_test "Session resume using cache, DTLS: openssl client" \
"$P_SRV dtls=1 debug_level=3 tickets=0" \
"( $O_CLI -dtls1 -sess_out $SESSION; \
@ -4782,8 +4878,8 @@ run_test "PSK callback: opaque psk on client, no callback" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4796,8 +4892,8 @@ run_test "PSK callback: opaque psk on client, no callback, SHA-384" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4810,8 +4906,8 @@ run_test "PSK callback: opaque psk on client, no callback, EMS" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4824,8 +4920,8 @@ run_test "PSK callback: opaque psk on client, no callback, SHA-384, EMS" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4838,8 +4934,8 @@ run_test "PSK callback: raw psk on client, static opaque on server, no callba
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4852,8 +4948,8 @@ run_test "PSK callback: raw psk on client, static opaque on server, no callba
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4865,8 +4961,8 @@ run_test "PSK callback: raw psk on client, static opaque on server, no callba
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123 extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
@ -4880,8 +4976,8 @@ run_test "PSK callback: raw psk on client, static opaque on server, no callba
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=foo psk=abc123 extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
@ -4896,8 +4992,8 @@ run_test "PSK callback: raw psk on client, no static PSK on server, opaque PS
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4910,8 +5006,8 @@ run_test "PSK callback: raw psk on client, no static PSK on server, opaque PS
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4923,8 +5019,8 @@ run_test "PSK callback: raw psk on client, no static PSK on server, opaque PS
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=dead extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
@ -4938,8 +5034,8 @@ run_test "PSK callback: raw psk on client, no static PSK on server, opaque PS
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=abc psk=dead extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-c "session hash for extended master secret"\
-s "session hash for extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
@ -4954,8 +5050,8 @@ run_test "PSK callback: raw psk on client, mismatching static raw PSK on serv
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4968,8 +5064,8 @@ run_test "PSK callback: raw psk on client, mismatching static opaque PSK on s
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4981,8 +5077,8 @@ run_test "PSK callback: raw psk on client, mismatching static opaque PSK on s
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -4994,8 +5090,8 @@ run_test "PSK callback: raw psk on client, id-matching but wrong raw PSK on s
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-C "session hash for extended master secret"\
-S "session hash for extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@ -8272,11 +8368,11 @@ run_test "DTLS reordering: Buffer encrypted Finished message" \
# without fragmentation or be reassembled within the bounds of
# MBEDTLS_SSL_DTLS_MAX_BUFFERING. Achieve this by testing with a PSK-based
# handshake, omitting CRTs.
requires_config_value_at_least "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 240
requires_config_value_at_most "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 280
requires_config_value_at_least "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 190
requires_config_value_at_most "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 230
run_test "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket" \
-p "$P_PXY delay_srv=NewSessionTicket delay_srv=NewSessionTicket delay_ccs=1" \
"$P_SRV mtu=190 dgram_packing=0 psk=abc123 psk_identity=foo cookies=0 dtls=1 debug_level=2" \
"$P_SRV mtu=140 response_size=90 dgram_packing=0 psk=abc123 psk_identity=foo cookies=0 dtls=1 debug_level=2" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 psk=abc123 psk_identity=foo" \
0 \
-s "Buffer record from epoch 1" \

View File

@ -58,6 +58,18 @@ ssl_dtls_replay:"abcd12340000abcd12340100":"abcd123400ff":0
SSL SET_HOSTNAME memory leak: call ssl_set_hostname twice
ssl_set_hostname_twice:"server0":"server1"
SSL session serialization: Wrong major version
ssl_session_serialize_version_check:1:0:0:0
SSL session serialization: Wrong minor version
ssl_session_serialize_version_check:0:1:0:0
SSL session serialization: Wrong patch version
ssl_session_serialize_version_check:0:0:1:0
SSL session serialization: Wrong config
ssl_session_serialize_version_check:0:0:0:1
Record crypt, AES-128-CBC, 1.2, SHA-384
depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SHA512_C
ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_MD_SHA384:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0
@ -8752,3 +8764,95 @@ ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA384:"1234567890abcdef1234567890abcdef12345678
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SHA256 SHA-256 not enabled
depends_on:!MBEDTLS_SHA256_C
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA256:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"7f9998393198a02c8d731ccc2ef90b2c":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
Session serialization, save-load: no ticket, no cert
ssl_serialize_session_save_load:0:""
Session serialization, save-load: small ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_save_load:42:""
Session serialization, save-load: large ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_save_load:1023:""
Session serialization, save-load: no ticket, cert
depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_load:0:"data_files/server5.crt"
Session serialization, save-load: small ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_load:42:"data_files/server5.crt"
Session serialization, save-load: large ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_load:1023:"data_files/server5.crt"
Session serialization, load-save: no ticket, no cert
ssl_serialize_session_load_save:0:""
Session serialization, load-save: small ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_load_save:42:""
Session serialization, load-save: large ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_load_save:1023:""
Session serialization, load-save: no ticket, cert
depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_save:0:"data_files/server5.crt"
Session serialization, load-save: small ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_save:42:"data_files/server5.crt"
Session serialization, load-save: large ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_save:1023:"data_files/server5.crt"
Session serialization, save buffer size: no ticket, no cert
ssl_serialize_session_save_buf_size:0:""
Session serialization, save buffer size: small ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_save_buf_size:42:""
Session serialization, save buffer size: large ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_save_buf_size:1023:""
Session serialization, save buffer size: no ticket, cert
depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_buf_size:0:"data_files/server5.crt"
Session serialization, save buffer size: small ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_buf_size:42:"data_files/server5.crt"
Session serialization, save buffer size: large ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_save_buf_size:1023:"data_files/server5.crt"
Session serialization, load buffer size: no ticket, no cert
ssl_serialize_session_load_buf_size:0:""
Session serialization, load buffer size: small ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_load_buf_size:42:""
Session serialization, load buffer size: large ticket, no cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
ssl_serialize_session_load_buf_size:1023:""
Session serialization, load buffer size: no ticket, cert
depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_buf_size:0:"data_files/server5.crt"
Session serialization, load buffer size: small ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_buf_size:42:"data_files/server5.crt"
Session serialization, load buffer size: large ticket, cert
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
ssl_serialize_session_load_buf_size:1023:"data_files/server5.crt"

View File

@ -267,6 +267,93 @@ cleanup:
return( ret );
}
/*
* Populate a session structure for serialization tests.
* Choose dummy values, mostly non-0 to distinguish from the init default.
*/
static int ssl_populate_session( mbedtls_ssl_session *session,
int ticket_len,
const char *crt_file )
{
#if defined(MBEDTLS_HAVE_TIME)
session->start = mbedtls_time( NULL ) - 42;
#endif
session->ciphersuite = 0xabcd;
session->compression = 1;
session->id_len = sizeof( session->id );
memset( session->id, 66, session->id_len );
memset( session->master, 17, sizeof( session->master ) );
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_FS_IO)
if( strlen( crt_file ) != 0 )
{
mbedtls_x509_crt tmp_crt;
int ret;
mbedtls_x509_crt_init( &tmp_crt );
ret = mbedtls_x509_crt_parse_file( &tmp_crt, crt_file );
if( ret != 0 )
return( ret );
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* Move temporary CRT. */
session->peer_cert = mbedtls_calloc( 1, sizeof( *session->peer_cert ) );
if( session->peer_cert == NULL )
return( -1 );
*session->peer_cert = tmp_crt;
memset( &tmp_crt, 0, sizeof( tmp_crt ) );
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Calculate digest of temporary CRT. */
session->peer_cert_digest =
mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
if( session->peer_cert_digest == NULL )
return( -1 );
ret = mbedtls_md( mbedtls_md_info_from_type(
MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
tmp_crt.raw.p, tmp_crt.raw.len,
session->peer_cert_digest );
if( ret != 0 )
return( ret );
session->peer_cert_digest_type =
MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
session->peer_cert_digest_len =
MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_x509_crt_free( &tmp_crt );
}
#else /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO */
(void) crt_file;
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO */
session->verify_result = 0xdeadbeef;
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if( ticket_len != 0 )
{
session->ticket = mbedtls_calloc( 1, ticket_len );
if( session->ticket == NULL )
return( -1 );
memset( session->ticket, 33, ticket_len );
}
session->ticket_len = ticket_len;
session->ticket_lifetime = 86401;
#else
(void) ticket_len;
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
session->mfl_code = 1;
#endif
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
session->trunc_hmac = 1;
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
session->encrypt_then_mac = 1;
#endif
return( 0 );
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@ -605,3 +692,295 @@ exit:
mbedtls_free( output );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_serialize_session_save_load( int ticket_len, char *crt_file )
{
mbedtls_ssl_session original, restored;
unsigned char *buf = NULL;
size_t len;
/*
* Test that a save-load pair is the identity
*/
mbedtls_ssl_session_init( &original );
mbedtls_ssl_session_init( &restored );
/* Prepare a dummy session to work on */
TEST_ASSERT( ssl_populate_session( &original, ticket_len, crt_file ) == 0 );
/* Serialize it */
TEST_ASSERT( mbedtls_ssl_session_save( &original, NULL, 0, &len )
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
TEST_ASSERT( ( buf = mbedtls_calloc( 1, len ) ) != NULL );
TEST_ASSERT( mbedtls_ssl_session_save( &original, buf, len, &len )
== 0 );
/* Restore session from serialized data */
TEST_ASSERT( mbedtls_ssl_session_load( &restored, buf, len) == 0 );
/*
* Make sure both session structures are identical
*/
#if defined(MBEDTLS_HAVE_TIME)
TEST_ASSERT( original.start == restored.start );
#endif
TEST_ASSERT( original.ciphersuite == restored.ciphersuite );
TEST_ASSERT( original.compression == restored.compression );
TEST_ASSERT( original.id_len == restored.id_len );
TEST_ASSERT( memcmp( original.id,
restored.id, sizeof( original.id ) ) == 0 );
TEST_ASSERT( memcmp( original.master,
restored.master, sizeof( original.master ) ) == 0 );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
TEST_ASSERT( ( original.peer_cert == NULL ) ==
( restored.peer_cert == NULL ) );
if( original.peer_cert != NULL )
{
TEST_ASSERT( original.peer_cert->raw.len ==
restored.peer_cert->raw.len );
TEST_ASSERT( memcmp( original.peer_cert->raw.p,
restored.peer_cert->raw.p,
original.peer_cert->raw.len ) == 0 );
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
TEST_ASSERT( original.peer_cert_digest_type ==
restored.peer_cert_digest_type );
TEST_ASSERT( original.peer_cert_digest_len ==
restored.peer_cert_digest_len );
TEST_ASSERT( ( original.peer_cert_digest == NULL ) ==
( restored.peer_cert_digest == NULL ) );
if( original.peer_cert_digest != NULL )
{
TEST_ASSERT( memcmp( original.peer_cert_digest,
restored.peer_cert_digest,
original.peer_cert_digest_len ) == 0 );
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
TEST_ASSERT( original.verify_result == restored.verify_result );
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
TEST_ASSERT( original.ticket_len == restored.ticket_len );
if( original.ticket_len != 0 )
{
TEST_ASSERT( original.ticket != NULL );
TEST_ASSERT( restored.ticket != NULL );
TEST_ASSERT( memcmp( original.ticket,
restored.ticket, original.ticket_len ) == 0 );
}
TEST_ASSERT( original.ticket_lifetime == restored.ticket_lifetime );
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
TEST_ASSERT( original.mfl_code == restored.mfl_code );
#endif
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
TEST_ASSERT( original.trunc_hmac == restored.trunc_hmac );
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
TEST_ASSERT( original.encrypt_then_mac == restored.encrypt_then_mac );
#endif
exit:
mbedtls_ssl_session_free( &original );
mbedtls_ssl_session_free( &restored );
mbedtls_free( buf );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_serialize_session_load_save( int ticket_len, char *crt_file )
{
mbedtls_ssl_session session;
unsigned char *buf1 = NULL, *buf2 = NULL;
size_t len0, len1, len2;
/*
* Test that a load-save pair is the identity
*/
mbedtls_ssl_session_init( &session );
/* Prepare a dummy session to work on */
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
/* Get desired buffer size for serializing */
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &len0 )
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
/* Allocate first buffer */
buf1 = mbedtls_calloc( 1, len0 );
TEST_ASSERT( buf1 != NULL );
/* Serialize to buffer and free live session */
TEST_ASSERT( mbedtls_ssl_session_save( &session, buf1, len0, &len1 )
== 0 );
TEST_ASSERT( len0 == len1 );
mbedtls_ssl_session_free( &session );
/* Restore session from serialized data */
TEST_ASSERT( mbedtls_ssl_session_load( &session, buf1, len1 ) == 0 );
/* Allocate second buffer and serialize to it */
buf2 = mbedtls_calloc( 1, len0 );
TEST_ASSERT( buf2 != NULL );
TEST_ASSERT( mbedtls_ssl_session_save( &session, buf2, len0, &len2 )
== 0 );
/* Make sure both serialized versions are identical */
TEST_ASSERT( len1 == len2 );
TEST_ASSERT( memcmp( buf1, buf2, len1 ) == 0 );
exit:
mbedtls_ssl_session_free( &session );
mbedtls_free( buf1 );
mbedtls_free( buf2 );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_serialize_session_save_buf_size( int ticket_len, char *crt_file )
{
mbedtls_ssl_session session;
unsigned char *buf = NULL;
size_t good_len, bad_len, test_len;
/*
* Test that session_save() fails cleanly on small buffers
*/
mbedtls_ssl_session_init( &session );
/* Prepare dummy session and get serialized size */
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
/* Try all possible bad lengths */
for( bad_len = 1; bad_len < good_len; bad_len++ )
{
/* Allocate exact size so that asan/valgrind can detect any overwrite */
mbedtls_free( buf );
TEST_ASSERT( ( buf = mbedtls_calloc( 1, bad_len ) ) != NULL );
TEST_ASSERT( mbedtls_ssl_session_save( &session, buf, bad_len,
&test_len )
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
TEST_ASSERT( test_len == good_len );
}
exit:
mbedtls_ssl_session_free( &session );
mbedtls_free( buf );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_serialize_session_load_buf_size( int ticket_len, char *crt_file )
{
mbedtls_ssl_session session;
unsigned char *good_buf = NULL, *bad_buf = NULL;
size_t good_len, bad_len;
/*
* Test that session_load() fails cleanly on small buffers
*/
mbedtls_ssl_session_init( &session );
/* Prepare serialized session data */
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
TEST_ASSERT( ( good_buf = mbedtls_calloc( 1, good_len ) ) != NULL );
TEST_ASSERT( mbedtls_ssl_session_save( &session, good_buf, good_len,
&good_len ) == 0 );
mbedtls_ssl_session_free( &session );
/* Try all possible bad lengths */
for( bad_len = 0; bad_len < good_len; bad_len++ )
{
/* Allocate exact size so that asan/valgrind can detect any overread */
mbedtls_free( bad_buf );
bad_buf = mbedtls_calloc( 1, bad_len ? bad_len : 1 );
TEST_ASSERT( bad_buf != NULL );
memcpy( bad_buf, good_buf, bad_len );
TEST_ASSERT( mbedtls_ssl_session_load( &session, bad_buf, bad_len )
== MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
exit:
mbedtls_ssl_session_free( &session );
mbedtls_free( good_buf );
mbedtls_free( bad_buf );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_session_serialize_version_check( int corrupt_major,
int corrupt_minor,
int corrupt_patch,
int corrupt_config )
{
unsigned char serialized_session[ 2048 ];
size_t serialized_session_len;
unsigned cur_byte;
mbedtls_ssl_session session;
uint8_t should_corrupt_byte[] = { corrupt_major == 1,
corrupt_minor == 1,
corrupt_patch == 1,
corrupt_config == 1,
corrupt_config == 1 };
mbedtls_ssl_session_init( &session );
/* Infer length of serialized session. */
TEST_ASSERT( mbedtls_ssl_session_save( &session,
serialized_session,
sizeof( serialized_session ),
&serialized_session_len ) == 0 );
mbedtls_ssl_session_free( &session );
/* Without any modification, we should be able to successfully
* de-serialize the session - double-check that. */
TEST_ASSERT( mbedtls_ssl_session_load( &session,
serialized_session,
serialized_session_len ) == 0 );
mbedtls_ssl_session_free( &session );
/* Go through the bytes in the serialized session header and
* corrupt them bit-by-bit. */
for( cur_byte = 0; cur_byte < sizeof( should_corrupt_byte ); cur_byte++ )
{
int cur_bit;
unsigned char * const byte = &serialized_session[ cur_byte ];
if( should_corrupt_byte[ cur_byte ] == 0 )
continue;
for( cur_bit = 0; cur_bit < CHAR_BIT; cur_bit++ )
{
unsigned char const corrupted_bit = 0x1u << cur_bit;
/* Modify a single bit in the serialized session. */
*byte ^= corrupted_bit;
/* Attempt to deserialize */
TEST_ASSERT( mbedtls_ssl_session_load( &session,
serialized_session,
serialized_session_len ) ==
MBEDTLS_ERR_SSL_VERSION_MISMATCH );
/* Undo the change */
*byte ^= corrupted_bit;
}
}
}
/* END_CASE */