From 732a77c3a4ae4ca179855361e1527688be7f0dac Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 16 Jun 2026 12:20:20 +0800 Subject: [PATCH] Clean TLS code --- CMakeLists.txt | 2 +- include/gmssl/tls.h | 17 +- include/gmssl/version.h | 2 +- src/tlcp.c | 589 +++++++++++----------------------------- src/tls.c | 199 +++++++------- src/tls12.c | 145 ++++++---- tools/tlcp_client.c | 2 +- tools/tlcp_help.h | 4 +- tools/tlcp_server.c | 2 +- tools/tls12_client.c | 2 +- tools/tls12_server.c | 2 +- tools/tls13_client.c | 2 +- tools/tls13_server.c | 2 +- 13 files changed, 381 insertions(+), 589 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2335a93..0e3eeab9 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.1059") +set(CPACK_PACKAGE_VERSION "3.2.0-dev.1060") 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 4a6e738a..589ddc73 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -1188,11 +1188,13 @@ typedef struct { BLOCK_CIPHER_KEY client_write_key; BLOCK_CIPHER_KEY server_write_key; - uint8_t pre_master_secret[48]; // 是否可以重用master_secret作为pre_master_secret呢? + uint8_t pre_master_secret[48]; + size_t pre_master_secret_len; uint8_t master_secret[48]; uint8_t resumption_master_secret[48]; uint8_t key_block[96]; + size_t key_block_len; uint8_t early_secret[32]; @@ -1214,6 +1216,9 @@ typedef struct { // CertificateRequest int certificate_request; + uint8_t transcript[TLS_MAX_RECORD_SIZE * 2]; + size_t transcript_len; + // NewSessionTicket int new_session_ticket; @@ -1493,14 +1498,22 @@ int tls13_ctx_set_change_cipher_spec_compat(TLS_CTX *ctx, int enable); int tls13_ctx_set_accept_change_cipher_spec(TLS_CTX *ctx, int enable); int tls13_ctx_enable_change_cipher_spec(TLS_CTX *ctx, int enable); +int tlcp_generate_pre_master_secret(TLS_CONNECT *conn); +int tlcp_check_pre_master_secret(TLS_CONNECT *conn); +int tls_derive_pre_master_secret(TLS_CONNECT *conn); +int tls_derive_master_secret(TLS_CONNECT *conn); +int tls_derive_key_block(TLS_CONNECT *conn); +int tls_init_application_keys(TLS_CONNECT *conn); -int tls_generate_keys(TLS_CONNECT *conn); int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12]); + + + int tls13_update_client_application_keys(TLS_CONNECT *conn); int tls13_update_server_application_keys(TLS_CONNECT *conn); diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 7a759b19..2bb6d721 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.1059" +#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1060" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/src/tlcp.c b/src/tlcp.c index 20c175fe..ad083db8 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -24,6 +24,40 @@ #include +/* +TLCP只支持SM3,这使得transcript-hash的计算更简单 + +对于服务器来说,ServerKeyExchange中的签名并不是对transcript-hash做的 +而是对random, server_cert做的,并且服务器知道自己的ID和公钥, +因此都可以在send_server_key_exchange中完成 + +但是如果要做CertificateVerify +被签名的消息: + +ClientHello +ServerHello +server Certificate +ServerKeyExchange +CertificateRequest +ServerHelloDone +client Certificate +ClientKeyExchange + +服务器只有在接收到client Certificate的时候才知道客户端的公钥,才能启动签名验证 +因此对于服务器来说,必须备份所有的消息。 + + +支持SNI的时候,客户端可能有多个签名私钥。 +为了简便起见,我们缓冲所有的消息,直到ClientKeyExchange +客户端在这个时候启动签名 + +服务器端也可以在这个时候验证签名 + +这是最简单的,而且对于TLCP, TLS12都是一样的 +*/ + + + const int tlcp_supported_groups[] = { TLS_curve_sm2p256v1, }; @@ -50,79 +84,6 @@ int tlcp_record_print(FILE *fp, int fmt, int ind, const uint8_t *record, size_t record, recordlen); } -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) -{ - switch (cipher_suite) { - case TLS_cipher_ecc_sm4_cbc_sm3: - 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: - if (tls_gcm_encrypt(key, fixed_iv, 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 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) -{ - switch (cipher_suite) { - case TLS_cipher_ecc_sm4_cbc_sm3: - 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: - if (tls_gcm_decrypt(key, fixed_iv, 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; -} - - /* ServerKeyExchange @@ -162,7 +123,6 @@ select (KeyExchangeAlgorithm) { `signed_params` is DER signature encoded in uint16array */ - int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t datalen, int fmt, int ind) { const uint8_t *sig; @@ -308,9 +268,8 @@ struct { opaque RSAEncryptedPreMasterSecret<0..2^16-1>; } exchange_keys; } ClientKeyExchange; - -// 不管算法是什么,数据格式都是uint16array */ + int tlcp_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen, const uint8_t *enced_pms, size_t enced_pms_len) { @@ -356,13 +315,16 @@ int tlcp_record_get_handshake_client_key_exchange(const uint8_t *record, error_print(); return -1; } + if (!enced_pms_len) { + error_print(); + return -1; + } return 1; } /* struct { ClientCertificateType certificate_types<1..2^8-1>; - SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; // TLS 1.2 only DistinguishedName certificate_authorities<0..2^16-1>; } CertificateRequest; */ @@ -566,9 +528,8 @@ int tlcp_send_client_hello(TLS_CONNECT *conn) error_print(); return -1; } - if (conn->verbose) { + if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); - } if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); @@ -625,6 +586,13 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn) if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + return -1; + } + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); + if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { error_print(); tls_send_alert(conn, TLS_alert_protocol_version); @@ -645,6 +613,8 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn) } memcpy(conn->server_random, server_random, 32); memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + if (tls_type_is_in_list(cipher_suite, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) { error_print(); @@ -793,13 +763,6 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn) conn->application_layer_protocol_negotiation = 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, "ServerHello", &conn->dgst_ctx); - if (conn->client_certs_len) { sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); } @@ -810,10 +773,9 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn) int tlcp_recv_server_certificate(TLS_CONNECT *conn) { int ret; - int verify_result; const uint8_t *server_cert; size_t server_cert_len; - + int verify_result; if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -826,26 +788,16 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn) if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); - if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - 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 (conn->client_certs_len) { - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - } + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); + tls_send_alert(conn, TLS_alert_protocol_version); return -1; } @@ -855,7 +807,6 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - 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(); @@ -874,6 +825,8 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn) return -1; } } + // FIXME: 需要根据密码套件、ClientHello扩展等对证书做进一步的验证 + // x509_certs_verify_tlcp 只是验证证书链有效,不能完全判定服务器证书有效 if (conn->ctx->cacertslen) { if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, @@ -884,6 +837,10 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn) } } + if (conn->client_certs_len) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + return 1; } @@ -913,6 +870,13 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn) if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + return -1; + } + if(conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); + if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { error_print(); tls_send_alert(conn, TLS_alert_protocol_version); @@ -924,18 +888,11 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn) 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, "ServerKeyExchange", &conn->dgst_ctx); // verify ServerKeyExchange if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, &sign_cert, &sign_cert_len) != 1 || x509_cert_get_subject_public_key(sign_cert, sign_cert_len, &sign_key) != 1 - || x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 1, &enc_cert, &enc_cert_len) != 1 - || x509_cert_get_subject_public_key(enc_cert, enc_cert_len, &conn->server_enc_key) != 1) { // 这个不应该在这里取 + || x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 1, &enc_cert, &enc_cert_len) != 1) { error_print(); return -1; } @@ -1015,7 +972,6 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn) return -1; } - // 当采用SM9时有什么特别处理? if (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); @@ -1026,8 +982,9 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn) error_print(); return -1; } + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx); - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx); sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); @@ -1149,7 +1106,10 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn) return -1; } - if (tls_pre_master_secret_generate(conn->pre_master_secret, TLS_protocol_tlcp) != 1) { + if (tlcp_generate_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; } @@ -1175,6 +1135,7 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn) } if (conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); + } if ((ret = tls_send_record(conn)) != 1) { @@ -1186,23 +1147,10 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn) tls_clean_record(conn); - if (tlcp_generate_keys(conn) != 1) { - error_print(); - return -1; - } return 1; } - - - - - - - - - int tlcp_send_certificate_verify(TLS_CONNECT *conn) { int ret; @@ -1251,12 +1199,12 @@ int tlcp_send_client_finished(TLS_CONNECT *conn) if (conn->recordlen == 0) { uint8_t verify_data[12]; - if(conn->verbose) tls_trace("send client {Finished}\n"); - + if (conn->verbose) + tls_trace("send client {Finished}\n"); if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, verify_data) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } @@ -1265,7 +1213,7 @@ int tlcp_send_client_finished(TLS_CONNECT *conn) if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, verify_data, sizeof(verify_data)) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } @@ -1276,19 +1224,17 @@ int tlcp_send_client_finished(TLS_CONNECT *conn) error_print(); return -1; } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx); + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx); - - if (tlcp_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) { - error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } - tls_seq_num_incr(conn->client_seq_num); } @@ -1298,8 +1244,6 @@ int tlcp_send_client_finished(TLS_CONNECT *conn) } return ret; } - - return 1; } @@ -1314,7 +1258,6 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn) uint8_t local_verify_data[12]; - if(conn->verbose) tls_trace("recv server {Finished}\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -1322,50 +1265,53 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn) } return ret; } + if(conn->verbose) + tls_trace("recv server {Finished}\n"); + if (conn->verbose) tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0); if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { error_print(); - tlcp_send_alert(conn, TLS_alert_unexpected_message); + tls12_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if (tlcp_record_decrypt(conn->cipher_suite, + 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(); - tlcp_send_alert(conn, TLS_alert_bad_record_mac); + tls12_send_alert(conn, TLS_alert_bad_record_mac); return -1; } tls_seq_num_incr(conn->server_seq_num); if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - - // 最后没有必要再计算handshke_digest了 + // no more digest_update if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_unexpected_message); + tls12_send_alert(conn, TLS_alert_unexpected_message); return -1; } if (verify_data_len != sizeof(local_verify_data)) { error_print(); - tlcp_send_alert(conn, TLS_alert_unexpected_message); + tls12_send_alert(conn, TLS_alert_unexpected_message); return -1; } if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, local_verify_data) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } + memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx)); if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { error_print(); - tlcp_send_alert(conn, TLS_alert_decrypt_error); + tls12_send_alert(conn, TLS_alert_decrypt_error); return -1; } @@ -1889,22 +1835,6 @@ int tlcp_send_server_hello(TLS_CONNECT *conn) return 1; } - -/* --- IBC_SM4_CBC_SM3 和 IBC_SM4_GCM_SM3 套件的服务器Certificate消息格式 - -opaque ASN.1IBCParam<1..2^24-1> - -struct { - opaque ibc_id<1..2^16-1>; - ASN.1IBCParam ibc_parameter; -} Certificate; - -其中ibc_id是服务器的SM9的ID,这个ID暂时是一个没有内部结构的字节串,后续有可能是一个DER结构的字节串 -ibc_parameter 是SM9 sm9_enc_master_key_to_der 输出的DER数据 - - -*/ int tlcp_send_server_certificate(TLS_CONNECT *conn) { int ret; @@ -2026,134 +1956,6 @@ int tlcp_send_server_key_exchange(TLS_CONNECT *conn) return 1; } - - - - - - - - - - - - - - - - -static int tlcp_generate_master_secret(TLS_CONNECT *conn) -{ - if (!conn) { - error_print(); - return -1; - } - if (tls_prf(conn->digest, conn->pre_master_secret, 48, "master secret", - conn->client_random, 32, - conn->server_random, 32, - 48, conn->master_secret) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - return 1; -} - -static int tlcp_generate_key_block(TLS_CONNECT *conn) -{ - size_t key_block_len; - - if (!conn) { - error_print(); - return -1; - } - switch (conn->cipher_suite) { - case TLS_cipher_ecc_sm4_gcm_sm3: - if (!conn->cipher) { - error_print(); - return -1; - } - key_block_len = conn->cipher->key_size * 2 + 8; - break; - case TLS_cipher_ecc_sm4_cbc_sm3: - key_block_len = 96; - break; - default: - error_print(); - return -1; - } - if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion", - conn->server_random, 32, - conn->client_random, 32, - key_block_len, conn->key_block) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - return 1; -} - -static int tlcp_generate_record_keys(TLS_CONNECT *conn) -{ - if (!conn) { - error_print(); - return -1; - } - switch (conn->cipher_suite) { - case TLS_cipher_ecc_sm4_gcm_sm3: - { - size_t keylen; - - if (!conn->cipher) { - error_print(); - return -1; - } - keylen = conn->cipher->key_size; - - memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv)); - memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv)); - memcpy(conn->client_write_iv, conn->key_block + keylen * 2, 4); - memcpy(conn->server_write_iv, conn->key_block + keylen * 2 + 4, 4); - - if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1 - || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + keylen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - break; - } - case TLS_cipher_ecc_sm4_cbc_sm3: - if (hmac_init(&conn->client_write_mac_ctx, conn->digest, conn->key_block, 32) != 1 - || hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - - if (conn->is_client) { - if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1 - || block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - } else { - if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1 - || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - } - break; - default: - error_print(); - return -1; - } - return 1; -} - static void tlcp_secrets_print(TLS_CONNECT *conn) { if (conn->verbose < 5) { @@ -2181,25 +1983,47 @@ static void tlcp_secrets_print(TLS_CONNECT *conn) } } -int tlcp_generate_keys(TLS_CONNECT *conn) +int tlcp_generate_pre_master_secret(TLS_CONNECT *conn) { - if(conn->verbose) tls_trace("generate secrets\n"); + uint8_t *pre_master_secret; + size_t len = 0; - if (tlcp_generate_master_secret(conn) != 1 - || tlcp_generate_key_block(conn) != 1 - || tlcp_generate_record_keys(conn) != 1) { + if (!conn || conn->protocol != TLS_protocol_tlcp) { error_print(); return -1; } - tls_seq_num_reset(conn->client_seq_num); - tls_seq_num_reset(conn->server_seq_num); - - tlcp_secrets_print(conn); - + pre_master_secret = conn->pre_master_secret; + tls_uint16_to_bytes((uint16_t)conn->protocol, &pre_master_secret, &len); + if (rand_bytes(pre_master_secret, 46) != 1) { + error_print(); + return -1; + } + conn->pre_master_secret_len = 48; return 1; } +int tlcp_check_pre_master_secret(TLS_CONNECT *conn) +{ + const uint8_t *pre_master_secret; + size_t len = 2; + uint16_t protocol; + if (!conn || conn->protocol != TLS_protocol_tlcp + || conn->pre_master_secret_len != 48) { + error_print(); + return -1; + } + pre_master_secret = conn->pre_master_secret; + if (tls_uint16_from_bytes(&protocol, &pre_master_secret, &len) != 1) { + error_print(); + return -1; + } + if (protocol != conn->protocol) { + error_print(); + return -1; + } + return 1; +} int tlcp_send_certificate_request(TLS_CONNECT *conn) { @@ -2259,13 +2083,10 @@ int tlcp_recv_client_certificate(TLS_CONNECT *conn) int tlcp_recv_client_key_exchange(TLS_CONNECT *conn) { + int ret; const uint8_t *enced_pms; size_t enced_pms_len; - size_t pre_master_secret_len; X509_KEY *enc_key; - int ret; - - if(conn->verbose) tls_trace("recv ClientKeyExchange\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -2273,6 +2094,8 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn) } return ret; } + if (conn->verbose) + tls_trace("recv ClientKeyExchange\n"); if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { error_print(); @@ -2282,11 +2105,24 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn) if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); - if (tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len) != 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, "ClientKeyExchange", &conn->dgst_ctx); + + if ((ret = tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_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 -1; } + + // decrypt enced_pre_master_secret if (!conn->cert_chain_idx) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); @@ -2298,34 +2134,20 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_internal_error); return -1; } - - // FIXME: - // 这里需要检查一下密钥的长度,因为输入的长度是确定的,因此输出的密文长度应该也是确定的 - if (sm2_decrypt(&enc_key->u.sm2_key, enced_pms, enced_pms_len, - conn->pre_master_secret, &pre_master_secret_len) != 1) { + conn->pre_master_secret, &conn->pre_master_secret_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_decrypt_error); return -1; } - if (pre_master_secret_len != 48) { + if (tlcp_check_pre_master_secret(conn) != 1) { error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); + tls_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - if ((((uint16_t)conn->pre_master_secret[0] << 8) | conn->pre_master_secret[1]) - != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - 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, "ClientKeyExchange", &conn->dgst_ctx); - - if (tlcp_generate_keys(conn) != 1) { + if (tls_derive_master_secret(conn) != 1 + || tls_derive_key_block(conn) != 1 + || tls_init_application_keys(conn) != 1) { error_print(); return -1; } @@ -2354,7 +2176,7 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn) if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, local_verify_data) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } @@ -2368,15 +2190,15 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn) } if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); - tlcp_send_alert(conn, TLS_alert_unexpected_message); + tls12_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if (tlcp_record_decrypt(conn->cipher_suite, + 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(); - tlcp_send_alert(conn, TLS_alert_bad_record_mac); + tls12_send_alert(conn, TLS_alert_bad_record_mac); return -1; } tls_seq_num_incr(conn->client_seq_num); @@ -2386,13 +2208,13 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn) if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_unexpected_message); + tls12_send_alert(conn, TLS_alert_unexpected_message); return -1; } if (verify_data_len != sizeof(local_verify_data) || memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { error_print(); - tlcp_send_alert(conn, TLS_alert_decrypt_error); + tls12_send_alert(conn, TLS_alert_decrypt_error); return -1; } @@ -2416,7 +2238,7 @@ int tlcp_send_server_finished(TLS_CONNECT *conn) if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, verify_data) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } @@ -2425,18 +2247,18 @@ int tlcp_send_server_finished(TLS_CONNECT *conn) if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, verify_data, sizeof(verify_data)) != 1) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } if (conn->verbose) tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - if (tlcp_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) { error_print(); - tlcp_send_alert(conn, TLS_alert_internal_error); + tls12_send_alert(conn, TLS_alert_internal_error); return -1; } tls_seq_num_incr(conn->server_seq_num); @@ -2564,98 +2386,6 @@ int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentle return 1; } -static int tlcp_send_encrypted_alert(TLS_CONNECT *conn, int level, int alert) -{ - const HMAC_CTX *hmac; - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - int ret; - - if (!conn) { - error_print(); - return -1; - } - if (!tls_alert_level_name(level) || !tls_alert_description_text(alert)) { - error_print(); - return -1; - } - if (conn->send_state && conn->send_state != TLS_state_send_record) { - error_print(); - return -1; - } - if (conn->send_state == TLS_state_send_record - && tls_record_type(conn->record) != TLS_record_alert) { - error_print(); - return -1; - } - - if (!conn->send_state) { - tls_clean_record(conn); - conn->plain_recordlen = 0; - - 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; - } - - tls_record_set_protocol(conn->plain_record, conn->protocol); - if (tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, level, alert) != 1) { - error_print(); - return -1; - } - if (conn->verbose) { - tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - } - - if (tlcp_record_encrypt(conn->cipher_suite, hmac, key, iv, seq_num, - conn->plain_record, conn->plain_recordlen, - conn->record, &conn->recordlen) != 1) { - error_print(); - conn->plain_recordlen = 0; - tls_clean_record(conn); - return -1; - } - tls_seq_num_incr(seq_num); - conn->record_offset = 0; - conn->send_state = TLS_state_send_record; - - if (conn->verbose) { - tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0); - } - } - - ret = tls_send_record(conn); - if (ret != 1) { - if (ret != TLS_ERROR_SEND_AGAIN) { - error_print(); - } - return ret; - } - - conn->send_state = 0; - conn->plain_recordlen = 0; - tls_clean_record(conn); - return 1; -} - -int tlcp_send_alert(TLS_CONNECT *conn, int alert) -{ - return tlcp_send_encrypted_alert(conn, TLS_alert_level_fatal, alert); -} - -int tlcp_send_warning(TLS_CONNECT *conn, int alert) -{ - return tlcp_send_encrypted_alert(conn, TLS_alert_level_warning, alert); -} - /* Client Server @@ -2902,7 +2632,6 @@ int tlcp_server_handshake(TLS_CONNECT *conn) { int ret; - while (conn->handshake_state != TLS_state_handshake_over) { ret = tlcp_do_server_handshake(conn); diff --git a/src/tls.c b/src/tls.c index 50202334..2d3c9ff8 100644 --- a/src/tls.c +++ b/src/tls.c @@ -789,21 +789,6 @@ int tls_prf(const DIGEST *digest, const uint8_t *secret, size_t secretlen, const return 1; } -int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol) -{ - if (!tls_protocol_name(protocol)) { - error_print(); - return -1; - } - pre_master_secret[0] = (uint8_t)(protocol >> 8); - pre_master_secret[1] = (uint8_t)(protocol); - if (rand_bytes(pre_master_secret + 2, 46) != 1) { - error_print(); - return -1; - } - return 1; -} - int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12]) { @@ -837,63 +822,83 @@ int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48 return 1; } -static int tls_generate_pre_master_secret(TLS_CONNECT *conn, - uint8_t *pre_master_secret, size_t *pre_master_secret_len) + + + +int tls_derive_pre_master_secret(TLS_CONNECT *conn) { - if (!conn || !pre_master_secret || !pre_master_secret_len) { + if (!conn || conn->peer_key_exchange_len != 65) { error_print(); return -1; } if (x509_key_exchange(&conn->key_exchanges[0], conn->peer_key_exchange, - conn->peer_key_exchange_len, pre_master_secret, pre_master_secret_len) != 1) { + conn->peer_key_exchange_len, conn->pre_master_secret, &conn->pre_master_secret_len) != 1) { error_print(); return -1; } - if (*pre_master_secret_len != 32) { + if (conn->pre_master_secret_len != 32) { error_print(); return -1; } - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "pre_master_secret", pre_master_secret, *pre_master_secret_len); - } return 1; } -static int tls_generate_master_secret(TLS_CONNECT *conn, - const uint8_t *pre_master_secret, size_t pre_master_secret_len) +int tls_derive_master_secret(TLS_CONNECT *conn) { - if (!conn || !pre_master_secret || pre_master_secret_len != 32) { + if (!conn || !conn->digest) { error_print(); return -1; } - if (tls_prf(conn->digest, pre_master_secret, pre_master_secret_len, - "master secret", - conn->client_random, 32, - conn->server_random, 32, - 48, conn->master_secret) != 1) { + switch (conn->protocol) { + case TLS_protocol_tlcp: + if (conn->pre_master_secret_len != 48) { + error_print(); + return -1; + } + break; + case TLS_protocol_tls12: + if (conn->pre_master_secret_len != 32) { + error_print(); + return -1; + } + break; + default: error_print(); return -1; } - if (conn->verbose >= 5) { + if (tls_prf(conn->digest, conn->pre_master_secret, conn->pre_master_secret_len, + "master secret", + conn->client_random, 32, + conn->server_random, 32, + 48, conn->master_secret) != 1) { + error_print(); + return -1; + } + if (conn->verbose == 5) { format_bytes(stderr, 0, 0, "master_secret", conn->master_secret, 48); } return 1; } -static int tls_generate_key_block(TLS_CONNECT *conn) +int tls_derive_key_block(TLS_CONNECT *conn) { - size_t key_block_len; + if (!conn || !conn->cipher || !conn->digest) { + error_print(); + return -1; + } switch (conn->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: - key_block_len = 96; + conn->key_block_len = (conn->cipher->key_size + conn->digest->digest_size) * 2; + assert(conn->key_block_len == 96); 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: - key_block_len = 40; + conn->key_block_len = (conn->cipher->key_size + 4) * 2; + assert(conn->key_block_len == 40); break; default: error_print(); @@ -901,68 +906,86 @@ static int tls_generate_key_block(TLS_CONNECT *conn) } if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion", - conn->server_random, 32, - conn->client_random, 32, - key_block_len, conn->key_block) != 1) { + conn->server_random, 32, + conn->client_random, 32, + conn->key_block_len, conn->key_block) != 1) { error_print(); return -1; } - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, key_block_len); + if (conn->verbose == 5) { + format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, conn->key_block_len); } return 1; } -static int tls_generate_record_keys(TLS_CONNECT *conn) +int tls_init_application_keys(TLS_CONNECT *conn) { + size_t keylen; + + if (!conn || !conn->cipher || !conn->digest || !conn->key_block_len) { + error_print(); + return -1; + } + keylen = conn->cipher->key_size; + switch (conn->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: + { + size_t dgstlen = conn->digest->digest_size; + + if (hmac_init(&conn->client_write_mac_ctx, conn->digest, + conn->key_block, dgstlen) != 1 + || hmac_init(&conn->server_write_mac_ctx, conn->digest, + conn->key_block + dgstlen, dgstlen) != 1) { + error_print(); + return -1; + } + if (conn->is_client) { + if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, + conn->key_block + dgstlen * 2) != 1 + || block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, + conn->key_block + dgstlen * 2 + keylen) != 1) { + error_print(); + return -1; + } + } else { + if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, + conn->key_block + dgstlen * 2) != 1 + || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, + conn->key_block + dgstlen * 2 + keylen) != 1) { + error_print(); + return -1; + } + } + if (conn->verbose >= 5) { + format_bytes(stderr, 0, 0, "client_write_mac_key", conn->key_block, dgstlen); + format_bytes(stderr, 0, 0, "server_write_mac_key", conn->key_block + dgstlen, dgstlen); + format_bytes(stderr, 0, 0, "client_write_key", conn->key_block + dgstlen * 2, keylen); + format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + dgstlen * 2 + keylen, keylen); + } + } + 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 (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1 - || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 16) != 1) { + || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + keylen) != 1) { error_print(); return -1; } memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv)); memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv)); - memcpy(conn->client_write_iv, conn->key_block + 32, 4); - memcpy(conn->server_write_iv, conn->key_block + 36, 4); + memcpy(conn->client_write_iv, conn->key_block + keylen * 2, 4); + memcpy(conn->server_write_iv, conn->key_block + keylen * 2 + 4, 4); if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "client_write_key", conn->key_block, 16); - format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + 16, 16); - format_bytes(stderr, 0, 0, "client_write_iv", conn->key_block + 32, 4); - format_bytes(stderr, 0, 0, "server_write_iv", conn->key_block + 36, 4); - } - break; - - 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 (hmac_init(&conn->client_write_mac_ctx, conn->digest, conn->key_block, 32) != 1 - || hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 1) { - error_print(); - return -1; - } - if (conn->is_client) { - if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1 - || block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) { - error_print(); - return -1; - } - } else { - if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1 - || block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) { - error_print(); - return -1; - } - } - if (conn->verbose >= 5) { - format_bytes(stderr, 0, 0, "client_write_mac_key", conn->key_block, 32); - format_bytes(stderr, 0, 0, "server_write_mac_key", conn->key_block + 32, 32); - format_bytes(stderr, 0, 0, "client_write_key", conn->key_block + 64, 16); - format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + 80, 16); + format_bytes(stderr, 0, 0, "client_write_key", conn->key_block, keylen); + format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + keylen, keylen); + format_bytes(stderr, 0, 0, "client_write_iv", conn->key_block + keylen * 2, 4); + format_bytes(stderr, 0, 0, "server_write_iv", conn->key_block + keylen * 2 + 4, 4); } break; @@ -970,28 +993,13 @@ static int tls_generate_record_keys(TLS_CONNECT *conn) error_print(); return -1; } - return 1; -} -int tls_generate_keys(TLS_CONNECT *conn) -{ - uint8_t pre_master_secret[32]; - size_t pre_master_secret_len; - - if (tls_generate_pre_master_secret(conn, pre_master_secret, &pre_master_secret_len) != 1 - || tls_generate_master_secret(conn, pre_master_secret, pre_master_secret_len) != 1 - || tls_generate_key_block(conn) != 1 - || tls_generate_record_keys(conn) != 1) { - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - error_print(); - return -1; - } - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); tls_seq_num_reset(conn->client_seq_num); tls_seq_num_reset(conn->server_seq_num); return 1; } + int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx) { if (!ctx) { @@ -1124,9 +1132,6 @@ int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t me 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, diff --git a/src/tls12.c b/src/tls12.c index 56dcf0c1..6424d5ee 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -22,8 +22,52 @@ #include #include +/* +TLS 1.2中,服务器和客户端的签名算法是独立的 +有可能密码套件中的哈希函数是SHA256 +服务器的签名算法是 ecdsa+sha512 +客户端的签名算法是 ecdsa+sha384 +客户端可以在ClientHello.signature_algorithms中限定服务器的签名算法 +客户端要等到ServerKeyExchange时,才能确定服务器的签名算法是什么 +这意味着,此时客户端才知道验证签名的transcript-hash到底是用什么计算出来的 + + +ClientHello +ServerHello +server Certificate +ServerKeyExchange +CertificateRequest +ServerHelloDone +client Certificate +ClientKeyExchange +CertificateVerify + + +如果客户端发送了 ClientHello.signature_algorithms +那么服务器的 CertificateRequest.supported_signature_algorithms 必须是ClientHello.signature_algorithms的子集 + + +struct { + uint8 hash_algorithm; + uint8 signature_algorithm; + uint16 signature_length; + opaque signature[signature_length]; +} CertificateVerify; + + +客户端CertificateVerify.(hash_algorithm+signature_algorithm) 必须是CertificateRequest.supported_signature_algorithms的子集 + + +如果不进行客户端证书认证 + 服务器: + 接收到ClientHello的时候,就能够确定自己的签名算法,也就是服务器一开始就可以确定hash算法 + 客户端: + ClientHello: 对服务器的签名算法限定 + +*/ + const int tls12_supported_groups[] = { TLS_curve_sm2p256v1, @@ -64,8 +108,6 @@ int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int f record, recordlen); } - - int tls_named_curve_oid(int named_curve) { switch (named_curve) { @@ -129,10 +171,6 @@ int tls12_record_get_handshake_client_key_exchange(const uint8_t *record, return 1; } - - - - /* struct { ClientCertificateType certificate_types<1..2^8-1>; @@ -1255,7 +1293,6 @@ int tls_recv_client_hello(TLS_CONNECT *conn) - /* if (client_verify) tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); @@ -2226,7 +2263,6 @@ int tls_send_server_hello_done(TLS_CONNECT *conn) return 1; } - // 这是一个非常特殊的状态,其他的所有recv状态都是要读取的 // 但是这个状态在大多数情况下,之前已经读取完了,但是我们无法判断这个信息 int tls_recv_server_hello_done(TLS_CONNECT *conn) @@ -2345,44 +2381,59 @@ 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 *p = point_octets; - size_t len = 0; + 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], &p, &len) != 1) { + if (x509_public_key_to_bytes(&conn->key_exchanges[0], &point_octets_ptr, &point_octets_len) != 1) { error_print(); return -1; } - if (len != sizeof(point_octets)) { + if (point_octets_len != sizeof(point_octets)) { error_print(); return -1; } - - if(conn->verbose) tls_trace("send ClientKeyExchange\n"); if (tls12_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen, - point_octets, len) != 1) { + point_octets, point_octets_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); return -1; } - if(conn->verbose) tls12_record_print(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(); return -1; } - if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); + + 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) { @@ -2392,14 +2443,6 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn) return ret; } - if (conn->client_certs_len) - sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); - - if (tls_generate_keys(conn) != 1) { - error_print(); - return -1; - } - return 1; } @@ -2409,19 +2452,29 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn) const uint8_t *point_octets; size_t point_octets_len; - if(conn->verbose) tls_trace("recv ClientKeyExchange\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); } return ret; } + if (conn->verbose) + tls_trace("recv ClientKeyExchange\n"); + if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); return -1; } - if(conn->verbose) tls12_record_print(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(); + return -1; + } + if (conn->verbose) + tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); if (tls12_record_get_handshake_client_key_exchange(conn->record, &point_octets, &point_octets_len) != 1) { @@ -2433,25 +2486,19 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn) error_print(); return -1; } - memcpy(conn->peer_key_exchange, point_octets, point_octets_len); conn->peer_key_exchange_len = point_octets_len; - - if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + 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(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); - - - if (conn->ctx->cacertslen) + if (conn->ctx->cacertslen) { tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); - - if (tls_generate_keys(conn) != 1) { - error_print(); - return -1; } return 1; @@ -2588,15 +2635,7 @@ int tls_send_change_cipher_spec(TLS_CONNECT *conn) int tls_recv_change_cipher_spec(TLS_CONNECT *conn) { int ret; - int (*send_alert)(TLS_CONNECT *conn, int alert) = tls_send_alert; - if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) { - if (conn->protocol == TLS_protocol_tlcp) { - send_alert = tlcp_send_alert; - } else { - send_alert = tls12_send_alert; - } - } if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); @@ -2608,14 +2647,20 @@ int tls_recv_change_cipher_spec(TLS_CONNECT *conn) if (tls_record_protocol(conn->record) != conn->protocol) { error_print(); - 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) + 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_get_change_cipher_spec(conn->record) != 1) { error_print(); - 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; } return 1; diff --git a/tools/tlcp_client.c b/tools/tlcp_client.c index 59bfdcb6..340110e8 100644 --- a/tools/tlcp_client.c +++ b/tools/tlcp_client.c @@ -341,7 +341,7 @@ int tlcp_client_main(int argc, char *argv[]) if (--argc < 1) goto bad; certoutfile = *(++argv); } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; diff --git a/tools/tlcp_help.h b/tools/tlcp_help.h index e01ccfa8..f77135c1 100644 --- a/tools/tlcp_help.h +++ b/tools/tlcp_help.h @@ -35,5 +35,5 @@ " cat sm2signkey.pem > tlcpkey.pem\n" " cat sm2enckey.pem >> tlcpkey.pem\n" "\n" -" gmssl tlcp_server -port 4431 -cert tlcpcert.pem -key tlcpkey.pem -pass 1234\n" -" gmssl tlcp_client -port 4431 -host 127.0.0.1 -cacert sm2rootcacert.pem\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" diff --git a/tools/tlcp_server.c b/tools/tlcp_server.c index f87e1f95..8bc67a28 100644 --- a/tools/tlcp_server.c +++ b/tools/tlcp_server.c @@ -203,7 +203,7 @@ int tlcp_server_main(int argc , char **argv) if (--argc < 1) goto bad; cacertfile = *(++argv); } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; diff --git a/tools/tls12_client.c b/tools/tls12_client.c index 33a92005..b8500ec5 100644 --- a/tools/tls12_client.c +++ b/tools/tls12_client.c @@ -324,7 +324,7 @@ int tls12_client_main(int argc, char *argv[]) if (--argc < 1) goto bad; infile = *(++argv); } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; diff --git a/tools/tls12_server.c b/tools/tls12_server.c index 03bc9fdf..324dfce9 100644 --- a/tools/tls12_server.c +++ b/tools/tls12_server.c @@ -260,7 +260,7 @@ int tls12_server_main(int argc , char **argv) } else if (!strcmp(*argv, "-renegotiation_info")) { renegotiation_info = 1; } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; diff --git a/tools/tls13_client.c b/tools/tls13_client.c index c98ca905..533675f1 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -476,7 +476,7 @@ int tls13_client_main(int argc, char *argv[]) if (--argc < 1) goto bad; infile = *(++argv); } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; diff --git a/tools/tls13_server.c b/tools/tls13_server.c index 4fa2b403..6eb0c7ad 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -329,7 +329,7 @@ int tls13_server_main(int argc , char **argv) } else if (!strcmp(*argv, "-tls13_change_cipher_spec")) { tls13_change_cipher_spec = 1; } else if (!strcmp(*argv, "-verbose")) { - verbose = 1; + verbose = 5; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1;