diff --git a/ChangeLog b/ChangeLog index 9817c594b..9776336cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,9 +5,8 @@ mbed TLS ChangeLog (Sorted per branch, date) Features * Add support for fragmentation of outgoing DTLS handshake messages. This is controlled by the maximum fragment length as set locally or negotiated - with the peer, as well as 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(). - * Add support for fragmentation of outoing DTLS handshake messages. * Add support for packing multiple records within a single datagram, enabled by default. diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index f72833e21..c86a0f928 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1395,23 +1395,28 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, * the maximum size datagram the DTLS layer will pass to the * \c f_send() callback set using \c mbedtls_ssl_set_bio(). * + * \note The limit on datagram size is converted to a limit on + * record payload by subtracting the current overhead of + * encapsulation and encryption/authentication if any. + * * \note This can be called at any point during the connection, for * example when a PMTU estimate becomes available from other * sources, such as lower (or higher) protocol layers. * - * \note This only controls the size of the packets we send. - * Client-side, you can request the server to use smaller - * records with \c mbedtls_ssl_conf_max_frag_len(). + * \note This setting only controls the size of the packets we send, + * and does not restrict the size of the datagrams we're + * willing to receive. Client-side, you can request the + * server to use smaller records with \c + * mbedtls_ssl_conf_max_frag_len(). * * \note If both a MTU and a maximum fragment length have been * configured (or negotiated with the peer), the resulting - * lower limit (after translating the MTU setting to a limit - * on the record content length) is used. + * lower limit on record payload (see first note) is used. * * \note This can only be used to decrease the maximum size - * of datagrams sent. It cannot be used to increase the - * maximum size of records over the limit set by - * #MBEDTLS_SSL_OUT_CONTENT_LEN. + * of datagrams (hence records, see first note) sent. It + * cannot be used to increase the maximum size of records over + * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. * * \note Values lower than the current record layer expansion will * result in an error when trying to send data. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e4ea5c2bc..95248686e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7323,6 +7323,11 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) { size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; +#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ + !defined(MBEDTLS_SSL_PROTO_DTLS) + (void) ssl; +#endif + #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index ab53cc46c..dab7eaf21 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -5144,6 +5144,8 @@ run_test "DTLS fragmenting: both (MTU)" \ -C "error" # 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 +# a HelloVerifyRequest, so only check for no retransmission server-side not_with_valgrind # spurious resend due to timeout requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C @@ -5160,7 +5162,26 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake" \ mtu=512" \ 0 \ -S "resend" \ - -C "resend" \ + -s "found fragmented DTLS handshake message" \ + -c "found fragmented DTLS handshake message" \ + -C "error" + +not_with_valgrind # spurious resend due to timeout +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, simple handshake, nbio" \ + -p "$P_PXY mtu=512" \ + "$P_SRV dtls=1 debug_level=2 auth_mode=required \ + crt_file=data_files/server7_int-ca.crt \ + key_file=data_files/server7.key \ + mtu=512 nbio=2" \ + "$P_CLI dtls=1 debug_level=2 \ + crt_file=data_files/server8_int-ca2.crt \ + key_file=data_files/server8.key \ + mtu=512 nbio=2" \ + 0 \ + -S "resend" \ -s "found fragmented DTLS handshake message" \ -c "found fragmented DTLS handshake message" \ -C "error" @@ -5171,9 +5192,10 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake" \ # Since we don't support reading fragmented ClientHello yet, # up the MTU to 1450 (larger than ClientHello with session ticket, # 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 +# resumed listening, which would result in a spurious resend. not_with_valgrind # spurious resend due to timeout requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C @@ -5187,7 +5209,7 @@ run_test "DTLS fragmenting: proxy MTU, resumed handshake" \ "$P_CLI dtls=1 debug_level=2 \ crt_file=data_files/server8_int-ca2.crt \ key_file=data_files/server8.key \ - mtu=1450 reconnect=1" \ + mtu=1450 reconnect=1 reco_delay=1" \ 0 \ -S "resend" \ -s "found fragmented DTLS handshake message" \ @@ -5363,6 +5385,25 @@ run_test "DTLS fragmenting: proxy MTU + 3d" \ -c "found fragmented DTLS handshake message" \ -C "error" +requires_config_enabled MBEDTLS_SSL_PROTO_DTLS +requires_config_enabled MBEDTLS_RSA_C +requires_config_enabled MBEDTLS_ECDSA_C +client_needs_more_time 2 +run_test "DTLS fragmenting: proxy MTU + 3d, nbio" \ + -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \ + "$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=250-10000 mtu=512 nbio=2" \ + "$P_CLI dtls=1 debug_level=2 \ + crt_file=data_files/server8_int-ca2.crt \ + key_file=data_files/server8.key \ + hs_timeout=250-10000 mtu=512 nbio=2" \ + 0 \ + -s "found fragmented DTLS handshake message" \ + -c "found fragmented DTLS handshake message" \ + -C "error" + # interop tests for DTLS fragmentating with reliable connection # # here and below we just want to test that the we fragment in a way that @@ -5372,6 +5413,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_gnutls run_test "DTLS fragmenting: gnutls server, DTLS 1.2" \ "$G_SRV -u" \ "$P_CLI dtls=1 debug_level=2 \ @@ -5387,6 +5429,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1 +requires_gnutls run_test "DTLS fragmenting: gnutls server, DTLS 1.0" \ "$G_SRV -u" \ "$P_CLI dtls=1 debug_level=2 \ @@ -5403,6 +5446,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_gnutls run_test "DTLS fragmenting: gnutls client, DTLS 1.2" \ "$P_SRV dtls=1 debug_level=2 server_addr=::1 \ crt_file=data_files/server7_int-ca.crt \ @@ -5418,6 +5462,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS requires_config_enabled MBEDTLS_RSA_C requires_config_enabled MBEDTLS_ECDSA_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1 +requires_gnutls run_test "DTLS fragmenting: gnutls client, DTLS 1.0" \ "$P_SRV dtls=1 debug_level=2 server_addr=::1 \ crt_file=data_files/server7_int-ca.crt \ @@ -5527,6 +5572,7 @@ run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \ ## ## # gnutls-cli always tries IPv6 first, and doesn't fall back to IPv4 with DTLS ## requires_ipv6 +## requires_gnutls ## requires_config_enabled MBEDTLS_SSL_PROTO_DTLS ## requires_config_enabled MBEDTLS_RSA_C ## requires_config_enabled MBEDTLS_ECDSA_C @@ -5544,6 +5590,7 @@ run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \ ## ## # gnutls-cli always tries IPv6 first, and doesn't fall back to IPv4 with DTLS ## requires_ipv6 +## requires_gnutls ## requires_config_enabled MBEDTLS_SSL_PROTO_DTLS ## requires_config_enabled MBEDTLS_RSA_C ## requires_config_enabled MBEDTLS_ECDSA_C