Merge pull request #6327 from yuhaoth/pr/tls13-psk-after-session-tickets
TLS 1.3: PSK and NewSessionTicket: Add support for sending PSK and Ticket together.
This commit is contained in:
commit
78317c832b
9 changed files with 697 additions and 311 deletions
|
@ -1390,10 +1390,12 @@ struct mbedtls_ssl_config
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/** Callback to retrieve PSK key from identity */
|
||||
int (*MBEDTLS_PRIVATE(f_psk))(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
|
||||
void *MBEDTLS_PRIVATE(p_psk); /*!< context for PSK callback */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
|
||||
/** Callback to create & write a cookie for ClientHello verification */
|
||||
|
@ -3415,6 +3417,7 @@ int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
|
|||
mbedtls_svc_key_id_t psk );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/**
|
||||
* \brief Set the PSK callback (server-side only).
|
||||
*
|
||||
|
@ -3457,6 +3460,7 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
|||
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
|
||||
size_t),
|
||||
void *p_psk );
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
|
||||
|
|
|
@ -713,12 +713,39 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
|
|||
MBEDTLS_CLIENT_HELLO_RANDOM_LEN - gmt_unix_time_len );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret;
|
||||
size_t session_id_len;
|
||||
mbedtls_ssl_session *session_negotiate = ssl->session_negotiate;
|
||||
|
||||
if( session_negotiate == NULL )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_HAVE_TIME)
|
||||
|
||||
/* Check if a tls13 ticket has been configured. */
|
||||
if( ssl->handshake->resume != 0 &&
|
||||
session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
session_negotiate->ticket != NULL )
|
||||
{
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
uint64_t age = (uint64_t)( now - session_negotiate->ticket_received );
|
||||
if( session_negotiate->ticket_received > now ||
|
||||
age > session_negotiate->ticket_lifetime )
|
||||
{
|
||||
/* Without valid ticket, disable session resumption.*/
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket expired, disable session resumption" ) );
|
||||
ssl->handshake->resume = 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
|
||||
MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_HAVE_TIME */
|
||||
|
||||
if( ssl->conf->f_rng == NULL )
|
||||
{
|
||||
|
@ -737,7 +764,7 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
if( ssl->handshake->resume )
|
||||
{
|
||||
ssl->tls_version = ssl->session_negotiate->tls_version;
|
||||
ssl->tls_version = session_negotiate->tls_version;
|
||||
ssl->handshake->min_tls_version = ssl->tls_version;
|
||||
}
|
||||
else
|
||||
|
@ -771,7 +798,7 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
* to zero, except in the case of a TLS 1.2 session renegotiation or
|
||||
* session resumption.
|
||||
*/
|
||||
session_id_len = ssl->session_negotiate->id_len;
|
||||
session_id_len = session_negotiate->id_len;
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 )
|
||||
|
@ -794,8 +821,8 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
{
|
||||
if( ( ssl->session_negotiate->ticket != NULL ) &&
|
||||
( ssl->session_negotiate->ticket_len != 0 ) )
|
||||
if( ( session_negotiate->ticket != NULL ) &&
|
||||
( session_negotiate->ticket_len != 0 ) )
|
||||
{
|
||||
session_id_len = 32;
|
||||
}
|
||||
|
@ -827,13 +854,13 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
}
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
||||
|
||||
if( session_id_len != ssl->session_negotiate->id_len )
|
||||
if( session_id_len != session_negotiate->id_len )
|
||||
{
|
||||
ssl->session_negotiate->id_len = session_id_len;
|
||||
session_negotiate->id_len = session_id_len;
|
||||
if( session_id_len > 0 )
|
||||
{
|
||||
ret = ssl->conf->f_rng( ssl->conf->p_rng,
|
||||
ssl->session_negotiate->id,
|
||||
session_negotiate->id,
|
||||
session_id_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
@ -845,7 +872,6 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write ClientHello handshake message.
|
||||
* Handler for MBEDTLS_SSL_CLIENT_HELLO
|
||||
|
|
|
@ -1373,6 +1373,23 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
|
|||
if( ssl->handshake->resume == 1 )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if( session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
mbedtls_ssl_ciphersuite_from_id( session->ciphersuite );
|
||||
|
||||
if( mbedtls_ssl_validate_ciphersuite(
|
||||
ssl, ciphersuite_info, MBEDTLS_SSL_VERSION_TLS1_3,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3 ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "%d is not a valid TLS 1.3 ciphersuite.",
|
||||
session->ciphersuite ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
|
||||
session ) ) != 0 )
|
||||
return( ret );
|
||||
|
@ -1795,6 +1812,7 @@ int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
||||
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
|
||||
size_t),
|
||||
|
@ -1803,6 +1821,8 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
|||
conf->f_psk = f_psk;
|
||||
conf->p_psk = p_psk;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
|
|
@ -665,54 +665,194 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
|||
return ( 0 );
|
||||
}
|
||||
|
||||
/* Check if we have any PSK to offer, returns 0 if a PSK is available. */
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_get_psk_to_offer(
|
||||
const mbedtls_ssl_context *ssl,
|
||||
int *psk_type,
|
||||
const unsigned char **psk, size_t *psk_len,
|
||||
const unsigned char **psk_identity, size_t *psk_identity_len )
|
||||
static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg( int ciphersuite )
|
||||
{
|
||||
*psk = NULL;
|
||||
*psk_len = 0;
|
||||
*psk_identity = NULL;
|
||||
*psk_identity_len = 0;
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
|
||||
|
||||
if( ciphersuite_info != NULL )
|
||||
return( mbedtls_psa_translate_md( ciphersuite_info->mac ) );
|
||||
|
||||
return( PSA_ALG_NONE );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/* Check if a ticket has been configured. */
|
||||
if( ssl->session_negotiate != NULL &&
|
||||
ssl->session_negotiate->ticket != NULL )
|
||||
static int ssl_tls13_has_configured_ticket( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
return( ssl->handshake->resume &&
|
||||
session != NULL && session->ticket != NULL );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_ticket_get_identity( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **identity,
|
||||
size_t *identity_len )
|
||||
{
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
|
||||
if( !ssl_tls13_has_configured_ticket( ssl ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = ssl_tls13_get_ciphersuite_hash_alg( session->ciphersuite );
|
||||
*identity = session->ticket;
|
||||
*identity_len = session->ticket_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_ticket_get_psk( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
|
||||
if( !ssl_tls13_has_configured_ticket( ssl ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = ssl_tls13_get_ciphersuite_hash_alg( session->ciphersuite );
|
||||
*psk = session->resumption_key;
|
||||
*psk_len = session->resumption_key_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
static int ssl_tls13_has_configured_psk( const mbedtls_ssl_config *conf )
|
||||
{
|
||||
return( conf->psk != NULL && conf->psk_identity != NULL );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_psk_get_identity( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **identity,
|
||||
size_t *identity_len )
|
||||
{
|
||||
|
||||
if( !ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
*identity = ssl->conf->psk_identity;
|
||||
*identity_len = ssl->conf->psk_identity_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_psk_get_psk( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
|
||||
if( !ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
*psk = ssl->conf->psk;
|
||||
*psk_len = ssl->conf->psk_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int ssl_tls13_get_configured_psk_count( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int configured_psk_count = 0;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_has_configured_ticket( ssl ) )
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
if( ssl->session_negotiate->ticket_received <= now &&
|
||||
(uint64_t)( now - ssl->session_negotiate->ticket_received )
|
||||
<= ssl->session_negotiate->ticket_lifetime )
|
||||
{
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
|
||||
*psk = ssl->session_negotiate->resumption_key;
|
||||
*psk_len = ssl->session_negotiate->resumption_key_len;
|
||||
*psk_identity = ssl->session_negotiate->ticket;
|
||||
*psk_identity_len = ssl->session_negotiate->ticket_len;
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket expired" ) );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Ticket is configured" ) );
|
||||
configured_psk_count++;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if an external PSK has been configured. */
|
||||
if( ssl->conf->psk != NULL )
|
||||
if( ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
{
|
||||
*psk = ssl->conf->psk;
|
||||
*psk_len = ssl->conf->psk_len;
|
||||
*psk_identity = ssl->conf->psk_identity;
|
||||
*psk_identity_len = ssl->conf->psk_identity_len;
|
||||
return( 0 );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK is configured" ) );
|
||||
configured_psk_count++;
|
||||
}
|
||||
return( configured_psk_count );
|
||||
}
|
||||
|
||||
return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_identity( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
const unsigned char *identity,
|
||||
size_t identity_len,
|
||||
uint32_t obfuscated_ticket_age,
|
||||
size_t *out_len )
|
||||
{
|
||||
((void) ssl);
|
||||
*out_len = 0;
|
||||
|
||||
/*
|
||||
* - identity_len (2 bytes)
|
||||
* - identity (psk_identity_len bytes)
|
||||
* - obfuscated_ticket_age (4 bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 6 + identity_len );
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( identity_len, buf, 0 );
|
||||
memcpy( buf + 2, identity, identity_len );
|
||||
MBEDTLS_PUT_UINT32_BE( obfuscated_ticket_age, buf, 2 + identity_len );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "write identity", buf, 6 + identity_len );
|
||||
|
||||
*out_len = 6 + identity_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_binder( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
int psk_type,
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *psk,
|
||||
size_t psk_len,
|
||||
size_t *out_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char binder_len;
|
||||
unsigned char transcript[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
|
||||
size_t transcript_len = 0;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
binder_len = PSA_HASH_LENGTH( hash_alg );
|
||||
|
||||
/*
|
||||
* - binder_len (1 bytes)
|
||||
* - binder (binder_len bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 1 + binder_len );
|
||||
|
||||
buf[0] = binder_len;
|
||||
|
||||
/* Get current state of handshake transcript. */
|
||||
ret = mbedtls_ssl_get_handshake_transcript(
|
||||
ssl, mbedtls_hash_info_md_from_psa( hash_alg ),
|
||||
transcript, sizeof( transcript ), &transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl, hash_alg,
|
||||
psk, psk_len, psk_type,
|
||||
transcript, buf + 1 );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_create_psk_binder", ret );
|
||||
return( ret );
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "write binder", buf, 1 + binder_len );
|
||||
|
||||
*out_len = 1 + binder_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -739,140 +879,104 @@ static int ssl_tls13_get_psk_to_offer(
|
|||
*
|
||||
*/
|
||||
int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, unsigned char *end,
|
||||
size_t *out_len, size_t *binders_len )
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end,
|
||||
size_t *out_len, size_t *binders_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int configured_psk_count = 0;
|
||||
unsigned char *p = buf;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
int psk_type;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
const int *ciphersuites;
|
||||
psa_algorithm_t psa_hash_alg;
|
||||
int hash_len = 0;
|
||||
size_t identities_len, l_binders_len;
|
||||
uint32_t obfuscated_ticket_age = 0;
|
||||
psa_algorithm_t hash_alg;
|
||||
const unsigned char *identity;
|
||||
size_t identity_len;
|
||||
size_t l_binders_len = 0;
|
||||
size_t output_len;
|
||||
|
||||
*out_len = 0;
|
||||
*binders_len = 0;
|
||||
|
||||
/* Check if we have any PSKs to offer. If so, return the first.
|
||||
*
|
||||
* NOTE: Ultimately, we want to be able to offer multiple PSKs,
|
||||
* in which case we want to iterate over them here.
|
||||
*
|
||||
* As it stands, however, we only ever offer one, chosen
|
||||
* by the following heuristic:
|
||||
* - If a ticket has been configured, offer the corresponding PSK.
|
||||
* - If no ticket has been configured by an external PSK has been
|
||||
* configured, offer that.
|
||||
* - Otherwise, skip the PSK extension.
|
||||
*/
|
||||
if( ssl_tls13_get_psk_to_offer( ssl, &psk_type, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
/* Check if we have any PSKs to offer. If no, skip pre_shared_key */
|
||||
configured_psk_count = ssl_tls13_get_configured_psk_count( ssl );
|
||||
if( configured_psk_count == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip pre_shared_key extensions" ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL )
|
||||
{
|
||||
/*
|
||||
* Ciphersuite list
|
||||
*/
|
||||
ciphersuites = ssl->conf->ciphersuite_list;
|
||||
for( int i = 0; ciphersuites[i] != 0; i++ )
|
||||
{
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ciphersuites[i] );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Pre-configured PSK number = %d",
|
||||
configured_psk_count ) );
|
||||
|
||||
if( mbedtls_ssl_validate_ciphersuite(
|
||||
ssl, ciphersuite_info,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3 ) != 0 )
|
||||
continue;
|
||||
|
||||
/* In this implementation we only add one pre-shared-key
|
||||
* extension.
|
||||
*/
|
||||
ssl->session_negotiate->ciphersuite = ciphersuites[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION )
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
|
||||
obfuscated_ticket_age =
|
||||
( (uint32_t)( now - ssl->session_negotiate->ticket_received ) * 1000 )
|
||||
+ ssl->session_negotiate->ticket_age_add;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "write_identities_of_pre_shared_key_ext: "
|
||||
"should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ssl->session_negotiate->ciphersuite );
|
||||
/* No suitable ciphersuite for the PSK */
|
||||
if( ciphersuite_info == NULL )
|
||||
return( 0 );
|
||||
|
||||
psa_hash_alg = mbedtls_psa_translate_md( ciphersuite_info->mac );
|
||||
hash_len = PSA_HASH_LENGTH( psa_hash_alg );
|
||||
if( hash_len == -1 )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
/* Check if we have space to write the extension, binder included.
|
||||
/* Check if we have space to write the extension, binders included.
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_len (2 bytes)
|
||||
* - identities_len (2 bytes)
|
||||
* - identity_len (2 bytes)
|
||||
* - identity (psk_identity_len bytes)
|
||||
* - obfuscated_ticket_age (4 bytes)
|
||||
* - binders_len (2 bytes)
|
||||
* - binder_len (1 byte)
|
||||
* - binder (hash_len bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
|
||||
p += 6;
|
||||
|
||||
identities_len = 6 + psk_identity_len;
|
||||
l_binders_len = 1 + hash_len;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_ticket_get_identity(
|
||||
ssl, &hash_alg, &identity, &identity_len ) == 0 )
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
uint32_t obfuscated_ticket_age =
|
||||
(uint32_t)( now - session->ticket_received );
|
||||
|
||||
obfuscated_ticket_age *= 1000;
|
||||
obfuscated_ticket_age += session->ticket_age_add;
|
||||
|
||||
ret = ssl_tls13_write_identity( ssl, p, end,
|
||||
identity, identity_len,
|
||||
obfuscated_ticket_age,
|
||||
&output_len );
|
||||
#else
|
||||
ret = ssl_tls13_write_identity( ssl, p, end, identity, identity_len,
|
||||
0, &output_len );
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p += output_len;
|
||||
l_binders_len += 1 + PSA_HASH_LENGTH( hash_alg );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
if( ssl_tls13_psk_get_identity(
|
||||
ssl, &hash_alg, &identity, &identity_len ) == 0 )
|
||||
{
|
||||
|
||||
ret = ssl_tls13_write_identity( ssl, p, end, identity, identity_len, 0,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p += output_len;
|
||||
l_binders_len += 1 + PSA_HASH_LENGTH( hash_alg );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
( "client hello, adding pre_shared_key extension, "
|
||||
"omitting PSK binder list" ) );
|
||||
|
||||
/* Extension header */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 8 );
|
||||
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_PRE_SHARED_KEY, p, 0 );
|
||||
MBEDTLS_PUT_UINT16_BE( 2 + identities_len + 2 + l_binders_len , p, 2 );
|
||||
/* Take into account the two bytes for the length of the binders. */
|
||||
l_binders_len += 2;
|
||||
/* Check if there is enough space for binders */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, l_binders_len );
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( identities_len, p, 4 );
|
||||
MBEDTLS_PUT_UINT16_BE( psk_identity_len, p, 6 );
|
||||
p += 8;
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, psk_identity_len );
|
||||
memcpy( p, psk_identity, psk_identity_len );
|
||||
p += psk_identity_len;
|
||||
/*
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_len (2 bytes)
|
||||
* - identities_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_PRE_SHARED_KEY, buf, 0 );
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 4 + l_binders_len , buf, 2 );
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 6 , buf, 4 );
|
||||
|
||||
/* add obfuscated ticket age */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
|
||||
MBEDTLS_PUT_UINT32_BE( obfuscated_ticket_age, p, 0 );
|
||||
p += 4;
|
||||
*out_len = ( p - buf ) + l_binders_len;
|
||||
*binders_len = l_binders_len;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 + l_binders_len );
|
||||
*out_len = ( p - buf ) + l_binders_len + 2;
|
||||
*binders_len = l_binders_len + 2;
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key identities", buf, p - buf );
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
|
||||
|
@ -880,67 +984,133 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
|
|||
}
|
||||
|
||||
int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, unsigned char *end )
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = buf;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
psa_algorithm_t psa_hash_alg;
|
||||
int hash_len = 0;
|
||||
const unsigned char *psk = NULL;
|
||||
size_t psk_len = 0;
|
||||
int psk_type;
|
||||
unsigned char transcript[MBEDTLS_MD_MAX_SIZE];
|
||||
size_t transcript_len;
|
||||
psa_algorithm_t hash_alg = PSA_ALG_NONE;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
size_t output_len;
|
||||
|
||||
if( ssl_tls13_get_psk_to_offer( ssl, &psk_type, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ssl->session_negotiate->ciphersuite );
|
||||
if( ciphersuite_info == NULL )
|
||||
return( 0 );
|
||||
|
||||
psa_hash_alg = mbedtls_psa_translate_md( ciphersuite_info->mac );
|
||||
hash_len = PSA_HASH_LENGTH( psa_hash_alg );
|
||||
if( ( hash_len == -1 ) || ( ( end - buf ) != 3 + hash_len ) )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding PSK binder list" ) );
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 + hash_len );
|
||||
/* 2 bytes length field for array of psk binders */
|
||||
MBEDTLS_PUT_UINT16_BE( hash_len + 1, p, 0 );
|
||||
/* Check if we have space to write binders_len.
|
||||
* - binders_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
|
||||
p += 2;
|
||||
|
||||
/* 1 bytes length field for next psk binder */
|
||||
*p++ = MBEDTLS_BYTE_0( hash_len );
|
||||
|
||||
/* Get current state of handshake transcript. */
|
||||
ret = mbedtls_ssl_get_handshake_transcript( ssl, ciphersuite_info->mac,
|
||||
transcript, sizeof( transcript ),
|
||||
&transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl,
|
||||
mbedtls_psa_translate_md( ciphersuite_info->mac ),
|
||||
psk, psk_len, psk_type,
|
||||
transcript, p );
|
||||
if( ret != 0 )
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_ticket_get_psk( ssl, &hash_alg, &psk, &psk_len ) == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_create_psk_binder", ret );
|
||||
return( ret );
|
||||
|
||||
ret = ssl_tls13_write_binder( ssl, p, end,
|
||||
MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION,
|
||||
hash_alg, psk, psk_len,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
if( ssl_tls13_psk_get_psk( ssl, &hash_alg, &psk, &psk_len ) == 0 )
|
||||
{
|
||||
|
||||
ret = ssl_tls13_write_binder( ssl, p, end,
|
||||
MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL,
|
||||
hash_alg, psk, psk_len,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding PSK binder list." ) );
|
||||
|
||||
/*
|
||||
* - binders_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 2, buf, 0 );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key binders", buf, p - buf );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
* uint32 obfuscated_ticket_age;
|
||||
* } PskIdentity;
|
||||
*
|
||||
* opaque PskBinderEntry<32..255>;
|
||||
*
|
||||
* struct {
|
||||
*
|
||||
* select (Handshake.msg_type) {
|
||||
* ...
|
||||
* case server_hello: uint16 selected_identity;
|
||||
* };
|
||||
*
|
||||
* } PreSharedKeyExtension;
|
||||
*
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int selected_identity;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
psa_algorithm_t hash_alg;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end, 2 );
|
||||
selected_identity = MBEDTLS_GET_UINT16_BE( buf, 0 );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected_identity = %d", selected_identity ) );
|
||||
|
||||
if( selected_identity >= ssl_tls13_get_configured_psk_count( ssl ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid PSK identity." ) );
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( selected_identity == 0 && ssl_tls13_has_configured_ticket( ssl ) )
|
||||
{
|
||||
ret = ssl_tls13_ticket_get_psk( ssl, &hash_alg, &psk, &psk_len );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
{
|
||||
ret = ssl_tls13_psk_get_psk( ssl, &hash_alg, &psk, &psk_len );
|
||||
}
|
||||
else
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_set_hs_psk( ssl, psk, psk_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_set_hs_psk", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
|
@ -1299,92 +1469,6 @@ static int ssl_tls13_check_server_hello_session_id_echo( mbedtls_ssl_context *ss
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
/*
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
* uint32 obfuscated_ticket_age;
|
||||
* } PskIdentity;
|
||||
*
|
||||
* opaque PskBinderEntry<32..255>;
|
||||
*
|
||||
* struct {
|
||||
*
|
||||
* select (Handshake.msg_type) {
|
||||
* ...
|
||||
* case server_hello: uint16 selected_identity;
|
||||
* };
|
||||
*
|
||||
* } PreSharedKeyExtension;
|
||||
*
|
||||
*/
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t selected_identity;
|
||||
|
||||
int psk_type;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
|
||||
/* Check which PSK we've offered.
|
||||
*
|
||||
* NOTE: Ultimately, we want to offer multiple PSKs, and in this
|
||||
* case, we need to iterate over them here.
|
||||
*/
|
||||
if( ssl_tls13_get_psk_to_offer( ssl, &psk_type, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
{
|
||||
/* If we haven't offered a PSK, the server must not send
|
||||
* a PSK identity extension. */
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 );
|
||||
selected_identity = MBEDTLS_GET_UINT16_BE( buf, 0 );
|
||||
|
||||
/* We have offered only one PSK, so the only valid choice
|
||||
* for the server is PSK index 0.
|
||||
*
|
||||
* This will change once we support multiple PSKs. */
|
||||
if( selected_identity > 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server's chosen PSK identity out of range" ) );
|
||||
|
||||
if( ( ret = mbedtls_ssl_send_alert_message( ssl,
|
||||
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
}
|
||||
|
||||
/* Set the chosen PSK
|
||||
*
|
||||
* TODO: We don't have to do this in case we offered 0-RTT and the
|
||||
* server accepted it, because in this case we've already
|
||||
* set the handshake PSK. */
|
||||
ret = mbedtls_ssl_set_hs_psk( ssl, psk, psk_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_set_hs_psk", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Parse ServerHello message and configure context
|
||||
*
|
||||
* struct {
|
||||
|
|
|
@ -186,9 +186,9 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
|||
if( now < session->start )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket expired: now=%" MBEDTLS_PRINTF_LONGLONG
|
||||
", start=%" MBEDTLS_PRINTF_LONGLONG,
|
||||
(long long)now, (long long)session->start ) );
|
||||
3, ( "Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG
|
||||
", start=%" MBEDTLS_PRINTF_LONGLONG " )",
|
||||
(long long)now, (long long)session->start ) );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
|||
if( age_in_s > 604800 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket expired: Ticket age exceed limitation ticket_age=%lu",
|
||||
3, ( "Ticket age exceeds limitation ticket_age=%lu",
|
||||
(long unsigned int)age_in_s ) );
|
||||
goto exit;
|
||||
}
|
||||
|
@ -231,8 +231,8 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
|||
age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket expired: Ticket age outside tolerance window "
|
||||
"( diff=%d )", (int)age_diff_in_ms ) );
|
||||
3, ( "Ticket age outside tolerance window ( diff=%d )",
|
||||
(int)age_diff_in_ms ) );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ int main( void )
|
|||
#define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
|
||||
#define DFL_TRUNC_HMAC -1
|
||||
#define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
|
||||
#define DFL_DUMMY_TICKET 0
|
||||
#define DFL_TICKET_ROTATE 0
|
||||
#define DFL_TICKET_TIMEOUT 86400
|
||||
#define DFL_TICKET_AEAD MBEDTLS_CIPHER_AES_256_GCM
|
||||
|
@ -638,6 +639,7 @@ struct options
|
|||
unsigned char mfl_code; /* code for maximum fragment length */
|
||||
int trunc_hmac; /* accept truncated hmac? */
|
||||
int tickets; /* enable / disable session tickets */
|
||||
int dummy_ticket; /* enable / disable dummy ticket generator */
|
||||
int ticket_rotate; /* session ticket rotate (code coverage) */
|
||||
int ticket_timeout; /* session ticket lifetime */
|
||||
int ticket_aead; /* session ticket protection */
|
||||
|
@ -1351,6 +1353,75 @@ int report_cid_usage( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_HAVE_TIME)
|
||||
/* Functions for session ticket tests */
|
||||
int dummy_ticket_write( void *p_ticket, const mbedtls_ssl_session *session,
|
||||
unsigned char *start, const unsigned char *end,
|
||||
size_t *tlen, uint32_t *ticket_lifetime )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *p = start;
|
||||
size_t clear_len;
|
||||
((void) p_ticket);
|
||||
|
||||
if( end - p < 4 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
|
||||
}
|
||||
*((uint32_t *)p) = 7 * 24 * 3600;
|
||||
*ticket_lifetime = 7 * 24 * 3600;
|
||||
p += 4;
|
||||
|
||||
/* Dump session state */
|
||||
if( ( ret = mbedtls_ssl_session_save( session, p, end - p,
|
||||
&clear_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*tlen = 4 + clear_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int dummy_ticket_parse( void *p_ticket, mbedtls_ssl_session *session,
|
||||
unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
((void) p_ticket);
|
||||
|
||||
if( ( ret = mbedtls_ssl_session_load( session, buf + 4, len - 4 ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
switch( opt.dummy_ticket % 7 )
|
||||
{
|
||||
case 1:
|
||||
return( MBEDTLS_ERR_SSL_INVALID_MAC );
|
||||
case 2:
|
||||
return( MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED );
|
||||
case 3:
|
||||
session->start = mbedtls_time( NULL ) + 10;
|
||||
break;
|
||||
case 4:
|
||||
session->start = mbedtls_time( NULL ) - 10 - 7 * 24 * 3600;
|
||||
break;
|
||||
case 5:
|
||||
session->start = mbedtls_time( NULL ) - 10;
|
||||
break;
|
||||
case 6:
|
||||
session->start = mbedtls_time( NULL );
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
session->ticket_age_add -= 1000;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_HAVE_TIME */
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
int ret = 0, len, written, frags, exchanges_left;
|
||||
|
@ -1607,6 +1678,7 @@ int main( int argc, char *argv[] )
|
|||
opt.mfl_code = DFL_MFL_CODE;
|
||||
opt.trunc_hmac = DFL_TRUNC_HMAC;
|
||||
opt.tickets = DFL_TICKETS;
|
||||
opt.dummy_ticket = DFL_DUMMY_TICKET;
|
||||
opt.ticket_rotate = DFL_TICKET_ROTATE;
|
||||
opt.ticket_timeout = DFL_TICKET_TIMEOUT;
|
||||
opt.ticket_aead = DFL_TICKET_AEAD;
|
||||
|
@ -2002,6 +2074,12 @@ int main( int argc, char *argv[] )
|
|||
if( opt.tickets < 0 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "dummy_ticket" ) == 0 )
|
||||
{
|
||||
opt.dummy_ticket = atoi( q );
|
||||
if( opt.dummy_ticket < 0 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "ticket_rotate" ) == 0 )
|
||||
{
|
||||
opt.ticket_rotate = atoi( q );
|
||||
|
@ -2919,19 +2997,34 @@ int main( int argc, char *argv[] )
|
|||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( opt.tickets != MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
|
||||
{
|
||||
if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
|
||||
rng_get, &rng,
|
||||
opt.ticket_aead,
|
||||
opt.ticket_timeout ) ) != 0 )
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
if( opt.dummy_ticket )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_ssl_ticket_setup returned %d\n\n", ret );
|
||||
goto exit;
|
||||
mbedtls_ssl_conf_session_tickets_cb( &conf,
|
||||
dummy_ticket_write,
|
||||
dummy_ticket_parse,
|
||||
NULL );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
{
|
||||
if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
|
||||
rng_get, &rng,
|
||||
opt.ticket_aead,
|
||||
opt.ticket_timeout ) ) != 0 )
|
||||
{
|
||||
mbedtls_printf(
|
||||
" failed\n ! mbedtls_ssl_ticket_setup returned %d\n\n",
|
||||
ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_session_tickets_cb( &conf,
|
||||
mbedtls_ssl_ticket_write,
|
||||
mbedtls_ssl_ticket_parse,
|
||||
&ticket_ctx );
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_session_tickets_cb( &conf,
|
||||
mbedtls_ssl_ticket_write,
|
||||
mbedtls_ssl_ticket_parse,
|
||||
&ticket_ctx );
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
mbedtls_ssl_conf_new_session_tickets( &conf, opt.tickets );
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,165 @@ run_test "TLS 1.3: PSK: No valid ciphersuite. O->m" \
|
|||
-s "Found PSK KEX MODE" \
|
||||
-s "No matched ciphersuite"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Multiple PSKs: valid ticket, reconnect with ticket" \
|
||||
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8" \
|
||||
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 2" \
|
||||
-s "sent selected_identity: 0" \
|
||||
-s "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "key exchange mode: ephemeral$" \
|
||||
-S "ticket is not authentic"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Multiple PSKs: invalid ticket, reconnect with PSK" \
|
||||
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8 dummy_ticket=1" \
|
||||
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 2" \
|
||||
-s "sent selected_identity: 1" \
|
||||
-s "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "key exchange mode: ephemeral$" \
|
||||
-s "ticket is not authentic"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed." \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=1" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-s "ticket is not authentic" \
|
||||
-S "ticket is expired" \
|
||||
-S "Invalid ticket start time" \
|
||||
-S "Ticket age exceeds limitation" \
|
||||
-S "Ticket age outside tolerance window"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=2" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "ticket is not authentic" \
|
||||
-s "ticket is expired" \
|
||||
-S "Invalid ticket start time" \
|
||||
-S "Ticket age exceeds limitation" \
|
||||
-S "Ticket age outside tolerance window"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=3" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "ticket is not authentic" \
|
||||
-S "ticket is expired" \
|
||||
-s "Invalid ticket start time" \
|
||||
-S "Ticket age exceeds limitation" \
|
||||
-S "Ticket age outside tolerance window"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=4" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "ticket is not authentic" \
|
||||
-S "ticket is expired" \
|
||||
-S "Invalid ticket start time" \
|
||||
-s "Ticket age exceeds limitation" \
|
||||
-S "Ticket age outside tolerance window"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too young." \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=5" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "ticket is not authentic" \
|
||||
-S "ticket is expired" \
|
||||
-S "Invalid ticket start time" \
|
||||
-S "Ticket age exceeds limitation" \
|
||||
-s "Ticket age outside tolerance window"
|
||||
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
|
||||
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too old." \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=6" \
|
||||
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
|
||||
0 \
|
||||
-c "Pre-configured PSK number = 1" \
|
||||
-S "sent selected_identity:" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-S "key exchange mode: psk_ephemeral" \
|
||||
-S "key exchange mode: psk$" \
|
||||
-S "ticket is not authentic" \
|
||||
-S "ticket is expired" \
|
||||
-S "Invalid ticket start time" \
|
||||
-S "Ticket age exceeds limitation" \
|
||||
-s "Ticket age outside tolerance window"
|
||||
|
||||
requires_gnutls_tls1_3
|
||||
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
|
||||
|
|
|
@ -12842,7 +12842,6 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \
|
|||
-s "key exchange mode: psk_ephemeral" \
|
||||
-s "found pre_shared_key extension"
|
||||
|
||||
|
||||
requires_openssl_tls1_3
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
|
|
|
@ -2184,8 +2184,9 @@ void perform_handshake( handshake_test_options *options )
|
|||
options->psk_str->len,
|
||||
(const unsigned char *) psk_identity,
|
||||
strlen( psk_identity ) ) == 0 );
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
mbedtls_ssl_conf_psk_cb( &server.conf, psk_dummy_callback, NULL );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
|
|
Loading…
Reference in a new issue