diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index 0c36303a..e6243810 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -304,7 +304,7 @@ int sm2_do_sign_fast(const SM2_Fn d, const uint8_t dgst[32], SM2_SIGNATURE *sig) int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); #define SM2_MIN_SIGNATURE_SIZE 8 -#define SM2_MAX_SIGNATURE_SIZE 72 +#define SM2_MAX_SIGNATURE_SIZE 74 int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen); int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32], diff --git a/src/tlcp.c b/src/tlcp.c index 34be96d3..ef18d2fb 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -28,6 +28,16 @@ static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 }; static const size_t tlcp_ciphers_count = sizeof(tlcp_ciphers)/sizeof(tlcp_ciphers[0]); +void printbyte(uint8_t *ptr, int len, char *name) { + fprintf(stderr, "%s", name); + for (int i = 0; i < len; i++) { + if (i % 16 == 0) + fprintf(stderr, "\n"); + fprintf(stderr, "0x%02X ", ptr[i]); + } + fprintf(stderr, "\n"); +} + int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) { // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 @@ -168,9 +178,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) // 准备Finished Context(和ClientVerify) sm3_init(&sm3_ctx); - if (conn->client_certs_len) - sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - // send ClientHello tls_random_generate(client_random); @@ -187,8 +194,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // recv ServerHello tls_trace("recv ServerHello\n"); @@ -229,8 +234,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) memcpy(conn->session_id, session_id, session_id_len); conn->cipher_suite = cipher_suite; sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // recv ServerCertificate tls_trace("recv ServerCertificate\n"); @@ -249,8 +252,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // verify ServerCertificate if (conn->ca_certs_len) { @@ -279,8 +280,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // verify ServerKeyExchange if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 @@ -343,7 +342,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // recv ServerHelloDone if (tls_record_recv(record, &recordlen, conn->sock) != 1 @@ -366,8 +364,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // send ClientCertificate if (conn->client_certs_len) { @@ -383,7 +379,6 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); } // generate MASTER_SECRET @@ -428,15 +423,29 @@ int tlcp_do_connect(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); // send CertificateVerify if (conn->client_certs_len) { tls_trace("send CertificateVerify\n"); uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; - if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 - || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { + memset(sigbuf, 0, SM2_MAX_SIGNATURE_SIZE); + SM3_CTX cert_verify_ctx; + uint8_t cert_verify_hash[SM3_DIGEST_SIZE] = {0}; + memset(&cert_verify_ctx, 0, sizeof(SM3_CTX)); + memset(cert_verify_hash, 0, SM3_DIGEST_SIZE); + memcpy(&cert_verify_ctx, &sm3_ctx, sizeof(sm3_ctx)); + sm3_finish(&cert_verify_ctx, cert_verify_hash); + sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_sign_update(&sign_ctx, cert_verify_hash, SM3_DIGEST_SIZE); + if (sm2_sign_finish(&sign_ctx, sigbuf+2, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + sigbuf[0] = siglen >> 8; + sigbuf[1] = siglen ; + siglen += 2; + if (tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); goto end; @@ -598,7 +607,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) size_t siglen; // ClientCertificate, CertificateVerify - TLS_CLIENT_VERIFY_CTX client_verify_ctx; SM2_KEY client_sign_key; const uint8_t *sig; const int verify_depth = 5; @@ -629,8 +637,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) // 初始化Finished和客户端验证环境 sm3_init(&sm3_ctx); - if (client_verify) - tls_client_verify_init(&client_verify_ctx); // recv ClientHello @@ -674,9 +680,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - // send ServerHello tls_trace("send ServerHello\n"); @@ -694,8 +697,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); // send ServerCertificate tls_trace("send ServerCertificate\n"); @@ -711,8 +712,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); // send ServerKeyExchange tls_trace("send ServerKeyExchange\n"); @@ -744,8 +743,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); // send CertificateRequest if (client_verify) { @@ -771,7 +768,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); } // send ServerHelloDone @@ -783,8 +779,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); // recv ClientCertificate if (conn->ca_certs_len) { @@ -808,7 +802,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); } // ClientKeyExchange @@ -837,8 +830,6 @@ int tlcp_do_accept(TLS_CONNECT *conn) goto end; } sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); // recv CertificateVerify if (client_verify) { @@ -861,7 +852,16 @@ int tlcp_do_accept(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_bad_certificate); goto end; } - if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) { + SM3_CTX cert_verify_ctx; + SM2_SIGN_CTX sm2_ctx; + uint8_t cert_verify_hash[SM3_DIGEST_SIZE] = {0}; + memset(&cert_verify_ctx, 0, sizeof(SM3_CTX)); + memset(cert_verify_hash, 0, SM3_DIGEST_SIZE); + memcpy(&cert_verify_ctx, &sm3_ctx, sizeof(sm3_ctx)); + sm3_finish(&cert_verify_ctx, cert_verify_hash); + sm2_verify_init(&sm2_ctx, &client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_verify_update(&sm2_ctx, cert_verify_hash, SM3_DIGEST_SIZE); + if (sm2_verify_finish(&sm2_ctx, sig+2, siglen-2) != 1) { error_print(); tls_send_alert(conn, TLS_alert_decrypt_error); goto end; @@ -1008,6 +1008,5 @@ int tlcp_do_accept(TLS_CONNECT *conn) end: gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - if (client_verify) tls_client_verify_cleanup(&client_verify_ctx); return ret; }