Update tls12_recv_server_certificate

This commit is contained in:
Zhi Guan
2026-06-11 21:42:08 +08:00
parent 475d29bbd3
commit 677d2bd721

View File

@@ -924,6 +924,23 @@ static int tls12_cert_chain_get_end_entity_group(const uint8_t *cert_chain, size
return 1; return 1;
} }
static int tls12_public_key_get_group(const X509_KEY *public_key, int *group)
{
if (!public_key || !group) {
error_print();
return -1;
}
if (public_key->algor != OID_ec_public_key) {
error_print();
return -1;
}
if ((*group = tls_named_curve_from_oid(public_key->algor_param)) == 0) {
error_print();
return -1;
}
return 1;
}
static int tls12_select_key_exchange_group(const int *groups, size_t groups_cnt, static int tls12_select_key_exchange_group(const int *groups, size_t groups_cnt,
int cipher_suite, int *selected_group) int cipher_suite, int *selected_group)
{ {
@@ -1595,10 +1612,15 @@ int tls_send_server_certificate(TLS_CONNECT *conn)
int tls_recv_server_certificate(TLS_CONNECT *conn) int tls_recv_server_certificate(TLS_CONNECT *conn)
{ {
int ret; int ret;
int verify_result; int verify_result = 0;
const uint8_t *server_cert; const uint8_t *server_cert;
size_t server_cert_len; size_t server_cert_len;
X509_KEY server_sign_key; X509_KEY server_sign_key;
int server_sig_alg = 0;
int server_group;
int cert_sig_alg = 0;
const int *signature_algorithms_cert = NULL;
size_t signature_algorithms_cert_cnt = 0;
tls_trace("recv server Certificate\n"); tls_trace("recv server Certificate\n");
@@ -1627,6 +1649,11 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_unexpected_message); tls_send_alert(conn, TLS_alert_unexpected_message);
return 0; return 0;
} }
if (!conn->peer_cert_chain_len) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
error_print(); error_print();
@@ -1635,7 +1662,7 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx);
// 这里取服务器证书似乎没有什么用处啊 // server_sign_key
if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0,
&server_cert, &server_cert_len) != 1) { &server_cert, &server_cert_len) != 1) {
error_print(); error_print();
@@ -1648,13 +1675,16 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
return -1; return -1;
} }
if (tls12_public_key_get_group(&server_sign_key, &server_group) != 1) {
// 这里的逻辑需要统筹考虑
// cipher_suite扩展证书之间的关系
// set conn->server_sig_alg (decided by cipher_suite and server_cert.sign_key.algor, algor_param)
if (server_sign_key.algor != OID_ec_public_key) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
// check server certificate matches negotiated cipher_suite
if (!tls12_cipher_suite_match_cert_group(conn->cipher_suite, server_group)) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1; return -1;
} }
switch (conn->cipher_suite) { switch (conn->cipher_suite) {
@@ -1662,43 +1692,106 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
case TLS_cipher_ecdhe_sm4_gcm_sm3: case TLS_cipher_ecdhe_sm4_gcm_sm3:
case TLS_cipher_ecc_sm4_cbc_sm3: case TLS_cipher_ecc_sm4_cbc_sm3:
case TLS_cipher_ecc_sm4_gcm_sm3: case TLS_cipher_ecc_sm4_gcm_sm3:
if (server_sign_key.algor_param != OID_sm2) { server_sig_alg = TLS_sig_sm2sig_sm3;
error_print();
return -1;
}
conn->signature_algorithms[0] = TLS_sig_sm2sig_sm3;
break; break;
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256: case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
if (server_sign_key.algor_param != OID_secp256r1) { server_sig_alg = TLS_sig_ecdsa_secp256r1_sha256;
error_print();
return -1;
}
conn->signature_algorithms[0] = TLS_sig_ecdsa_secp256r1_sha256;
break; break;
default: default:
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1; return -1;
} }
// check server certificate matches ClientHello.supported_groups
if (conn->ctx->supported_groups_cnt) {
if (!tls_type_is_in_list(server_group, conn->ctx->supported_groups,
conn->ctx->supported_groups_cnt)) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
}
// check server certificate matches ClientHello.signature_algorithms
if (conn->ctx->signature_algorithms_cnt) {
if ((ret = tls_cert_match_signature_algorithms(server_cert, server_cert_len,
conn->ctx->signature_algorithms,
conn->ctx->signature_algorithms_cnt,
&cert_sig_alg)) < 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
} else if (ret == 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
if (!tls12_signature_scheme_match_cert_group(cert_sig_alg, server_group)
|| !tls12_signature_scheme_match_cipher_suite(cert_sig_alg, conn->cipher_suite)) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
server_sig_alg = cert_sig_alg;
}
// check certificate-chain signatures match ClientHello.signature_algorithms_cert
if (conn->signature_algorithms_cert) {
signature_algorithms_cert = conn->ctx->signature_algorithms;
signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt;
} else if (conn->ctx->signature_algorithms_cnt) {
signature_algorithms_cert = conn->ctx->signature_algorithms;
signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt;
}
if (signature_algorithms_cert && signature_algorithms_cert_cnt) {
if ((ret = tls_cert_chain_match_signature_algorithms_cert(
conn->peer_cert_chain, conn->peer_cert_chain_len,
signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
} else if (ret == 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
}
// check server certificate matches ClientHello.server_name
if (conn->server_name) {
if ((ret = tls_cert_match_server_name(server_cert, server_cert_len,
conn->host_name, conn->host_name_len)) < 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
} else if (ret == 0) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
}
conn->signature_algorithms[0] = server_sig_alg;
conn->signature_algorithms_cnt = 1;
if (conn->client_certs_len) { 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);
} }
assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10); assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10);
// verify ServerCertificate // verify server Certificate
if (conn->ctx->cacertslen) { if (conn->ctx->cacertslen) {
if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
// 按道理来说,这只是验证证书,并应该出错啊
if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) {
error_print(); error_print();
//tls_send_alert(conn, TLS_alert_bad_certificate); conn->verify_result = verify_result;
//return -1; tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
} }
} }
conn->verify_result = verify_result;
return 1; return 1;
} }