Fix TLCP CertificateRequest

This commit is contained in:
Zhi Guan
2026-06-16 17:23:15 +08:00
parent 732a77c3a4
commit 171c88bb4c
7 changed files with 287 additions and 161 deletions

View File

@@ -818,7 +818,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1060") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1061")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -1507,13 +1507,14 @@ int tls_derive_key_block(TLS_CONNECT *conn);
int tls_init_application_keys(TLS_CONNECT *conn); int tls_init_application_keys(TLS_CONNECT *conn);
int tls_update_transcript(TLS_CONNECT *conn, const uint8_t *record);
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48], 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]); 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_client_application_keys(TLS_CONNECT *conn);
int tls13_update_server_application_keys(TLS_CONNECT *conn); int tls13_update_server_application_keys(TLS_CONNECT *conn);

View File

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

View File

@@ -24,40 +24,6 @@
#include <gmssl/tls.h> #include <gmssl/tls.h>
/*
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[] = { const int tlcp_supported_groups[] = {
TLS_curve_sm2p256v1, TLS_curve_sm2p256v1,
}; };
@@ -538,6 +504,11 @@ int tlcp_send_client_hello(TLS_CONNECT *conn)
if(conn->verbose) if(conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (conn->client_certificate_verify) { if (conn->client_certificate_verify) {
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
} }
@@ -593,6 +564,11 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_protocol_version); tls_send_alert(conn, TLS_alert_protocol_version);
@@ -795,6 +771,11 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_protocol_version); tls_send_alert(conn, TLS_alert_protocol_version);
@@ -877,6 +858,11 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn)
if(conn->verbose) if(conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_protocol_version); tls_send_alert(conn, TLS_alert_protocol_version);
@@ -985,8 +971,10 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); error_print();
return -1;
}
conn->recordlen = 0; conn->recordlen = 0;
@@ -1024,26 +1012,17 @@ int tlcp_recv_server_hello_done(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
if (conn->client_certs_len) { return -1;
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
} }
return 1; return 1;
} }
int tlcp_send_client_certificate(TLS_CONNECT *conn) int tlcp_send_client_certificate(TLS_CONNECT *conn)
{ {
int ret; int ret;
if(conn->verbose) tls_trace("send client Certificate\n");
// 如果我们没有证书并且也没有设置optional那么就得返回错误了
// 可能还需要返回一个alert
if (conn->client_certs_len == 0) { if (conn->client_certs_len == 0) {
error_print(); error_print();
@@ -1051,7 +1030,10 @@ int tlcp_send_client_certificate(TLS_CONNECT *conn)
} }
if (conn->recordlen == 0) { if (conn->recordlen == 0) {
// 这里的证书应该是
if (conn->verbose)
tls_trace("send client Certificate\n");
if (tls_record_set_handshake_certificate(conn->record, &conn->recordlen, if (tls_record_set_handshake_certificate(conn->record, &conn->recordlen,
conn->cert_chain, conn->cert_chain_len) != 1) { conn->cert_chain, conn->cert_chain_len) != 1) {
error_print(); error_print();
@@ -1061,16 +1043,17 @@ int tlcp_send_client_certificate(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
error_print(); error_print();
return -1; return -1;
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "client Certificate", &conn->dgst_ctx); if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "client Certificate", &conn->dgst_ctx);
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1084,7 +1067,6 @@ int tlcp_send_client_certificate(TLS_CONNECT *conn)
return 1; return 1;
} }
int tlcp_send_client_key_exchange(TLS_CONNECT *conn) int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
{ {
int ret; int ret;
@@ -1136,6 +1118,10 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1157,19 +1143,22 @@ int tlcp_send_certificate_verify(TLS_CONNECT *conn)
uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
size_t siglen; size_t siglen;
if(conn->verbose) tls_trace("send CertificateVerify\n"); if (conn->verbose)
tls_trace("send CertificateVerify\n");
// 这句应该是没用的
if (!conn->client_certificate_verify) {
error_print();
return -1;
}
if (conn->recordlen == 0) { if (conn->recordlen == 0) {
if (sm2_sign_finish(&conn->sign_ctx, sig, &siglen) != 1) { X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx - 1];
X509_SIGN_CTX sign_ctx;
if (x509_sign_init(&sign_ctx, sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|| x509_sign_update(&sign_ctx, conn->transcript, conn->transcript_len) != 1
|| x509_sign_finish(&sign_ctx, sig, &siglen) != 1) {
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
error_print(); error_print();
return -1; return -1;
} }
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
if (tls_record_set_handshake_certificate_verify(conn->record, &conn->recordlen, sig, siglen) != 1) { if (tls_record_set_handshake_certificate_verify(conn->record, &conn->recordlen, sig, siglen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls_send_alert(conn, TLS_alert_internal_error);
@@ -1177,6 +1166,19 @@ int tlcp_send_certificate_verify(TLS_CONNECT *conn)
} }
if (conn->verbose) if (conn->verbose)
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen); 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, "ClientKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1186,9 +1188,6 @@ int tlcp_send_certificate_verify(TLS_CONNECT *conn)
return ret; return ret;
} }
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
//tlcp_handshake_digest_print(stderr, 0, 0, "CertificateVerify", &conn->sm3_ctx);
return 1; return 1;
} }
@@ -1227,6 +1226,11 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->plain_record) != 1) {
error_print();
return -1;
}
if (tls_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_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
conn->client_seq_num, conn->plain_record, conn->plain_recordlen, conn->client_seq_num, conn->plain_record, conn->plain_recordlen,
@@ -1318,33 +1322,6 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
return 1; return 1;
} }
// Server // Server
static int tlcp_cert_chains_select(TLS_CONNECT *conn, static int tlcp_cert_chains_select(TLS_CONNECT *conn,
@@ -1711,6 +1688,11 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
//tlcp_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->sm3_ctx); //tlcp_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->sm3_ctx);
@@ -1813,6 +1795,12 @@ int tlcp_send_server_hello(TLS_CONNECT *conn)
return -1; return -1;
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1861,6 +1849,12 @@ int tlcp_send_server_certificate(TLS_CONNECT *conn)
return -1; 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);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1940,6 +1934,11 @@ int tlcp_send_server_key_exchange(TLS_CONNECT *conn)
} }
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -2041,6 +2040,7 @@ int tlcp_send_certificate_request(TLS_CONNECT *conn)
} }
if (conn->recordlen == 0) { if (conn->recordlen == 0) {
if(conn->verbose) tls_trace("send CertificateRequest\n"); if(conn->verbose) tls_trace("send CertificateRequest\n");
if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names),
conn->ctx->cacerts, conn->ctx->cacertslen) != 1) { conn->ctx->cacerts, conn->ctx->cacertslen) != 1) {
@@ -2055,7 +2055,19 @@ int tlcp_send_certificate_request(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_internal_error); tls_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0); 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 (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -2071,16 +2083,6 @@ int tlcp_send_certificate_request(TLS_CONNECT *conn)
return 1; return 1;
} }
int tlcp_recv_client_certificate(TLS_CONNECT *conn)
{
int ret;
return 1;
}
int tlcp_recv_client_key_exchange(TLS_CONNECT *conn) int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
{ {
int ret; int ret;
@@ -2112,6 +2114,12 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if ((ret = tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len)) < 0) { if ((ret = tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len)) < 0) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
@@ -2203,6 +2211,11 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn)
} }
tls_seq_num_incr(conn->client_seq_num); tls_seq_num_incr(conn->client_seq_num);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (conn->verbose) if (conn->verbose)
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
@@ -2253,6 +2266,11 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
if (tls_update_transcript(conn, conn->plain_record) != 1) {
error_print();
return -1;
}
if (tls_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_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
conn->server_seq_num, conn->plain_record, conn->plain_recordlen, conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
@@ -2549,7 +2567,7 @@ int tlcp_do_server_handshake(TLS_CONNECT *conn)
break; break;
case TLS_state_client_certificate: case TLS_state_client_certificate:
ret = tlcp_recv_client_certificate(conn); ret = tls_recv_client_certificate(conn);
next_state = TLS_state_client_key_exchange; next_state = TLS_state_client_key_exchange;
break; break;

View File

@@ -789,6 +789,35 @@ int tls_prf(const DIGEST *digest, const uint8_t *secret, size_t secretlen, const
return 1; return 1;
} }
int tls_update_transcript(TLS_CONNECT *conn, const uint8_t *record)
{
size_t recordlen;
if (!conn) {
error_print();
return -1;
}
if (record == conn->record) {
recordlen = conn->recordlen;
} else if (record == conn->plain_record) {
recordlen = conn->plain_recordlen;
} else {
error_print();
return -1;
}
if (recordlen < 5 || recordlen > TLS_MAX_PLAINTEXT_SIZE) {
error_print();
return -1;
}
if (conn->transcript_len + recordlen > sizeof(conn->transcript)) {
error_print();
return -1;
}
memcpy(conn->transcript + conn->transcript_len, record + 5, recordlen - 5);
conn->transcript_len += recordlen - 5;
return 1;
}
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48], 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]) const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12])
{ {
@@ -2828,11 +2857,10 @@ int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable)
} }
ctx->certificate_request = enable ? 1 : 0; ctx->certificate_request = enable ? 1 : 0;
return 1; return 1;
} }
int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_cnt) int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_cnt)
{ {
const int *supported_groups; const int *supported_groups;
@@ -3298,6 +3326,15 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx)
conn->pre_shared_key = 1; conn->pre_shared_key = 1;
} }
if (ctx->certificate_request) {
conn->client_certificate_verify = 1;
}
return 1; return 1;
} }

View File

@@ -22,52 +22,6 @@
#include <gmssl/mem.h> #include <gmssl/mem.h>
#include <gmssl/tls.h> #include <gmssl/tls.h>
/*
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[] = { const int tls12_supported_groups[] = {
TLS_curve_sm2p256v1, TLS_curve_sm2p256v1,
@@ -444,6 +398,12 @@ int tls_send_client_hello(TLS_CONNECT *conn)
// backup ClientHello // backup ClientHello
memcpy(conn->plain_record, conn->record, conn->recordlen); memcpy(conn->plain_record, conn->record, conn->recordlen);
conn->plain_recordlen = conn->recordlen; conn->plain_recordlen = conn->recordlen;
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
/* /*
@@ -1291,6 +1251,10 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
/* /*
@@ -1378,6 +1342,10 @@ int tls_send_server_hello(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -1571,6 +1539,10 @@ int tls_recv_server_hello(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
@@ -1604,6 +1576,10 @@ int tls_send_server_certificate(TLS_CONNECT *conn)
return -1; 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);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
@@ -1674,6 +1650,10 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
} }
if(conn->verbose) if(conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
// server_sign_key // server_sign_key
@@ -1879,6 +1859,11 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
@@ -2027,6 +2012,10 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
if(conn->verbose) if(conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls_signature_scheme_match_cipher_suite(sig_alg, conn->cipher_suite) != 1) { if (tls_signature_scheme_match_cipher_suite(sig_alg, conn->cipher_suite) != 1) {
error_print(); error_print();
@@ -2149,6 +2138,16 @@ int tls12_send_certificate_request(TLS_CONNECT *conn)
return -1; 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 (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -2217,6 +2216,10 @@ int tls12_recv_certificate_request(TLS_CONNECT *conn)
error_print(); error_print();
return -1; return -1;
} }
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1 if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1
|| tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) {
@@ -2247,6 +2250,10 @@ int tls_send_server_hello_done(TLS_CONNECT *conn)
return -1; return -1;
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
@@ -2295,6 +2302,10 @@ int tls_recv_server_hello_done(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHelloDone", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (conn->client_certs_len) if (conn->client_certs_len)
@@ -2322,6 +2333,17 @@ int tls_send_client_certificate(TLS_CONNECT *conn)
return -1; 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, "client Certificate", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -2375,6 +2397,20 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_bad_certificate); tls_send_alert(conn, TLS_alert_bad_certificate);
return -1; 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, "client Certificate", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5); //sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
@@ -2423,6 +2459,11 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (conn->client_certs_len) { if (conn->client_certs_len) {
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
} }
@@ -2476,6 +2517,11 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn)
if (conn->verbose) if (conn->verbose)
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
if (tls12_record_get_handshake_client_key_exchange(conn->record, if (tls12_record_get_handshake_client_key_exchange(conn->record,
&point_octets, &point_octets_len) != 1) { &point_octets, &point_octets_len) != 1) {
error_print(); error_print();
@@ -2531,6 +2577,11 @@ int tls_send_certificate_verify(TLS_CONNECT *conn)
return -1; 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_update_transcript(conn, conn->record) != 1) {
error_print();
return -1;
}
} }
if ((ret = tls_send_record(conn)) != 1) { if ((ret = tls_send_record(conn)) != 1) {
@@ -2561,6 +2612,7 @@ int tls_recv_certificate_verify(TLS_CONNECT *conn)
} }
if (conn->verbose) tls_trace("recv CertificateVerify\n"); if (conn->verbose) tls_trace("recv CertificateVerify\n");
if ((ret = tls_recv_record(conn)) != 1) { if ((ret = tls_recv_record(conn)) != 1) {
if (ret != TLS_ERROR_RECV_AGAIN) { if (ret != TLS_ERROR_RECV_AGAIN) {
error_print(); error_print();
@@ -2601,12 +2653,16 @@ int tls_recv_certificate_verify(TLS_CONNECT *conn)
return -1; return -1;
} }
if (tls_client_verify_finish(&conn->client_verify_ctx, sig, siglen, &client_sign_key.u.sm2_key) != 1) {
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
error_print();
return -1;
}
if (tls_update_transcript(conn, conn->record) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_decrypt_error);
return -1; return -1;
} }
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
return 1; return 1;
} }
@@ -2700,6 +2756,11 @@ int tls_send_client_finished(TLS_CONNECT *conn)
} }
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Finished", &conn->dgst_ctx); if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Finished", &conn->dgst_ctx);
if (tls_update_transcript(conn, conn->plain_record) != 1) {
error_print();
return -1;
}
if (tls_record_encrypt(conn->cipher_suite, if (tls_record_encrypt(conn->cipher_suite,
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv, &conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
conn->client_seq_num, conn->plain_record, conn->plain_recordlen, conn->client_seq_num, conn->plain_record, conn->plain_recordlen,
@@ -2805,6 +2866,11 @@ int tls_recv_client_finished(TLS_CONNECT *conn)
} }
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 (tls_update_transcript(conn, conn->plain_record) != 1) {
error_print();
return -1;
}
// verify ClientFinished // verify ClientFinished

View File

@@ -262,6 +262,10 @@ bad:
error_print(); error_print();
return -1; return -1;
} }
if (tls_ctx_enable_certificate_request(&ctx, 1) != 1) {
error_print();
return -1;
}
} }