From ebd30ae205b3d76ffd7101006a46e38a8ba09eea Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 6 Jan 2018 03:34:20 +0100 Subject: [PATCH] ssl_write_server_key_exchange refactor: ssl_resume_server_key_exchange Continue clarifying the control flow. This gets rid of the last goto introduced by the initial code for asynchronous signature support. --- library/ssl_srv.c | 71 ++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index f6db3c715..da6069d84 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2826,6 +2826,27 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ + defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) +static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, + size_t *signature_len ) +{ + size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_MAX_CONTENT_LEN + - ( ssl->out_msg + ssl->out_msglen + 2 ) ); + int ret = ssl->conf->f_async_resume( ssl->conf->p_async_connection_ctx, + ssl->handshake->p_async_operation_ctx, + ssl->out_msg + ssl->out_msglen + 2, + signature_len, sig_max_len ); + MBEDTLS_SSL_DEBUG_RET( 3, "f_async_resume", ret ); + if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) + { + ssl->handshake->p_async_operation_ctx = NULL; + } + return( ret ); +} +#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && + defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) */ + static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, size_t *signature_len ) { @@ -2844,16 +2865,6 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) - if( ssl->handshake->p_async_operation_ctx != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); - goto async_resume; - } -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) */ - /* * * Part 1: Provide key exchange parameters for chosen ciphersuite. @@ -3187,8 +3198,6 @@ curve_matching_done: #if defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) if( ssl->conf->f_async_sign_start != NULL ) { - size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_MAX_CONTENT_LEN - - ( ssl->out_msg + ssl->out_msglen + 2 ) ); ret = ssl->conf->f_async_sign_start( ssl->conf->p_async_connection_ctx, &ssl->handshake->p_async_operation_ctx, @@ -3200,19 +3209,7 @@ curve_matching_done: /* act as if f_async_sign was null */ break; case 0: - async_resume: - ret = ssl->conf->f_async_resume( - ssl->conf->p_async_connection_ctx, - ssl->handshake->p_async_operation_ctx, - ssl->out_msg + ssl->out_msglen + 2, - signature_len, sig_max_len ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->p_async_operation_ctx = NULL; - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_resume", ret ); - return( ret ); - } - /* FALLTHROUGH */ + return( ssl_resume_server_key_exchange( ssl, signature_len ) ); case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); @@ -3275,10 +3272,26 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */ - /* ServerKeyExchange is needed. Prepare the message. */ - ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); - if( ret != 0 ) - return( ret ); + /* If we have already prepared the message and there is an ongoing + signature operation, resume signing. */ +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ + defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) + if( ssl->handshake->p_async_operation_ctx != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); + ret = ssl_resume_server_key_exchange( ssl, &signature_len ); + if( ret != 0 ) + return( ret ); + } + else +#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && + defined(MBEDTLS_SSL_ASYNC_PRIVATE_C) */ + { + /* ServerKeyExchange is needed. Prepare the message. */ + ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); + if( ret != 0 ) + return( ret ); + } /* If there is a signature, write its length. ssl_prepare_server_key_exchange already wrote the signature