diff --git a/CMakeLists.txt b/CMakeLists.txt index ccf3ad8d..4a691f14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -751,6 +751,12 @@ add_test(NAME cert_commands COMMAND ${CMAKE_COMMAND} -P "${CMAKE_SOURCE_DIR}/cma set_tests_properties(cert_commands PROPERTIES FIXTURES_SETUP gmssl_cert_files) if(ENABLE_TLS AND NOT WIN32) find_program(OPENSSL_EXECUTABLE openssl) + set(GMSSL_OPENSSL_INTEROP_ENABLED OFF) + if(ENABLE_AES AND ENABLE_SHA2 AND ENABLE_SECP256R1) + set(GMSSL_OPENSSL_INTEROP_ENABLED ON) + else() + message(STATUS "OpenSSL TLS interop tests require ENABLE_AES=ON, ENABLE_SHA2=ON and ENABLE_SECP256R1=ON; skipping") + endif() add_test(NAME tlcp_sm4_cbc COMMAND ${CMAKE_COMMAND} -DTEST_CASE=tlcp_sm4_cbc -P "${CMAKE_SOURCE_DIR}/cmake/tlcp_commands.cmake") add_test(NAME tlcp_sm4_gcm COMMAND ${CMAKE_COMMAND} -DTEST_CASE=tlcp_sm4_gcm -P "${CMAKE_SOURCE_DIR}/cmake/tlcp_commands.cmake") add_test(NAME tls12_sm4_cbc COMMAND ${CMAKE_COMMAND} -DTEST_CASE=tls12_sm4_cbc -P "${CMAKE_SOURCE_DIR}/cmake/tls12_commands.cmake") @@ -776,17 +782,29 @@ if(ENABLE_TLS AND NOT WIN32) tls13_psk_only_sm4_gcm tls13_early_data_sm4_gcm PROPERTIES DISABLED TRUE) - if(OPENSSL_EXECUTABLE) + if(OPENSSL_EXECUTABLE AND GMSSL_OPENSSL_INTEROP_ENABLED) add_test(NAME 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 tls12_openssl_client COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls12_openssl_client -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") add_test(NAME tls13_openssl_server COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_openssl_server -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") add_test(NAME tls13_openssl_client COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_openssl_client -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") + add_test(NAME tls13_hrr_openssl_client COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_hrr_openssl_client -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") + add_test(NAME tls13_psk_dhe_openssl_server COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_psk_dhe_openssl_server -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") + add_test(NAME tls13_psk_dhe_openssl_client COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_psk_dhe_openssl_client -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") + add_test(NAME tls13_psk_only_openssl_server COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_psk_only_openssl_server -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") + add_test(NAME tls13_psk_only_openssl_client COMMAND ${CMAKE_COMMAND} -DOPENSSL_EXECUTABLE=${OPENSSL_EXECUTABLE} -DTEST_CASE=tls13_psk_only_openssl_client -P "${CMAKE_SOURCE_DIR}/cmake/openssl_interop_commands.cmake") set_tests_properties( tls12_openssl_server tls12_openssl_client tls13_openssl_server tls13_openssl_client + tls13_hrr_openssl_client + tls13_psk_dhe_openssl_server + tls13_psk_dhe_openssl_client + tls13_psk_only_openssl_server + tls13_psk_only_openssl_client PROPERTIES FIXTURES_REQUIRED gmssl_cert_files) + elseif(NOT OPENSSL_EXECUTABLE) + message(STATUS "openssl executable not found; skipping OpenSSL TLS interop tests") endif() endif() @@ -800,7 +818,7 @@ endif() # set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_VENDOR "GmSSL develop team") -set(CPACK_PACKAGE_VERSION "3.2.0-dev.1057") +set(CPACK_PACKAGE_VERSION "3.2.0-dev.1058") set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_NSIS_MODIFY_PATH ON) include(CPack) diff --git a/cmake/openssl_interop_commands.cmake b/cmake/openssl_interop_commands.cmake index fadfc0fb..94daf5a2 100644 --- a/cmake/openssl_interop_commands.cmake +++ b/cmake/openssl_interop_commands.cmake @@ -18,6 +18,8 @@ if(NOT DEFINED TEST_CASE) set(TEST_CASE tls12_openssl_server) endif() +set(TLS13_PSK 1122334455667788112233445566778811223344556677881122334455667788) + if(TEST_CASE STREQUAL tls12_openssl_server) set(TEST_NAME tls12_openssl_server) set(TEST_PORT 4450) @@ -62,6 +64,62 @@ elseif(TEST_CASE STREQUAL tls13_openssl_client) SERVER_COMMAND "${SERVER_COMMAND}" CLIENT_COMMAND "${CLIENT_COMMAND}" EXPECT_CLIENT_LOG "Verification: OK") +elseif(TEST_CASE STREQUAL tls13_hrr_openssl_client) + set(TEST_NAME tls13_hrr_openssl_client) + set(TEST_PORT 4454) + set(SERVER_COMMAND "bin/gmssl tls13_server -port ${TEST_PORT} -cert p256certs.pem -key p256signkey.pem -pass P@ssw0rd -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 -verbose") + set(CLIENT_COMMAND "printf 'GET / HTTP/1.0\\r\\n\\r\\n' | ${OPENSSL_EXECUTABLE} s_client -connect 127.0.0.1:${TEST_PORT} -tls1_3 -CAfile p256rootcacert.pem -ciphersuites TLS_AES_128_GCM_SHA256 -groups secp384r1:prime256v1 -sigalgs ecdsa_secp256r1_sha256 -no_middlebox -brief -msg") + gmssl_run_command_interop_test( + TEST_NAME ${TEST_NAME} + PORT ${TEST_PORT} + SERVER_COMMAND "${SERVER_COMMAND}" + CLIENT_COMMAND "${CLIENT_COMMAND}" + EXPECT_CLIENT_LOG "Verification: OK" + EXPECT_SERVER_LOG "selected_group: secp256r1") +elseif(TEST_CASE STREQUAL tls13_psk_dhe_openssl_server) + set(TEST_NAME tls13_psk_dhe_openssl_server) + set(TEST_PORT 4455) + set(SERVER_COMMAND "${OPENSSL_EXECUTABLE} s_server -accept ${TEST_PORT} -tls1_3 -no_middlebox -nocert -psk_identity 001 -psk ${TLS13_PSK} -ciphersuites TLS_AES_128_GCM_SHA256 -groups prime256v1 -www -naccept 1 -quiet") + set(CLIENT_COMMAND "bin/gmssl tls13_client -host 127.0.0.1 -port ${TEST_PORT} -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -psk_dhe_ke -psk_identity 001 -psk_cipher_suite TLS_AES_128_GCM_SHA256 -psk_key ${TLS13_PSK} -get /") + gmssl_run_command_interop_test( + TEST_NAME ${TEST_NAME} + PORT ${TEST_PORT} + SERVER_COMMAND "${SERVER_COMMAND}" + CLIENT_COMMAND "${CLIENT_COMMAND}" + EXPECT_CLIENT_LOG "HTTP/1.0 200 ok") +elseif(TEST_CASE STREQUAL tls13_psk_dhe_openssl_client) + set(TEST_NAME tls13_psk_dhe_openssl_client) + set(TEST_PORT 4456) + set(SERVER_COMMAND "bin/gmssl tls13_server -port ${TEST_PORT} -cert p256certs.pem -key p256signkey.pem -pass P@ssw0rd -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -psk_dhe_ke -psk_identity 001 -psk_cipher_suite TLS_AES_128_GCM_SHA256 -psk_key ${TLS13_PSK}") + set(CLIENT_COMMAND "printf 'GET / HTTP/1.0\\r\\n\\r\\n' | ${OPENSSL_EXECUTABLE} s_client -connect 127.0.0.1:${TEST_PORT} -tls1_3 -psk_identity 001 -psk ${TLS13_PSK} -ciphersuites TLS_AES_128_GCM_SHA256 -groups prime256v1 -no_middlebox -brief") + gmssl_run_command_interop_test( + TEST_NAME ${TEST_NAME} + PORT ${TEST_PORT} + SERVER_COMMAND "${SERVER_COMMAND}" + CLIENT_COMMAND "${CLIENT_COMMAND}" + EXPECT_CLIENT_LOG "CONNECTION ESTABLISHED") +elseif(TEST_CASE STREQUAL tls13_psk_only_openssl_server) + set(TEST_NAME tls13_psk_only_openssl_server) + set(TEST_PORT 4457) + set(SERVER_COMMAND "${OPENSSL_EXECUTABLE} s_server -accept ${TEST_PORT} -tls1_3 -no_middlebox -allow_no_dhe_kex -nocert -psk_identity 001 -psk ${TLS13_PSK} -ciphersuites TLS_AES_128_GCM_SHA256 -www -naccept 1 -quiet") + set(CLIENT_COMMAND "bin/gmssl tls13_client -host 127.0.0.1 -port ${TEST_PORT} -cipher_suite TLS_AES_128_GCM_SHA256 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_AES_128_GCM_SHA256 -psk_key ${TLS13_PSK} -get /") + gmssl_run_command_interop_test( + TEST_NAME ${TEST_NAME} + PORT ${TEST_PORT} + SERVER_COMMAND "${SERVER_COMMAND}" + CLIENT_COMMAND "${CLIENT_COMMAND}" + EXPECT_CLIENT_LOG "HTTP/1.0 200 ok") +elseif(TEST_CASE STREQUAL tls13_psk_only_openssl_client) + set(TEST_NAME tls13_psk_only_openssl_client) + set(TEST_PORT 4458) + set(SERVER_COMMAND "bin/gmssl tls13_server -port ${TEST_PORT} -cert p256certs.pem -key p256signkey.pem -pass P@ssw0rd -cipher_suite TLS_AES_128_GCM_SHA256 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_AES_128_GCM_SHA256 -psk_key ${TLS13_PSK}") + set(CLIENT_COMMAND "printf 'GET / HTTP/1.0\\r\\n\\r\\n' | ${OPENSSL_EXECUTABLE} s_client -connect 127.0.0.1:${TEST_PORT} -tls1_3 -psk_identity 001 -psk ${TLS13_PSK} -ciphersuites TLS_AES_128_GCM_SHA256 -allow_no_dhe_kex -prefer_no_dhe_kex -no_middlebox -brief") + gmssl_run_command_interop_test( + TEST_NAME ${TEST_NAME} + PORT ${TEST_PORT} + SERVER_COMMAND "${SERVER_COMMAND}" + CLIENT_COMMAND "${CLIENT_COMMAND}" + EXPECT_CLIENT_LOG "CONNECTION ESTABLISHED") else() message(FATAL_ERROR "unknown OpenSSL interop test case: ${TEST_CASE}") endif() diff --git a/cmake/tls13_commands.cmake b/cmake/tls13_commands.cmake index 8fa57490..e3941895 100644 --- a/cmake/tls13_commands.cmake +++ b/cmake/tls13_commands.cmake @@ -36,11 +36,11 @@ if(TEST_CASE STREQUAL tls13_sm4_gcm) elseif(TEST_CASE STREQUAL tls13_hrr_sm4_gcm) gmssl_run_tls_command_test( TEST_NAME tls13_hrr_sm4_gcm - PORT 4436 + PORT 4460 EXPECT_CLIENT_LOG "selected_group: sm2p256v1" SERVER_ARGS tls13_server - -port 4436 + -port 4460 -cert tls_server_certs.pem -key signkey.pem -pass P@ssw0rd @@ -51,7 +51,7 @@ elseif(TEST_CASE STREQUAL tls13_hrr_sm4_gcm) CLIENT_ARGS tls13_client -host 127.0.0.1 - -port 4436 + -port 4460 -cacert rootcacert.pem -cipher_suite TLS_SM4_GCM_SM3 -supported_group prime256v1 @@ -92,10 +92,10 @@ elseif(TEST_CASE STREQUAL tls13_psk_dhe_sm4_gcm) elseif(TEST_CASE STREQUAL tls13_psk_only_sm4_gcm) gmssl_run_tls_command_test( TEST_NAME tls13_psk_only_sm4_gcm - PORT 4438 + PORT 4461 SERVER_ARGS tls13_server - -port 4438 + -port 4461 -cert tls_server_certs.pem -key signkey.pem -pass P@ssw0rd @@ -107,7 +107,7 @@ elseif(TEST_CASE STREQUAL tls13_psk_only_sm4_gcm) CLIENT_ARGS tls13_client -host 127.0.0.1 - -port 4438 + -port 4461 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 @@ -118,11 +118,11 @@ elseif(TEST_CASE STREQUAL tls13_psk_only_sm4_gcm) elseif(TEST_CASE STREQUAL tls13_early_data_sm4_gcm) gmssl_run_tls_command_test( TEST_NAME tls13_early_data_sm4_gcm - PORT 4439 + PORT 4462 EXPECT_SERVER_LOG "EarlyData" SERVER_ARGS tls13_server - -port 4439 + -port 4462 -cert tls_server_certs.pem -key signkey.pem -pass P@ssw0rd @@ -135,7 +135,7 @@ elseif(TEST_CASE STREQUAL tls13_early_data_sm4_gcm) CLIENT_ARGS tls13_client -host 127.0.0.1 - -port 4439 + -port 4462 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index ebc86102..4a6e738a 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -1282,10 +1282,13 @@ typedef struct { // 41. pre_shared_key // in ClientHello; ServerHello +#define TLS13_PSK_IDENTITY_EXTERNAL 0 +#define TLS13_PSK_IDENTITY_RESUMPTION 1 int pre_shared_key; uint8_t psk_identities[512]; // list of PskIdentity objects size_t psk_identities_len; int psk_cipher_suites[8]; + uint8_t psk_identity_types[8]; size_t psk_cipher_suites_cnt; uint8_t psk_keys[32 * 8]; // uint8array size_t psk_keys_len; @@ -1694,7 +1697,7 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], # define tls12_record_trace(fp,rec,reclen,fmt,ind) tls12_record_print(fp,rec,reclen,fmt,ind) # define tls13_record_trace(fp,rec,reclen,fmt,ind) tls13_record_print(fp,fmt,ind,rec,reclen) #else -# define tls_trace(s) +# define tls_trace(s) fprintf(stderr,(s)) # define tls_record_trace(fp,rec,reclen,fmt,ind) # define tls_encrypted_record_trace(fp,rec,reclen,fmt,ind) # define tlcp_record_trace(fp,rec,reclen,fmt,ind) @@ -2052,6 +2055,7 @@ int tls13_psk_binders_generate_empty(const int *psk_cipher_suites, size_t psk_ci uint8_t *binders, size_t *binders_len); int tls13_psk_binders_generate( const int *psk_cipher_suites, size_t psk_cipher_suites_cnt, + const uint8_t *psk_identity_types, const uint8_t *psk_keys, size_t psk_keys_len, const uint8_t *truncated_client_hello, size_t truncated_client_hello_len, uint8_t *binders, size_t *binders_len); diff --git a/include/gmssl/version.h b/include/gmssl/version.h index cb336ea4..0c18a966 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -18,7 +18,7 @@ extern "C" { #define GMSSL_VERSION_NUM 30200 -#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1057" +#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1058" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/src/tlcp.c b/src/tlcp.c index 0cc1232d..bbca3a95 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -50,21 +50,6 @@ int tlcp_record_print(FILE *fp, int fmt, int ind, const uint8_t *record, size_t record, recordlen); } -static int tlcp_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest) -{ - switch (cipher_suite) { - case TLS_cipher_ecc_sm4_cbc_sm3: - case TLS_cipher_ecc_sm4_gcm_sm3: - *cipher = BLOCK_CIPHER_sm4(); - *digest = DIGEST_sm3(); - break; - default: - error_print(); - return -1; - } - return 1; -} - int tlcp_record_encrypt(int cipher_suite, const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], const uint8_t seq_num[8], const uint8_t *in, size_t inlen, @@ -387,18 +372,11 @@ struct { opaque RSAEncryptedPreMasterSecret<0..2^16-1>; } exchange_keys; } ClientKeyExchange; - -这里比较特殊的是需要打印一个SM2Ciphertext,也许直接打印二进制就可以了 */ // Handshakes -// 一般来说digest_init是在cipher_suite定下来之后才能设置 -// 但是TLCP中的SM3是确定的,因此可以在ClientHello, ServerHello中设置 - - -// 这个一定是要不同的 int tlcp_send_client_hello(TLS_CONNECT *conn) { int ret; @@ -413,13 +391,16 @@ int tlcp_send_client_hello(TLS_CONNECT *conn) error_print(); return -1; } - if (tlcp_cipher_suite_get(conn->ctx->cipher_suites[0], &conn->cipher, &conn->digest) != 1 - || digest_init(&conn->dgst_ctx, conn->digest) != 1) { + + // TLCP only use sm4 and sm3 + conn->cipher = BLOCK_CIPHER_sm4(); + conn->digest = DIGEST_sm3(); + + if (digest_init(&conn->dgst_ctx, conn->digest) != 1) { error_print(); return -1; } - tls_record_set_protocol(conn->record, TLS_protocol_tlcp); if (tls_random_generate(conn->client_random) != 1) { @@ -508,15 +489,19 @@ int tlcp_send_client_hello(TLS_CONNECT *conn) return -1; } - if(conn->verbose) tls_trace("send ClientHello\n"); - if (conn->verbose) + if (conn->verbose) { + tls_trace("send ClientHello\n"); tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); + } if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); return -1; } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); + if(conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); + + if (conn->client_certificate_verify) { sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); @@ -593,11 +578,6 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn) return -1; } conn->cipher_suite = cipher_suite; - if (tlcp_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } while (extslen) { int ext_type; @@ -1479,9 +1459,14 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn) const uint8_t *host_name = NULL; size_t host_name_len = 0; + // TLCP only use sm4 and sm3 + conn->cipher = BLOCK_CIPHER_sm4(); + conn->digest = DIGEST_sm3(); - - + if (digest_init(&conn->dgst_ctx, conn->digest) != 1) { + error_print(); + return -1; + } // 这个判断应该改为一个函数 /* @@ -1648,12 +1633,6 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn) } } - if (tlcp_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (supported_groups) { int common_group; size_t common_groups_cnt = 0; @@ -1748,8 +1727,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn) return -1; } - if (digest_init(&conn->dgst_ctx, conn->digest) != 1 - || digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); return -1; } diff --git a/src/tls13.c b/src/tls13.c index 4017f49c..76cc775c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -646,6 +646,7 @@ int tls13_generate_early_keys(TLS_CONNECT *conn) error_print(); return -1; } + conn->cipher_suite = conn->psk_cipher_suites[0]; client_write_key_len = conn->cipher->key_size; if (digest_init(&conn->dgst_ctx, conn->digest) != 1 @@ -692,8 +693,8 @@ int tls13_generate_early_keys(TLS_CONNECT *conn) int tls13_generate_handshake_secrets(TLS_CONNECT *conn) { const uint8_t zeros[32] = {0}; - uint8_t ecdhe_shared_secret[32]; - size_t ecdhe_shared_secret_len; + uint8_t ecdhe_shared_secret[32] = {0}; + size_t ecdhe_shared_secret_len = sizeof(ecdhe_shared_secret); uint8_t derived_secret[32]; DIGEST_CTX null_dgst_ctx; @@ -2714,7 +2715,8 @@ int tls13_record_get_handshake_hello_retry_request(uint8_t *record, error_print(); return -1; } - if (type != TLS_handshake_hello_retry_request) { + if (type != TLS_handshake_hello_retry_request + && type != TLS_handshake_server_hello) { error_print(); return -1; } @@ -4285,8 +4287,9 @@ int tls13_send_client_hello(TLS_CONNECT *conn) // generate binders and output final pre_shared_key ext if (tls13_psk_binders_generate( conn->psk_cipher_suites, conn->psk_cipher_suites_cnt, + conn->psk_identity_types, conn->psk_keys, conn->psk_keys_len, - conn->record + 5, conn->recordlen - 5, + conn->record + 5, conn->recordlen - 5 - 2 - binderslen, binders, &binderslen) != 1) { error_print(); return -1; @@ -4425,7 +4428,8 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) error_print(); return -1; } - if (handshake_type != TLS_handshake_hello_retry_request) { + if (handshake_type != TLS_handshake_hello_retry_request + && handshake_type != TLS_handshake_server_hello) { if(conn->verbose) tls_trace(" no HelloRetryRequest\n"); return 0; } @@ -4440,6 +4444,10 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_decode_error); return -1; } + if (memcmp(random, TLS13_HELLO_RETRY_REQUEST_RANDOM, 32) != 0) { + if(conn->verbose) tls_trace(" no HelloRetryRequest\n"); + return 0; + } conn->hello_retry_request = 1; @@ -4731,12 +4739,6 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) // record_version tls_record_set_protocol(conn->record, TLS_protocol_tls1); - // client_random - if (tls13_random_generate(conn->client_random) != 1) { - error_print(); - return -1; - } - // Extensions // keep ClientHello extensions except @@ -4915,8 +4917,9 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) // generate binders and output final pre_shared_key ext if (tls13_psk_binders_generate( conn->psk_cipher_suites, conn->psk_cipher_suites_cnt, + conn->psk_identity_types, conn->psk_keys, conn->psk_keys_len, - conn->record + 5, conn->recordlen - 5, + conn->record + 5, conn->recordlen - 5 - 2 - binderslen, binders, &binderslen) != 1) { error_print(); return -1; @@ -6681,9 +6684,6 @@ int tls13_send_client_finished(TLS_CONNECT *conn) tls13_compute_verify_data(conn->client_handshake_traffic_secret, &conn->dgst_ctx, verify_data, &verify_data_len); - memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx)); - - if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, verify_data, verify_data_len) != 1) { error_print(); @@ -6716,6 +6716,10 @@ int tls13_send_client_finished(TLS_CONNECT *conn) tls13_generate_client_application_keys(conn); + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } return 1; } @@ -6838,7 +6842,8 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) } tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); - if (tls_record_protocol(record) != TLS_protocol_tls1) { + if (tls_record_protocol(record) != TLS_protocol_tls1 + && tls_record_protocol(record) != TLS_protocol_tls12) { error_print(); tls13_send_alert(conn, TLS_alert_protocol_version); return -1; @@ -7465,17 +7470,15 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) * key_exchange_group * [key_exchanges_cnt] */ - if (common_key_exchange_modes & TLS_KE_PSK_DHE) { - if (conn->selected_psk_identity && conn->key_exchange_group) { + if ((common_key_exchange_modes & TLS_KE_PSK_DHE) && conn->selected_psk_identity) { + if (conn->key_exchange_group) { conn->key_exchange_modes = TLS_KE_PSK_DHE; if (!conn->peer_key_exchange_len) { conn->hello_retry_request = 1; } } - } else if (common_key_exchange_modes & TLS_KE_PSK) { - if (conn->selected_psk_identity) { - conn->key_exchange_modes = TLS_KE_PSK; - } + } else if ((common_key_exchange_modes & TLS_KE_PSK) && conn->selected_psk_identity) { + conn->key_exchange_modes = TLS_KE_PSK; } else if (common_key_exchange_modes & TLS_KE_CERT_DHE) { if (conn->cert_chain && conn->key_exchange_group) { conn->key_exchange_modes = TLS_KE_CERT_DHE; @@ -7690,7 +7693,8 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn) } tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); - if (tls_record_protocol(record) != TLS_protocol_tls12) { + if (tls_record_protocol(record) != TLS_protocol_tls1 + && tls_record_protocol(record) != TLS_protocol_tls12) { error_print(); tls13_send_alert(conn, TLS_alert_protocol_version); return -1; @@ -8026,7 +8030,7 @@ int tls13_send_server_hello(TLS_CONNECT *conn) } // pre_shared_key - if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { + if (conn->selected_psk_identity) { if (tls13_server_pre_shared_key_ext_to_bytes( conn->selected_psk_identity, &pexts, &extslen) != 1) { error_print(); @@ -8730,8 +8734,6 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) error_print(); return -1; } - memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx)); - // 当客户端发送了Certificate的时候,这个验证是不对的 // 服务器多发送了CertificateRequest @@ -8745,14 +8747,16 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) } tls13_generate_client_application_keys(conn); + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } return 1; } int tls13_send_early_data(TLS_CONNECT *conn) { - size_t sentlen; - if(conn->verbose) tls_trace("send EarlyData\n"); if (!conn->early_data) { @@ -8766,13 +8770,48 @@ int tls13_send_early_data(TLS_CONNECT *conn) while (conn->early_data_offset < conn->early_data_len) { int ret; - if ((ret = tls13_send(conn, conn->early_data_buf + conn->early_data_offset, - conn->early_data_len - conn->early_data_offset, &sentlen)) <= 0) { + if (conn->recordlen == 0) { + uint8_t plain_record[TLS_MAX_RECORD_SIZE]; + size_t plain_recordlen; + size_t datalen; + size_t padding_len; + + datalen = conn->early_data_len - conn->early_data_offset; + if (datalen > TLS_MAX_PLAINTEXT_SIZE) { + datalen = TLS_MAX_PLAINTEXT_SIZE; + } + + tls13_padding_len_rand(&padding_len); + if (tls_record_set_application_data(plain_record, &plain_recordlen, + conn->early_data_buf + conn->early_data_offset, datalen) != 1) { + error_print(); + return -1; + } + if (tls13_record_encrypt(conn->cipher_suite, &conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, plain_record, plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + + conn->record_offset = 0; + conn->sentlen = datalen; + + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + } + + if ((ret = tls_send_record(conn)) != 1) { if (ret == TLS_ERROR_SEND_AGAIN) { return ret; } + error_print(); + return -1; } - conn->early_data_offset += sentlen; + + conn->early_data_offset += conn->sentlen; + conn->record_offset = 0; + conn->recordlen = 0; } conn->record_offset = 0; @@ -9033,6 +9072,7 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) int tls13_do_server_handshake(TLS_CONNECT *conn) { int ret; + int state = conn->handshake_state; int next_state; switch (conn->handshake_state) { @@ -9164,7 +9204,9 @@ int tls13_do_server_handshake(TLS_CONNECT *conn) conn->handshake_state = next_state; - tls_clean_record(conn); + if (!(state == TLS_state_client_change_cipher_spec && ret == 0)) { + tls_clean_record(conn); + } return 1; } diff --git a/src/tls_psk.c b/src/tls_psk.c index 27510bf3..ffe49212 100644 --- a/src/tls_psk.c +++ b/src/tls_psk.c @@ -629,6 +629,7 @@ int tls13_add_pre_shared_key_from_session_file(TLS_CONNECT *conn, FILE *fp) error_print(); return -1; } + conn->psk_identity_types[conn->psk_cipher_suites_cnt - 1] = TLS13_PSK_IDENTITY_RESUMPTION; conn->pre_shared_key = 1; return 1; @@ -681,8 +682,6 @@ int tls13_send_new_session_ticket(TLS_CONNECT *conn) // generate resumption_master_secret - digest_init(&conn->dgst_ctx, conn->digest); - /* [14] */ tls13_derive_secret(conn->master_secret, "res master", &conn->dgst_ctx, resumption_master_secret); // pre_shared_key = HKDF-Expand-Label(resumption_master_secret, "resumption", ticket_nonce, Hash.length) @@ -808,8 +807,6 @@ int tls13_process_new_session_ticket(TLS_CONNECT *conn) size_t dgstlen = 32; uint8_t pre_shared_key[32]; - digest_init(&conn->dgst_ctx, conn->digest); - // generate resumption_master_secret /* [14] */ tls13_derive_secret(conn->master_secret, "res master", &conn->dgst_ctx, resumption_master_secret); @@ -1000,6 +997,7 @@ int tls13_psk_binders_generate_empty(const int *psk_cipher_suites, size_t psk_ci int tls13_psk_binders_generate( const int *psk_cipher_suites, size_t psk_cipher_suites_cnt, + const uint8_t *psk_identity_types, const uint8_t *psk_keys, size_t psk_keys_len, const uint8_t *truncated_client_hello, size_t truncated_client_hello_len, uint8_t *binders, size_t *binders_len) @@ -1028,11 +1026,16 @@ int tls13_psk_binders_generate( const DIGEST *digest; const uint8_t *psk_key; size_t psk_key_len; + const char *binder_label = "ext binder"; if (tls13_cipher_suite_get(psk_cipher_suites[i], &cipher, &digest) != 1) { error_print(); return -1; } + if (psk_identity_types + && psk_identity_types[i] == TLS13_PSK_IDENTITY_RESUMPTION) { + binder_label = "res binder"; + } if (digest->digest_size != sizeof(secret)) { error_print(); @@ -1058,7 +1061,7 @@ int tls13_psk_binders_generate( // [1] tls13_hkdf_extract(digest, zeros, psk_key, early_secret); // [2] - tls13_derive_secret(early_secret, "res binder", &null_dgst_ctx, binder_key); + tls13_derive_secret(early_secret, binder_label, &null_dgst_ctx, binder_key); tls13_compute_verify_data(binder_key, &dgst_ctx, binder, &binderlen); @@ -1069,10 +1072,10 @@ int tls13_psk_binders_generate( return 1; } -int tls13_psk_binder_verify(const DIGEST *digest, +static int tls13_psk_binder_verify_with_label(const DIGEST *digest, const uint8_t *pre_shared_key, size_t pre_shared_key_len, const DIGEST_CTX *truncated_client_hello_dgst_ctx, - const uint8_t *binder, size_t binderlen) + const uint8_t *binder, size_t binderlen, const char *binder_label) { uint8_t secret[32] = {0}; uint8_t *zeros = secret; @@ -1090,7 +1093,7 @@ int tls13_psk_binder_verify(const DIGEST *digest, // [1] tls13_hkdf_extract(digest, zeros, pre_shared_key, early_secret); // [2] - tls13_derive_secret(early_secret, "res binder", &null_dgst_ctx, binder_key); + tls13_derive_secret(early_secret, binder_label, &null_dgst_ctx, binder_key); tls13_compute_verify_data(binder_key, truncated_client_hello_dgst_ctx, local_binder, &local_binder_len); @@ -1101,6 +1104,15 @@ int tls13_psk_binder_verify(const DIGEST *digest, return 1; } +int tls13_psk_binder_verify(const DIGEST *digest, + const uint8_t *pre_shared_key, size_t pre_shared_key_len, + const DIGEST_CTX *truncated_client_hello_dgst_ctx, + const uint8_t *binder, size_t binderlen) +{ + return tls13_psk_binder_verify_with_label(digest, pre_shared_key, pre_shared_key_len, + truncated_client_hello_dgst_ctx, binder, binderlen, "res binder"); +} + int tls13_client_pre_shared_key_ext_to_bytes(const uint8_t *identities, size_t identitieslen, const uint8_t *binders, size_t binderslen, uint8_t **out, size_t *outlen) { @@ -1288,7 +1300,9 @@ int tls13_add_pre_shared_key(TLS_CONNECT *conn, error_print(); return -1; } - conn->psk_cipher_suites[conn->psk_cipher_suites_cnt++] = psk_cipher_suite; + conn->psk_cipher_suites[conn->psk_cipher_suites_cnt] = psk_cipher_suite; + conn->psk_identity_types[conn->psk_cipher_suites_cnt] = TLS13_PSK_IDENTITY_EXTERNAL; + conn->psk_cipher_suites_cnt++; return 1; } @@ -1343,8 +1357,8 @@ int tls13_process_client_pre_shared_key_external(TLS_CONNECT *conn, size_t identitieslen; const uint8_t *binders; size_t binderslen; - const uint8_t *truncated_binders; - size_t truncated_binderslen; + const uint8_t *truncated_client_hello; + size_t truncated_client_hello_len; size_t i; if (!conn || !ext_data || !ext_datalen) { @@ -1364,21 +1378,12 @@ int tls13_process_client_pre_shared_key_external(TLS_CONNECT *conn, return -1; } - // truncate client_hello => plain_record - memcpy(conn->plain_record, conn->record, conn->recordlen); - conn->plain_recordlen = conn->recordlen; - truncated_binders = conn->plain_record + (binders - conn->record); - truncated_binderslen = binderslen; - while (truncated_binderslen) { - const uint8_t *truncated_binder; - size_t truncated_binderlen; - if (tls_uint8array_from_bytes(&truncated_binder, &truncated_binderlen, - &truncated_binders, &truncated_binderslen) != 1) { - error_print(); - return -1; - } - memset((uint8_t *)truncated_binder, 0, truncated_binderlen); + if (binders < conn->record + TLS_RECORD_HEADER_SIZE + 2) { + error_print(); + return -1; } + truncated_client_hello = conn->record + TLS_RECORD_HEADER_SIZE; + truncated_client_hello_len = (size_t)((binders - 2) - truncated_client_hello); // search psk for (i = 0; identitieslen; i++) { @@ -1423,12 +1428,12 @@ int tls13_process_client_pre_shared_key_external(TLS_CONNECT *conn, // verify binder if (digest_init(&dgst_ctx, conn->digest) != 1 - || digest_update(&dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + || digest_update(&dgst_ctx, truncated_client_hello, truncated_client_hello_len) != 1) { error_print(); return -1; } - if ((ret = tls13_psk_binder_verify(conn->digest, matched_psk, matched_psk_len, - &dgst_ctx, binder, binderlen)) < 0) { + if ((ret = tls13_psk_binder_verify_with_label(conn->digest, matched_psk, matched_psk_len, + &dgst_ctx, binder, binderlen, "ext binder")) < 0) { error_print(); return -1; } else if (ret == 0) { @@ -1456,8 +1461,8 @@ int tls13_process_client_pre_shared_key_from_ticket(TLS_CONNECT *conn, size_t identitieslen; const uint8_t *binders; size_t binderslen; - const uint8_t *truncated_binders; - size_t truncated_binderslen; + const uint8_t *truncated_client_hello; + size_t truncated_client_hello_len; size_t i; if (!conn || !ext_data || !ext_datalen) { @@ -1485,21 +1490,12 @@ int tls13_process_client_pre_shared_key_from_ticket(TLS_CONNECT *conn, return -1; } - // truncate client_hello - memcpy(conn->plain_record, conn->record, conn->recordlen); - conn->plain_recordlen = conn->recordlen; - truncated_binders = conn->plain_record + (binders - conn->record); - truncated_binderslen = binderslen; - while (truncated_binderslen) { - const uint8_t *truncated_binder; - size_t truncated_binderlen; - if (tls_uint8array_from_bytes(&truncated_binder, &truncated_binderlen, - &truncated_binders, &truncated_binderslen) != 1) { - error_print(); - return -1; - } - memset((uint8_t *)truncated_binder, 0, truncated_binderlen); + if (binders < conn->record + TLS_RECORD_HEADER_SIZE + 2) { + error_print(); + return -1; } + truncated_client_hello = conn->record + TLS_RECORD_HEADER_SIZE; + truncated_client_hello_len = (size_t)((binders - 2) - truncated_client_hello); // search psk for (i = 0; identitieslen; i++) { @@ -1552,7 +1548,7 @@ int tls13_process_client_pre_shared_key_from_ticket(TLS_CONNECT *conn, // verify binder if (digest_init(&dgst_ctx, conn->digest) != 1 - || digest_update(&dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + || digest_update(&dgst_ctx, truncated_client_hello, truncated_client_hello_len) != 1) { error_print(); return -1; }