Fix TLS 1.3

This commit is contained in:
Zhi Guan
2026-06-21 09:18:23 +08:00
parent 08b925207e
commit 27908d8af1
4 changed files with 144 additions and 29 deletions

View File

@@ -825,11 +825,6 @@ if(ENABLE_TLS AND NOT WIN32)
tool_tls13_psk_only_sm4_gcm tool_tls13_psk_only_sm4_gcm
tool_tls13_early_data_sm4_gcm tool_tls13_early_data_sm4_gcm
PROPERTIES FIXTURES_REQUIRED gmssl_cert_files) PROPERTIES FIXTURES_REQUIRED gmssl_cert_files)
set_tests_properties(
tool_tls13_hrr_sm4_gcm
tool_tls13_psk_only_sm4_gcm
tool_tls13_early_data_sm4_gcm
PROPERTIES DISABLED TRUE)
if(OPENSSL_EXECUTABLE AND GMSSL_OPENSSL_INTEROP_ENABLED) if(OPENSSL_EXECUTABLE AND GMSSL_OPENSSL_INTEROP_ENABLED)
add_test(NAME tool_tls12_openssl_server COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls12_openssl_server -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") add_test(NAME tool_tls12_openssl_server COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls12_openssl_server -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake")
add_test(NAME tool_tls12_openssl_server_renegotiation_info COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls12_openssl_server_renegotiation_info -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") add_test(NAME tool_tls12_openssl_server_renegotiation_info COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls12_openssl_server_renegotiation_info -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake")
@@ -855,10 +850,6 @@ if(ENABLE_TLS AND NOT WIN32)
tool_tls13_psk_only_openssl_server tool_tls13_psk_only_openssl_server
tool_tls13_psk_only_openssl_client tool_tls13_psk_only_openssl_client
PROPERTIES FIXTURES_REQUIRED gmssl_cert_files) PROPERTIES FIXTURES_REQUIRED gmssl_cert_files)
set_tests_properties(
tool_tls13_psk_only_openssl_server
tool_tls13_psk_only_openssl_client
PROPERTIES DISABLED TRUE)
elseif(NOT OPENSSL_EXECUTABLE) elseif(NOT OPENSSL_EXECUTABLE)
message(STATUS "openssl executable not found; skipping OpenSSL TLS interop tests") message(STATUS "openssl executable not found; skipping OpenSSL TLS interop tests")
endif() endif()
@@ -874,7 +865,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1133") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1134")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -5,6 +5,11 @@ function(gmssl_require_file file)
endfunction() endfunction()
function(gmssl_run_command_interop_test) function(gmssl_run_command_interop_test)
if(POLICY CMP0053)
cmake_policy(PUSH)
cmake_policy(SET CMP0053 NEW)
endif()
set(one_value_args TEST_NAME PORT SERVER_COMMAND CLIENT_COMMAND EXPECT_CLIENT_LOG EXPECT_SERVER_LOG) set(one_value_args TEST_NAME PORT SERVER_COMMAND CLIENT_COMMAND EXPECT_CLIENT_LOG EXPECT_SERVER_LOG)
cmake_parse_arguments(TEST "" "${one_value_args}" "" ${ARGN}) cmake_parse_arguments(TEST "" "${one_value_args}" "" ${ARGN})
@@ -81,9 +86,18 @@ function(gmssl_run_command_interop_test)
message(FATAL_ERROR "server log does not contain expected text: ${TEST_EXPECT_SERVER_LOG}") message(FATAL_ERROR "server log does not contain expected text: ${TEST_EXPECT_SERVER_LOG}")
endif() endif()
endif() endif()
if(POLICY CMP0053)
cmake_policy(POP)
endif()
endfunction() endfunction()
function(gmssl_run_tls_command_test) function(gmssl_run_tls_command_test)
if(POLICY CMP0053)
cmake_policy(PUSH)
cmake_policy(SET CMP0053 NEW)
endif()
set(one_value_args TEST_NAME PORT EXPECT_CLIENT_LOG EXPECT_SERVER_LOG) set(one_value_args TEST_NAME PORT EXPECT_CLIENT_LOG EXPECT_SERVER_LOG)
set(multi_value_args SERVER_ARGS CLIENT_ARGS) set(multi_value_args SERVER_ARGS CLIENT_ARGS)
cmake_parse_arguments(TEST "" "${one_value_args}" "${multi_value_args}" ${ARGN}) cmake_parse_arguments(TEST "" "${one_value_args}" "${multi_value_args}" ${ARGN})
@@ -180,4 +194,8 @@ function(gmssl_run_tls_command_test)
message(FATAL_ERROR "server log does not contain expected text: ${TEST_EXPECT_SERVER_LOG}") message(FATAL_ERROR "server log does not contain expected text: ${TEST_EXPECT_SERVER_LOG}")
endif() endif()
endif() endif()
if(POLICY CMP0053)
cmake_policy(POP)
endif()
endfunction() endfunction()

View File

@@ -18,7 +18,7 @@ extern "C" {
#define GMSSL_VERSION_NUM 30200 #define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1133" #define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1134"
int gmssl_version_num(void); int gmssl_version_num(void);
const char *gmssl_version_str(void); const char *gmssl_version_str(void);

View File

@@ -7634,11 +7634,15 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
// Extensions // Extensions
const uint8_t *key_share = NULL; const uint8_t *key_share = NULL;
size_t key_share_len; size_t key_share_len = 0;
const uint8_t *pre_shared_key = NULL; const uint8_t *pre_shared_key = NULL;
size_t pre_shared_key_len; size_t pre_shared_key_len = 0;
const uint8_t *cookie = NULL; const uint8_t *cookie = NULL;
size_t cookie_len; size_t cookie_len = 0;
const uint8_t *client_hello1_exts;
size_t client_hello1_exts_len;
const uint8_t *client_hello2_exts;
size_t client_hello2_exts_len;
const uint8_t *key_exchange; const uint8_t *key_exchange;
size_t key_exchange_len; size_t key_exchange_len;
@@ -7702,14 +7706,20 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
// update client_server // update client_server
memcpy(conn->client_random, random, 32); memcpy(conn->client_random, random, 32);
client_hello1_exts = _exts;
client_hello1_exts_len = _extslen;
client_hello2_exts = exts;
client_hello2_exts_len = extslen;
while (extslen) { while (extslen) {
int ext_type; int ext_type;
const uint8_t *ext_data; const uint8_t *ext_data;
size_t ext_datalen; size_t ext_datalen;
int _ext_type; const uint8_t *matching_ext_data = NULL;
const uint8_t *_ext_data; size_t matching_ext_datalen = 0;
size_t _ext_datalen; int matching_ext_found = 0;
const uint8_t *search_exts = client_hello1_exts;
size_t search_exts_len = client_hello1_exts_len;
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) {
error_print(); error_print();
@@ -7717,6 +7727,29 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
return -1; return -1;
} }
{
const uint8_t *dup_exts = exts;
size_t dup_exts_len = extslen;
while (dup_exts_len) {
int dup_ext_type;
const uint8_t *dup_ext_data;
size_t dup_ext_datalen;
if (tls_ext_from_bytes(&dup_ext_type, &dup_ext_data, &dup_ext_datalen,
&dup_exts, &dup_exts_len) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_decode_error);
return -1;
}
if (dup_ext_type == ext_type) {
error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1;
}
}
}
// ClientHello2 extensions // ClientHello2 extensions
// * key_share - must exist, only one key_exchange based on conn->key_exchange_group // * key_share - must exist, only one key_exchange based on conn->key_exchange_group
// * pre_shared_key - might be subset of ClientHello1.pre_shared_key // * pre_shared_key - might be subset of ClientHello1.pre_shared_key
@@ -7747,20 +7780,30 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
continue; continue;
} }
// get ext in ClientHello1 (omit early_data) // Find the corresponding ClientHello1 extension by type. The order
if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen, &_exts, &_extslen) != 1) { // can change after HRR; early_data is intentionally omitted.
error_print(); while (search_exts_len) {
tls13_send_alert(conn, TLS_alert_decode_error); int _ext_type;
return -1; const uint8_t *_ext_data;
} size_t _ext_datalen;
if (_ext_type == TLS_extension_early_data) {
if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen, &_exts, &_extslen) != 1) { if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen, &search_exts, &search_exts_len) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls13_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
if (_ext_type == TLS_extension_early_data) {
continue;
}
if (ext_type == _ext_type) {
matching_ext_data = _ext_data;
matching_ext_datalen = _ext_datalen;
matching_ext_found = 1;
break;
}
} }
if (ext_type != _ext_type) { if (!matching_ext_found) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
@@ -7774,6 +7817,11 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
tls13_send_alert(conn, TLS_alert_decode_error); tls13_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
if (key_share) {
error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1;
}
key_share = ext_data; key_share = ext_data;
key_share_len = ext_datalen; key_share_len = ext_datalen;
break; break;
@@ -7785,13 +7833,20 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
const uint8_t *binders; const uint8_t *binders;
size_t binders_len; size_t binders_len;
const uint8_t *_psk_identities; const uint8_t *_psk_identities;
const uint8_t *_psk_identities_start;
size_t _psk_identities_len; size_t _psk_identities_len;
size_t _psk_identities_start_len;
if (!ext_data) { if (!ext_data) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls13_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
if (pre_shared_key) {
error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1;
}
if (tls13_client_pre_shared_key_from_bytes(&psk_identities, &psk_identities_len, if (tls13_client_pre_shared_key_from_bytes(&psk_identities, &psk_identities_len,
&binders, &binders_len, ext_data, ext_datalen) != 1) { &binders, &binders_len, ext_data, ext_datalen) != 1) {
error_print(); error_print();
@@ -7799,10 +7854,12 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
return -1; return -1;
} }
if (tls13_client_pre_shared_key_from_bytes(&_psk_identities, &_psk_identities_len, if (tls13_client_pre_shared_key_from_bytes(&_psk_identities, &_psk_identities_len,
&binders, &binders_len, _ext_data, _ext_datalen) != 1) { &binders, &binders_len, matching_ext_data, matching_ext_datalen) != 1) {
error_print(); error_print();
return -1; return -1;
} }
_psk_identities_start = _psk_identities;
_psk_identities_start_len = _psk_identities_len;
while (psk_identities_len) { while (psk_identities_len) {
const uint8_t *id; const uint8_t *id;
size_t idlen; size_t idlen;
@@ -7810,6 +7867,8 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
const uint8_t *_id; const uint8_t *_id;
size_t _idlen; size_t _idlen;
int match = 0; int match = 0;
_psk_identities = _psk_identities_start;
_psk_identities_len = _psk_identities_start_len;
if (tls13_psk_identity_from_bytes(&id, &idlen, &age, &psk_identities, &psk_identities_len) != 1) { if (tls13_psk_identity_from_bytes(&id, &idlen, &age, &psk_identities, &psk_identities_len) != 1) {
error_print(); error_print();
@@ -7838,8 +7897,8 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
break; break;
default: default:
if (ext_datalen != _ext_datalen if (ext_datalen != matching_ext_datalen
|| memcmp(ext_data, _ext_data, _ext_datalen) != 0) { || (ext_datalen && memcmp(ext_data, matching_ext_data, matching_ext_datalen) != 0)) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
@@ -7847,6 +7906,53 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn)
} }
} }
// ClientHello2 must not drop any ClientHello1 extension except early_data.
while (client_hello1_exts_len) {
int _ext_type;
const uint8_t *_ext_data;
size_t _ext_datalen;
const uint8_t *search_exts = client_hello2_exts;
size_t search_exts_len = client_hello2_exts_len;
int found = 0;
if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen,
&client_hello1_exts, &client_hello1_exts_len) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_decode_error);
return -1;
}
if (_ext_type == TLS_extension_early_data) {
continue;
}
if (_ext_type == TLS_extension_key_share && key_share) {
continue;
}
if (_ext_type == TLS_extension_pre_shared_key && pre_shared_key) {
continue;
}
while (!found && search_exts_len) {
int ext_type;
const uint8_t *ext_data;
size_t ext_datalen;
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &search_exts, &search_exts_len) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_decode_error);
return -1;
}
if (ext_type == _ext_type
&& ext_datalen == _ext_datalen
&& (!ext_datalen || memcmp(ext_data, _ext_data, _ext_datalen) == 0)) {
found = 1;
}
}
if (!found) {
error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter);
return -1;
}
}
// client must echo ClientHello1.cookie // client must echo ClientHello1.cookie
if (conn->cookie && !cookie) { if (conn->cookie && !cookie) {
error_print(); error_print();