mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-29 01:03:38 +08:00
Add TLS cert verify
This commit is contained in:
50
src/tlcp.c
50
src/tlcp.c
@@ -746,9 +746,8 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
||||
int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *server_cert;
|
||||
size_t server_cert_len;
|
||||
int verify_result = X509_verify_ok;
|
||||
int sig_alg = 0;
|
||||
|
||||
if ((ret = tls_recv_record(conn)) != 1) {
|
||||
if (ret != TLS_ERROR_RECV_AGAIN) {
|
||||
@@ -785,41 +784,28 @@ 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) {
|
||||
if (tls_cert_chain_verify(conn->protocol, X509_cert_chain_server, conn->cipher_suite,
|
||||
conn->ctx->cacertslen ? 1 : 0,
|
||||
conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth,
|
||||
NULL, 0,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
conn->host_name, conn->host_name_len,
|
||||
&verify_result, &sig_alg) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
if (conn->host_name_len) {
|
||||
if ((ret = tls_cert_match_server_name(server_cert, server_cert_len,
|
||||
conn->host_name, conn->host_name_len)) < 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
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,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth, &verify_result) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
conn->verify_result = verify_result;
|
||||
conn->signature_algorithms[0] = sig_alg;
|
||||
conn->signature_algorithms_cnt = 1;
|
||||
|
||||
if (conn->client_certs_len) {
|
||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||
|
||||
172
src/tls12.c
172
src/tls12.c
@@ -1245,13 +1245,8 @@ int tls_recv_server_hello(TLS_CONNECT *conn)
|
||||
int tls_recv_server_certificate(TLS_CONNECT *conn)
|
||||
{
|
||||
int ret;
|
||||
int verify_result = 0;
|
||||
const uint8_t *server_cert;
|
||||
size_t server_cert_len;
|
||||
X509_KEY server_sign_key;
|
||||
int verify_result = X509_verify_ok;
|
||||
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;
|
||||
|
||||
@@ -1301,91 +1296,6 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// server_sign_key
|
||||
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();
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_get_subject_public_key(server_cert, server_cert_len, &server_sign_key) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tls12_public_key_get_group(&server_sign_key, &server_group) != 1) {
|
||||
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();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
switch (conn->cipher_suite) {
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
server_sig_alg = TLS_sig_sm2sig_sm3;
|
||||
break;
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||
#ifdef ENABLE_AES_CCM
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm:
|
||||
#endif
|
||||
server_sig_alg = TLS_sig_ecdsa_secp256r1_sha256;
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
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();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
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();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
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();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
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;
|
||||
@@ -1394,40 +1304,6 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
|
||||
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();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// check server certificate matches configured hostname
|
||||
if (conn->host_name_len) {
|
||||
if ((ret = tls_cert_match_server_name(server_cert, server_cert_len,
|
||||
conn->host_name, conn->host_name_len)) < 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
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) {
|
||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||
@@ -1436,18 +1312,28 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
|
||||
assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10);
|
||||
|
||||
// verify server Certificate
|
||||
if (conn->ctx->cacertslen) {
|
||||
if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth, &verify_result) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
if (tls_cert_chain_verify(conn->protocol, X509_cert_chain_server, conn->cipher_suite,
|
||||
conn->ctx->cacertslen ? 1 : 0,
|
||||
conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth,
|
||||
conn->ctx->supported_groups, conn->ctx->supported_groups_cnt,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
conn->host_name, conn->host_name_len,
|
||||
&verify_result, &server_sig_alg) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
conn->verify_result = verify_result;
|
||||
conn->signature_algorithms[0] = server_sig_alg;
|
||||
conn->signature_algorithms_cnt = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -2803,10 +2689,20 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
|
||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||
return -1;
|
||||
}
|
||||
if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
|
||||
if (tls_cert_chain_verify(conn->protocol, X509_cert_chain_client, conn->cipher_suite,
|
||||
1,
|
||||
conn->client_certs, conn->client_certs_len,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth, &verify_result) != 1) {
|
||||
NULL, 0,
|
||||
conn->ctx->verify_depth,
|
||||
NULL, 0,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&verify_result, NULL) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls_send_alert(conn, TLS_alert_bad_certificate);
|
||||
|
||||
90
src/tls13.c
90
src/tls13.c
@@ -6242,50 +6242,23 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
|
||||
host_name = conn->host_name;
|
||||
host_name_len = conn->host_name_len;
|
||||
}
|
||||
if (host_name && host_name_len) {
|
||||
if (x509_certs_get_cert_by_index(conn->peer_cert_chain,
|
||||
conn->peer_cert_chain_len, 0, &cert, &certlen) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_certificate;
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tls_cert_match_server_name(cert, certlen, host_name, host_name_len)) < 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_hostname;
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (tls_cert_chain_match_extensions(conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len, // certificate_authorities
|
||||
NULL, 0, // oid_filters
|
||||
host_name, host_name_len,
|
||||
NULL) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// verify server cert_chain
|
||||
// 函数x509_certs_verify的设计有问题
|
||||
// 验证一个证书链之前,应该首先判断一下这个证书链对应的根证书是否存在
|
||||
// 如果我们没有根证书,那么就根本不能验证
|
||||
// 把查找根证书和验证证书链的函数分开
|
||||
ret = x509_certs_verify(
|
||||
conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
|
||||
ret = tls_cert_chain_verify(
|
||||
conn->protocol, X509_cert_chain_server, conn->cipher_suite,
|
||||
1,
|
||||
conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
leaf_status_request_ocsp_response, leaf_status_request_ocsp_response_len,
|
||||
conn->ctx->verify_depth, &verify_result);
|
||||
conn->ctx->verify_depth,
|
||||
NULL, 0,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len,
|
||||
NULL, 0,
|
||||
host_name, host_name_len,
|
||||
&verify_result, NULL);
|
||||
if (ret < 0) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
@@ -6295,7 +6268,12 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls13_send_alert(conn, TLS_alert_certificate_revoked);
|
||||
if (verify_result == X509_verify_err_crl
|
||||
|| verify_result == X509_verify_err_ocsp) {
|
||||
tls13_send_alert(conn, TLS_alert_certificate_revoked);
|
||||
} else {
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
conn->verify_result = verify_result;
|
||||
@@ -8626,25 +8604,22 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
|
||||
oid_filters = conn->ctx->oid_filters;
|
||||
oid_filters_len = conn->ctx->oid_filters_len;
|
||||
}
|
||||
if (tls_cert_chain_match_extensions(conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
// verify client cert_chain
|
||||
ret = tls_cert_chain_verify(
|
||||
conn->protocol, X509_cert_chain_client, conn->cipher_suite,
|
||||
1,
|
||||
conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
status_request_ocsp_response, status_request_ocsp_response_len,
|
||||
conn->ctx->verify_depth,
|
||||
NULL, 0,
|
||||
conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len,
|
||||
oid_filters, oid_filters_len,
|
||||
NULL, 0, // server_name not in CertificateRequest
|
||||
NULL) != 1) {
|
||||
error_print();
|
||||
conn->verify_result = X509_verify_err_tls_extensions;
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// verify client cert_chain
|
||||
ret = x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_client,
|
||||
conn->ctx->cacerts, conn->ctx->cacertslen,
|
||||
NULL, 0,
|
||||
status_request_ocsp_response, status_request_ocsp_response_len,
|
||||
conn->ctx->verify_depth, &verify_result);
|
||||
&verify_result, NULL);
|
||||
if (ret < 0) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
@@ -8654,7 +8629,12 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
conn->verify_result = verify_result;
|
||||
tls13_send_alert(conn, TLS_alert_certificate_revoked);
|
||||
if (verify_result == X509_verify_err_crl
|
||||
|| verify_result == X509_verify_err_ocsp) {
|
||||
tls13_send_alert(conn, TLS_alert_certificate_revoked);
|
||||
} else {
|
||||
tls13_send_alert(conn, TLS_alert_bad_certificate);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
conn->verify_result = verify_result;
|
||||
|
||||
422
src/tls_vrf.c
Normal file
422
src/tls_vrf.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/tls.h>
|
||||
|
||||
|
||||
static void tls_cert_verify_set_result(int *verify_result, int result)
|
||||
{
|
||||
if (verify_result) {
|
||||
*verify_result = result;
|
||||
}
|
||||
}
|
||||
|
||||
static int tls_cert_verify_get_cert_group(const uint8_t *cert, size_t certlen, int *group)
|
||||
{
|
||||
X509_KEY public_key;
|
||||
|
||||
if (!cert || !certlen || !group) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
|
||||
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_cipher_suite_match_cert_group(int cipher_suite, int cert_group)
|
||||
{
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||
return cert_group == TLS_curve_sm2p256v1;
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm:
|
||||
return cert_group == TLS_curve_secp256r1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int tls12_signature_scheme_match_cert_group(int sig_alg, int cert_group)
|
||||
{
|
||||
return tls_signature_scheme_group_oid(sig_alg) == tls_named_curve_oid(cert_group);
|
||||
}
|
||||
|
||||
static int tls12_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite)
|
||||
{
|
||||
switch (sig_alg) {
|
||||
case TLS_sig_sm2sig_sm3:
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case TLS_sig_ecdsa_secp256r1_sha256:
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm:
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls12_signature_scheme_from_cipher_suite(int cipher_suite)
|
||||
{
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
return TLS_sig_sm2sig_sm3;
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_ccm:
|
||||
return TLS_sig_ecdsa_secp256r1_sha256;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int tls_cert_chain_check_name(const uint8_t *cert_chain, size_t cert_chain_len,
|
||||
const uint8_t *host_name, size_t host_name_len, int *verify_result)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
|
||||
if (!host_name || !host_name_len) {
|
||||
return 1;
|
||||
}
|
||||
if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_certificate);
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tls_cert_match_server_name(cert, certlen, host_name, host_name_len)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_hostname);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_hostname);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tls12_cert_chain_match(
|
||||
int cert_chain_type, int cipher_suite,
|
||||
const uint8_t *cert_chain, size_t cert_chain_len,
|
||||
const int *supported_groups, size_t supported_groups_cnt,
|
||||
const int *signature_algorithms, size_t signature_algorithms_cnt,
|
||||
const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt,
|
||||
const uint8_t *ca_names, size_t ca_names_len,
|
||||
const uint8_t *host_name, size_t host_name_len,
|
||||
int *verify_result, int *selected_sig_alg)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
int cert_group;
|
||||
int sig_alg;
|
||||
|
||||
if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_certificate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cert_chain_type == X509_cert_chain_server) {
|
||||
if (tls_cert_verify_get_cert_group(cert, certlen, &cert_group) != 1) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_certificate);
|
||||
return -1;
|
||||
}
|
||||
if (!tls12_cipher_suite_match_cert_group(cipher_suite, cert_group)) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
if (supported_groups && supported_groups_cnt) {
|
||||
if (!tls_type_is_in_list(cert_group, supported_groups, supported_groups_cnt)) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sig_alg = tls12_signature_scheme_from_cipher_suite(cipher_suite);
|
||||
if (sig_alg < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (selected_sig_alg) {
|
||||
*selected_sig_alg = sig_alg;
|
||||
}
|
||||
}
|
||||
|
||||
if (signature_algorithms && signature_algorithms_cnt) {
|
||||
if ((ret = tls_cert_match_signature_algorithms(cert, certlen,
|
||||
signature_algorithms, signature_algorithms_cnt, &sig_alg)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
if (cert_chain_type == X509_cert_chain_server) {
|
||||
if (!tls12_signature_scheme_match_cert_group(sig_alg, cert_group)
|
||||
|| !tls12_signature_scheme_match_cipher_suite(sig_alg, cipher_suite)) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (selected_sig_alg) {
|
||||
*selected_sig_alg = sig_alg;
|
||||
}
|
||||
}
|
||||
|
||||
if (signature_algorithms_cert && signature_algorithms_cert_cnt) {
|
||||
if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ca_names && ca_names_len) {
|
||||
if ((ret = tls_authorities_issued_certificate(ca_names, ca_names_len,
|
||||
cert_chain, cert_chain_len)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return tls_cert_chain_check_name(cert_chain, cert_chain_len,
|
||||
host_name, host_name_len, verify_result);
|
||||
}
|
||||
|
||||
static int tlcp_cert_chain_match(
|
||||
int cert_chain_type, int cipher_suite,
|
||||
const uint8_t *cert_chain, size_t cert_chain_len,
|
||||
const int *signature_algorithms, size_t signature_algorithms_cnt,
|
||||
const uint8_t *ca_names, size_t ca_names_len,
|
||||
const uint8_t *host_name, size_t host_name_len,
|
||||
int *verify_result, int *selected_sig_alg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (signature_algorithms && signature_algorithms_cnt) {
|
||||
if (!tls_type_is_in_list(TLS_sig_sm2sig_sm3,
|
||||
signature_algorithms, signature_algorithms_cnt)) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (selected_sig_alg) {
|
||||
*selected_sig_alg = TLS_sig_sm2sig_sm3;
|
||||
}
|
||||
|
||||
if (ca_names && ca_names_len) {
|
||||
if ((ret = tls_authorities_issued_certificate(ca_names, ca_names_len,
|
||||
cert_chain, cert_chain_len)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cert_chain_type == X509_cert_chain_server) {
|
||||
return tls_cert_chain_check_name(cert_chain, cert_chain_len,
|
||||
host_name, host_name_len, verify_result);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tls13_cert_chain_match(
|
||||
const uint8_t *cert_chain, size_t cert_chain_len,
|
||||
const int *signature_algorithms, size_t signature_algorithms_cnt,
|
||||
const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt,
|
||||
const uint8_t *ca_names, size_t ca_names_len,
|
||||
const uint8_t *oid_filters, size_t oid_filters_len,
|
||||
const uint8_t *host_name, size_t host_name_len,
|
||||
int *verify_result, int *selected_sig_alg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = tls_cert_chain_check_name(cert_chain, cert_chain_len,
|
||||
host_name, host_name_len, verify_result)) != 1) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = tls_cert_chain_match_extensions(cert_chain, cert_chain_len,
|
||||
signature_algorithms, signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len,
|
||||
oid_filters, oid_filters_len,
|
||||
NULL, 0,
|
||||
selected_sig_alg)) < 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_cert_chain_verify(
|
||||
int protocol, int cert_chain_type, int cipher_suite,
|
||||
int verify_chain,
|
||||
const uint8_t *cert_chain, size_t cert_chain_len,
|
||||
const uint8_t *cacerts, size_t cacerts_len,
|
||||
const uint8_t *crl, size_t crl_len,
|
||||
const uint8_t *ocsp, size_t ocsp_len,
|
||||
int verify_depth,
|
||||
const int *supported_groups, size_t supported_groups_cnt,
|
||||
const int *signature_algorithms, size_t signature_algorithms_cnt,
|
||||
const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt,
|
||||
const uint8_t *ca_names, size_t ca_names_len,
|
||||
const uint8_t *oid_filters, size_t oid_filters_len,
|
||||
const uint8_t *host_name, size_t host_name_len,
|
||||
int *verify_result,
|
||||
int *selected_sig_alg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!cert_chain || !cert_chain_len) {
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_certificate);
|
||||
return -1;
|
||||
}
|
||||
if (selected_sig_alg) {
|
||||
*selected_sig_alg = 0;
|
||||
}
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_ok);
|
||||
|
||||
switch (protocol) {
|
||||
case TLS_protocol_tls12:
|
||||
ret = tls12_cert_chain_match(cert_chain_type, cipher_suite,
|
||||
cert_chain, cert_chain_len,
|
||||
supported_groups, supported_groups_cnt,
|
||||
signature_algorithms, signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len,
|
||||
host_name, host_name_len,
|
||||
verify_result, selected_sig_alg);
|
||||
break;
|
||||
case TLS_protocol_tlcp:
|
||||
ret = tlcp_cert_chain_match(cert_chain_type, cipher_suite,
|
||||
cert_chain, cert_chain_len,
|
||||
signature_algorithms, signature_algorithms_cnt,
|
||||
ca_names, ca_names_len,
|
||||
host_name, host_name_len,
|
||||
verify_result, selected_sig_alg);
|
||||
break;
|
||||
case TLS_protocol_tls13:
|
||||
ret = tls13_cert_chain_match(cert_chain, cert_chain_len,
|
||||
signature_algorithms, signature_algorithms_cnt,
|
||||
signature_algorithms_cert, signature_algorithms_cert_cnt,
|
||||
ca_names, ca_names_len,
|
||||
oid_filters, oid_filters_len,
|
||||
host_name, host_name_len,
|
||||
verify_result, selected_sig_alg);
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_err_tls_extensions);
|
||||
return -1;
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verify_chain) {
|
||||
if (protocol == TLS_protocol_tlcp && cert_chain_type == X509_cert_chain_server) {
|
||||
ret = x509_certs_verify_tlcp(cert_chain, cert_chain_len, cert_chain_type,
|
||||
cacerts, cacerts_len, crl, crl_len, ocsp, ocsp_len,
|
||||
verify_depth, verify_result);
|
||||
} else {
|
||||
ret = x509_certs_verify(cert_chain, cert_chain_len, cert_chain_type,
|
||||
cacerts, cacerts_len, crl, crl_len, ocsp, ocsp_len,
|
||||
verify_depth, verify_result);
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error_print();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
tls_cert_verify_set_result(verify_result, X509_verify_ok);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user