From e180ed8e9b742e38441e4f903f8d8aa58dd2ced6 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 16 Jun 2026 23:03:11 +0800 Subject: [PATCH] Clean TLS code --- CMakeLists.txt | 2 +- include/gmssl/tls.h | 8 +- include/gmssl/version.h | 2 +- src/tls.c | 34 +- src/tls12.c | 3028 +++++++++++++++++++-------------------- src/tls13.c | 36 +- src/tls_ext.c | 42 + src/tls_psk.c | 8 +- src/tls_trace.c | 18 + src/x509_ext.c | 2 - tools/tlcp_help.h | 4 + tools/tls12_help.h | 5 + tools/tls13_client.c | 2 +- tools/tls13_server.c | 2 +- 14 files changed, 1592 insertions(+), 1601 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d24c5e96..10a2a46e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -818,7 +818,7 @@ endif() # set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_VENDOR "GmSSL develop team") -set(CPACK_PACKAGE_VERSION "3.2.0-dev.1063") +set(CPACK_PACKAGE_VERSION "3.2.0-dev.1064") set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_NSIS_MODIFY_PATH ON) include(CPack) diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index 5d4ce366..7f63e219 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -1816,6 +1816,7 @@ int tls_trusted_authorities_print(FILE *fp, int fmt, int ind, const uint8_t *ext +int tls_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest); @@ -1823,7 +1824,6 @@ int tls_trusted_authorities_print(FILE *fp, int fmt, int ind, const uint8_t *ext // TLS 1.3 cipher/key related int tls13_random_generate(uint8_t random[32]); -int tls13_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest); int tls13_padding_len_rand(size_t *padding_len); int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], @@ -1912,6 +1912,7 @@ int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable); // Extensions + // 0. server_name (SNI): in ClientHello, EncryptedExtensions int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len); // client only int tls_server_name_ext_to_bytes(const uint8_t *host_name, size_t host_name_len, uint8_t **out, size_t *outlen); @@ -2010,6 +2011,11 @@ int tls_process_supported_groups(const uint8_t *ext_data, size_t ext_datalen, // 11. ec_point_format +extern const int ec_point_formats[]; +extern size_t ec_point_formats_cnt; + +int tls_ec_point_formats_support_uncompressed(const uint8_t *ext_data, size_t ext_datalen); + int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, uint8_t **out, size_t *outlen); int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 32156d86..c0d7deb8 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.1063" +#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1064" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/src/tls.c b/src/tls.c index 4a9f618d..401ecf65 100644 --- a/src/tls.c +++ b/src/tls.c @@ -278,6 +278,32 @@ int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen) return 1; } +int tls_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest) +{ + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + case TLS_cipher_sm4_gcm_sm3: + case TLS_cipher_sm4_ccm_sm3: + *cipher = BLOCK_CIPHER_sm4(); + *digest = DIGEST_sm3(); + break; + + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + case TLS_cipher_aes_128_gcm_sha256: + case TLS_cipher_aes_128_ccm_sha256: + *cipher = BLOCK_CIPHER_aes128(); + *digest = DIGEST_sha256(); + break; + default: + error_print(); + return -1; + } + return 1; +} + int tls_cbc_encrypt(const HMAC_CTX *inited_hmac_ctx, const BLOCK_CIPHER_KEY *enc_key, const uint8_t seq_num[8], const uint8_t header[5], const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) @@ -3321,8 +3347,6 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) } - - return 1; } @@ -3377,3 +3401,9 @@ int tls_get_verify_result(TLS_CONNECT *conn, int *result) *result = conn->verify_result; return 1; } + +void tls_clean_record(TLS_CONNECT *conn) +{ + conn->record_offset = 0; + conn->recordlen = 0; +} diff --git a/src/tls12.c b/src/tls12.c index 43217e0d..dcb062de 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -23,6 +23,10 @@ #include + + + + const int tls12_supported_groups[] = { TLS_curve_sm2p256v1, #ifdef ENABLE_SECP256R1 @@ -56,66 +60,128 @@ const size_t tls12_cipher_suites_cnt = sizeof(tls12_cipher_suites)/sizeof(tls12_cipher_suites[0]); -int tls_named_curve_oid(int named_curve) -{ - switch (named_curve) { - case TLS_curve_secp256r1: return OID_secp256r1; - case TLS_curve_sm2p256v1: return OID_sm2; - } - return OID_undef; -} -int tls_named_curve_from_oid(int oid) -{ - switch (oid) { - case OID_secp256r1: return TLS_curve_secp256r1; - case OID_sm2: return TLS_curve_sm2p256v1; - } - return 0; -} +// Handshake messages - -int tls12_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen, - const uint8_t *point_octets, size_t point_octets_len) +int tls12_record_set_handshake_server_key_exchange(uint8_t *record, size_t *recordlen, + int server_key_exchange_alg, const uint8_t *server_ecdh_params, size_t server_ecdh_params_len, + int sig_alg, const uint8_t *sig, size_t siglen) { - int type = TLS_handshake_client_key_exchange; + const int type = TLS_handshake_server_key_exchange; uint8_t *p = tls_handshake_data(tls_record_data(record)); size_t len = 0; - if (point_octets_len != 65) { + if (!record || !recordlen || !sig || !siglen) { error_print(); return -1; } - tls_uint8array_to_bytes(point_octets, (uint8_t)point_octets_len, &p, &len); + if (!tls_signature_scheme_name(sig_alg)) { + error_print(); + return -1; + } + if (siglen > TLS_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + + switch (server_key_exchange_alg) { + case TLS_server_key_exchange_ecdhe: + if (!server_ecdh_params || !server_ecdh_params_len) { + error_print(); + return -1; + } + tls_array_to_bytes(server_ecdh_params, server_ecdh_params_len, &p, &len); + break; + case TLS_server_key_exchange_ecc: + if (server_ecdh_params || server_ecdh_params_len) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + + tls_uint16_to_bytes((uint16_t)sig_alg, &p, &len); + tls_uint16array_to_bytes(sig, siglen, &p, &len); tls_record_set_handshake(record, recordlen, type, NULL, len); return 1; } -int tls12_record_get_handshake_client_key_exchange(const uint8_t *record, - const uint8_t **point_octets, size_t *point_octets_len) +int tls12_record_get_handshake_server_key_exchange(const uint8_t *record, + int server_key_exchange_alg, const uint8_t **server_ecdh_params, size_t *server_ecdh_params_len, + int *sig_alg, const uint8_t **sig, size_t *siglen) { int type; const uint8_t *p; size_t len; + uint16_t alg; - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_client_key_exchange) { + if (!record || !sig_alg || !sig || !siglen) { error_print(); return -1; } - if (tls_uint8array_from_bytes(point_octets, point_octets_len, &p, &len) != 1) { + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { error_print(); return -1; } - if (*point_octets_len != 65) { + if (type != TLS_handshake_server_key_exchange) { + error_print(); + return 0; + } + + switch (server_key_exchange_alg) { + case TLS_server_key_exchange_ecdhe: + if (!server_ecdh_params || !server_ecdh_params_len) { + error_print(); + return -1; + } + *server_ecdh_params = p; + *server_ecdh_params_len = len; + { + int key_exchange_group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (tls_server_ecdh_params_from_bytes(&key_exchange_group, + &key_exchange, &key_exchange_len, &p, &len) != 1) { + error_print(); + return -1; + } + } + *server_ecdh_params_len -= len; + break; + + case TLS_server_key_exchange_ecc: + if (server_ecdh_params || server_ecdh_params_len) { + error_print(); + return -1; + } + break; + + default: error_print(); return -1; } - if (len) { + + if (tls_uint16_from_bytes(&alg, &p, &len) != 1 + || tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { error_print(); return -1; } + if (!tls_signature_scheme_name(alg)) { + error_print(); + return -1; + } + if (!siglen) { + error_print(); + return -1; + } + *sig_alg = alg; + return 1; } @@ -217,25 +283,83 @@ int tls12_record_get_handshake_certificate_request(const uint8_t *record, return 1; } -void tls_clean_record(TLS_CONNECT *conn) +int tls12_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen, + const uint8_t *point_octets, size_t point_octets_len) { - conn->record_offset = 0; - conn->recordlen = 0; -} - - -int tls_handshake_init(TLS_CONNECT *conn) -{ - - //sm3_init(&conn->sm3_ctx); - digest_init(&conn->dgst_ctx, DIGEST_sm3()); + int type = TLS_handshake_client_key_exchange; + uint8_t *p = tls_handshake_data(tls_record_data(record)); + size_t len = 0; + if (point_octets_len != 65) { + error_print(); + return -1; + } + tls_uint8array_to_bytes(point_octets, (uint8_t)point_octets_len, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); return 1; } -const int ec_point_formats[] = { TLS_point_uncompressed }; -size_t ec_point_formats_cnt = sizeof(ec_point_formats)/sizeof(ec_point_formats[0]); +int tls12_record_get_handshake_client_key_exchange(const uint8_t *record, + const uint8_t **point_octets, size_t *point_octets_len) +{ + int type; + const uint8_t *p; + size_t len; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_client_key_exchange) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(point_octets, point_octets_len, &p, &len) != 1) { + error_print(); + return -1; + } + if (*point_octets_len != 65) { + error_print(); + return -1; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + int tls12_ctx_set_renegotiation_info(TLS_CTX *ctx, int enable) { @@ -290,6 +414,379 @@ static int tls12_cipher_suites_include_empty_renegotiation_info_scsv( + + +int tls_curve_match_cipher_suite(int named_curve, int cipher_suite) +{ + switch (named_curve) { + case TLS_curve_sm2p256v1: + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + break; + default: + error_print(); + return -1; + } + break; + case TLS_curve_secp256r1: + switch (cipher_suite) { + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + break; + default: + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite) +{ + switch (sig_alg) { + case TLS_sig_sm2sig_sm3: + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecc_sm4_gcm_sm3: + break; + default: + error_print(); + return -1; + } + break; + case TLS_sig_ecdsa_secp256r1_sha256: + switch (cipher_suite) { + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + break; + default: + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +static int tls12_cipher_suite_match_cert_group(int cipher_suite, int cert_group) +{ + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + return cert_group == TLS_curve_sm2p256v1; + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + return cert_group == TLS_curve_secp256r1; + default: + return 0; + } +} + +static int tls12_signature_scheme_match_cert_group(int sig_alg, int cert_group) +{ + return tls_signature_scheme_group_oid(sig_alg) == tls_named_curve_oid(cert_group); +} + +static int tls12_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite) +{ + switch (sig_alg) { + case TLS_sig_sm2sig_sm3: + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + return 1; + } + break; + case TLS_sig_ecdsa_secp256r1_sha256: + switch (cipher_suite) { + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + return 1; + } + break; + } + return 0; +} + +static int tls12_key_exchange_group_match_cipher_suite(int group, int cipher_suite) +{ + switch (cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + return group == TLS_curve_sm2p256v1; + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: + return group == TLS_curve_secp256r1; + default: + return 0; + } +} + + + + + + + + +static int tls12_select_common_cipher_suites(const uint8_t *client_ciphers, size_t client_ciphers_len, + const int *server_ciphers, size_t server_ciphers_cnt, + int *common_ciphers, size_t *common_ciphers_cnt, size_t max_cnt) +{ + size_t i; + + if (!client_ciphers || !client_ciphers_len + || !server_ciphers || !server_ciphers_cnt + || !common_ciphers || !common_ciphers_cnt || !max_cnt) { + error_print(); + return -1; + } + + *common_ciphers_cnt = 0; + for (i = 0; i < server_ciphers_cnt && *common_ciphers_cnt < max_cnt; i++) { + const uint8_t *p = client_ciphers; + size_t len = client_ciphers_len; + while (len) { + uint16_t cipher; + if (tls_uint16_from_bytes(&cipher, &p, &len) != 1) { + error_print(); + return -1; + } + if (cipher == server_ciphers[i]) { + common_ciphers[(*common_ciphers_cnt)++] = server_ciphers[i]; + break; + } + } + } + + return *common_ciphers_cnt ? 1 : 0; +} + +static int tls12_cert_chain_get_end_entity_group(const uint8_t *cert_chain, size_t cert_chain_len, int *group) +{ + const uint8_t *cert; + size_t certlen; + X509_KEY public_key; + + if (!cert_chain || !cert_chain_len || !group) { + error_print(); + return -1; + } + if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + return -1; + } + if (public_key.algor != OID_ec_public_key) { + error_print(); + return -1; + } + if ((*group = tls_named_curve_from_oid(public_key.algor_param)) == 0) { + error_print(); + return -1; + } + return 1; +} + +// 应该去掉 +static int tls12_public_key_get_group(const X509_KEY *public_key, int *group) +{ + if (!public_key || !group) { + error_print(); + return -1; + } + if (public_key->algor != OID_ec_public_key) { + error_print(); + return -1; + } + if ((*group = tls_named_curve_from_oid(public_key->algor_param)) == 0) { + error_print(); + return -1; + } + return 1; +} + +// 应该去掉 +static int tls12_select_key_exchange_group(const int *groups, size_t groups_cnt, + int cipher_suite, int *selected_group) +{ + size_t i; + + if (!groups || !groups_cnt || !selected_group) { + error_print(); + return -1; + } + for (i = 0; i < groups_cnt; i++) { + if (tls12_key_exchange_group_match_cipher_suite(groups[i], cipher_suite)) { + *selected_group = groups[i]; + return 1; + } + } + return 0; +} + +// 这个函数的名字最好换一下 +static int tls12_select_parameters(TLS_CONNECT *conn, + const int *common_cipher_suites, size_t common_cipher_suites_cnt, + const int *common_supported_groups, size_t common_supported_groups_cnt, + const int *common_signature_algorithms, size_t common_signature_algorithms_cnt, + const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, + const uint8_t *host_name, size_t host_name_len) +{ + const uint8_t *cert_chains = conn->ctx->cert_chains; + size_t cert_chains_len = conn->ctx->cert_chains_len; + size_t cert_chain_idx; + + if (!conn || !common_cipher_suites || !common_cipher_suites_cnt + || !common_supported_groups || !common_supported_groups_cnt + || !common_signature_algorithms || !common_signature_algorithms_cnt) { + error_print(); + return -1; + } + if (!cert_chains || !cert_chains_len) { + error_print(); + return -1; + } + + for (cert_chain_idx = 1; cert_chains_len; cert_chain_idx++) { + const uint8_t *cert_chain; + size_t cert_chain_len; + const uint8_t *cert; + size_t certlen; + int cert_group; + size_t i; + int ret; + + if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len, + &cert_chains, &cert_chains_len) != 1) { + error_print(); + return -1; + } + if (tls12_cert_chain_get_end_entity_group(cert_chain, cert_chain_len, &cert_group) != 1) { + error_print(); + return -1; + } + if (!tls_type_is_in_list(cert_group, common_supported_groups, common_supported_groups_cnt)) { + continue; + } + if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1) { + error_print(); + return -1; + } + if (host_name && host_name_len) { + if ((ret = tls_cert_match_server_name(cert, certlen, host_name, host_name_len)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + continue; + } + } + if (signature_algorithms_cert && signature_algorithms_cert_cnt) { + if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, + signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + continue; + } + } + + for (i = 0; i < common_cipher_suites_cnt; i++) { + size_t j; + int cipher_suite = common_cipher_suites[i]; + int key_exchange_group; + + if (!tls12_cipher_suite_match_cert_group(cipher_suite, cert_group)) { + continue; + } + if ((ret = tls12_select_key_exchange_group(common_supported_groups, + common_supported_groups_cnt, cipher_suite, &key_exchange_group)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + continue; + } + + for (j = 0; j < common_signature_algorithms_cnt; j++) { + int sig_alg = common_signature_algorithms[j]; + + if (!tls12_signature_scheme_match_cert_group(sig_alg, cert_group)) { + continue; + } + if (!tls12_signature_scheme_match_cipher_suite(sig_alg, cipher_suite)) { + continue; + } + + conn->cipher_suite = cipher_suite; + conn->cert_chain = cert_chain; + conn->cert_chain_len = cert_chain_len; + conn->cert_chain_idx = cert_chain_idx; + conn->sig_alg = sig_alg; + conn->key_exchange_group = key_exchange_group; + return 1; + } + } + } + + warning_print(); + return 0; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// TODO: Client Handshake + int tls_send_client_hello(TLS_CONNECT *conn) { int ret; @@ -417,378 +914,490 @@ int tls_send_client_hello(TLS_CONNECT *conn) return 1; } -/* -const int server_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3 }; -const size_t server_ciphers_cnt = 1; -*/ -const int curve = TLS_curve_sm2p256v1; - -static int tls12_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest) +int tls_recv_server_hello(TLS_CONNECT *conn) { - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - *cipher = BLOCK_CIPHER_sm4(); - *digest = DIGEST_sm3(); - break; -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) && defined(ENABLE_SECP256R1) - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_aes_128_ccm: -#endif - *cipher = BLOCK_CIPHER_aes128(); - *digest = DIGEST_sha256(); - break; -#endif - default: + int ret; + int protocol; + int cipher_suite; + const uint8_t *server_random; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *exts; + size_t extslen; + + const uint8_t *ec_point_formats = NULL; + size_t ec_point_formats_len = 0; + int server_name = 0; + int trusted_ca_keys = 0; + int renegotiation_info = 0; + + if(conn->verbose) + tls_trace("recv ServerHello\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + if (conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + if ((ret = tls_record_get_handshake_server_hello(conn->record, + &protocol, &server_random, &session_id, &session_id_len, &cipher_suite, + &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // version + if (protocol != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // random + memcpy(conn->server_random, server_random, 32); + + // session_id + memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + + // cipher_suite + if (tls_type_is_in_list(cipher_suite, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + conn->cipher_suite = cipher_suite; + + if (tls_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + if (digest_init(&conn->dgst_ctx, conn->digest) != 1) { error_print(); return -1; } + + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + + switch (ext_type) { + case TLS_extension_ec_point_formats: + if (ec_point_formats) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + ec_point_formats = ext_data; + ec_point_formats_len = ext_datalen; + break; + case TLS_extension_server_name: + if (!conn->server_name || server_name || ext_datalen) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + server_name = 1; + break; + case TLS_extension_trusted_ca_keys: + if (!conn->ctx->trusted_ca_keys || trusted_ca_keys || ext_datalen) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + trusted_ca_keys = 1; + conn->trusted_ca_keys = 1; + break; + case TLS_extension_renegotiation_info: + if ((!conn->ctx->renegotiation_info && !conn->ctx->empty_renegotiation_info_scsv) + || renegotiation_info) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if ((ret = tls12_renegotiation_info_ext_is_empty(ext_data, ext_datalen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + renegotiation_info = 1; + conn->secure_renegotiation = 1; + break; + default: + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } + + if ((conn->ctx->renegotiation_info || conn->ctx->empty_renegotiation_info_scsv) + && !renegotiation_info) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + + if (ec_point_formats) { + if ((ret = tls_ec_point_formats_support_uncompressed(ec_point_formats, ec_point_formats_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } + + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } + if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); + + 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, "ServerHello", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + return 1; } -static int tls12_cipher_suite_match_cert_group(int cipher_suite, int cert_group) +int tls_recv_server_certificate(TLS_CONNECT *conn) { - switch (cipher_suite) { + int ret; + int verify_result = 0; + const uint8_t *server_cert; + size_t server_cert_len; + X509_KEY server_sign_key; + int server_sig_alg = 0; + int server_group; + int cert_sig_alg = 0; + const int *signature_algorithms_cert = NULL; + size_t signature_algorithms_cert_cnt = 0; + + + if(conn->verbose) + tls_trace("recv server Certificate\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + if(conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + if ((ret = tls_record_get_handshake_certificate(conn->record, + conn->peer_cert_chain, &conn->peer_cert_chain_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return 0; + } + if (!conn->peer_cert_chain_len) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + + 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, "Certificate", &conn->dgst_ctx); + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + + // server_sign_key + if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, + &server_cert, &server_cert_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + if (x509_cert_get_subject_public_key(server_cert, server_cert_len, &server_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + + if (tls12_public_key_get_group(&server_sign_key, &server_group) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + + // check server certificate matches negotiated cipher_suite + if (!tls12_cipher_suite_match_cert_group(conn->cipher_suite, server_group)) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + switch (conn->cipher_suite) { case TLS_cipher_ecdhe_sm4_cbc_sm3: case TLS_cipher_ecdhe_sm4_gcm_sm3: - return cert_group == TLS_curve_sm2p256v1; -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) && defined(ENABLE_SECP256R1) + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecc_sm4_gcm_sm3: + server_sig_alg = TLS_sig_sm2sig_sm3; + break; case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: #ifdef ENABLE_AES_CCM case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: #endif - return cert_group == TLS_curve_secp256r1; -#endif + server_sig_alg = TLS_sig_ecdsa_secp256r1_sha256; + break; default: + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + + // check server certificate matches ClientHello.supported_groups + if (conn->ctx->supported_groups_cnt) { + if (!tls_type_is_in_list(server_group, conn->ctx->supported_groups, + conn->ctx->supported_groups_cnt)) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + } + + // check server certificate matches ClientHello.signature_algorithms + if (conn->ctx->signature_algorithms_cnt) { + if ((ret = tls_cert_match_signature_algorithms(server_cert, server_cert_len, + conn->ctx->signature_algorithms, + conn->ctx->signature_algorithms_cnt, + &cert_sig_alg)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + if (!tls12_signature_scheme_match_cert_group(cert_sig_alg, server_group) + || !tls12_signature_scheme_match_cipher_suite(cert_sig_alg, conn->cipher_suite)) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + server_sig_alg = cert_sig_alg; + } + + // check certificate-chain signatures match ClientHello.signature_algorithms_cert + if (conn->signature_algorithms_cert) { + signature_algorithms_cert = conn->ctx->signature_algorithms; + signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; + } else if (conn->ctx->signature_algorithms_cnt) { + signature_algorithms_cert = conn->ctx->signature_algorithms; + signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; + } + if (signature_algorithms_cert && signature_algorithms_cert_cnt) { + if ((ret = tls_cert_chain_match_signature_algorithms_cert( + conn->peer_cert_chain, conn->peer_cert_chain_len, + signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + } + + // check server certificate matches ClientHello.server_name + if (conn->server_name) { + if ((ret = tls_cert_match_server_name(server_cert, server_cert_len, + conn->host_name, conn->host_name_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + } + + conn->signature_algorithms[0] = server_sig_alg; + conn->signature_algorithms_cnt = 1; + + if (conn->client_certs_len) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10); + + // verify server Certificate + if (conn->ctx->cacertslen) { + if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, + conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { + error_print(); + conn->verify_result = verify_result; + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + } + conn->verify_result = verify_result; + + return 1; +} + +int tls_recv_server_key_exchange(TLS_CONNECT *conn) +{ + int ret; + + // 这部分是被签名的值,必须要拿到 + const uint8_t *server_ecdh_params; + size_t server_ecdh_params_len; + + + const uint8_t *server_key_exchange; + size_t server_key_exchange_len; + int sig_alg; + const uint8_t *sig; + size_t siglen; + + // verify ServerKeyExchange + X509_KEY server_sign_key; + + int server_cert_index = 0; + const uint8_t *server_cert; + size_t server_cert_len; + + X509_SIGN_CTX sign_ctx; + const void *sign_args = NULL; + size_t sign_argslen = 0; + + if(conn->verbose) tls_trace("recv ServerKeyExchange\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); + + + if ((ret = tls12_record_get_handshake_server_key_exchange(conn->record, + TLS_server_key_exchange_ecdhe, &server_ecdh_params, &server_ecdh_params_len, + &sig_alg, &sig, &siglen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); return 0; } -} + 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, "ServerKeyExchange", &conn->dgst_ctx); -static int tls12_signature_scheme_match_cert_group(int sig_alg, int cert_group) -{ - return tls_signature_scheme_group_oid(sig_alg) == tls_named_curve_oid(cert_group); -} + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + if (tls_signature_scheme_match_cipher_suite(sig_alg, conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + if (conn->client_certs_len) + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + + + if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, + server_cert_index, &server_cert, &server_cert_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + if (x509_cert_get_subject_public_key(server_cert, server_cert_len, &server_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } -static int tls12_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite) -{ switch (sig_alg) { case TLS_sig_sm2sig_sm3: - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - return 1; + if (server_sign_key.algor != OID_ec_public_key + || server_sign_key.algor_param != OID_sm2) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; } break; case TLS_sig_ecdsa_secp256r1_sha256: -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) && defined(ENABLE_SECP256R1) - switch (cipher_suite) { - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: -#endif - return 1; - } -#endif - break; - } - return 0; -} - -static int tls12_key_exchange_group_match_cipher_suite(int group, int cipher_suite) -{ - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - return group == TLS_curve_sm2p256v1; -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) && defined(ENABLE_SECP256R1) - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: -#endif - return group == TLS_curve_secp256r1; -#endif - default: - return 0; - } -} - -static int tls12_select_common_cipher_suites(const uint8_t *client_ciphers, size_t client_ciphers_len, - const int *server_ciphers, size_t server_ciphers_cnt, - int *common_ciphers, size_t *common_ciphers_cnt, size_t max_cnt) -{ - size_t i; - - if (!client_ciphers || !client_ciphers_len - || !server_ciphers || !server_ciphers_cnt - || !common_ciphers || !common_ciphers_cnt || !max_cnt) { - error_print(); - return -1; - } - - *common_ciphers_cnt = 0; - for (i = 0; i < server_ciphers_cnt && *common_ciphers_cnt < max_cnt; i++) { - const uint8_t *p = client_ciphers; - size_t len = client_ciphers_len; - while (len) { - uint16_t cipher; - if (tls_uint16_from_bytes(&cipher, &p, &len) != 1) { - error_print(); - return -1; - } - if (cipher == server_ciphers[i]) { - common_ciphers[(*common_ciphers_cnt)++] = server_ciphers[i]; - break; - } - } - } - - return *common_ciphers_cnt ? 1 : 0; -} - -// support_uncompressed -static int tls_ec_point_formats_support_uncompressed(const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *formats; - size_t formats_len; - int uncompressed = 0; - - if (tls_uint8array_from_bytes(&formats, &formats_len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (!formats_len) { - error_print(); - return -1; - } - - while (formats_len) { - uint8_t format; - if (tls_uint8_from_bytes(&format, &formats, &formats_len) != 1) { - error_print(); - return -1; - } - if (!tls_ec_point_format_name(format)) { - error_print(); - return -1; - } - if (format == TLS_point_uncompressed) { - uncompressed = 1; - } - } - - if (!uncompressed) { - error_print(); - return 0; - } - return 1; -} - -static int tls12_cert_chain_get_end_entity_group(const uint8_t *cert_chain, size_t cert_chain_len, int *group) -{ - const uint8_t *cert; - size_t certlen; - X509_KEY public_key; - - if (!cert_chain || !cert_chain_len || !group) { - error_print(); - return -1; - } - if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { - error_print(); - return -1; - } - if (public_key.algor != OID_ec_public_key) { - error_print(); - return -1; - } - if ((*group = tls_named_curve_from_oid(public_key.algor_param)) == 0) { - error_print(); - return -1; - } - return 1; -} - -static int tls12_public_key_get_group(const X509_KEY *public_key, int *group) -{ - if (!public_key || !group) { - error_print(); - return -1; - } - if (public_key->algor != OID_ec_public_key) { - error_print(); - return -1; - } - if ((*group = tls_named_curve_from_oid(public_key->algor_param)) == 0) { - error_print(); - return -1; - } - return 1; -} - -static int tls12_select_key_exchange_group(const int *groups, size_t groups_cnt, - int cipher_suite, int *selected_group) -{ - size_t i; - - if (!groups || !groups_cnt || !selected_group) { - error_print(); - return -1; - } - for (i = 0; i < groups_cnt; i++) { - if (tls12_key_exchange_group_match_cipher_suite(groups[i], cipher_suite)) { - *selected_group = groups[i]; - return 1; - } - } - return 0; -} - -// 这个函数的名字最好换一下 -static int tls12_select_parameters(TLS_CONNECT *conn, - const int *common_cipher_suites, size_t common_cipher_suites_cnt, - const int *common_supported_groups, size_t common_supported_groups_cnt, - const int *common_signature_algorithms, size_t common_signature_algorithms_cnt, - const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, - const uint8_t *host_name, size_t host_name_len) -{ - const uint8_t *cert_chains = conn->ctx->cert_chains; - size_t cert_chains_len = conn->ctx->cert_chains_len; - size_t cert_chain_idx; - - if (!conn || !common_cipher_suites || !common_cipher_suites_cnt - || !common_supported_groups || !common_supported_groups_cnt - || !common_signature_algorithms || !common_signature_algorithms_cnt) { - error_print(); - return -1; - } - if (!cert_chains || !cert_chains_len) { - error_print(); - return -1; - } - - for (cert_chain_idx = 1; cert_chains_len; cert_chain_idx++) { - const uint8_t *cert_chain; - size_t cert_chain_len; - const uint8_t *cert; - size_t certlen; - int cert_group; - size_t i; - int ret; - - if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len, - &cert_chains, &cert_chains_len) != 1) { - error_print(); - return -1; - } - if (tls12_cert_chain_get_end_entity_group(cert_chain, cert_chain_len, &cert_group) != 1) { - error_print(); - return -1; - } - if (!tls_type_is_in_list(cert_group, common_supported_groups, common_supported_groups_cnt)) { - continue; - } - if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1) { - error_print(); - return -1; - } - if (host_name && host_name_len) { - if ((ret = tls_cert_match_server_name(cert, certlen, host_name, host_name_len)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - if (signature_algorithms_cert && signature_algorithms_cert_cnt) { - if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, - signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - - for (i = 0; i < common_cipher_suites_cnt; i++) { - size_t j; - int cipher_suite = common_cipher_suites[i]; - int key_exchange_group; - - if (!tls12_cipher_suite_match_cert_group(cipher_suite, cert_group)) { - continue; - } - if ((ret = tls12_select_key_exchange_group(common_supported_groups, - common_supported_groups_cnt, cipher_suite, &key_exchange_group)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - - for (j = 0; j < common_signature_algorithms_cnt; j++) { - int sig_alg = common_signature_algorithms[j]; - - if (!tls12_signature_scheme_match_cert_group(sig_alg, cert_group)) { - continue; - } - if (!tls12_signature_scheme_match_cipher_suite(sig_alg, cipher_suite)) { - continue; - } - - conn->cipher_suite = cipher_suite; - conn->cert_chain = cert_chain; - conn->cert_chain_len = cert_chain_len; - conn->cert_chain_idx = cert_chain_idx; - conn->sig_alg = sig_alg; - conn->key_exchange_group = key_exchange_group; - return 1; - } - } - } - - warning_print(); - return 0; -} - -int tls12_record_set_handshake_server_key_exchange(uint8_t *record, size_t *recordlen, - int server_key_exchange_alg, const uint8_t *server_ecdh_params, size_t server_ecdh_params_len, - int sig_alg, const uint8_t *sig, size_t siglen) -{ - const int type = TLS_handshake_server_key_exchange; - uint8_t *p = tls_handshake_data(tls_record_data(record)); - size_t len = 0; - - if (!record || !recordlen || !sig || !siglen) { - error_print(); - return -1; - } - if (!tls_signature_scheme_name(sig_alg)) { - error_print(); - return -1; - } - if (siglen > TLS_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - - switch (server_key_exchange_alg) { - case TLS_server_key_exchange_ecdhe: - if (!server_ecdh_params || !server_ecdh_params_len) { - error_print(); - return -1; - } - tls_array_to_bytes(server_ecdh_params, server_ecdh_params_len, &p, &len); - break; - case TLS_server_key_exchange_ecc: - if (server_ecdh_params || server_ecdh_params_len) { + if (server_sign_key.algor != OID_ec_public_key + || server_sign_key.algor_param != OID_secp256r1) { error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); return -1; } break; @@ -797,88 +1406,469 @@ int tls12_record_set_handshake_server_key_exchange(uint8_t *record, size_t *reco return -1; } - tls_uint16_to_bytes((uint16_t)sig_alg, &p, &len); - tls_uint16array_to_bytes(sig, siglen, &p, &len); + if (server_sign_key.algor == OID_ec_public_key && server_sign_key.algor_param == OID_sm2) { + sign_args = SM2_DEFAULT_ID; + sign_argslen = SM2_DEFAULT_ID_LENGTH; + } + + if (x509_verify_init(&sign_ctx, &server_sign_key, sign_args, sign_argslen, sig, siglen) != 1 + || x509_verify_update(&sign_ctx, conn->client_random, 32) != 1 + || x509_verify_update(&sign_ctx, conn->server_random, 32) != 1 + || x509_verify_update(&sign_ctx, server_ecdh_params, server_ecdh_params_len) != 1 + || x509_verify_finish(&sign_ctx) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + return -1; + } + + if (tls_server_ecdh_params_from_bytes(&conn->key_exchange_group, + &server_key_exchange, &server_key_exchange_len, + &server_ecdh_params, &server_ecdh_params_len) != 1 + || tls_length_is_zero(server_ecdh_params_len) != 1) { + error_print(); + return -1; + } + if (server_key_exchange_len != sizeof(conn->peer_key_exchange)) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if (tls_curve_match_cipher_suite(conn->key_exchange_group, conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + memcpy(conn->peer_key_exchange, server_key_exchange, server_key_exchange_len); + conn->peer_key_exchange_len = server_key_exchange_len; + - tls_record_set_handshake(record, recordlen, type, NULL, len); return 1; } -int tls12_record_get_handshake_server_key_exchange(const uint8_t *record, - int server_key_exchange_alg, const uint8_t **server_ecdh_params, size_t *server_ecdh_params_len, - int *sig_alg, const uint8_t **sig, size_t *siglen) +int tls12_recv_certificate_request(TLS_CONNECT *conn) { - int type; - const uint8_t *p; + int ret; + uint8_t *record = conn->record; + const uint8_t *cp; size_t len; - uint16_t alg; + int handshake_type; - if (!record || !sig_alg || !sig || !siglen) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_server_key_exchange) { - error_print(); - return 0; - } + const uint8_t *cert_types; + size_t cert_types_len; + const uint8_t *sig_algs; + size_t sig_algs_len; + const uint8_t *ca_names; + size_t ca_names_len; - switch (server_key_exchange_alg) { - case TLS_server_key_exchange_ecdhe: - if (!server_ecdh_params || !server_ecdh_params_len) { + if(conn->verbose) tls_trace("recv CertificateRequest*\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); - return -1; } - *server_ecdh_params = p; - *server_ecdh_params_len = len; - { - int key_exchange_group; - const uint8_t *key_exchange; - size_t key_exchange_len; + return ret; + } - if (tls_server_ecdh_params_from_bytes(&key_exchange_group, - &key_exchange, &key_exchange_len, &p, &len) != 1) { - error_print(); - return -1; - } - } - *server_ecdh_params_len -= len; - break; + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } - case TLS_server_key_exchange_ecc: - if (server_ecdh_params || server_ecdh_params_len) { + if (handshake_type != TLS_handshake_certificate_request) { + if(conn->verbose) tls_trace(" no CertificateRequest\n"); + return 0; // 表明对方没有发送预期的报文 + } + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); + + + if (tls12_record_get_handshake_certificate_request(conn->record, + &cert_types, &cert_types_len, &sig_algs, &sig_algs_len, &ca_names, &ca_names_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + return -1; + } + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1 + || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unsupported_certificate); + return -1; + } + + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + + conn->recordlen = 0; + return 1; +} + +// 这是一个非常特殊的状态,其他的所有recv状态都是要读取的 +// 但是这个状态在大多数情况下,之前已经读取完了,但是我们无法判断这个信息 +int tls_recv_server_hello_done(TLS_CONNECT *conn) +{ + int ret; + if(conn->verbose) tls_trace("recv ServerHelloDone\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); - return -1; } - break; + return ret; + } + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - default: + if (tls_record_get_handshake_server_hello_done(conn->record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + 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, "ServerHelloDone", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->record) != 1) { error_print(); return -1; } - if (tls_uint16_from_bytes(&alg, &p, &len) != 1 - || tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (!tls_signature_scheme_name(alg)) { - error_print(); - return -1; - } - if (!siglen) { - error_print(); - return -1; - } - *sig_alg = alg; + + if (conn->client_certs_len) + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + return 1; } +int tls_send_client_certificate(TLS_CONNECT *conn) +{ + int ret; + if(conn->verbose) tls_trace("send ClientCertificate\n"); + + if (conn->client_certs_len == 0) { + error_print(); + return -1; + } + + if (conn->recordlen == 0) { + if (tls_record_set_handshake_certificate(conn->record, &conn->recordlen, + conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "client Certificate", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + + //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + + return 1; +} + +int tls_send_client_key_exchange(TLS_CONNECT *conn) +{ + int ret; + + if (conn->recordlen == 0) { + uint8_t point_octets[65]; + uint8_t *point_octets_ptr = point_octets; + size_t point_octets_len = 0; + int curve_oid = tls_named_curve_oid(conn->key_exchange_group); + + if (conn->verbose) + tls_trace("send ClientKeyExchange\n"); + + + if (x509_key_generate(&conn->key_exchanges[0], OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { + error_print(); + return -1; + } + if (x509_public_key_to_bytes(&conn->key_exchanges[0], &point_octets_ptr, &point_octets_len) != 1) { + error_print(); + return -1; + } + if (point_octets_len != sizeof(point_octets)) { + error_print(); + return -1; + } + if (tls12_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen, + point_octets, point_octets_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "ClientKeyExchange", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + if (conn->client_certs_len) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + if (tls_derive_pre_master_secret(conn) != 1 + || tls_derive_master_secret(conn) != 1 + || tls_derive_key_block(conn) != 1 + || tls_init_application_keys(conn) != 1) { + error_print(); + return -1; + } + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls_send_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + if (conn->verbose) + tls_trace("send CertificateVerify\n"); + + if (conn->recordlen == 0) { + X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx - 1]; + X509_SIGN_CTX sign_ctx; + const uint8_t *signer_id = NULL; + size_t signer_idlen = 0; + + if (sign_key->algor == OID_ec_public_key && sign_key->algor_param == OID_sm2) { + signer_id = (uint8_t *)SM2_DEFAULT_ID; + signer_idlen = SM2_DEFAULT_ID_LENGTH; + } + + if (x509_sign_init(&sign_ctx, sign_key, signer_id, signer_idlen) != 1 + || x509_sign_update(&sign_ctx, conn->transcript, conn->transcript_len) != 1 + || x509_sign_finish(&sign_ctx, sig, &siglen) != 1) { + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + error_print(); + return -1; + } + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + + if (tls_record_set_handshake_certificate_verify(conn->record, &conn->recordlen, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "ClientKeyExchange", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->record) != 1) { + error_print(); + return -1; + } + + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls_send_client_finished(TLS_CONNECT *conn) +{ + int ret; + + + if (conn->recordlen == 0) { + if(conn->verbose) tls_trace("send client {Finished}\n"); + + uint8_t local_verify_data[12]; + + if (tls_compute_verify_data(conn->digest, conn->master_secret, + "client finished", &conn->dgst_ctx, local_verify_data) != 1) { + error_print(); + tls12_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + tls_record_set_protocol(conn->plain_record, conn->protocol); + + if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls12_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->plain_record, conn->plain_recordlen); + + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } + if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Finished", &conn->dgst_ctx); + + if (tls_update_transcript(conn, conn->plain_record) != 1) { + error_print(); + return -1; + } + + if (tls_record_encrypt(conn->cipher_suite, + &conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, conn->plain_record, conn->plain_recordlen, + conn->record, &conn->recordlen) != 1) { + + error_print(); + tls12_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls_recv_server_finished(TLS_CONNECT *conn) +{ + int ret; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; + size_t finished_record_len; + + const uint8_t *verify_data; + size_t verify_data_len; + uint8_t local_verify_data[12]; + + if (tls_compute_verify_data(conn->digest, conn->master_secret, + "server finished", &conn->dgst_ctx, local_verify_data) != 1) { + error_print(); + tls12_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + // Finished + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + if(conn->verbose) + tls_trace("recv server Finished\n"); + + if (tls_record_protocol(conn->record) != conn->protocol) { + error_print(); + tls12_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + if (tls_record_decrypt(conn->cipher_suite, &conn->server_write_mac_ctx, &conn->server_write_key, + conn->server_write_iv, conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { + error_print(); + tls12_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + if(conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->plain_record, conn->plain_recordlen); + + tls_seq_num_incr(conn->server_seq_num); + + if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls12_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls12_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_puts("server_finished.verify_data verification failure"); + tls12_send_alert(conn, TLS_alert_decrypt_error); + return -1; + } + + return 1; +} + + + +//TODO: Server Handshake + int tls_recv_client_hello(TLS_CONNECT *conn) { @@ -923,11 +1913,6 @@ int tls_recv_client_hello(TLS_CONNECT *conn) const uint8_t *host_name = NULL; size_t host_name_len = 0; - /* - if (client_verify) - tls_client_verify_init(&conn->client_verify_ctx); - */ - if(conn->verbose) tls_trace("recv ClientHello\n"); @@ -1229,7 +2214,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn) return -1; } - if (tls12_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); return -1; @@ -1250,16 +2235,6 @@ int tls_recv_client_hello(TLS_CONNECT *conn) return -1; } - - /* - if (client_verify) - tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); - - */ - - if(conn->verbose) { - fprintf(stderr, "end of recv_client_hello\n"); - } tls_clean_record(conn); return 1; } @@ -1357,196 +2332,6 @@ int tls_send_server_hello(TLS_CONNECT *conn) return 1; } -int tls_recv_server_hello(TLS_CONNECT *conn) -{ - int ret; - int protocol; - int cipher_suite; - const uint8_t *server_random; - const uint8_t *session_id; - size_t session_id_len; - const uint8_t *exts; - size_t extslen; - - const uint8_t *ec_point_formats = NULL; - size_t ec_point_formats_len = 0; - int server_name = 0; - int trusted_ca_keys = 0; - int renegotiation_info = 0; - - if(conn->verbose) - tls_trace("recv ServerHello\n"); - - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - if (conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - return -1; - } - - if ((ret = tls_record_get_handshake_server_hello(conn->record, - &protocol, &server_random, &session_id, &session_id_len, &cipher_suite, - &exts, &extslen)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - - // version - if (protocol != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - return -1; - } - - // random - memcpy(conn->server_random, server_random, 32); - - // session_id - memcpy(conn->session_id, session_id, session_id_len); - conn->session_id_len = session_id_len; - - // cipher_suite - if (tls_type_is_in_list(cipher_suite, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - conn->cipher_suite = cipher_suite; - - if (tls12_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - - if (digest_init(&conn->dgst_ctx, conn->digest) != 1) { - error_print(); - return -1; - } - - - while (extslen) { - int ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } - - switch (ext_type) { - case TLS_extension_ec_point_formats: - if (ec_point_formats) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - ec_point_formats = ext_data; - ec_point_formats_len = ext_datalen; - break; - case TLS_extension_server_name: - if (!conn->server_name || server_name || ext_datalen) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - server_name = 1; - break; - case TLS_extension_trusted_ca_keys: - if (!conn->ctx->trusted_ca_keys || trusted_ca_keys || ext_datalen) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - trusted_ca_keys = 1; - conn->trusted_ca_keys = 1; - break; - case TLS_extension_renegotiation_info: - if ((!conn->ctx->renegotiation_info && !conn->ctx->empty_renegotiation_info_scsv) - || renegotiation_info) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - if ((ret = tls12_renegotiation_info_ext_is_empty(ext_data, ext_datalen)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - renegotiation_info = 1; - conn->secure_renegotiation = 1; - break; - default: - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - } - - if ((conn->ctx->renegotiation_info || conn->ctx->empty_renegotiation_info_scsv) - && !renegotiation_info) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - - if (ec_point_formats) { - if ((ret = tls_ec_point_formats_support_uncompressed(ec_point_formats, ec_point_formats_len)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - } - - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); - - 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, "ServerHello", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - - //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); - if (conn->client_certs_len) { - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - } - - return 1; -} - int tls_send_server_certificate(TLS_CONNECT *conn) { int ret; @@ -1583,204 +2368,6 @@ int tls_send_server_certificate(TLS_CONNECT *conn) return 1; } -int tls_recv_server_certificate(TLS_CONNECT *conn) -{ - int ret; - int verify_result = 0; - const uint8_t *server_cert; - size_t server_cert_len; - X509_KEY server_sign_key; - int server_sig_alg = 0; - int server_group; - int cert_sig_alg = 0; - const int *signature_algorithms_cert = NULL; - size_t signature_algorithms_cert_cnt = 0; - - - if(conn->verbose) - tls_trace("recv server Certificate\n"); - - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - if(conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - - if ((ret = tls_record_get_handshake_certificate(conn->record, - conn->peer_cert_chain, &conn->peer_cert_chain_len)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return 0; - } - if (!conn->peer_cert_chain_len) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - 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, "Certificate", &conn->dgst_ctx); - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - - // server_sign_key - if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, - &server_cert, &server_cert_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - if (x509_cert_get_subject_public_key(server_cert, server_cert_len, &server_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - if (tls12_public_key_get_group(&server_sign_key, &server_group) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - // check server certificate matches negotiated cipher_suite - if (!tls12_cipher_suite_match_cert_group(conn->cipher_suite, server_group)) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - switch (conn->cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - case TLS_cipher_ecc_sm4_cbc_sm3: - case TLS_cipher_ecc_sm4_gcm_sm3: - server_sig_alg = TLS_sig_sm2sig_sm3; - break; - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: -#endif - server_sig_alg = TLS_sig_ecdsa_secp256r1_sha256; - break; - default: - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - // check server certificate matches ClientHello.supported_groups - if (conn->ctx->supported_groups_cnt) { - if (!tls_type_is_in_list(server_group, conn->ctx->supported_groups, - conn->ctx->supported_groups_cnt)) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - } - - // check server certificate matches ClientHello.signature_algorithms - if (conn->ctx->signature_algorithms_cnt) { - if ((ret = tls_cert_match_signature_algorithms(server_cert, server_cert_len, - conn->ctx->signature_algorithms, - conn->ctx->signature_algorithms_cnt, - &cert_sig_alg)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - if (!tls12_signature_scheme_match_cert_group(cert_sig_alg, server_group) - || !tls12_signature_scheme_match_cipher_suite(cert_sig_alg, conn->cipher_suite)) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - server_sig_alg = cert_sig_alg; - } - - // check certificate-chain signatures match ClientHello.signature_algorithms_cert - if (conn->signature_algorithms_cert) { - signature_algorithms_cert = conn->ctx->signature_algorithms; - signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; - } else if (conn->ctx->signature_algorithms_cnt) { - signature_algorithms_cert = conn->ctx->signature_algorithms; - signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; - } - if (signature_algorithms_cert && signature_algorithms_cert_cnt) { - if ((ret = tls_cert_chain_match_signature_algorithms_cert( - conn->peer_cert_chain, conn->peer_cert_chain_len, - signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - } - - // check server certificate matches ClientHello.server_name - if (conn->server_name) { - if ((ret = tls_cert_match_server_name(server_cert, server_cert_len, - conn->host_name, conn->host_name_len)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - } - - conn->signature_algorithms[0] = server_sig_alg; - conn->signature_algorithms_cnt = 1; - - if (conn->client_certs_len) { - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - } - - assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10); - - // verify server Certificate - if (conn->ctx->cacertslen) { - if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, - conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { - error_print(); - conn->verify_result = verify_result; - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - } - conn->verify_result = verify_result; - - return 1; -} - int tls_send_server_key_exchange(TLS_CONNECT *conn) { int ret; @@ -1862,228 +2449,6 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn) return 1; } -// match the ecdhe of cipher_suite -int tls_curve_match_cipher_suite(int named_curve, int cipher_suite) -{ - switch (named_curve) { - case TLS_curve_sm2p256v1: - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - break; - default: - error_print(); - return -1; - } - break; - case TLS_curve_secp256r1: - switch (cipher_suite) { - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: -#endif - break; - default: - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int tls_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite) -{ - switch (sig_alg) { - case TLS_sig_sm2sig_sm3: - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - case TLS_cipher_ecc_sm4_cbc_sm3: - case TLS_cipher_ecc_sm4_gcm_sm3: - break; - default: - error_print(); - return -1; - } - break; - case TLS_sig_ecdsa_secp256r1_sha256: - switch (cipher_suite) { - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm: -#endif - break; - default: - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int tls_recv_server_key_exchange(TLS_CONNECT *conn) -{ - int ret; - - // 这部分是被签名的值,必须要拿到 - const uint8_t *server_ecdh_params; - size_t server_ecdh_params_len; - - - const uint8_t *server_key_exchange; - size_t server_key_exchange_len; - int sig_alg; - const uint8_t *sig; - size_t siglen; - - // verify ServerKeyExchange - X509_KEY server_sign_key; - - int server_cert_index = 0; - const uint8_t *server_cert; - size_t server_cert_len; - - X509_SIGN_CTX sign_ctx; - const void *sign_args = NULL; - size_t sign_argslen = 0; - - if(conn->verbose) tls_trace("recv ServerKeyExchange\n"); - - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - - - if ((ret = tls12_record_get_handshake_server_key_exchange(conn->record, - TLS_server_key_exchange_ecdhe, &server_ecdh_params, &server_ecdh_params_len, - &sig_alg, &sig, &siglen)) < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return 0; - } - 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, "ServerKeyExchange", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - if (tls_signature_scheme_match_cipher_suite(sig_alg, conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - - if (conn->client_certs_len) - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - - - if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, - server_cert_index, &server_cert, &server_cert_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - if (x509_cert_get_subject_public_key(server_cert, server_cert_len, &server_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - switch (sig_alg) { - case TLS_sig_sm2sig_sm3: - if (server_sign_key.algor != OID_ec_public_key - || server_sign_key.algor_param != OID_sm2) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - break; - case TLS_sig_ecdsa_secp256r1_sha256: - if (server_sign_key.algor != OID_ec_public_key - || server_sign_key.algor_param != OID_secp256r1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - break; - default: - error_print(); - return -1; - } - - if (server_sign_key.algor == OID_ec_public_key && server_sign_key.algor_param == OID_sm2) { - sign_args = SM2_DEFAULT_ID; - sign_argslen = SM2_DEFAULT_ID_LENGTH; - } - - if (x509_verify_init(&sign_ctx, &server_sign_key, sign_args, sign_argslen, sig, siglen) != 1 - || x509_verify_update(&sign_ctx, conn->client_random, 32) != 1 - || x509_verify_update(&sign_ctx, conn->server_random, 32) != 1 - || x509_verify_update(&sign_ctx, server_ecdh_params, server_ecdh_params_len) != 1 - || x509_verify_finish(&sign_ctx) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - return -1; - } - - if(conn->verbose) { - fprintf(stderr, ">>>>>> ServerKeyExchange verify success\n"); - } - - if (tls_server_ecdh_params_from_bytes(&conn->key_exchange_group, - &server_key_exchange, &server_key_exchange_len, - &server_ecdh_params, &server_ecdh_params_len) != 1 - || tls_length_is_zero(server_ecdh_params_len) != 1) { - error_print(); - return -1; - } - if (server_key_exchange_len != sizeof(conn->peer_key_exchange)) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - if (tls_curve_match_cipher_suite(conn->key_exchange_group, conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - - memcpy(conn->peer_key_exchange, server_key_exchange, server_key_exchange_len); - conn->peer_key_exchange_len = server_key_exchange_len; - - - return 1; -} - int tls12_send_certificate_request(TLS_CONNECT *conn) { int ret; @@ -2138,76 +2503,9 @@ int tls12_send_certificate_request(TLS_CONNECT *conn) return 1; } -int tls12_recv_certificate_request(TLS_CONNECT *conn) -{ - int ret; - uint8_t *record = conn->record; - const uint8_t *cp; - size_t len; - int handshake_type; - - const uint8_t *cert_types; - size_t cert_types_len; - const uint8_t *sig_algs; - size_t sig_algs_len; - const uint8_t *ca_names; - size_t ca_names_len; - - if(conn->verbose) tls_trace("recv CertificateRequest*\n"); - - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - - if (handshake_type != TLS_handshake_certificate_request) { - if(conn->verbose) tls_trace(" no CertificateRequest\n"); - return 0; // 表明对方没有发送预期的报文 - } - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - if (tls12_record_get_handshake_certificate_request(conn->record, - &cert_types, &cert_types_len, &sig_algs, &sig_algs_len, &ca_names, &ca_names_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { - error_print(); - return -1; - } - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1 - || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unsupported_certificate); - return -1; - } - - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - - conn->recordlen = 0; - return 1; -} int tls_send_server_hello_done(TLS_CONNECT *conn) { @@ -2245,95 +2543,7 @@ int tls_send_server_hello_done(TLS_CONNECT *conn) return 1; } -// 这是一个非常特殊的状态,其他的所有recv状态都是要读取的 -// 但是这个状态在大多数情况下,之前已经读取完了,但是我们无法判断这个信息 -int tls_recv_server_hello_done(TLS_CONNECT *conn) -{ - int ret; - if(conn->verbose) tls_trace("recv ServerHelloDone\n"); - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - - if (tls_record_get_handshake_server_hello_done(conn->record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - - 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, "ServerHelloDone", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - - if (conn->client_certs_len) - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - - - return 1; -} - -int tls_send_client_certificate(TLS_CONNECT *conn) -{ - int ret; - if(conn->verbose) tls_trace("send ClientCertificate\n"); - - if (conn->client_certs_len == 0) { - error_print(); - return -1; - } - - if (conn->recordlen == 0) { - if (tls_record_set_handshake_certificate(conn->record, &conn->recordlen, - conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "client Certificate", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - } - - if ((ret = tls_send_record(conn)) != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - - //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - - return 1; -} // 只有在需要验证客户端证书的时候这个函数才执行,是否内部要判断一下 int tls_recv_client_certificate(TLS_CONNECT *conn) @@ -2392,75 +2602,7 @@ int tls_recv_client_certificate(TLS_CONNECT *conn) return 1; } -int tls_send_client_key_exchange(TLS_CONNECT *conn) -{ - int ret; - if (conn->recordlen == 0) { - uint8_t point_octets[65]; - uint8_t *point_octets_ptr = point_octets; - size_t point_octets_len = 0; - int curve_oid = tls_named_curve_oid(conn->key_exchange_group); - - if (conn->verbose) - tls_trace("send ClientKeyExchange\n"); - - - if (x509_key_generate(&conn->key_exchanges[0], OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { - error_print(); - return -1; - } - if (x509_public_key_to_bytes(&conn->key_exchanges[0], &point_octets_ptr, &point_octets_len) != 1) { - error_print(); - return -1; - } - if (point_octets_len != sizeof(point_octets)) { - error_print(); - return -1; - } - if (tls12_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen, - point_octets, point_octets_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "ClientKeyExchange", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - if (conn->client_certs_len) { - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - } - - if (tls_derive_pre_master_secret(conn) != 1 - || tls_derive_master_secret(conn) != 1 - || tls_derive_key_block(conn) != 1 - || tls_init_application_keys(conn) != 1) { - error_print(); - return -1; - } - } - - if ((ret = tls_send_record(conn)) != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - return 1; -} int tls_recv_client_key_exchange(TLS_CONNECT *conn) { @@ -2526,67 +2668,6 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn) } -int tls_send_certificate_verify(TLS_CONNECT *conn) -{ - int ret; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - if (conn->verbose) - tls_trace("send CertificateVerify\n"); - - if (conn->recordlen == 0) { - X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx - 1]; - X509_SIGN_CTX sign_ctx; - const uint8_t *signer_id = NULL; - size_t signer_idlen = 0; - - if (sign_key->algor == OID_ec_public_key && sign_key->algor_param == OID_sm2) { - signer_id = (uint8_t *)SM2_DEFAULT_ID; - signer_idlen = SM2_DEFAULT_ID_LENGTH; - } - - if (x509_sign_init(&sign_ctx, sign_key, signer_id, signer_idlen) != 1 - || x509_sign_update(&sign_ctx, conn->transcript, conn->transcript_len) != 1 - || x509_sign_finish(&sign_ctx, sig, &siglen) != 1) { - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - error_print(); - return -1; - } - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - - if (tls_record_set_handshake_certificate_verify(conn->record, &conn->recordlen, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, 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, "ClientKeyExchange", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->record) != 1) { - error_print(); - return -1; - } - - } - - if ((ret = tls_send_record(conn)) != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - return 1; -} - int tls_recv_certificate_verify(TLS_CONNECT *conn) { int ret; @@ -2637,9 +2718,8 @@ int tls_recv_certificate_verify(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_bad_certificate); return -1; } - // 这里是否要验证证书的类型呢?我们现在还不支持其他签名算法 - if (client_sign_key.algor != OID_ec_public_key - || client_sign_key.algor_param != OID_sm2) { + + if (client_sign_key.algor != OID_ec_public_key) { error_print(); tls_send_alert(conn, TLS_alert_bad_certificate); return -1; @@ -2659,125 +2739,6 @@ int tls_recv_certificate_verify(TLS_CONNECT *conn) return 1; } -int tls_send_change_cipher_spec(TLS_CONNECT *conn) -{ - int ret; - if (conn->recordlen == 0) { - if(conn->verbose) tls_trace("send [ChangeCipherSpec]\n"); - if (tls_record_set_change_cipher_spec(conn->record, &conn->recordlen) !=1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - } - if ((ret = tls_send_record(conn)) != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - return 1; -} - -int tls_recv_change_cipher_spec(TLS_CONNECT *conn) -{ - int ret; - - if ((ret = tls_recv_record(conn)) != 1) { - if (ret != TLS_ERROR_RECV_AGAIN) { - error_print(); - } - return ret; - } - if(conn->verbose) - tls_trace("recv [ChangeCipherSpec]\n"); - - if (tls_record_protocol(conn->record) != conn->protocol) { - error_print(); - if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) - tls12_send_alert(conn, TLS_alert_unexpected_message); - else tls_send_alert(conn, TLS_alert_unexpected_message); - - return -1; - } - if (conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - - if (tls_record_get_change_cipher_spec(conn->record) != 1) { - error_print(); - if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) - tls12_send_alert(conn, TLS_alert_unexpected_message); - else tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - return 1; -} - -int tls_send_client_finished(TLS_CONNECT *conn) -{ - int ret; - - - if (conn->recordlen == 0) { - if(conn->verbose) tls_trace("send client {Finished}\n"); - - uint8_t local_verify_data[12]; - - if (tls_compute_verify_data(conn->digest, conn->master_secret, - "client finished", &conn->dgst_ctx, local_verify_data) != 1) { - error_print(); - tls12_send_alert(conn, TLS_alert_internal_error); - return -1; - } - - tls_record_set_protocol(conn->plain_record, conn->protocol); - - if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, - local_verify_data, sizeof(local_verify_data)) != 1) { - error_print(); - tls12_send_alert(conn, TLS_alert_internal_error); - return -1; - } - - if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->plain_record, conn->plain_recordlen); - - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Finished", &conn->dgst_ctx); - - if (tls_update_transcript(conn, conn->plain_record) != 1) { - error_print(); - return -1; - } - - if (tls_record_encrypt(conn->cipher_suite, - &conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, conn->plain_record, conn->plain_recordlen, - conn->record, &conn->recordlen) != 1) { - - error_print(); - tls12_send_alert(conn, TLS_alert_internal_error); - return -1; - } - tls_seq_num_incr(conn->client_seq_num); - - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "encrypted finsished ..... ", conn->record, conn->recordlen); - } - } - - if ((ret = tls_send_record(conn)) != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - return 1; -} int tls_recv_client_finished(TLS_CONNECT *conn) { @@ -2793,10 +2754,6 @@ int tls_recv_client_finished(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "verify_data", local_verify_data, 12); - } - // recv ClientFinished if(conn->verbose) tls_trace("recv client {Finished}\n"); @@ -2808,11 +2765,6 @@ int tls_recv_client_finished(TLS_CONNECT *conn) } //tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "Finished", conn->record, conn->recordlen); - } - - if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); @@ -2820,13 +2772,6 @@ int tls_recv_client_finished(TLS_CONNECT *conn) } // decrypt ClientFinished - if(conn->verbose) tls_trace(">>>>>>>decrypt Finished\n"); - - - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "client_seq_num", conn->client_seq_num, 8); - } - if (tls_record_decrypt(conn->cipher_suite, &conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv, conn->client_seq_num, conn->record, conn->recordlen, conn->plain_record, &conn->plain_recordlen) != 1) { @@ -2929,27 +2874,31 @@ int tls_send_server_finished(TLS_CONNECT *conn) return 1; } -int tls_recv_server_finished(TLS_CONNECT *conn) +int tls_send_change_cipher_spec(TLS_CONNECT *conn) { int ret; - uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; - size_t finished_record_len; - - const uint8_t *verify_data; - size_t verify_data_len; - uint8_t local_verify_data[12]; - - if (tls_compute_verify_data(conn->digest, conn->master_secret, - "server finished", &conn->dgst_ctx, local_verify_data) != 1) { - error_print(); - tls12_send_alert(conn, TLS_alert_internal_error); - return -1; + if (conn->recordlen == 0) { + if(conn->verbose) tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(conn->record, &conn->recordlen) !=1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if(conn->verbose) tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); } - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, ">>> verify_data", local_verify_data, 12); + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; } + return 1; +} + +int tls_recv_change_cipher_spec(TLS_CONNECT *conn) +{ + int ret; - // Finished if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); @@ -2957,50 +2906,26 @@ int tls_recv_server_finished(TLS_CONNECT *conn) return ret; } if(conn->verbose) - tls_trace("recv server Finished\n"); + tls_trace("recv [ChangeCipherSpec]\n"); if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); - tls12_send_alert(conn, TLS_alert_unexpected_message); + if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) + tls12_send_alert(conn, TLS_alert_unexpected_message); + else tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; } + if (conn->verbose) + tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->record, conn->recordlen); - if(conn->verbose) tls_trace("decrypt Finished\n"); - - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); - } - - if (tls_record_decrypt(conn->cipher_suite, &conn->server_write_mac_ctx, &conn->server_write_key, - conn->server_write_iv, conn->server_seq_num, conn->record, conn->recordlen, - conn->plain_record, &conn->plain_recordlen) != 1) { + if (tls_record_get_change_cipher_spec(conn->record) != 1) { error_print(); - tls12_send_alert(conn, TLS_alert_bad_record_mac); + if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) + tls12_send_alert(conn, TLS_alert_unexpected_message); + else tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) - tls_record_print(stderr, 0, 0, conn->cipher_suite, conn->plain_record, conn->plain_recordlen); - - tls_seq_num_incr(conn->server_seq_num); - - if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { - error_print(); - tls12_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (verify_data_len != sizeof(local_verify_data)) { - error_print(); - tls12_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - - - if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { - error_puts("server_finished.verify_data verification failure"); - tls12_send_alert(conn, TLS_alert_decrypt_error); - return -1; - } - return 1; } @@ -3272,24 +3197,13 @@ int tls12_do_client_handshake(TLS_CONNECT *conn) next_state = TLS_state_certificate_request; break; - // the only optional state case TLS_state_certificate_request: - if(conn->verbose) { - fprintf(stderr, "TLS_state_certificate_request\n"); - } ret = tls12_recv_certificate_request(conn); - if(conn->verbose) { - fprintf(stderr, " ret = %d\n", ret); - } - if (ret == 1) conn->client_certificate_verify = 1; next_state = TLS_state_server_hello_done; break; case TLS_state_server_hello_done: - if(conn->verbose) { - fprintf(stderr, "TLS_state_server_hello_done\n"); - } ret = tls_recv_server_hello_done(conn); if (conn->client_certificate_verify) next_state = TLS_state_client_certificate; diff --git a/src/tls13.c b/src/tls13.c index 76cc775c..3b678b3f 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -74,32 +74,6 @@ int tls13_random_generate(uint8_t random[32]) } -int tls13_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest) -{ - switch (cipher_suite) { - case TLS_cipher_sm4_gcm_sm3: -#ifdef ENABLE_SM4_CCM - case TLS_cipher_sm4_ccm_sm3: -#endif - *digest = DIGEST_sm3(); - *cipher = BLOCK_CIPHER_sm4(); - break; -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) - case TLS_cipher_aes_128_gcm_sha256: -#ifdef ENABLE_AES_CCM - case TLS_cipher_aes_128_ccm_sha256: -#endif - *digest = DIGEST_sha256(); - *cipher = BLOCK_CIPHER_aes128(); - break; -#endif - default: - error_print(); - return -1; - } - return 1; -} - int tls13_padding_len_rand(size_t *padding_len) { @@ -642,7 +616,7 @@ int tls13_generate_early_keys(TLS_CONNECT *conn) return -1; } - if (tls13_cipher_suite_get(conn->psk_cipher_suites[0], &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(conn->psk_cipher_suites[0], &conn->cipher, &conn->digest) != 1) { error_print(); return -1; } @@ -4479,7 +4453,7 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - if (tls13_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; @@ -5075,7 +5049,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) return -1; } conn->cipher_suite = cipher_suite; - if (tls13_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; @@ -6749,7 +6723,7 @@ static int tls13_cipher_suites_match_signature_scheme( const BLOCK_CIPHER *cipher; const DIGEST *digest; - if (tls13_cipher_suite_get(cipher_suites[i], &cipher, &digest) != 1) { + if (tls_cipher_suite_get(cipher_suites[i], &cipher, &digest) != 1) { error_print(); return -1; } @@ -7305,7 +7279,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) // format_print(stderr, 0, 0, "conn->cipher_suite: %s\n", tls_cipher_suite_name(conn->cipher_suite)); - if (tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { error_print(); return -1; } diff --git a/src/tls_ext.c b/src/tls_ext.c index 28f6a415..f5e4de00 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -382,6 +382,48 @@ Example: ec_point_format_list: 0x00 (uncompressed) */ +const int ec_point_formats[] = { TLS_point_uncompressed }; +size_t ec_point_formats_cnt = sizeof(ec_point_formats)/sizeof(ec_point_formats[0]); + +int tls_ec_point_formats_support_uncompressed(const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *formats; + size_t formats_len; + int uncompressed = 0; + + if (tls_uint8array_from_bytes(&formats, &formats_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (!formats_len) { + error_print(); + return -1; + } + + while (formats_len) { + uint8_t format; + if (tls_uint8_from_bytes(&format, &formats, &formats_len) != 1) { + error_print(); + return -1; + } + if (!tls_ec_point_format_name(format)) { + error_print(); + return -1; + } + if (format == TLS_point_uncompressed) { + uncompressed = 1; + } + } + + if (!uncompressed) { + error_print(); + return 0; + } + return 1; +} + + int tls_ec_point_formats_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen) { const uint8_t *ec_point_format_list; diff --git a/src/tls_psk.c b/src/tls_psk.c index ffe49212..5c3dc88f 100644 --- a/src/tls_psk.c +++ b/src/tls_psk.c @@ -982,7 +982,7 @@ int tls13_psk_binders_generate_empty(const int *psk_cipher_suites, size_t psk_ci const BLOCK_CIPHER *cipher; const DIGEST *digest; - if (tls13_cipher_suite_get(psk_cipher_suites[i], &cipher, &digest) != 1) { + if (tls_cipher_suite_get(psk_cipher_suites[i], &cipher, &digest) != 1) { error_print(); return -1; } @@ -1028,7 +1028,7 @@ int tls13_psk_binders_generate( size_t psk_key_len; const char *binder_label = "ext binder"; - if (tls13_cipher_suite_get(psk_cipher_suites[i], &cipher, &digest) != 1) { + if (tls_cipher_suite_get(psk_cipher_suites[i], &cipher, &digest) != 1) { error_print(); return -1; } @@ -1260,7 +1260,7 @@ int tls13_add_pre_shared_key(TLS_CONNECT *conn, error_print(); return -1; } - if (tls13_cipher_suite_get(psk_cipher_suite, &cipher, &digest) != 1) { + if (tls_cipher_suite_get(psk_cipher_suite, &cipher, &digest) != 1) { error_print(); return -1; } @@ -1421,7 +1421,7 @@ int tls13_process_client_pre_shared_key_external(TLS_CONNECT *conn, conn->cipher_suite = conn->psk_cipher_suites[matched_psk_idx]; - if (tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { + if (tls_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { error_print(); return -1; } diff --git a/src/tls_trace.c b/src/tls_trace.c index b5091cc8..d69fda4d 100644 --- a/src/tls_trace.c +++ b/src/tls_trace.c @@ -364,6 +364,24 @@ int tls_named_curve_from_name(const char *name) return 0; } +int tls_named_curve_oid(int named_curve) +{ + switch (named_curve) { + case TLS_curve_secp256r1: return OID_secp256r1; + case TLS_curve_sm2p256v1: return OID_sm2; + } + return OID_undef; +} + +int tls_named_curve_from_oid(int oid) +{ + switch (oid) { + case OID_secp256r1: return TLS_curve_secp256r1; + case OID_sm2: return TLS_curve_sm2p256v1; + } + return 0; +} + const char *tls_signature_scheme_name(int scheme) { switch (scheme) { diff --git a/src/x509_ext.c b/src/x509_ext.c index ef4ed59d..091be47e 100644 --- a/src/x509_ext.c +++ b/src/x509_ext.c @@ -1120,8 +1120,6 @@ int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, cons format_print(fp, fmt, ind, "%s\n", label); ind += 4; - format_bytes(fp, 0, 0, "der", d, dlen); - while (dlen) { if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) { error_print(); diff --git a/tools/tlcp_help.h b/tools/tlcp_help.h index f77135c1..c45fb3da 100644 --- a/tools/tlcp_help.h +++ b/tools/tlcp_help.h @@ -37,3 +37,7 @@ "\n" " gmssl tlcp_server -port 4431 -cert tlcpcert.pem -key tlcpkey.pem -pass 1234 -cipher_suite TLS_ECC_SM4_CBC_SM3\n" " gmssl tlcp_client -port 4431 -host 127.0.0.1 -cacert sm2rootcacert.pem -cipher_suite TLS_ECC_SM4_CBC_SM3\n" +"\n" +" gmssl tlcp_server -port 4431 -cert tlcpcert.pem -key tlcpkey.pem -pass 1234 -cacert sm2cacert.pem -verbose\n" +" gmssl tlcp_client -port 4431 -host 127.0.0.1 -cacert sm2rootcacert.pem -cipher_suite TLS_ECC_SM4_CBC_SM3 -cert sm2signcert.pem -key sm2signkey.pem -pass 1234 -verbose\n" +"\n" diff --git a/tools/tls12_help.h b/tools/tls12_help.h index 301ebe8a..1c4b5093 100644 --- a/tools/tls12_help.h +++ b/tools/tls12_help.h @@ -98,3 +98,8 @@ " -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" " -cacert rootcacerts.pem\n" "\n" +" gmssl tls12_server -port 4430 -cipher_suite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 -cert p256certs.pem -key p256signkey.pem -pass 1234 \\\n" +" -cacert p256cacert.pem -verbose -cert_request\n" +" gmssl tls12_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -cert p256signcert.pem -key p256signkey.pem -pass 1234 -cacert p256rootcacert.pem -verbose\n" +"\n" diff --git a/tools/tls13_client.c b/tools/tls13_client.c index 533675f1..1d2c2190 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -673,7 +673,7 @@ bad: uint8_t psk_key[64]; size_t psk_key_len; - if (tls13_cipher_suite_get(psk_cipher_suites[i], &psk_cipher, &psk_digest) != 1) { + if (tls_cipher_suite_get(psk_cipher_suites[i], &psk_cipher, &psk_digest) != 1) { error_print(); goto end; } diff --git a/tools/tls13_server.c b/tools/tls13_server.c index 6eb0c7ad..060c668b 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -557,7 +557,7 @@ bad: error_print(); goto end; } - if (tls13_cipher_suite_get(psk_cipher_suite, &psk_cipher, &psk_digest) != 1) { + if (tls_cipher_suite_get(psk_cipher_suite, &psk_cipher, &psk_digest) != 1) { error_print(); goto end; }