Restructure SrvKeyExchange: Add frame for structure

This commit adds declarations and dummy implementations for
the restructured incoming server key exchange handling that
will replace the previous ssl_parse_server_key_exchange().

The entry point for the SrvKeyExchange handling that is called
from the handshake state machine is

   `ssl_process_server_key_exchange()`,

splitting the processing into the following steps:

- Preparation: For a static DH key exchange, extract
               DH parameters from the server's CRT.
- Coordination: Check if a SrvKeyExchange message is expected
  (e.g., it isn't for a RSA-based key exchange)
- Reading: Fetch and check content and handshake type
           of incoming message.
- Parsing: Parse and store the ServerKeyExchange message.
- Postprocessing: Update handstate state machine.

The subsequent commits will scatter the code from the previous
monolithic function ssl_parse_server_key_exchange() among those
dedicated functions, commenting out each part of
ssl_parse_server_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_parse_server_key_exchange() will be removed.
This commit is contained in:
Hanno Becker 2018-05-21 09:03:36 +01:00
parent 09d236419e
commit 04769ddb84

View file

@ -2595,6 +2595,134 @@ cleanup:
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
/*
*
* STATE HANDLING: ServerKeyExchange
*
*/
/*
* Overview
*/
/* Main entry point; orchestrates the other functions. */
static int ssl_process_server_key_exchange( mbedtls_ssl_context *ssl );
/* Coordination:
* Check if a ServerKeyExchange message is expected, and skip if not.
* Returns a negative code on failure, or
* - SSL_SRV_KEY_EXCHANGE_SKIP
* - SSL_SRV_KEY_EXCHANGE_EXPECTED
* indicating if a ServerKeyExchange message is expected or not.
*/
#define SSL_SRV_KEY_EXCHANGE_SKIP 0
#define SSL_SRV_KEY_EXCHANGE_EXPECTED 1
static int ssl_server_key_exchange_coordinate( mbedtls_ssl_context *ssl );
/* Preparation
* If applicable, prepare DH parameters from Server certificate. */
static int ssl_server_key_exchange_prepare( mbedtls_ssl_context *ssl );
/* Parse SrvKeyExchange message and store contents
* (PSK or DH parameters) in handshake structure. */
static int ssl_server_key_exchange_parse( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t buflen );
/* Update the handshake state */
static int ssl_server_key_exchange_postprocess( mbedtls_ssl_context *ssl );
/*
* Implementation
*/
static int ssl_process_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
/* Preparation:
* Potentially extract DH parameters from Server's certificate.
*
* Consider: Why don't we do this as post-processing after
* the server certificate has been read?
*/
SSL_PROC_CHK( ssl_server_key_exchange_prepare( ssl ) );
/* Coordination:
* Check if we expect a ServerKeyExchange */
SSL_PROC_CHK( ssl_server_key_exchange_coordinate( ssl ) );
if( ret == SSL_SRV_KEY_EXCHANGE_EXPECTED )
{
/* Reading step */
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_pend_alert_message( ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
goto cleanup;
}
else
{
SSL_PROC_CHK( ssl_server_key_exchange_parse( ssl, ssl->in_msg,
ssl->in_hslen ) );
}
}
else if( ret == SSL_SRV_KEY_EXCHANGE_SKIP )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
}
/* Update state */
SSL_PROC_CHK( ssl_server_key_exchange_postprocess( ssl ) );
cleanup:
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
ssl->keep_current_message = 1;
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
return( ret );
}
static int ssl_server_key_exchange_prepare( mbedtls_ssl_context *ssl )
{
/* TBD */
}
static int ssl_server_key_exchange_coordinate( mbedtls_ssl_context *ssl )
{
/* TBD */
}
static int ssl_server_key_exchange_parse( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t buflen )
{
/* TBD */
}
static int ssl_server_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_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret;
@ -3997,7 +4125,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
break;
case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
ret = ssl_parse_server_key_exchange( ssl );
ret = ssl_process_server_key_exchange( ssl );
break;
case MBEDTLS_SSL_CERTIFICATE_REQUEST: