From 82202f0a9ce7ecf0a37c224e6cb307d8e9d15b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 23 Jul 2014 00:28:58 +0200 Subject: [PATCH] Make DTLS_HELLO_VERIFY a compile option --- include/polarssl/check_config.h | 5 +++++ include/polarssl/config.h | 17 +++++++++++++++++ include/polarssl/ssl.h | 6 +++--- library/ssl_srv.c | 33 ++++++++++++++++++++++----------- library/ssl_tls.c | 4 ++-- programs/ssl/ssl_server2.c | 6 +++--- 6 files changed, 52 insertions(+), 19 deletions(-) diff --git a/include/polarssl/check_config.h b/include/polarssl/check_config.h index 9a64c1062..9fa19c834 100644 --- a/include/polarssl/check_config.h +++ b/include/polarssl/check_config.h @@ -263,6 +263,11 @@ #error "Illegal protocol selection" #endif +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) && \ + ( !defined(POLARSSL_SSL_SRV_C) || !defined(POLARSSL_SSL_PROTO_DTLS) ) +#error "POLARSSL_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" +#endif + #if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \ ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) || \ !defined(POLARSSL_CIPHER_MODE_CBC) ) diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 731b90c39..4988f39f6 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -923,6 +923,23 @@ */ #define POLARSSL_SSL_ALPN +/** + * \def POLARSSL_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * Requires: POLARSSL_SSL_SRV_C + * POLARSSL_POLARSSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +#define POLARSSL_SSL_DTLS_HELLO_VERIFY + /** * \def POLARSSL_SSL_SESSION_TICKETS * diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 05bb3de31..0bb450510 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -878,7 +878,7 @@ struct _ssl_context /* * Client id (IP/port) for DTLS hello verify */ -#if defined(POLARSSL_SSL_PROTO_DTLS) && defined(POLARSSL_SSL_SRV_C) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) unsigned char *cli_id; /*!< transport-level ID of the client */ size_t cli_id_len; /*!< length of cli_id */ md_context_t hvr_hmac_ctx; /*!< HMAC data for HelloVerifyRequest */ @@ -1067,7 +1067,7 @@ void ssl_set_bio( ssl_context *ssl, int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, int (*f_send)(void *, const unsigned char *, size_t), void *p_send ); -#if defined(POLARSSL_SSL_PROTO_DTLS) && defined(POLARSSL_SSL_SRV_C) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) /** * \brief Set client's transport-level identification info. * (Only usable on server.) @@ -1095,7 +1095,7 @@ int ssl_set_client_transport_id( ssl_context *ssl, /* Temporary */ int ssl_setup_hvr_key( ssl_context *ssl ); -#endif /* POLARSSL_SSL_PROTO_DTLS && POLARSSL_SSL_SRV_C */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ /** * \brief Set the session cache callbacks (server-side only) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 2b1a654ba..2b06f7e8a 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -351,7 +351,7 @@ static int ssl_parse_ticket( ssl_context *ssl, } #endif /* POLARSSL_SSL_SESSION_TICKETS */ -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) int ssl_set_client_transport_id( ssl_context *ssl, const unsigned char *info, size_t ilen ) @@ -369,7 +369,7 @@ int ssl_set_client_transport_id( ssl_context *ssl, return( 0 ); } -#endif /* POLARSSL_SSL_PROTO_DTLS */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) /* @@ -1136,7 +1136,7 @@ have_ciphersuite_v2: } #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) /* * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is @@ -1186,7 +1186,7 @@ int ssl_setup_hvr_key( ssl_context *ssl ) /* * Generate cookie for DTLS ClientHello verification */ -static int ssl_generate_verify_cookie( ssl_context *ssl ) +static int ssl_cookie_generate( ssl_context *ssl ) { int ret; unsigned char *cookie = ssl->handshake->verify_cookie; @@ -1219,7 +1219,7 @@ static int ssl_generate_verify_cookie( ssl_context *ssl ) return( 0 ); } -#endif /* POLARSSL_SSL_PROTO_DTLS */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ static int ssl_parse_client_hello( ssl_context *ssl ) { @@ -1515,14 +1515,15 @@ static int ssl_parse_client_hello( ssl_context *ssl ) SSL_DEBUG_BUF( 3, "client hello, cookie", buf + cookie_offset + 1, cookie_len ); +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) /* * Generate reference cookie content: * - used for verification below, * - stored to be sent if verification fails */ - if( ( ret = ssl_generate_verify_cookie( ssl ) ) != 0 ) + if( ( ret = ssl_cookie_generate( ssl ) ) != 0 ) { - SSL_DEBUG_RET( 1, "ssl_generate_verify_cookie", ret ); + SSL_DEBUG_RET( 1, "ssl_cookie_generate", ret ); return( ret ); } @@ -1540,7 +1541,16 @@ static int ssl_parse_client_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "client hello, cookie verification %s", ssl->handshake->verify_cookie == NULL ? "passed" : "failed" ) ); +#else + /* We know we didn't send a cookie, so it should be empty */ + if( cookie_len != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + SSL_DEBUG_MSG( 2, ( "cookie verification disabled" ) ); +#endif } #endif /* POLARSSL_SSL_PROTO_DTLS */ @@ -1603,6 +1613,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) ssl->session_negotiate->compression = SSL_COMPRESS_NULL; #endif + /* * Check the extension length */ @@ -2037,7 +2048,7 @@ static void ssl_write_alpn_ext( ssl_context *ssl, } #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) static int ssl_write_hello_verify_request( ssl_context *ssl ) { int ret; @@ -2081,7 +2092,7 @@ static int ssl_write_hello_verify_request( ssl_context *ssl ) return( 0 ); } -#endif /* POLARSSL_SSL_PROTO_DTLS */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ static int ssl_write_server_hello( ssl_context *ssl ) { @@ -2094,7 +2105,7 @@ static int ssl_write_server_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) if( ssl->transport == SSL_TRANSPORT_DATAGRAM && ssl->handshake->verify_cookie != NULL ) { @@ -2109,7 +2120,7 @@ static int ssl_write_server_hello( ssl_context *ssl ) return( POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED ); } -#endif /* POLARSSL_SSL_PROTO_DTLS */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ if( ssl->f_rng == NULL ) { diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d0f1ccc9f..4a111c63f 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3749,7 +3749,7 @@ int ssl_session_reset( ssl_context *ssl ) ssl->alpn_chosen = NULL; #endif -#if defined(POLARSSL_SSL_PROTO_DTLS) && defined(POLARSSL_SSL_SRV_C) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) polarssl_free( ssl->cli_id ); ssl->cli_id = NULL; ssl->cli_id_len = 0; @@ -5039,7 +5039,7 @@ void ssl_free( ssl_context *ssl ) } #endif -#if defined(POLARSSL_SSL_PROTO_DTLS) && defined(POLARSSL_SSL_SRV_C) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) polarssl_free( ssl->cli_id ); md_free( &ssl->hvr_hmac_ctx ); #endif diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 07c1e0779..df88502db 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1344,7 +1344,7 @@ int main( int argc, char *argv[] ) ssl_set_session_ticket_lifetime( &ssl, opt.ticket_timeout ); #endif -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) if( opt.transport == SSL_TRANSPORT_DATAGRAM && ( ret = ssl_setup_hvr_key( &ssl ) ) != 0 ) { @@ -1538,7 +1538,7 @@ reset: else ssl_set_bio( &ssl, net_recv, &client_fd, net_send, &client_fd ); -#if defined(POLARSSL_SSL_PROTO_DTLS) +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) if( opt.transport == SSL_TRANSPORT_DATAGRAM ) { if( ( ret = ssl_set_client_transport_id( &ssl, client_ip, @@ -1549,7 +1549,7 @@ reset: goto exit; } } -#endif /* POLARSSL_SSL_PROTO_DTLS */ +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ printf( " ok\n" );