From 5d397686a9ac2361a38b9f9a2545af631e54058e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 21 May 2018 12:50:34 +0100 Subject: [PATCH] Restructure outgoing CliKeyExch: Add frame for new structure This commit adds declarations and dummy implementations for the restructured outgoing client key exchange handling that will replace the previous ssl_write_client_key_exchange(). The entry point for the CliKeyExchange handling that is called from the handshake state machine is `ssl_process_client_key_exchange()`, splitting the processing into the following steps: - Preparation Compute the keying material to be sent. * For (EC)DH: Pick parameters and compute PMS. * For ECJPAKE: Run round 2 * For RSA: Encrypt PMS - Writing: Prepare the writing of a new messae. - Postprocessing: Update handstate state machine. The subsequent commits will scatter the code from the previous monolithic function ssl_write_client_key_exchange() among those dedicated functions, commenting out each part of ssl_write_client_key_exchange() that has already been dealt with. This gradual progression is meant to ease reviewing. Once all code has been moved and all changes explained, ssl_write_client_key_exchange() will be removed. --- include/mbedtls/ssl_internal.h | 2 + library/ssl_cli.c | 93 +++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index ee0fa297b..f53d747d4 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1806,4 +1806,6 @@ MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_pend_fatal_alert( ssl->pending_fatal_alert_msg = message; } +#define SSL_PROC_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 ) + #endif /* ssl_internal.h */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 003aa10c9..63596c46b 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -3187,6 +3187,97 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) return( 0 ); } +/* + * + * STATE HANDLING: Client Key Exchange + * + */ + +/* + * Overview + */ + +/* Main entry point; orchestrates the other functions */ +static int ssl_process_client_key_exchange( mbedtls_ssl_context *ssl ); + +/* Preparation + * - For ECDH: Generate client params and derive premater secret + * - For RSA-suites: Encrypt PMS + * - For ECJPAKE: Do Round 2 + */ +static int ssl_client_key_exchange_prepare( mbedtls_ssl_context *ssl ); +static int ssl_client_key_exchange_write( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t buflen, + size_t *olen ); +static int ssl_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ); + +/* + * Implementation + */ + +static int ssl_process_client_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret = 0; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> process client key exchange" ) ); + + SSL_PROC_CHK( ssl_client_key_exchange_prepare( ssl ) ); + + /* Prepare CertificateVerify message in output buffer. */ + SSL_PROC_CHK( ssl_client_key_exchange_write( ssl, ssl->out_msg, + MBEDTLS_SSL_MAX_CONTENT_LEN, + &ssl->out_msglen ) ); + + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; + + /* Update state */ + SSL_PROC_CHK( ssl_client_key_exchange_postprocess( ssl ) ); + + /* Dispatch message */ + + SSL_PROC_CHK( mbedtls_ssl_write_handshake_msg( ssl ) ); + + /* NOTE: For the new messaging layer, the postprocessing step + * might come after the dispatching step if the latter + * doesn't send the message immediately. + * At the moment, we must do the postprocessing + * prior to the dispatching because if the latter + * returns WANT_WRITE, we want the handshake state + * to be updated in order to not enter + * this function again on retry. */ + +cleanup: + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= process client key exchange" ) ); + return( ret ); +} + +static int ssl_client_key_exchange_prepare( mbedtls_ssl_context *ssl ) +{ + /* TBD */ +} + +static int ssl_client_key_exchange_write( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t buflen, + size_t *olen ) +{ + /* TBD */ +} + +static int ssl_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) +{ + /* TBD */ +} + +/* OLD CODE + * + * Temporarily included to gradually move it to the correct + * place in the restructured code. + * + */ + static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) { int ret; @@ -3892,7 +3983,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_write_client_key_exchange( ssl ); + ret = ssl_process_client_key_exchange( ssl ); break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: