Merge remote-tracking branch 'public/pr/1918' into development

This commit is contained in:
Simon Butcher 2018-08-28 12:21:41 +01:00
commit 14dac0953e
8 changed files with 672 additions and 195 deletions

View File

@ -7,6 +7,15 @@ Features
is controlled by the maximum fragment length as set locally or negotiated is controlled by the maximum fragment length as set locally or negotiated
with the peer, as well as by a new per-connection MTU option, set using with the peer, as well as by a new per-connection MTU option, set using
mbedtls_ssl_set_mtu(). mbedtls_ssl_set_mtu().
* Add support for auto-adjustment of MTU to a safe value during the
handshake when flights do not get through (RFC 6347, section 4.1.1.1,
last paragraph).
* Add support for packing multiple records within a single datagram,
enabled by default.
API Changes
* Add function mbedtls_ssl_set_datagram_packing() to configure
the use of datagram packing (enabled by default).
Bugfix Bugfix
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if * Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if

View File

@ -1098,6 +1098,11 @@ struct mbedtls_ssl_context
int keep_current_message; /*!< drop or reuse current message int keep_current_message; /*!< drop or reuse current message
on next call to record layer? */ on next call to record layer? */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint8_t disable_datagram_packing; /*!< Disable packing multiple records
* within a single datagram. */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/* /*
* Record layer (outgoing data) * Record layer (outgoing data)
*/ */
@ -1112,6 +1117,8 @@ struct mbedtls_ssl_context
size_t out_msglen; /*!< record header: message length */ size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */ size_t out_left; /*!< amount of data not yet written */
unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */
#endif #endif
@ -1806,6 +1813,38 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
/**
* \brief Allow or disallow packing of multiple handshake records
* within a single datagram.
*
* \param ssl The SSL context to configure.
* \param allow_packing This determines whether datagram packing may
* be used or not. A value of \c 0 means that every
* record will be sent in a separate datagram; a
* value of \c 1 means that, if space permits,
* multiple handshake messages (including CCS) belonging to
* a single flight may be packed within a single datagram.
*
* \note This is enabled by default and should only be disabled
* for test purposes, or if datagram packing causes
* interoperability issues with peers that don't support it.
*
* \note Allowing datagram packing reduces the network load since
* there's less overhead if multiple messages share the same
* datagram. Also, it increases the handshake efficiency
* since messages belonging to a single datagram will not
* be reordered in transit, and so future message buffering
* or flight retransmission (if no buffering is used) as
* means to deal with reordering are needed less frequently.
*
* \note Application records are not affected by this option and
* are currently always sent in separate datagrams.
*
*/
void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
unsigned allow_packing );
/** /**
* \brief Set retransmit timeout values for the DTLS handshake. * \brief Set retransmit timeout values for the DTLS handshake.
* (DTLS only, no effect on TLS.) * (DTLS only, no effect on TLS.)

View File

@ -307,6 +307,7 @@ struct mbedtls_ssl_handshake_params
resending messages */ resending messages */
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
for resending messages */ for resending messages */
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
/* /*
@ -561,7 +562,7 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl );
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ); int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );

View File

@ -1294,7 +1294,7 @@ read_record_header:
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )

View File

@ -54,6 +54,8 @@
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#endif #endif
static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
/* Length of the "epoch" field in the record header */ /* Length of the "epoch" field in the record header */
static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
{ {
@ -96,7 +98,90 @@ static int ssl_check_timer( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform );
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform );
#define SSL_DONT_FORCE_FLUSH 0
#define SSL_FORCE_FLUSH 1
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
{
size_t mtu = ssl_get_current_mtu( ssl );
if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
return( mtu );
return( MBEDTLS_SSL_OUT_BUFFER_LEN );
}
static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
{
size_t const bytes_written = ssl->out_left;
size_t const mtu = ssl_get_maximum_datagram_size( ssl );
/* Double-check that the write-index hasn't gone
* past what we can transmit in a single datagram. */
if( bytes_written > mtu )
{
/* Should never happen... */
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
return( (int) ( mtu - bytes_written ) );
}
static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
{
int ret;
size_t remaining, expansion;
size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
if( max_len > mfl )
max_len = mfl;
/* By the standard (RFC 6066 Sect. 4), the MFL extension
* only limits the maximum record payload size, so in theory
* we would be allowed to pack multiple records of payload size
* MFL into a single datagram. However, this would mean that there's
* no way to explicitly communicate MTU restrictions to the peer.
*
* The following reduction of max_len makes sure that we never
* write datagrams larger than MFL + Record Expansion Overhead.
*/
if( max_len <= ssl->out_left )
return( 0 );
max_len -= ssl->out_left;
#endif
ret = ssl_get_remaining_space_in_datagram( ssl );
if( ret < 0 )
return( ret );
remaining = (size_t) ret;
ret = mbedtls_ssl_get_record_expansion( ssl );
if( ret < 0 )
return( ret );
expansion = (size_t) ret;
if( remaining <= expansion )
return( 0 );
remaining -= expansion;
if( remaining >= max_len )
remaining = max_len;
return( (int) remaining );
}
/* /*
* Double the retransmit timeout value, within the allowed range, * Double the retransmit timeout value, within the allowed range,
* returning -1 if the maximum value has already been reached. * returning -1 if the maximum value has already been reached.
@ -108,6 +193,15 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
return( -1 ); return( -1 );
/* Implement the final paragraph of RFC 6347 section 4.1.1.1
* in the following way: after the initial transmission and a first
* retransmission, back off to a temporary estimated MTU of 508 bytes.
* This value is guaranteed to be deliverable (if not guaranteed to be
* delivered) of any compliant IPv4 (and IPv6) network, and should work
* on most non-IP stacks too. */
if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
ssl->handshake->mtu = 508;
new_timeout = 2 * ssl->handshake->retransmit_timeout; new_timeout = 2 * ssl->handshake->retransmit_timeout;
/* Avoid arithmetic overflow and range overflow */ /* Avoid arithmetic overflow and range overflow */
@ -1345,14 +1439,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen ); ssl->out_msg, ssl->out_msglen );
if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
(unsigned) ssl->out_msglen,
MBEDTLS_SSL_OUT_CONTENT_LEN ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
/* /*
* Add MAC before if needed * Add MAC before if needed
*/ */
@ -2644,7 +2730,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
unsigned char *buf, i; unsigned char *buf;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
@ -2667,8 +2753,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) + buf = ssl->out_hdr - ssl->out_left;
ssl->out_msglen - ssl->out_left;
ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
@ -2687,16 +2772,17 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
ssl->out_left -= ret; ssl->out_left -= ret;
} }
for( i = 8; i > ssl_ep_len( ssl ); i-- ) #if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ++ssl->out_ctr[i - 1] != 0 ) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
break;
/* The loop goes to its end iff the counter is wrapping */
if( i == ssl_ep_len( ssl ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); ssl->out_hdr = ssl->out_buf;
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
} }
else
#endif
{
ssl->out_hdr = ssl->out_buf + 8;
}
ssl_update_out_pointers( ssl, ssl->transform_out );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
@ -2713,6 +2799,9 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
static int ssl_flight_append( mbedtls_ssl_context *ssl ) static int ssl_flight_append( mbedtls_ssl_context *ssl )
{ {
mbedtls_ssl_flight_item *msg; mbedtls_ssl_flight_item *msg;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
ssl->out_msg, ssl->out_msglen );
/* Allocate space for current message */ /* Allocate space for current message */
if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
@ -2746,6 +2835,7 @@ static int ssl_flight_append( mbedtls_ssl_context *ssl )
cur->next = msg; cur->next = msg;
} }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
return( 0 ); return( 0 );
} }
@ -2794,19 +2884,12 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
ssl->handshake->alt_transform_out = tmp_transform; ssl->handshake->alt_transform_out = tmp_transform;
/* Swap epoch + sequence_number */ /* Swap epoch + sequence_number */
memcpy( tmp_out_ctr, ssl->out_ctr, 8 ); memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 ); memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
/* Adjust to the newly activated transform */ /* Adjust to the newly activated transform */
if( ssl->transform_out != NULL && ssl_update_out_pointers( ssl, ssl->transform_out );
ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
{
ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen -
ssl->transform_out->fixed_ivlen;
}
else
ssl->out_msg = ssl->out_iv;
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_activate != NULL ) if( mbedtls_ssl_hw_record_activate != NULL )
@ -2845,6 +2928,7 @@ int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
*/ */
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
{ {
int ret;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
@ -2860,22 +2944,43 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
while( ssl->handshake->cur_msg != NULL ) while( ssl->handshake->cur_msg != NULL )
{ {
int ret; size_t max_frag_len;
const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
int const is_finished =
( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
/* Swap epochs before sending Finished: we can't do it after /* Swap epochs before sending Finished: we can't do it after
* sending ChangeCipherSpec, in case write returns WANT_READ. * sending ChangeCipherSpec, in case write returns WANT_READ.
* Must be done before copying, may change out_msg pointer */ * Must be done before copying, may change out_msg pointer */
if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
cur->p[0] == MBEDTLS_SSL_HS_FINISHED )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
ssl_swap_epochs( ssl ); ssl_swap_epochs( ssl );
} }
ret = ssl_get_remaining_payload_in_datagram( ssl );
if( ret < 0 )
return( ret );
max_frag_len = (size_t) ret;
/* CCS is copied as is, while HS messages may need fragmentation */ /* CCS is copied as is, while HS messages may need fragmentation */
if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
{ {
if( max_frag_len == 0 )
{
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
continue;
}
memcpy( ssl->out_msg, cur->p, cur->len ); memcpy( ssl->out_msg, cur->p, cur->len );
ssl->out_msglen = cur->len; ssl->out_msglen = cur->len;
ssl->out_msgtype = cur->type; ssl->out_msgtype = cur->type;
/* Update position inside current message */ /* Update position inside current message */
@ -2883,29 +2988,32 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
} }
else else
{ {
const int ret_payload = mbedtls_ssl_get_max_out_record_payload( ssl );
const size_t max_record_payload = (size_t) ret_payload;
/* DTLS handshake headers are 12 bytes */
const size_t max_hs_fragment_len = max_record_payload - 12;
const unsigned char * const p = ssl->handshake->cur_msg_p; const unsigned char * const p = ssl->handshake->cur_msg_p;
const size_t hs_len = cur->len - 12; const size_t hs_len = cur->len - 12;
const size_t frag_off = p - ( cur->p + 12 ); const size_t frag_off = p - ( cur->p + 12 );
const size_t rem_len = hs_len - frag_off; const size_t rem_len = hs_len - frag_off;
const size_t frag_len = rem_len > max_hs_fragment_len size_t cur_hs_frag_len, max_hs_frag_len;
? max_hs_fragment_len : rem_len;
if( ret_payload < 0 ) if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", if( is_finished )
ret_payload ); ssl_swap_epochs( ssl );
return( ret_payload );
}
if( frag_off == 0 && frag_len != hs_len ) if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
continue;
}
max_hs_frag_len = max_frag_len - 12;
cur_hs_frag_len = rem_len > max_hs_frag_len ?
max_hs_frag_len : rem_len;
if( frag_off == 0 && cur_hs_frag_len != hs_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
(unsigned) hs_len, (unsigned) cur_hs_frag_len,
(unsigned) max_hs_fragment_len ) ); (unsigned) max_hs_frag_len ) );
} }
/* Messages are stored with handshake headers as if not fragmented, /* Messages are stored with handshake headers as if not fragmented,
@ -2917,19 +3025,19 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff ); ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff );
ssl->out_msg[8] = ( ( frag_off ) & 0xff ); ssl->out_msg[8] = ( ( frag_off ) & 0xff );
ssl->out_msg[ 9] = ( ( frag_len >> 16 ) & 0xff ); ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
ssl->out_msg[10] = ( ( frag_len >> 8 ) & 0xff ); ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff );
ssl->out_msg[11] = ( ( frag_len ) & 0xff ); ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff );
MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
/* Copy the handshake message content and set records fields */ /* Copy the handshame message content and set records fields */
memcpy( ssl->out_msg + 12, p, frag_len ); memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
ssl->out_msglen = frag_len + 12; ssl->out_msglen = cur_hs_frag_len + 12;
ssl->out_msgtype = cur->type; ssl->out_msgtype = cur->type;
/* Update position inside current message */ /* Update position inside current message */
ssl->handshake->cur_msg_p += frag_len; ssl->handshake->cur_msg_p += cur_hs_frag_len;
} }
/* If done with the current message move to the next one if any */ /* If done with the current message move to the next one if any */
@ -2948,13 +3056,16 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
} }
/* Actually send the message out */ /* Actually send the message out */
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret ); return( ret );
} }
} }
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
/* Update state and set timer */ /* Update state and set timer */
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
@ -3082,6 +3193,23 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
} }
#endif #endif
/* Double-check that we did not exceed the bounds
* of the outgoing record buffer.
* This should never fail as the various message
* writing functions must obey the bounds of the
* outgoing record buffer, but better be safe.
*
* Note: We deliberately do not check for the MTU or MFL here.
*/
if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
"size %u, maximum %u",
(unsigned) ssl->out_msglen,
(unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/* /*
* Fill handshake headers * Fill handshake headers
*/ */
@ -3154,7 +3282,7 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
else else
#endif #endif
{ {
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret ); return( ret );
@ -3178,10 +3306,11 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
* - ssl->out_msglen: length of the record content (excl headers) * - ssl->out_msglen: length of the record content (excl headers)
* - ssl->out_msg: record content * - ssl->out_msg: record content
*/ */
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
{ {
int ret, done = 0; int ret, done = 0;
size_t len = ssl->out_msglen; size_t len = ssl->out_msglen;
uint8_t flush = force_flush;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
@ -3217,10 +3346,14 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
if( !done ) if( !done )
{ {
unsigned i;
size_t protected_record_size;
ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
ssl->conf->transport, ssl->out_hdr + 1 ); ssl->conf->transport, ssl->out_hdr + 1 );
memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
ssl->out_len[0] = (unsigned char)( len >> 8 ); ssl->out_len[0] = (unsigned char)( len >> 8 );
ssl->out_len[1] = (unsigned char)( len ); ssl->out_len[1] = (unsigned char)( len );
@ -3237,18 +3370,74 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
ssl->out_len[1] = (unsigned char)( len ); ssl->out_len[1] = (unsigned char)( len );
} }
ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen; protected_record_size = len + mbedtls_ssl_hdr_len( ssl );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
/* In case of DTLS, double-check that we don't exceed
* the remaining space in the datagram. */
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
ret = ssl_get_remaining_space_in_datagram( ssl );
if( ret < 0 )
return( ret );
if( protected_record_size > (size_t) ret )
{
/* Should never happen */
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
"version = [%d:%d], msglen = %d", "version = [%d:%d], msglen = %d",
ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], len ) );
( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) );
MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen ); ssl->out_hdr, protected_record_size );
ssl->out_left += protected_record_size;
ssl->out_hdr += protected_record_size;
ssl_update_out_pointers( ssl, ssl->transform_out );
for( i = 8; i > ssl_ep_len( ssl ); i-- )
if( ++ssl->cur_out_ctr[i - 1] != 0 )
break;
/* The loop goes to its end iff the counter is wrapping */
if( i == ssl_ep_len( ssl ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
}
} }
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) #if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
flush == SSL_DONT_FORCE_FLUSH )
{
size_t remaining;
ret = ssl_get_remaining_payload_in_datagram( ssl );
if( ret < 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
ret );
return( ret );
}
remaining = (size_t) ret;
if( remaining == 0 )
flush = SSL_FORCE_FLUSH;
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
}
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
if( ( flush == SSL_FORCE_FLUSH ) &&
( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
return( ret ); return( ret );
@ -4530,7 +4719,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
ssl->out_msg[0] = level; ssl->out_msg[0] = level;
ssl->out_msg[1] = message; ssl->out_msg[1] = message;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret ); return( ret );
@ -5179,16 +5368,7 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->in_ctr, 0, 8 ); memset( ssl->in_ctr, 0, 8 );
/* ssl_update_in_pointers( ssl, ssl->transform_negotiate );
* Set the in_msg pointer to the correct location based on IV length
*/
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
{
ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
ssl->transform_negotiate->fixed_ivlen;
}
else
ssl->in_msg = ssl->in_iv;
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_activate != NULL ) if( mbedtls_ssl_hw_record_activate != NULL )
@ -5639,16 +5819,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
/* ssl_update_out_pointers( ssl, ssl->transform_negotiate );
* Set the out_msg pointer to the correct location based on IV length
*/
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
{
ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
ssl->transform_negotiate->fixed_ivlen;
}
else
ssl->out_msg = ssl->out_iv;
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
@ -5700,14 +5871,14 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
/* Remember current epoch settings for resending */ /* Remember current epoch settings for resending */
ssl->handshake->alt_transform_out = ssl->transform_out; ssl->handshake->alt_transform_out = ssl->transform_out;
memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 ); memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
/* Set sequence_number to zero */ /* Set sequence_number to zero */
memset( ssl->out_ctr + 2, 0, 6 ); memset( ssl->cur_out_ctr + 2, 0, 6 );
/* Increment epoch */ /* Increment epoch */
for( i = 2; i > 0; i-- ) for( i = 2; i > 0; i-- )
if( ++ssl->out_ctr[i - 1] != 0 ) if( ++ssl->cur_out_ctr[i - 1] != 0 )
break; break;
/* The loop goes to its end iff the counter is wrapping */ /* The loop goes to its end iff the counter is wrapping */
@ -5719,7 +5890,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->out_ctr, 0, 8 ); memset( ssl->cur_out_ctr, 0, 8 );
ssl->transform_out = ssl->transform_negotiate; ssl->transform_out = ssl->transform_negotiate;
ssl->session_out = ssl->session_negotiate; ssl->session_out = ssl->session_negotiate;
@ -6007,6 +6178,78 @@ static int ssl_cookie_check_dummy( void *ctx,
} }
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
/* Once ssl->out_hdr as the address of the beginning of the
* next outgoing record is set, deduce the other pointers.
*
* Note: For TLS, we save the implicit record sequence number
* (entering MAC computation) in the 8 bytes before ssl->out_hdr,
* and the caller has to make sure there's space for this.
*/
static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
ssl->out_ctr = ssl->out_hdr + 3;
ssl->out_len = ssl->out_hdr + 11;
ssl->out_iv = ssl->out_hdr + 13;
}
else
#endif
{
ssl->out_ctr = ssl->out_hdr - 8;
ssl->out_len = ssl->out_hdr + 3;
ssl->out_iv = ssl->out_hdr + 5;
}
/* Adjust out_msg to make space for explicit IV, if used. */
if( transform != NULL &&
ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
{
ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
}
else
ssl->out_msg = ssl->out_iv;
}
/* Once ssl->in_hdr as the address of the beginning of the
* next incoming record is set, deduce the other pointers.
*
* Note: For TLS, we save the implicit record sequence number
* (entering MAC computation) in the 8 bytes before ssl->in_hdr,
* and the caller has to make sure there's space for this.
*/
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
ssl->in_ctr = ssl->in_hdr + 3;
ssl->in_len = ssl->in_hdr + 11;
ssl->in_iv = ssl->in_hdr + 13;
}
else
#endif
{
ssl->in_ctr = ssl->in_hdr - 8;
ssl->in_len = ssl->in_hdr + 3;
ssl->in_iv = ssl->in_hdr + 5;
}
/* Offset in_msg from in_iv to allow space for explicit IV, if used. */
if( transform != NULL &&
ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
{
ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen;
}
else
ssl->in_msg = ssl->in_iv;
}
/* /*
* Initialize an SSL context * Initialize an SSL context
*/ */
@ -6018,6 +6261,28 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
/* /*
* Setup an SSL context * Setup an SSL context
*/ */
static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
{
/* Set the incoming and outgoing record pointers. */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
ssl->out_hdr = ssl->out_buf;
ssl->in_hdr = ssl->in_buf;
}
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
{
ssl->out_hdr = ssl->out_buf + 8;
ssl->in_hdr = ssl->in_buf + 8;
}
/* Derive other internal pointers. */
ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ );
}
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf ) const mbedtls_ssl_config *conf )
{ {
@ -6044,36 +6309,7 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
} }
#if defined(MBEDTLS_SSL_PROTO_DTLS) ssl_reset_in_out_pointers( ssl );
if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
ssl->out_hdr = ssl->out_buf;
ssl->out_ctr = ssl->out_buf + 3;
ssl->out_len = ssl->out_buf + 11;
ssl->out_iv = ssl->out_buf + 13;
ssl->out_msg = ssl->out_buf + 13;
ssl->in_hdr = ssl->in_buf;
ssl->in_ctr = ssl->in_buf + 3;
ssl->in_len = ssl->in_buf + 11;
ssl->in_iv = ssl->in_buf + 13;
ssl->in_msg = ssl->in_buf + 13;
}
else
#endif
{
ssl->out_ctr = ssl->out_buf;
ssl->out_hdr = ssl->out_buf + 8;
ssl->out_len = ssl->out_buf + 11;
ssl->out_iv = ssl->out_buf + 13;
ssl->out_msg = ssl->out_buf + 13;
ssl->in_ctr = ssl->in_buf;
ssl->in_hdr = ssl->in_buf + 8;
ssl->in_len = ssl->in_buf + 11;
ssl->in_iv = ssl->in_buf + 13;
ssl->in_msg = ssl->in_buf + 13;
}
if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
return( ret ); return( ret );
@ -6092,6 +6328,11 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
{ {
int ret; int ret;
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
!defined(MBEDTLS_SSL_SRV_C)
((void) partial);
#endif
ssl->state = MBEDTLS_SSL_HELLO_REQUEST; ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
/* Cancel any possibly running timer */ /* Cancel any possibly running timer */
@ -6108,12 +6349,10 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
ssl->in_offt = NULL; ssl->in_offt = NULL;
ssl_reset_in_out_pointers( ssl );
ssl->in_msg = ssl->in_buf + 13;
ssl->in_msgtype = 0; ssl->in_msgtype = 0;
ssl->in_msglen = 0; ssl->in_msglen = 0;
if( partial == 0 )
ssl->in_left = 0;
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
ssl->next_record_offset = 0; ssl->next_record_offset = 0;
ssl->in_epoch = 0; ssl->in_epoch = 0;
@ -6127,7 +6366,6 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->keep_current_message = 0; ssl->keep_current_message = 0;
ssl->out_msg = ssl->out_buf + 13;
ssl->out_msgtype = 0; ssl->out_msgtype = 0;
ssl->out_msglen = 0; ssl->out_msglen = 0;
ssl->out_left = 0; ssl->out_left = 0;
@ -6136,6 +6374,8 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->split_done = 0; ssl->split_done = 0;
#endif #endif
memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
ssl->transform_in = NULL; ssl->transform_in = NULL;
ssl->transform_out = NULL; ssl->transform_out = NULL;
@ -6143,8 +6383,14 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->session_out = NULL; ssl->session_out = NULL;
memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN ); memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 ) if( partial == 0 )
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
{
ssl->in_left = 0;
memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN ); memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
}
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_reset != NULL ) if( mbedtls_ssl_hw_record_reset != NULL )
@ -6177,7 +6423,9 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
#endif #endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
if( partial == 0 ) if( partial == 0 )
#endif
{ {
mbedtls_free( ssl->cli_id ); mbedtls_free( ssl->cli_id );
ssl->cli_id = NULL; ssl->cli_id = NULL;
@ -6228,7 +6476,15 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max )
void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
unsigned allow_packing )
{
ssl->disable_datagram_packing = !allow_packing;
}
void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf,
uint32_t min, uint32_t max )
{ {
conf->hs_timeout_min = min; conf->hs_timeout_min = min;
conf->hs_timeout_max = max; conf->hs_timeout_max = max;
@ -7025,7 +7281,6 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_ZLIB_SUPPORT) #if defined(MBEDTLS_ZLIB_SUPPORT)
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
#endif #endif
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
@ -7095,6 +7350,20 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
{
if( ssl->handshake == NULL || ssl->handshake->mtu == 0 )
return( ssl->mtu );
if( ssl->mtu == 0 )
return( ssl->handshake->mtu );
return( ssl->mtu < ssl->handshake->mtu ?
ssl->mtu : ssl->handshake->mtu );
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
{ {
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
@ -7112,9 +7381,9 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->mtu != 0 ) if( ssl_get_current_mtu( ssl ) != 0 )
{ {
const size_t mtu = ssl->mtu; const size_t mtu = ssl_get_current_mtu( ssl );
const int ret = mbedtls_ssl_get_record_expansion( ssl ); const int ret = mbedtls_ssl_get_record_expansion( ssl );
const size_t overhead = (size_t) ret; const size_t overhead = (size_t) ret;
@ -7130,6 +7399,11 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
if( max_len > mtu - overhead ) if( max_len > mtu - overhead )
max_len = mtu - overhead; max_len = mtu - overhead;
} }
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
!defined(MBEDTLS_SSL_PROTO_DTLS)
((void) ssl);
#endif #endif
return( (int) max_len ); return( (int) max_len );
@ -7354,7 +7628,7 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len ); ssl->conf->renego_period + ep_len, 8 - ep_len );
out_ctr_cmp = memcmp( ssl->out_ctr + ep_len, out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len ); ssl->conf->renego_period + ep_len, 8 - ep_len );
if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
@ -7735,7 +8009,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
memcpy( ssl->out_msg, buf, len ); memcpy( ssl->out_msg, buf, len );
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret ); return( ret );

View File

@ -107,6 +107,7 @@ int main( void )
#define DFL_HS_TO_MIN 0 #define DFL_HS_TO_MIN 0
#define DFL_HS_TO_MAX 0 #define DFL_HS_TO_MAX 0
#define DFL_DTLS_MTU -1 #define DFL_DTLS_MTU -1
#define DFL_DGRAM_PACKING 1
#define DFL_FALLBACK -1 #define DFL_FALLBACK -1
#define DFL_EXTENDED_MS -1 #define DFL_EXTENDED_MS -1
#define DFL_ETM -1 #define DFL_ETM -1
@ -200,7 +201,10 @@ int main( void )
" dtls=%%d default: 0 (TLS)\n" \ " dtls=%%d default: 0 (TLS)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \ " hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \ " range of DTLS handshake timeouts in millisecs\n" \
" mtu=%%d default: (library default: unlimited)\n" " mtu=%%d default: (library default: unlimited)\n" \
" dgram_packing=%%d default: 1 (allowed)\n" \
" allow or forbid packing of multiple\n" \
" records within a single datgram.\n"
#else #else
#define USAGE_DTLS "" #define USAGE_DTLS ""
#endif #endif
@ -349,6 +353,7 @@ struct options
uint32_t hs_to_max; /* Max value of DTLS handshake timer */ uint32_t hs_to_max; /* Max value of DTLS handshake timer */
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */ int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
int fallback; /* is this a fallback connection? */ int fallback; /* is this a fallback connection? */
int dgram_packing; /* allow/forbid datagram packing */
int extended_ms; /* negotiate extended master secret? */ int extended_ms; /* negotiate extended master secret? */
int etm; /* negotiate encrypt then mac? */ int etm; /* negotiate encrypt then mac? */
} opt; } opt;
@ -624,6 +629,7 @@ int main( int argc, char *argv[] )
opt.fallback = DFL_FALLBACK; opt.fallback = DFL_FALLBACK;
opt.extended_ms = DFL_EXTENDED_MS; opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM; opt.etm = DFL_ETM;
opt.dgram_packing = DFL_DGRAM_PACKING;
for( i = 1; i < argc; i++ ) for( i = 1; i < argc; i++ )
{ {
@ -937,6 +943,15 @@ int main( int argc, char *argv[] )
if( opt.dtls_mtu < 0 ) if( opt.dtls_mtu < 0 )
goto usage; goto usage;
} }
else if( strcmp( p, "dgram_packing" ) == 0 )
{
opt.dgram_packing = atoi( q );
if( opt.dgram_packing != 0 &&
opt.dgram_packing != 1 )
{
goto usage;
}
}
else if( strcmp( p, "recsplit" ) == 0 ) else if( strcmp( p, "recsplit" ) == 0 )
{ {
opt.recsplit = atoi( q ); opt.recsplit = atoi( q );
@ -1337,7 +1352,10 @@ int main( int argc, char *argv[] )
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX ) if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min,
opt.hs_to_max ); opt.hs_to_max );
#endif
if( opt.dgram_packing != DFL_DGRAM_PACKING )
mbedtls_ssl_set_datagram_packing( &ssl, opt.dgram_packing );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 ) if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )

View File

@ -152,6 +152,7 @@ int main( void )
#define DFL_HS_TO_MAX 0 #define DFL_HS_TO_MAX 0
#define DFL_DTLS_MTU -1 #define DFL_DTLS_MTU -1
#define DFL_BADMAC_LIMIT -1 #define DFL_BADMAC_LIMIT -1
#define DFL_DGRAM_PACKING 1
#define DFL_EXTENDED_MS -1 #define DFL_EXTENDED_MS -1
#define DFL_ETM -1 #define DFL_ETM -1
@ -299,7 +300,10 @@ int main( void )
" dtls=%%d default: 0 (TLS)\n" \ " dtls=%%d default: 0 (TLS)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \ " hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \ " range of DTLS handshake timeouts in millisecs\n" \
" mtu=%%d default: (library default: unlimited)\n" " mtu=%%d default: (library default: unlimited)\n" \
" dgram_packing=%%d default: 1 (allowed)\n" \
" allow or forbid packing of multiple\n" \
" records within a single datgram.\n"
#else #else
#define USAGE_DTLS "" #define USAGE_DTLS ""
#endif #endif
@ -473,6 +477,7 @@ struct options
uint32_t hs_to_min; /* Initial value of DTLS handshake timer */ uint32_t hs_to_min; /* Initial value of DTLS handshake timer */
uint32_t hs_to_max; /* Max value of DTLS handshake timer */ uint32_t hs_to_max; /* Max value of DTLS handshake timer */
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */ int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
int dgram_packing; /* allow/forbid datagram packing */
int badmac_limit; /* Limit of records with bad MAC */ int badmac_limit; /* Limit of records with bad MAC */
} opt; } opt;
@ -1342,6 +1347,7 @@ int main( int argc, char *argv[] )
opt.hs_to_min = DFL_HS_TO_MIN; opt.hs_to_min = DFL_HS_TO_MIN;
opt.hs_to_max = DFL_HS_TO_MAX; opt.hs_to_max = DFL_HS_TO_MAX;
opt.dtls_mtu = DFL_DTLS_MTU; opt.dtls_mtu = DFL_DTLS_MTU;
opt.dgram_packing = DFL_DGRAM_PACKING;
opt.badmac_limit = DFL_BADMAC_LIMIT; opt.badmac_limit = DFL_BADMAC_LIMIT;
opt.extended_ms = DFL_EXTENDED_MS; opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM; opt.etm = DFL_ETM;
@ -1694,6 +1700,15 @@ int main( int argc, char *argv[] )
if( opt.dtls_mtu < 0 ) if( opt.dtls_mtu < 0 )
goto usage; goto usage;
} }
else if( strcmp( p, "dgram_packing" ) == 0 )
{
opt.dgram_packing = atoi( q );
if( opt.dgram_packing != 0 &&
opt.dgram_packing != 1 )
{
goto usage;
}
}
else if( strcmp( p, "sni" ) == 0 ) else if( strcmp( p, "sni" ) == 0 )
{ {
opt.sni = q; opt.sni = q;
@ -2165,6 +2180,9 @@ int main( int argc, char *argv[] )
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX ) if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max ); mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
if( opt.dgram_packing != DFL_DGRAM_PACKING )
mbedtls_ssl_set_datagram_packing( &ssl, opt.dgram_packing );
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)

View File

@ -931,6 +931,35 @@ run_test "SHA-256 allowed by default in client certificate" \
"$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha256.crt" \ "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha256.crt" \
0 0
# Tests for datagram packing
run_test "DTLS: multiple records in same datagram, client and server" \
"$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
0 \
-c "next record in same datagram" \
-s "next record in same datagram"
run_test "DTLS: multiple records in same datagram, client only" \
"$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
0 \
-s "next record in same datagram" \
-C "next record in same datagram"
run_test "DTLS: multiple records in same datagram, server only" \
"$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-S "next record in same datagram" \
-c "next record in same datagram"
run_test "DTLS: multiple records in same datagram, neither client nor server" \
"$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-S "next record in same datagram" \
-C "next record in same datagram"
# Tests for Truncated HMAC extension # Tests for Truncated HMAC extension
run_test "Truncated HMAC: client default, server default" \ run_test "Truncated HMAC: client default, server default" \
@ -4979,11 +5008,11 @@ run_test "DTLS fragmenting: none (for reference)" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \ "$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \ crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \ key_file=data_files/server7.key \
max_frag_len=2048" \ max_frag_len=4096" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
max_frag_len=2048" \ max_frag_len=4096" \
0 \ 0 \
-S "found fragmented DTLS handshake message" \ -S "found fragmented DTLS handshake message" \
-C "found fragmented DTLS handshake message" \ -C "found fragmented DTLS handshake message" \
@ -5007,6 +5036,10 @@ run_test "DTLS fragmenting: server only (max_frag_len)" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# With the MFL extension, the server has no way of forcing
# the client to not exceed a certain MTU; hence, the following
# test can't be replicated with an MTU proxy such as the one
# `client-initiated, server only (max_frag_len)` below.
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_ECDSA_C
@ -5019,7 +5052,7 @@ run_test "DTLS fragmenting: server only (more) (max_frag_len)" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
max_frag_len=2048" \ max_frag_len=4096" \
0 \ 0 \
-S "found fragmented DTLS handshake message" \ -S "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
@ -5043,6 +5076,32 @@ run_test "DTLS fragmenting: client-initiated, server only (max_frag_len)" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# While not required by the standard defining the MFL extension
# (according to which it only applies to records, not to datagrams),
# Mbed TLS will never send datagrams larger than MFL + { Max record expansion },
# as otherwise there wouldn't be any means to communicate MTU restrictions
# to the peer.
# The next test checks that no datagrams significantly larger than the
# negotiated MFL are sent.
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
run_test "DTLS fragmenting: client-initiated, server only (max_frag_len), proxy MTU" \
-p "$P_PXY mtu=560" \
"$P_SRV dtls=1 debug_level=2 auth_mode=none \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
max_frag_len=2048" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
max_frag_len=512" \
0 \
-S "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_ECDSA_C
@ -5061,6 +5120,32 @@ run_test "DTLS fragmenting: client-initiated, both (max_frag_len)" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# While not required by the standard defining the MFL extension
# (according to which it only applies to records, not to datagrams),
# Mbed TLS will never send datagrams larger than MFL + { Max record expansion },
# as otherwise there wouldn't be any means to communicate MTU restrictions
# to the peer.
# The next test checks that no datagrams significantly larger than the
# negotiated MFL are sent.
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
run_test "DTLS fragmenting: client-initiated, both (max_frag_len), proxy MTU" \
-p "$P_PXY mtu=560" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
max_frag_len=2048" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
max_frag_len=512" \
0 \
-s "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_ECDSA_C
@ -5068,11 +5153,11 @@ run_test "DTLS fragmenting: none (for reference) (MTU)" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \ "$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \ crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \ key_file=data_files/server7.key \
mtu=2048" \ mtu=4096" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
mtu=2048" \ mtu=4096" \
0 \ 0 \
-S "found fragmented DTLS handshake message" \ -S "found fragmented DTLS handshake message" \
-C "found fragmented DTLS handshake message" \ -C "found fragmented DTLS handshake message" \
@ -5085,7 +5170,7 @@ run_test "DTLS fragmenting: client (MTU)" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \ "$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \ crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \ key_file=data_files/server7.key \
mtu=2048" \ mtu=4096" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
@ -5130,6 +5215,25 @@ run_test "DTLS fragmenting: both (MTU)" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# Test for automatic MTU reduction on repeated resend
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C
run_test "DTLS fragmenting: proxy MTU: auto-reduction" \
-p "$P_PXY mtu=508" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key\
hs_timeout=100-400" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
hs_timeout=100-400" \
0 \
-s "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \
-C "error"
# the proxy shouldn't drop or mess up anything, so we shouldn't need to resend # the proxy shouldn't drop or mess up anything, so we shouldn't need to resend
# OTOH the client might resend if the server is to slow to reset after sending # OTOH the client might resend if the server is to slow to reset after sending
# a HelloVerifyRequest, so only check for no retransmission server-side # a HelloVerifyRequest, so only check for no retransmission server-side
@ -5179,6 +5283,8 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake, nbio" \
# Since we don't support reading fragmented ClientHello yet, # Since we don't support reading fragmented ClientHello yet,
# up the MTU to 1450 (larger than ClientHello with session ticket, # up the MTU to 1450 (larger than ClientHello with session ticket,
# but still smaller than client's Certificate to ensure fragmentation). # but still smaller than client's Certificate to ensure fragmentation).
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
# reco_delay avoids races where the client reconnects before the server has # reco_delay avoids races where the client reconnects before the server has
# resumed listening, which would result in a spurious resend. # resumed listening, which would result in a spurious resend.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
@ -5201,6 +5307,8 @@ run_test "DTLS fragmenting: proxy MTU, resumed handshake" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
@ -5228,6 +5336,8 @@ run_test "DTLS fragmenting: proxy MTU, ChachaPoly renego" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
@ -5256,6 +5366,8 @@ run_test "DTLS fragmenting: proxy MTU, AES-GCM renego" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
@ -5284,6 +5396,8 @@ run_test "DTLS fragmenting: proxy MTU, AES-CCM renego" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
@ -5313,6 +5427,8 @@ run_test "DTLS fragmenting: proxy MTU, AES-CBC EtM renego" \
-c "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \
-C "error" -C "error"
# A resend on the client-side might happen if the server is
# slow to reset, therefore omitting '-C "resend"' below.
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
@ -5347,11 +5463,11 @@ requires_config_enabled MBEDTLS_ECDSA_C
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS fragmenting: proxy MTU + 3d" \ run_test "DTLS fragmenting: proxy MTU + 3d" \
-p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \ -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \ "$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \ crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \ key_file=data_files/server7.key \
hs_timeout=250-10000 mtu=512" \ hs_timeout=250-10000 mtu=512" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
hs_timeout=250-10000 mtu=512" \ hs_timeout=250-10000 mtu=512" \
@ -5383,6 +5499,7 @@ run_test "DTLS fragmenting: proxy MTU + 3d, nbio" \
# #
# here and below we just want to test that the we fragment in a way that # here and below we just want to test that the we fragment in a way that
# pleases other implementations, so we don't need the peer to fragment # pleases other implementations, so we don't need the peer to fragment
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_ECDSA_C
@ -5398,6 +5515,7 @@ run_test "DTLS fragmenting: gnutls server, DTLS 1.2" \
-c "fragmenting handshake message" \ -c "fragmenting handshake message" \
-C "error" -C "error"
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_ECDSA_C
@ -5508,7 +5626,7 @@ client_needs_more_time 4
run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \ run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \ -p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \ "$G_NEXT_SRV -u" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \ hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
@ -5525,7 +5643,7 @@ client_needs_more_time 4
run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \ run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \ -p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \ "$G_NEXT_SRV -u" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \ hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@ -5604,7 +5722,7 @@ client_needs_more_time 4
run_test "DTLS fragmenting: 3d, openssl server, DTLS 1.0" \ run_test "DTLS fragmenting: 3d, openssl server, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \ -p "$P_PXY drop=8 delay=8 duplicate=8" \
"$O_LEGACY_SRV -dtls1 -verify 10" \ "$O_LEGACY_SRV -dtls1 -verify 10" \
"$P_CLI dtls=1 debug_level=2 \ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \ crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \ key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \ hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@ -5638,7 +5756,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
client_needs_more_time 4 client_needs_more_time 4
run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \ run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \ -p "$P_PXY drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 \ "$P_SRV dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server7_int-ca.crt \ crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \ key_file=data_files/server7.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \ hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@ -5667,8 +5785,8 @@ run_test "DTLS proxy: reference" \
not_with_valgrind # spurious resend due to timeout not_with_valgrind # spurious resend due to timeout
run_test "DTLS proxy: duplicate every packet" \ run_test "DTLS proxy: duplicate every packet" \
-p "$P_PXY duplicate=1" \ -p "$P_PXY duplicate=1" \
"$P_SRV dtls=1 debug_level=2" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 debug_level=2" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \ 0 \
-c "replayed record" \ -c "replayed record" \
-s "replayed record" \ -s "replayed record" \
@ -5680,8 +5798,8 @@ run_test "DTLS proxy: duplicate every packet" \
run_test "DTLS proxy: duplicate every packet, server anti-replay off" \ run_test "DTLS proxy: duplicate every packet, server anti-replay off" \
-p "$P_PXY duplicate=1" \ -p "$P_PXY duplicate=1" \
"$P_SRV dtls=1 debug_level=2 anti_replay=0" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=2 anti_replay=0" \
"$P_CLI dtls=1 debug_level=2" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \ 0 \
-c "replayed record" \ -c "replayed record" \
-S "replayed record" \ -S "replayed record" \
@ -5694,24 +5812,24 @@ run_test "DTLS proxy: duplicate every packet, server anti-replay off" \
run_test "DTLS proxy: multiple records in same datagram" \ run_test "DTLS proxy: multiple records in same datagram" \
-p "$P_PXY pack=50" \ -p "$P_PXY pack=50" \
"$P_SRV dtls=1 debug_level=2" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 debug_level=2" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \ 0 \
-c "next record in same datagram" \ -c "next record in same datagram" \
-s "next record in same datagram" -s "next record in same datagram"
run_test "DTLS proxy: multiple records in same datagram, duplicate every packet" \ run_test "DTLS proxy: multiple records in same datagram, duplicate every packet" \
-p "$P_PXY pack=50 duplicate=1" \ -p "$P_PXY pack=50 duplicate=1" \
"$P_SRV dtls=1 debug_level=2" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 debug_level=2" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \ 0 \
-c "next record in same datagram" \ -c "next record in same datagram" \
-s "next record in same datagram" -s "next record in same datagram"
run_test "DTLS proxy: inject invalid AD record, default badmac_limit" \ run_test "DTLS proxy: inject invalid AD record, default badmac_limit" \
-p "$P_PXY bad_ad=1" \ -p "$P_PXY bad_ad=1" \
"$P_SRV dtls=1 debug_level=1" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=1" \
"$P_CLI dtls=1 debug_level=1 read_timeout=100" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
0 \ 0 \
-c "discarding invalid record (mac)" \ -c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \ -s "discarding invalid record (mac)" \
@ -5722,8 +5840,8 @@ run_test "DTLS proxy: inject invalid AD record, default badmac_limit" \
run_test "DTLS proxy: inject invalid AD record, badmac_limit 1" \ run_test "DTLS proxy: inject invalid AD record, badmac_limit 1" \
-p "$P_PXY bad_ad=1" \ -p "$P_PXY bad_ad=1" \
"$P_SRV dtls=1 debug_level=1 badmac_limit=1" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=1" \
"$P_CLI dtls=1 debug_level=1 read_timeout=100" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
1 \ 1 \
-C "discarding invalid record (mac)" \ -C "discarding invalid record (mac)" \
-S "discarding invalid record (mac)" \ -S "discarding invalid record (mac)" \
@ -5734,8 +5852,8 @@ run_test "DTLS proxy: inject invalid AD record, badmac_limit 1" \
run_test "DTLS proxy: inject invalid AD record, badmac_limit 2" \ run_test "DTLS proxy: inject invalid AD record, badmac_limit 2" \
-p "$P_PXY bad_ad=1" \ -p "$P_PXY bad_ad=1" \
"$P_SRV dtls=1 debug_level=1 badmac_limit=2" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2" \
"$P_CLI dtls=1 debug_level=1 read_timeout=100" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
0 \ 0 \
-c "discarding invalid record (mac)" \ -c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \ -s "discarding invalid record (mac)" \
@ -5746,8 +5864,8 @@ run_test "DTLS proxy: inject invalid AD record, badmac_limit 2" \
run_test "DTLS proxy: inject invalid AD record, badmac_limit 2, exchanges 2"\ run_test "DTLS proxy: inject invalid AD record, badmac_limit 2, exchanges 2"\
-p "$P_PXY bad_ad=1" \ -p "$P_PXY bad_ad=1" \
"$P_SRV dtls=1 debug_level=1 badmac_limit=2 exchanges=2" \ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2 exchanges=2" \
"$P_CLI dtls=1 debug_level=1 read_timeout=100 exchanges=2" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100 exchanges=2" \
1 \ 1 \
-c "discarding invalid record (mac)" \ -c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \ -s "discarding invalid record (mac)" \
@ -5758,8 +5876,8 @@ run_test "DTLS proxy: inject invalid AD record, badmac_limit 2, exchanges 2"\
run_test "DTLS proxy: delay ChangeCipherSpec" \ run_test "DTLS proxy: delay ChangeCipherSpec" \
-p "$P_PXY delay_ccs=1" \ -p "$P_PXY delay_ccs=1" \
"$P_SRV dtls=1 debug_level=1" \ "$P_SRV dtls=1 debug_level=1 dgram_packing=0" \
"$P_CLI dtls=1 debug_level=1" \ "$P_CLI dtls=1 debug_level=1 dgram_packing=0" \
0 \ 0 \
-c "record from another epoch" \ -c "record from another epoch" \
-s "record from another epoch" \ -s "record from another epoch" \
@ -5771,9 +5889,9 @@ run_test "DTLS proxy: delay ChangeCipherSpec" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \ run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123" \ psk=abc123" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
@ -5782,8 +5900,8 @@ run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" RSA handshake" \ run_test "DTLS proxy: 3d, \"short\" RSA handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 \
force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
@ -5792,8 +5910,8 @@ run_test "DTLS proxy: 3d, \"short\" RSA handshake" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \ run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5801,8 +5919,8 @@ run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, client auth" \ run_test "DTLS proxy: 3d, FS, client auth" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=required" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5810,8 +5928,8 @@ run_test "DTLS proxy: 3d, FS, client auth" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, ticket" \ run_test "DTLS proxy: 3d, FS, ticket" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=none" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5819,8 +5937,8 @@ run_test "DTLS proxy: 3d, FS, ticket" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \ run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=required" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5828,9 +5946,9 @@ run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
client_needs_more_time 2 client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake, nbio" \ run_test "DTLS proxy: 3d, max handshake, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 nbio=2 tickets=1 \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 nbio=2 tickets=1 \
auth_mode=required" \ auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 nbio=2 tickets=1" \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 nbio=2 tickets=1" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5838,9 +5956,9 @@ run_test "DTLS proxy: 3d, max handshake, nbio" \
client_needs_more_time 4 client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption" \ run_test "DTLS proxy: 3d, min handshake, resumption" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3" \ psk=abc123 debug_level=3" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \ debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
@ -5852,9 +5970,9 @@ run_test "DTLS proxy: 3d, min handshake, resumption" \
client_needs_more_time 4 client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption, nbio" \ run_test "DTLS proxy: 3d, min handshake, resumption, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3 nbio=2" \ psk=abc123 debug_level=3 nbio=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \ debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \
0 \ 0 \
@ -5867,9 +5985,9 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego" \ run_test "DTLS proxy: 3d, min handshake, client-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \ psk=abc123 renegotiation=1 debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \ renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
@ -5882,9 +6000,9 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego, nbio" \ run_test "DTLS proxy: 3d, min handshake, client-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \ psk=abc123 renegotiation=1 debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \ renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
@ -5897,10 +6015,10 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego" \ run_test "DTLS proxy: 3d, min handshake, server-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \ psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2" \ debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 \ renegotiation=1 exchanges=4 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
@ -5913,10 +6031,10 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego, nbio" \ run_test "DTLS proxy: 3d, min handshake, server-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \ psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2 nbio=2" \ debug_level=2 nbio=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 nbio=2 \ renegotiation=1 exchanges=4 debug_level=2 nbio=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \ force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \ 0 \
@ -5930,7 +6048,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server" \ run_test "DTLS proxy: 3d, openssl server" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \ -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 2048" \ "$O_SRV -dtls1 -mtu 2048" \
"$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 tickets=0" \
0 \ 0 \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5939,7 +6057,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server, fragmentation" \ run_test "DTLS proxy: 3d, openssl server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \ -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \ "$O_SRV -dtls1 -mtu 768" \
"$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 tickets=0" \
0 \ 0 \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5948,7 +6066,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server, fragmentation, nbio" \ run_test "DTLS proxy: 3d, openssl server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \ -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \ "$O_SRV -dtls1 -mtu 768" \
"$P_CLI dtls=1 hs_timeout=250-60000 nbio=2 tickets=0" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 nbio=2 tickets=0" \
0 \ 0 \
-c "HTTP/1.0 200 OK" -c "HTTP/1.0 200 OK"
@ -5958,7 +6076,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server" \ run_test "DTLS proxy: 3d, gnutls server" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 2048 -a" \ "$G_SRV -u --mtu 2048 -a" \
"$P_CLI dtls=1 hs_timeout=250-60000" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "Extra-header:" -c "Extra-header:"
@ -5969,7 +6087,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server, fragmentation" \ run_test "DTLS proxy: 3d, gnutls server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \ "$G_SRV -u --mtu 512" \
"$P_CLI dtls=1 hs_timeout=250-60000" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "Extra-header:" -c "Extra-header:"
@ -5980,7 +6098,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \ run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \ "$G_SRV -u --mtu 512" \
"$P_CLI dtls=1 hs_timeout=250-60000 nbio=2" \ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 nbio=2" \
0 \ 0 \
-s "Extra-header:" \ -s "Extra-header:" \
-c "Extra-header:" -c "Extra-header:"