From 823fe11897f59621347a8ac527389382545eb279 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Mon, 15 Jun 2026 11:15:33 +0800 Subject: [PATCH] Clean TLS code --- CMakeLists.txt | 2 +- include/gmssl/tls.h | 25 ++- include/gmssl/version.h | 2 +- src/tlcp.c | 110 +++++++++++ src/tls.c | 412 +++++++++++++++++++++------------------- src/tls12.c | 384 ++++++++++++++++++------------------- 6 files changed, 533 insertions(+), 402 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be049301..1f00ee3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -764,7 +764,7 @@ endif() # set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_VENDOR "GmSSL develop team") -set(CPACK_PACKAGE_VERSION "3.2.0-dev.1047") +set(CPACK_PACKAGE_VERSION "3.2.0-dev.1048") 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 762954e9..88ccaf7e 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -424,18 +424,18 @@ int tls_ccm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], int tls_ccm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], const uint8_t seq_num[8], const uint8_t header[5], const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int tls12_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx, + + +int tls_record_encrypt(int cipher_suite, + const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); +int tls_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], const uint8_t seq_num[8], const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int tlcp_record_encrypt(int cipher_suite, - const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); -int tlcp_record_decrypt(int cipher_suite, - const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); + + int tls_seq_num_incr(uint8_t seq_num[8]); void tls_seq_num_reset(uint8_t seq_num[8]); @@ -493,6 +493,7 @@ int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen); // parse ServerKeyExchange, ClientKeyExchange depends on current cipher_suite #define tls_format_set_cipher_suite(fmt,cipher) do {(fmt)|=((cipher)<<8);} while (0) int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); +int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); int tlcp_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen); int tls_record_send(const uint8_t *record, size_t recordlen, tls_socket_t sock); @@ -1605,6 +1606,9 @@ int tls12_do_connect(TLS_CONNECT *conn); int tls12_do_accept(TLS_CONNECT *conn); + +int tls12_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen); + int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx); @@ -1620,6 +1624,9 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen); +int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen); + + #define TLS13_SM2_ID "TLSv1.3+GM+Cipher+Suite" diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 25cc104e..58c62671 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.1047" +#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1048" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/src/tlcp.c b/src/tlcp.c index a7674aef..141056ef 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -2379,7 +2379,117 @@ int tlcp_send_server_finished(TLS_CONNECT *conn) return 1; } +int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) +{ + const HMAC_CTX *hmac_ctx; + const BLOCK_CIPHER_KEY *enc_key; + const uint8_t *iv; + uint8_t *seq_num; + size_t recordlen; + int ret; + if (!conn) { + error_print(); + return -1; + } + if (!in || !inlen || !sentlen) { + error_print(); + return -1; + } + if (conn->recv_state) { + *sentlen = 0; + return TLS_ERROR_RECV_AGAIN; + } + if (conn->send_state && conn->send_state != TLS_state_send_record) { + error_print(); + return -1; + } + + *sentlen = 0; + + if (!conn->recordlen) { + + if (inlen > TLS_MAX_PLAINTEXT_SIZE) { + inlen = TLS_MAX_PLAINTEXT_SIZE; + } + + if (conn->datalen) { + error_puts("recv all buffered data before send"); + return -1; + } + + if (conn->is_client) { + hmac_ctx = &conn->client_write_mac_ctx; + enc_key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + hmac_ctx = &conn->server_write_mac_ctx; + enc_key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls_record_set_type(conn->databuf, TLS_record_application_data) != 1 + || tls_record_set_protocol(conn->databuf, conn->protocol) != 1 + || tls_record_set_data(conn->databuf, in, inlen) != 1) { + error_print(); + return -1; + } + if(conn->verbose) tls_record_trace(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); + + switch (conn->cipher_suite) { + case TLS_cipher_ecc_sm4_cbc_sm3: + if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, conn->databuf, + conn->databuf + 5, tls_record_data_length(conn->databuf), + conn->record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + break; + + case TLS_cipher_ecc_sm4_gcm_sm3: + if (tls_gcm_encrypt(enc_key, iv, seq_num, conn->databuf, + conn->databuf + 5, tls_record_data_length(conn->databuf), + conn->record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + break; + + default: + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + + conn->record[0] = conn->databuf[0]; + conn->record[1] = conn->databuf[1]; + conn->record[2] = conn->databuf[2]; + conn->record[3] = (uint8_t)(recordlen >> 8); + conn->record[4] = (uint8_t)(recordlen); + recordlen += 5; + + conn->recordlen = recordlen; + conn->record_offset = 0; + conn->sentlen = inlen; + conn->send_state = TLS_state_send_record; + if(conn->verbose) tls_encrypted_record_trace(stderr, conn->record, recordlen, 0, 0); + } + + ret = tls_send_record(conn); + if (ret != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + *sentlen = conn->sentlen; + conn->send_state = 0; + tls_clean_record(conn); + return 1; +} /* diff --git a/src/tls.c b/src/tls.c index 5f743bfa..47fdacea 100644 --- a/src/tls.c +++ b/src/tls.c @@ -698,6 +698,21 @@ int tls_ccm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], return 1; } +int tls_seq_num_incr(uint8_t seq_num[8]) +{ + int i; + for (i = 7; i > 0; i--) { + seq_num[i]++; + if (seq_num[i]) break; + } + return 1; +} + +void tls_seq_num_reset(uint8_t seq_num[8]) +{ + memset(seq_num, 0, 8); +} + int tls_random_generate(uint8_t random[32]) { uint32_t gmt_unix_time = (uint32_t)time(NULL); @@ -1094,14 +1109,123 @@ int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_cipher return 0; } +int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t methslen) +{ + if (!meths || !methslen) { + error_print(); + return -1; + } + while (methslen--) { + if (*meths++ == TLS_compression_null) { + return 1; + } + } + error_print(); + return -1; +} +int tls_record_encrypt(int cipher_suite, + const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + switch (cipher_suite) { + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + if (tls_cbc_encrypt(hmac_ctx, key, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; + case TLS_cipher_ecc_sm4_gcm_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + if (tls_gcm_encrypt(key, fixed_iv, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; +#ifdef ENABLE_AES_CCM + case TLS_cipher_aes_128_ccm_sha256: + if (tls_ccm_encrypt(key, fixed_iv, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; +#endif + default: + error_print(); + return -1; + } + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = (uint8_t)((*outlen) >> 8); + out[4] = (uint8_t)(*outlen); + (*outlen) += 5; + return 1; +} +int tls_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx, + const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + switch (cipher_suite) { + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + if (tls_cbc_decrypt(hmac_ctx, key, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; + case TLS_cipher_ecc_sm4_gcm_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + if (tls_gcm_decrypt(key, fixed_iv, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; +#ifdef ENABLE_AES_CCM + case TLS_cipher_aes_128_ccm_sha256: + if (tls_ccm_decrypt(key, fixed_iv, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + break; +#endif + default: + error_print(); + return -1; + } - + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = (uint8_t)((*outlen) >> 8); + out[4] = (uint8_t)(*outlen); + (*outlen) += 5; + return 1; +} @@ -1115,10 +1239,6 @@ int tls_record_set_handshake(uint8_t *record, size_t *recordlen, error_print(); return -1; } - if (!data && datalen) { - error_print(); - return -1; - } if (datalen > TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE) { error_print(); return -1; @@ -1584,7 +1704,7 @@ int tls_server_ecdh_params_to_bytes(const X509_KEY *public_key, uint8_t **out, s { int named_curve; uint8_t point[65]; - uint8_t *point_ptr; + uint8_t *point_ptr = point; size_t point_len = 0; if (!public_key || !outlen) { @@ -2178,35 +2298,6 @@ int tls_recv_record(TLS_CONNECT *conn) } -int tls_seq_num_incr(uint8_t seq_num[8]) -{ - int i; - for (i = 7; i > 0; i--) { - seq_num[i]++; - if (seq_num[i]) break; - } - return 1; -} - -void tls_seq_num_reset(uint8_t seq_num[8]) -{ - memset(seq_num, 0, 8); -} - -int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t methslen) -{ - if (!meths || !methslen) { - error_print(); - return -1; - } - while (methslen--) { - if (*meths++ == TLS_compression_null) { - return 1; - } - } - error_print(); - return -1; -} int tls_send_alert(TLS_CONNECT *conn, int alert) { @@ -2225,7 +2316,13 @@ int tls_send_alert(TLS_CONNECT *conn, int alert) error_print(); return -1; } - if(conn->verbose) tls_record_trace(stderr, record, sizeof(record), 0, 0); + if (conn->verbose) { + if (conn->protocol == TLS_protocol_tls12) { + tls12_record_print(stderr, record, sizeof(record), 0, 0); + } else { + tls_record_trace(stderr, record, sizeof(record), 0, 0); + } + } return 1; } @@ -2274,153 +2371,18 @@ int tls_send_warning(TLS_CONNECT *conn, int alert) error_print(); return -1; } - if(conn->verbose) tls_record_trace(stderr, record, sizeof(record), 0, 0); - return 1; -} - -static int tls_encrypt_send(TLS_CONNECT *conn, int record_type, const uint8_t *in, size_t inlen, size_t *sentlen) -{ - const HMAC_CTX *hmac_ctx; - const BLOCK_CIPHER_KEY *enc_key; - const uint8_t *fixed_iv; - uint8_t *seq_num; - size_t recordlen; - int ret; - - if (!conn) { - error_print(); - return -1; - } - if (!in || !inlen || !sentlen) { - error_print(); - return -1; - } - if (conn->recv_state) { - *sentlen = 0; - return TLS_ERROR_RECV_AGAIN; - } - if (conn->send_state && conn->send_state != TLS_state_send_record) { - error_print(); - return -1; - } - - *sentlen = 0; - - if (!conn->recordlen) { - - if (inlen > TLS_MAX_PLAINTEXT_SIZE) { - inlen = TLS_MAX_PLAINTEXT_SIZE; - } - - if (conn->datalen) { - error_puts("recv all buffered data before send"); - return -1; - } - - if (conn->is_client) { - hmac_ctx = &conn->client_write_mac_ctx; - enc_key = &conn->client_write_key; - fixed_iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } else { - hmac_ctx = &conn->server_write_mac_ctx; - enc_key = &conn->server_write_key; - fixed_iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } - - if (tls_record_set_type(conn->databuf, record_type) != 1 - || tls_record_set_protocol(conn->databuf, conn->protocol) != 1 - || tls_record_set_data(conn->databuf, in, inlen) != 1) { - error_print(); - return -1; - } - if(conn->verbose) tls_record_trace(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); - + if (conn->verbose) { if (conn->protocol == TLS_protocol_tls12) { - switch (conn->cipher_suite) { - case TLS_cipher_ecdhe_sm4_gcm_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: - if (tls_gcm_encrypt(enc_key, fixed_iv, seq_num, conn->databuf, - conn->databuf + 5, tls_record_data_length(conn->databuf), - conn->record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - break; -#ifdef ENABLE_AES_CCM - case TLS_cipher_aes_128_ccm_sha256: - if (tls_ccm_encrypt(enc_key, fixed_iv, seq_num, conn->databuf, - conn->databuf + 5, tls_record_data_length(conn->databuf), - conn->record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - break; -#endif - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, conn->databuf, - conn->databuf + 5, tls_record_data_length(conn->databuf), - conn->record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - conn->record[0] = conn->databuf[0]; - conn->record[1] = conn->databuf[1]; - conn->record[2] = conn->databuf[2]; - conn->record[3] = (uint8_t)(recordlen >> 8); - conn->record[4] = (uint8_t)(recordlen); - recordlen += 5; - } else if (conn->protocol == TLS_protocol_tlcp) { - if (tlcp_record_encrypt(conn->cipher_suite, hmac_ctx, enc_key, fixed_iv, seq_num, - conn->databuf, tls_record_length(conn->databuf), - conn->record, &recordlen) != 1) { - error_print(); - return -1; - } + tls12_record_print(stderr, record, sizeof(record), 0, 0); } else { - if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, conn->databuf, - conn->databuf + 5, tls_record_data_length(conn->databuf), - conn->record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - conn->record[0] = conn->databuf[0]; - conn->record[1] = conn->databuf[1]; - conn->record[2] = conn->databuf[2]; - conn->record[3] = (uint8_t)(recordlen >> 8); - conn->record[4] = (uint8_t)(recordlen); - recordlen += 5; + tls_record_trace(stderr, record, sizeof(record), 0, 0); } - tls_seq_num_incr(seq_num); - - conn->recordlen = recordlen; - conn->record_offset = 0; - conn->sentlen = inlen; - conn->send_state = TLS_state_send_record; - if(conn->verbose) tls_encrypted_record_trace(stderr, conn->record, recordlen, 0, 0); } - - ret = tls_send_record(conn); - if (ret != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - *sentlen = conn->sentlen; - conn->send_state = 0; - tls_clean_record(conn); return 1; } + + int tls_decrypt_recv(TLS_CONNECT *conn) { int ret; @@ -2459,16 +2421,22 @@ int tls_decrypt_recv(TLS_CONNECT *conn) } conn->recv_state = 0; recordlen = conn->recordlen; - if(conn->verbose) tls_encrypted_record_trace(stderr, record, recordlen, 0, 0); + if (conn->verbose) { + if (conn->protocol == TLS_protocol_tls12) { + tls_encrypted_record_print(stderr, record, recordlen, 0, 0); + } else { + tls_encrypted_record_trace(stderr, record, recordlen, 0, 0); + } + } if (conn->protocol == TLS_protocol_tls12) { - if (tls12_record_decrypt(conn->cipher_suite, hmac_ctx, dec_key, fixed_iv, seq_num, + if (tls_record_decrypt(conn->cipher_suite, hmac_ctx, dec_key, fixed_iv, seq_num, record, recordlen, conn->databuf, &conn->datalen) != 1) { error_print(); return -1; } } else if (conn->protocol == TLS_protocol_tlcp) { - if (tlcp_record_decrypt(conn->cipher_suite, hmac_ctx, dec_key, fixed_iv, seq_num, + if (tls_record_decrypt(conn->cipher_suite, hmac_ctx, dec_key, fixed_iv, seq_num, record, recordlen, conn->databuf, &conn->datalen) != 1) { error_print(); return -1; @@ -2492,17 +2460,17 @@ int tls_decrypt_recv(TLS_CONNECT *conn) conn->data = tls_record_data(conn->databuf); conn->datalen = tls_record_data_length(conn->databuf); - if(conn->verbose) tls_record_trace(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); + if (conn->verbose) { + if (conn->protocol == TLS_protocol_tls12) { + tls12_record_print(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); + } else { + tls_record_trace(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); + } + } return 1; } -static int tls12_tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) -{ - if(conn->verbose) tls_trace("send ApplicationData\n"); - return tls_encrypt_send(conn, TLS_record_application_data, in, inlen, sentlen); -} - int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) { if (!conn) { @@ -2512,8 +2480,9 @@ int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen switch (conn->protocol) { case TLS_protocol_tlcp: + return tlcp_send(conn, in, inlen, sentlen); case TLS_protocol_tls12: - return tls12_tlcp_send(conn, in, inlen, sentlen); + return tls12_send(conn, in, inlen, sentlen); case TLS_protocol_tls13: return tls13_send(conn, in, inlen, sentlen); default: @@ -2600,6 +2569,61 @@ int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen) } } +static int tls12_send_close_notify(TLS_CONNECT *conn) +{ + int ret; + const HMAC_CTX *hmac; + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + + if (!conn) { + error_print(); + return -1; + } + + if (!conn->recordlen) { + if (conn->is_client) { + hmac = &conn->client_write_mac_ctx; + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + hmac = &conn->server_write_mac_ctx; + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if(conn->verbose) tls_trace("send Alert.close_notify\n"); + + tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, + TLS_alert_level_warning, TLS_alert_close_notify); + + if (tls_record_encrypt(conn->cipher_suite, hmac, key, iv, seq_num, + conn->plain_record, conn->plain_recordlen, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + conn->record_offset = 0; + conn->send_state = TLS_state_send_record; + } + + ret = tls_send_record(conn); + if (ret != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + conn->send_state = 0; + tls_clean_record(conn); + return 1; +} + static int tls13_send_close_notify(TLS_CONNECT *conn) { int ret; @@ -2662,14 +2686,15 @@ static int tls_send_close_notify(TLS_CONNECT *conn) return -1; } - if (conn->protocol == TLS_protocol_tls13) { + switch (conn->protocol) { + case TLS_protocol_tlcp: + case TLS_protocol_tls12: + return tls12_send_close_notify(conn); + case TLS_protocol_tls13: return tls13_send_close_notify(conn); } - - alert[0] = TLS_alert_level_warning; - alert[1] = TLS_alert_close_notify; - if(conn->verbose) tls_trace("send Alert.close_notify\n"); - return tls_encrypt_send(conn, TLS_record_alert, alert, sizeof(alert), &sentlen); + error_print(); + return -1; } int tls_shutdown(TLS_CONNECT *conn) @@ -3444,4 +3469,3 @@ int tls_get_verify_result(TLS_CONNECT *conn, int *result) *result = conn->verify_result; return 1; } - diff --git a/src/tls12.c b/src/tls12.c index 220e9e55..c92657b8 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -66,101 +66,6 @@ int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int f return tls_record_print(fp, record, recordlen, format, indent); } -static int tls12_record_encrypt(int cipher_suite, - const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_gcm_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: - if (tls_gcm_encrypt(key, fixed_iv, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; -#ifdef ENABLE_AES_CCM - case TLS_cipher_aes_128_ccm_sha256: - if (tls_ccm_encrypt(key, fixed_iv, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; -#endif - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - if (tls_cbc_encrypt(hmac_ctx, key, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (uint8_t)((*outlen) >> 8); - out[4] = (uint8_t)(*outlen); - (*outlen) += 5; - return 1; -} - -int tls12_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx, - const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - switch (cipher_suite) { - case TLS_cipher_ecdhe_sm4_gcm_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: - if (tls_gcm_decrypt(key, fixed_iv, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; -#ifdef ENABLE_AES_CCM - case TLS_cipher_aes_128_ccm_sha256: - if (tls_ccm_decrypt(key, fixed_iv, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; -#endif - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: - if (tls_cbc_decrypt(hmac_ctx, key, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (uint8_t)((*outlen) >> 8); - out[4] = (uint8_t)(*outlen); - (*outlen) += 5; - return 1; -} int tls_named_curve_oid(int named_curve) @@ -426,7 +331,8 @@ int tls_send_client_hello(TLS_CONNECT *conn) const int *client_cipher_suites = conn->ctx->cipher_suites; size_t client_cipher_suites_cnt = conn->ctx->cipher_suites_cnt; - if(conn->verbose) tls_trace("send ClientHello\n"); + if(conn->verbose) + tls_trace("send ClientHello\n"); tls_record_set_protocol(conn->record, TLS_protocol_tls1); @@ -509,7 +415,8 @@ int tls_send_client_hello(TLS_CONNECT *conn) return -1; } - tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); + if (conn->verbose) + tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); // backup ClientHello memcpy(conn->plain_record, conn->record, conn->recordlen); @@ -931,7 +838,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn) } return ret; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_protocol(conn->record) != TLS_protocol_tls1) { error_print(); @@ -1318,7 +1225,7 @@ int tls_send_server_hello(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { @@ -1361,7 +1268,8 @@ int tls_recv_server_hello(TLS_CONNECT *conn) int trusted_ca_keys = 0; int renegotiation_info = 0; - if(conn->verbose) tls_trace("recv ServerHello\n"); + if(conn->verbose) + tls_trace("recv ServerHello\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -1369,7 +1277,8 @@ int tls_recv_server_hello(TLS_CONNECT *conn) } return ret; } - tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); + if (conn->verbose) + tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); @@ -1543,7 +1452,7 @@ int tls_send_server_certificate(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); @@ -1580,7 +1489,8 @@ int tls_recv_server_certificate(TLS_CONNECT *conn) size_t signature_algorithms_cert_cnt = 0; - if(conn->verbose) tls_trace("recv server Certificate\n"); + if(conn->verbose) + tls_trace("recv server Certificate\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -1588,7 +1498,8 @@ int tls_recv_server_certificate(TLS_CONNECT *conn) } return ret; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) + tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); @@ -1616,7 +1527,8 @@ int tls_recv_server_certificate(TLS_CONNECT *conn) error_print(); return -1; } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); + if(conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); // server_sign_key @@ -1815,7 +1727,7 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); @@ -1914,10 +1826,6 @@ int tls_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite) int tls_recv_server_key_exchange(TLS_CONNECT *conn) { int ret; - uint8_t curve_type = 0; - uint16_t named_curve = 0; - const uint8_t *point_octets = NULL; - size_t point_octets_len = 0; // 这部分是被签名的值,必须要拿到 const uint8_t *server_ecdh_params; @@ -1954,7 +1862,7 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if ((ret = tls_record_get_handshake_server_key_exchange(conn->record, @@ -1969,73 +1877,24 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return 0; } - - 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(); - return -1; - } - memcpy(conn->peer_key_exchange, server_key_exchange, server_key_exchange_len); - conn->peer_key_exchange_len = server_key_exchange_len; - - - 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 (curve_type != TLS_curve_type_named_curve) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - // named_curve应该在supported_groups里面 - - conn->key_exchange_group = named_curve; - memcpy(conn->peer_key_exchange, point_octets, point_octets_len); - conn->peer_key_exchange_len = point_octets_len; + if(conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); - - if (point_octets_len != 65) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - - - if (tls_curve_match_cipher_suite(named_curve, conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_illegal_parameter); - 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; } - // 解析server_key_exchange, curve_type, curve_name, point 这三个信息 - // 判断curve_type == named_curve - // 判断curve_name在supported_groups中并记录这个信息 - // 验证point确实在curve_name的group中 - - //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); - - - 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(); @@ -2048,14 +1907,6 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn) return -1; } - - - - - // 这个检查是否是多余的? - // 这个值是签名算法和椭圆曲线名字的结合 - // cipher_suite只能决定签名算法类型 - // 公钥证书里面的公钥实际上只包含曲线的类型(而不决定签名算法,因为一个椭圆曲线本质上支持多种不同的签名算法) switch (sig_alg) { case TLS_sig_sm2sig_sm3: if (server_sign_key.algor != OID_ec_public_key @@ -2083,7 +1934,6 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn) sign_argslen = SM2_DEFAULT_ID_LENGTH; } - // 这里应该是SM2的签名和验证 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 @@ -2098,6 +1948,27 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn) 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; + // xxxx // 这里的签名错了,肯定是sign_ctx就是不对的,因此是不可能正确的 @@ -2138,7 +2009,7 @@ int tls12_send_certificate_request(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); } if ((ret = tls_send_record(conn)) != 1) { @@ -2193,7 +2064,7 @@ int tls12_recv_certificate_request(TLS_CONNECT *conn) if(conn->verbose) tls_trace(" no CertificateRequest\n"); return 0; // 表明对方没有发送预期的报文 } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls12_record_get_handshake_certificate_request(conn->record, @@ -2229,7 +2100,7 @@ int tls_send_server_hello_done(TLS_CONNECT *conn) if (conn->recordlen == 0) { tls_record_set_handshake_server_hello_done(conn->record, &conn->recordlen); - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { @@ -2272,7 +2143,7 @@ int tls_recv_server_hello_done(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_get_handshake_server_hello_done(conn->record) != 1) { error_print(); @@ -2312,7 +2183,7 @@ int tls_send_client_certificate(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); } if ((ret = tls_send_record(conn)) != 1) { @@ -2354,7 +2225,7 @@ int tls_recv_client_certificate(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_get_handshake_certificate(conn->record, conn->client_certs, &conn->client_certs_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); @@ -2377,12 +2248,6 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn) { int ret; - // 客户端的ECDHE的公钥肯定和服务器是保持一致的 - // 因此在接收到服务器的公钥之后,应该保存这个信息 - - - // 客户端是怎么确定密钥交换的group的?大概是从ServerKeyExchange中确定的 - if (conn->recordlen == 0) { uint8_t point_octets[65]; uint8_t *p = point_octets; @@ -2409,7 +2274,7 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); @@ -2454,7 +2319,7 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls12_record_get_handshake_client_key_exchange(conn->record, &point_octets, &point_octets_len) != 1) { @@ -2516,7 +2381,7 @@ int tls_send_certificate_verify(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); } if ((ret = tls_send_record(conn)) != 1) { @@ -2558,7 +2423,7 @@ int tls_recv_certificate_verify(TLS_CONNECT *conn) error_print(); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); // get signature from certificate_verify if (tls_record_get_handshake_certificate_verify(conn->record, &sig, &siglen) != 1) { @@ -2607,7 +2472,7 @@ int tls_send_change_cipher_spec(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); } if ((ret = tls_send_record(conn)) != 1) { if (ret != TLS_ERROR_SEND_AGAIN) { @@ -2636,7 +2501,7 @@ int tls_recv_change_cipher_spec(TLS_CONNECT *conn) return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_get_change_cipher_spec(conn->record) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); @@ -2671,7 +2536,7 @@ int tls_send_client_finished(TLS_CONNECT *conn) return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { error_print(); @@ -2679,7 +2544,7 @@ int tls_send_client_finished(TLS_CONNECT *conn) } if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Finished", &conn->dgst_ctx); - if (tls12_record_encrypt(conn->cipher_suite, + 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) { @@ -2753,7 +2618,7 @@ int tls_recv_client_finished(TLS_CONNECT *conn) format_bytes(stderr, 0, 0, "client_seq_num", conn->client_seq_num, 8); } - if (tls12_record_decrypt(conn->cipher_suite, &conn->client_write_mac_ctx, &conn->client_write_key, + 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) { error_print(); @@ -2764,7 +2629,7 @@ int tls_recv_client_finished(TLS_CONNECT *conn) - if(conn->verbose) tls12_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { error_print(); @@ -2825,9 +2690,9 @@ int tls_send_server_finished(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); - if (tls12_record_encrypt(conn->cipher_suite, + if (tls_record_encrypt(conn->cipher_suite, &conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv, conn->server_seq_num, conn->plain_record, conn->plain_recordlen, conn->record, &conn->recordlen) != 1) { @@ -2892,14 +2757,14 @@ int tls_recv_server_finished(TLS_CONNECT *conn) format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); } - if (tls12_record_decrypt(conn->cipher_suite, &conn->server_write_mac_ctx, &conn->server_write_key, + 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(); tls_send_alert(conn, TLS_alert_bad_record_mac); return -1; } - tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); + if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); tls_seq_num_incr(conn->server_seq_num); @@ -2924,6 +2789,131 @@ int tls_recv_server_finished(TLS_CONNECT *conn) return 1; } +int tls12_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) +{ + const HMAC_CTX *hmac_ctx; + const BLOCK_CIPHER_KEY *enc_key; + const uint8_t *fixed_iv; + uint8_t *seq_num; + size_t recordlen; + int ret; + + if (!conn) { + error_print(); + return -1; + } + if (!in || !inlen || !sentlen) { + error_print(); + return -1; + } + if (conn->recv_state) { + *sentlen = 0; + return TLS_ERROR_RECV_AGAIN; + } + if (conn->send_state && conn->send_state != TLS_state_send_record) { + error_print(); + return -1; + } + + *sentlen = 0; + + if (!conn->recordlen) { + + if (inlen > TLS_MAX_PLAINTEXT_SIZE) { + inlen = TLS_MAX_PLAINTEXT_SIZE; + } + + if (conn->datalen) { + error_puts("recv all buffered data before send"); + return -1; + } + + if (conn->is_client) { + hmac_ctx = &conn->client_write_mac_ctx; + enc_key = &conn->client_write_key; + fixed_iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + hmac_ctx = &conn->server_write_mac_ctx; + enc_key = &conn->server_write_key; + fixed_iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls_record_set_type(conn->databuf, TLS_record_application_data) != 1 + || tls_record_set_protocol(conn->databuf, conn->protocol) != 1 + || tls_record_set_data(conn->databuf, in, inlen) != 1) { + error_print(); + return -1; + } + if(conn->verbose) tls12_record_print(stderr, conn->databuf, tls_record_length(conn->databuf), 0, 0); + + switch (conn->cipher_suite) { + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: + if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, conn->databuf, + conn->databuf + 5, tls_record_data_length(conn->databuf), + conn->record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + break; + + case TLS_cipher_ecdhe_sm4_gcm_sm3: + case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256: + if (tls_gcm_encrypt(enc_key, fixed_iv, seq_num, conn->databuf, + conn->databuf + 5, tls_record_data_length(conn->databuf), + conn->record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + break; + +#ifdef ENABLE_AES_CCM + case TLS_cipher_ecdhe_ecdsa_aes_128_ccm_sha256: + if (tls_ccm_encrypt(enc_key, fixed_iv, seq_num, conn->databuf, + conn->databuf + 5, tls_record_data_length(conn->databuf), + conn->record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + break; +#endif + + default: + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + + conn->record[0] = conn->databuf[0]; + conn->record[1] = conn->databuf[1]; + conn->record[2] = conn->databuf[2]; + conn->record[3] = (uint8_t)(recordlen >> 8); + conn->record[4] = (uint8_t)(recordlen); + recordlen += 5; + + conn->recordlen = recordlen; + conn->record_offset = 0; + conn->sentlen = inlen; + conn->send_state = TLS_state_send_record; + if(conn->verbose) tls12_record_print(stderr, conn->record, recordlen, 0, 0); + } + + ret = tls_send_record(conn); + if (ret != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + *sentlen = conn->sentlen; + conn->send_state = 0; + tls_clean_record(conn); + return 1; +} + /*