From 232edd46bed6629172c3c96e4f4cff3ae8072740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 23 Jul 2014 16:56:27 +0200 Subject: [PATCH] Move cookie callbacks implementation to own module --- include/polarssl/ssl.h | 41 --------- include/polarssl/ssl_cookie.h | 85 ++++++++++++++++++ library/CMakeLists.txt | 1 + library/Makefile | 1 + library/ssl_cookie.c | 157 ++++++++++++++++++++++++++++++++++ library/ssl_srv.c | 111 +----------------------- programs/ssl/ssl_server2.c | 4 + 7 files changed, 249 insertions(+), 151 deletions(-) create mode 100644 include/polarssl/ssl_cookie.h create mode 100644 library/ssl_cookie.c diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index e52609836..7493fce5a 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -1083,8 +1083,6 @@ void ssl_set_bio( ssl_context *ssl, * network stack. Used for HelloVerifyRequest with DTLS. * This is *not* used to route the actual packets. * - * \warning (TODO-DTLS) May change and even be removed before 2.0.0! - * * \param ssl SSL context * \param info Transport-level info identifying the client (eg IP + port) * \param ilen Length of info in bytes @@ -1147,45 +1145,6 @@ void ssl_set_dtls_cookies( ssl_context *ssl, ssl_cookie_write_t *f_cookie_write, ssl_cookie_check_t *f_cookie_check, void *p_cookie ); - -/* Note: the next things up to endif are to be moved in a separate module */ - -/** - * \brief Default cookie generation function. - * (See description of ssl_cookie_write_t.) - */ -ssl_cookie_write_t ssl_cookie_write; - -/** - * \brief Default cookie verification function. - * (See description of ssl_cookie_check_t.) - */ -ssl_cookie_check_t ssl_cookie_check; - -/** - * \brief Context for the default cookie functions. - */ -typedef struct -{ - md_context_t hmac_ctx; -} ssl_cookie_ctx; - -/** - * \brief Initialize cookie context - */ -void ssl_cookie_init( ssl_cookie_ctx *ctx ); - -/** - * \brief Setup cookie context (generate keys) - */ -int ssl_cookie_setup( ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Free cookie context - */ -void ssl_cookie_free( ssl_cookie_ctx *ctx ); #endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ /** diff --git a/include/polarssl/ssl_cookie.h b/include/polarssl/ssl_cookie.h new file mode 100644 index 000000000..a28f33829 --- /dev/null +++ b/include/polarssl/ssl_cookie.h @@ -0,0 +1,85 @@ +/** + * \file ssl_cookie.h + * + * \brief DTLS cookie callbacks implementation + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SSL_COOKIE_H +#define POLARSSL_SSL_COOKIE_H + +#include "ssl.h" + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* \} name SECTION: Module settings */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Context for the default cookie functions. + */ +typedef struct +{ + md_context_t hmac_ctx; +} ssl_cookie_ctx; + +/** + * \brief Initialize cookie context + */ +void ssl_cookie_init( ssl_cookie_ctx *ctx ); + +/** + * \brief Setup cookie context (generate keys) + */ +int ssl_cookie_setup( ssl_cookie_ctx *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Free cookie context + */ +void ssl_cookie_free( ssl_cookie_ctx *ctx ); + +/** + * \brief Generate cookie, see \c ssl_cookie_write_t + */ +ssl_cookie_write_t ssl_cookie_write; + +/** + * \brief Verify cookie, see \c ssl_cookie_write_t + */ +ssl_cookie_check_t ssl_cookie_check; + +#ifdef __cplusplus +} +#endif + +#endif /* ssl_cookie.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 33d96b47f..d01a8a790 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -55,6 +55,7 @@ set(src sha256.c sha512.c ssl_cache.c + ssl_cookie.c ssl_ciphersuites.c ssl_cli.c ssl_srv.c diff --git a/library/Makefile b/library/Makefile index d637417c5..44bc00c0b 100644 --- a/library/Makefile +++ b/library/Makefile @@ -55,6 +55,7 @@ OBJS= aes.o aesni.o arc4.o \ pkwrite.o platform.o ripemd160.o \ rsa.o sha1.o sha256.o \ sha512.o ssl_cache.o ssl_cli.o \ + ssl_cookie.o \ ssl_srv.o ssl_ciphersuites.o \ ssl_tls.o threading.o timing.o \ version.o version_features.o \ diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c new file mode 100644 index 000000000..5b6a79a36 --- /dev/null +++ b/library/ssl_cookie.c @@ -0,0 +1,157 @@ +/* + * DTLS cookie callbacks implementation + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) + +#include "polarssl/ssl_cookie.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is + * available. Try SHA-256 first, 512 wastes resources since we need to stay + * with max 32 bytes of cookie for DTLS 1.0 + */ +#if defined(POLARSSL_SHA256_C) +#define HVR_MD POLARSSL_MD_SHA256 +#define HVR_MD_LEN 32 +#define HVR_MD_USE 32 +#elif defined(POLARSSL_SHA512_C) +#define HVR_MD POLARSSL_MD_SHA384 +#define HVR_MD_LEN 48 +#define HVR_MD_USE 32 +#elif defined(POLARSSL_SHA1_C) +#define HVR_MD POLARSSL_MD_SHA1 +#define HVR_MD_LEN 20 +#define HVR_MD_USE 20 +#else +#error "DTLS hello verify needs SHA-1 or SHA-2" +#endif + +void ssl_cookie_init( ssl_cookie_ctx *ctx ) +{ + md_init( &ctx->hmac_ctx ); +} + +void ssl_cookie_free( ssl_cookie_ctx *ctx ) +{ + md_free( &ctx->hmac_ctx ); +} + +int ssl_cookie_setup( ssl_cookie_ctx *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char key[HVR_MD_LEN]; + + if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) + return( ret ); + + ret = md_init_ctx( &ctx->hmac_ctx, md_info_from_type( HVR_MD ) ); + if( ret != 0 ) + return( ret ); + + ret = md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); + if( ret != 0 ) + return( ret ); + + polarssl_zeroize( key, sizeof( key ) ); + + return( 0 ); +} + +/* + * Generate cookie for DTLS ClientHello verification + */ +int ssl_cookie_write( void *ctx, + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + int ret; + unsigned char hmac_out[HVR_MD_LEN]; + md_context_t *hmac_ctx = (md_context_t *) ctx; + + if( (size_t)( end - *p ) < HVR_MD_USE ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + if( ( ret = md_hmac_reset( hmac_ctx ) ) != 0 || + ( ret = md_hmac_update( hmac_ctx, cli_id, cli_id_len ) ) != 0 || + ( ret = md_hmac_finish( hmac_ctx, hmac_out ) ) != 0 ) + { + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( *p, hmac_out, HVR_MD_USE ); + *p += HVR_MD_USE; + + return( 0 ); +} + +/* + * Check a cookie + */ +int ssl_cookie_check( void *ctx, + const unsigned char *cookie, size_t cookie_len, + const unsigned char *cli_id, size_t cli_id_len ) +{ + unsigned char ref_cookie[HVR_MD_USE]; + unsigned char *p = ref_cookie; + md_context_t *hmac_ctx = (md_context_t *) ctx; + + if( cookie_len != HVR_MD_USE ) + return( -1 ); + + if( ssl_cookie_write( hmac_ctx, + &p, p + sizeof( ref_cookie ), + cli_id, cli_id_len ) != 0 ) + return( -1 ); + + if( safer_memcmp( cookie, ref_cookie, sizeof( ref_cookie ) ) != 0 ) + return( -1 ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_COOKIE_C */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index e22132bff..13af7a150 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1146,115 +1146,6 @@ have_ciphersuite_v2: } #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ -#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) - -/* - * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is - * available. Try SHA-256 first, 512 wastes resources since we need to stay - * with max 32 bytes of cookie for DTLS 1.0 - */ -#if defined(POLARSSL_SHA256_C) -#define HVR_MD POLARSSL_MD_SHA256 -#define HVR_MD_LEN 32 -#define HVR_MD_USE 32 -#elif defined(POLARSSL_SHA512_C) -#define HVR_MD POLARSSL_MD_SHA384 -#define HVR_MD_LEN 48 -#define HVR_MD_USE 32 -#elif defined(POLARSSL_SHA1_C) -#define HVR_MD POLARSSL_MD_SHA1 -#define HVR_MD_LEN 20 -#define HVR_MD_USE 20 -#else -#error "DTLS hello verify needs SHA-1 or SHA-2" -#endif - -void ssl_cookie_init( ssl_cookie_ctx *ctx ) -{ - md_init( &ctx->hmac_ctx ); -} - -void ssl_cookie_free( ssl_cookie_ctx *ctx ) -{ - md_free( &ctx->hmac_ctx ); -} - -int ssl_cookie_setup( ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char key[HVR_MD_LEN]; - - if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) - return( ret ); - - ret = md_init_ctx( &ctx->hmac_ctx, md_info_from_type( HVR_MD ) ); - if( ret != 0 ) - return( ret ); - - ret = md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); - if( ret != 0 ) - return( ret ); - - polarssl_zeroize( key, sizeof( key ) ); - - return( 0 ); -} - -/* - * Generate cookie for DTLS ClientHello verification - */ -int ssl_cookie_write( void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - int ret; - unsigned char hmac_out[HVR_MD_LEN]; - md_context_t *hmac_ctx = (md_context_t *) ctx; - - if( (size_t)( end - *p ) < HVR_MD_USE ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - - if( ( ret = md_hmac_reset( hmac_ctx ) ) != 0 || - ( ret = md_hmac_update( hmac_ctx, cli_id, cli_id_len ) ) != 0 || - ( ret = md_hmac_finish( hmac_ctx, hmac_out ) ) != 0 ) - { - return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( *p, hmac_out, HVR_MD_USE ); - *p += HVR_MD_USE; - - return( 0 ); -} - -/* - * Check a cookie - */ -int ssl_cookie_check( void *ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len ) -{ - unsigned char ref_cookie[HVR_MD_USE]; - unsigned char *p = ref_cookie; - md_context_t *hmac_ctx = (md_context_t *) ctx; - - if( cookie_len != HVR_MD_USE ) - return( -1 ); - - if( ssl_cookie_write( hmac_ctx, - &p, p + sizeof( ref_cookie ), - cli_id, cli_id_len ) != 0 ) - return( -1 ); - - if( safer_memcmp( cookie, ref_cookie, sizeof( ref_cookie ) ) != 0 ) - return( -1 ); - - return( 0 ); -} -#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ - static int ssl_parse_client_hello( ssl_context *ssl ) { int ret; @@ -1571,7 +1462,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) } SSL_DEBUG_MSG( 2, ( "client hello, cookie verification skipped" ) ); -#endif +#endif /* POLARSSL_SSL_DTLS_HELLO_VERIFY */ } #endif /* POLARSSL_SSL_PROTO_DTLS */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 67661eaa9..3186accd1 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -81,6 +81,10 @@ int main( int argc, char *argv[] ) #include "polarssl/ssl_cache.h" #endif +#if defined(POLARSSL_SSL_DTLS_HELLO_VERIFY) +#include "polarssl/ssl_cookie.h" +#endif + #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) #include "polarssl/memory.h" #endif