diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 79d7dddeae..6e593ab0de 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -647,6 +647,8 @@ typedef enum MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO, + MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO, + MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REUEST, } mbedtls_ssl_states; diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 5be338d3ff..d50be5d532 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1273,7 +1273,16 @@ static int ssl_tls13_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_write_server_hello( ssl ) ); +#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + /* The server sends a dummy change_cipher_spec record immediately + * after its first handshake message. This may either be after + * a ServerHello or a HelloRetryRequest. + */ + mbedtls_ssl_handshake_set_state( ssl, + MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO ); +#else mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS ); +#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ cleanup: @@ -1339,7 +1348,16 @@ static int ssl_tls13_write_hello_retry_request( mbedtls_ssl_context *ssl ) ssl->handshake->hello_retry_request_count++; +#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + /* The server sends a dummy change_cipher_spec record immediately + * after its first handshake message. This may either be after + * a ServerHello or a HelloRetryRequest. + */ + mbedtls_ssl_handshake_set_state( ssl, + MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REUEST ); +#else mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO ); +#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ cleanup: MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello retry request" ) ); @@ -1719,6 +1737,23 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl ) break; #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + /* + * Injection of dummy-CCS's for middlebox compatibility + */ +#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + case MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REUEST: + ret = mbedtls_ssl_tls13_write_change_cipher_spec( ssl ); + if( ret == 0 ) + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO ); + break; + + case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO: + ret = mbedtls_ssl_tls13_write_change_cipher_spec( ssl ); + if( ret == 0 ) + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS ); + break; +#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ + case MBEDTLS_SSL_SERVER_FINISHED: ret = ssl_tls13_write_server_finished( ssl ); break;