dns_client: add verify subject alt name

This commit is contained in:
Nick Peng
2023-03-14 22:12:53 +08:00
parent 81ab3f413a
commit 12e7bc752c
2 changed files with 75 additions and 15 deletions

View File

@@ -1622,9 +1622,10 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
{
int len = 0;
int i = 0;
int j = 0;
int qtype = 0;
int qclass = 0;
char domain[DNS_MAX_CNAME_LEN];
char domain[DNS_MAX_CNAME_LEN] = {0};
int rr_count = 0;
struct dns_rrs *rrs = NULL;
unsigned char packet_buff[DNS_PACKSIZE];
@@ -1662,10 +1663,13 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
dns_get_OPT_payload_size(packet));
/* get question */
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
dns_get_domain(rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
tlog(TLOG_DEBUG, "domain: %s qtype: %d qclass: %d\n", domain, qtype, qclass);
for (j = 0; j < DNS_RRS_END && domain[0] == '\0'; j++) {
rrs = dns_get_rrs_start(packet, (dns_rr_type)j, &rr_count);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
dns_get_domain(rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
tlog(TLOG_DEBUG, "domain: %s qtype: %d qclass: %d\n", domain, qtype, qclass);
break;
}
}
if (dns_get_OPT_payload_size(packet) > 0) {
@@ -2741,6 +2745,61 @@ errout:
return -1;
}
static int _dns_client_verify_common_name(struct dns_server_info *server_info, X509 *cert, char *peer_CN)
{
char *tls_host_verify = NULL;
GENERAL_NAMES *alt_names = NULL;
int i = 0;
/* check tls host */
tls_host_verify = _dns_client_server_get_tls_host_verify(server_info);
if (tls_host_verify == NULL) {
return 0;
}
if (tls_host_verify) {
if (_dns_client_tls_matchName(tls_host_verify, peer_CN, strnlen(peer_CN, DNS_MAX_CNAME_LEN)) == 0) {
return 0;
}
}
alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
if (alt_names == NULL) {
goto errout;
}
/* found subject alt name */
for (i = 0; i < sk_GENERAL_NAME_num(alt_names); i++) {
GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
if (name == NULL) {
continue;
}
switch (name->type) {
case GEN_DNS:
ASN1_IA5STRING *dns = name->d.dNSName;
if (dns == NULL) {
continue;
}
tlog(TLOG_DEBUG, "peer SAN: %s", dns->data);
if (_dns_client_tls_matchName(tls_host_verify, (char *)dns->data, dns->length) == 0) {
tlog(TLOG_INFO, "peer SAN match: %s", dns->data);
return 0;
}
break;
case GEN_IPADD:
break;
default:
break;
}
}
errout:
tlog(TLOG_WARN, "server %s CN is invalid, peer CN: %s, expect CN: %s", server_info->ip, peer_CN, tls_host_verify);
server_info->prohibit = 1;
return -1;
}
static int _dns_client_tls_verify(struct dns_server_info *server_info)
{
X509 *cert = NULL;
@@ -2754,7 +2813,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
unsigned char *key_sha256 = NULL;
char *spki = NULL;
int spki_len = 0;
char *tls_host_verify = NULL;
if (server_info->ssl == NULL) {
return -1;
}
@@ -2773,7 +2832,8 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
pthread_mutex_unlock(&server_info->lock);
peer_CN[0] = '\0';
_dns_client_tls_get_cert_CN(cert, peer_CN, sizeof(peer_CN));
tlog(TLOG_WARN, "peer server %s certificate verify failed, ret = %ld", server_info->ip, res);
tlog(TLOG_WARN, "peer server %s certificate verify failed, %s", server_info->ip,
X509_verify_cert_error_string(res));
tlog(TLOG_WARN, "peer CN: %s", peer_CN);
goto errout;
}
@@ -2786,14 +2846,9 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
}
tlog(TLOG_DEBUG, "peer CN: %s", peer_CN);
/* check tls host */
tls_host_verify = _dns_client_server_get_tls_host_verify(server_info);
if (tls_host_verify) {
if (_dns_client_tls_matchName(tls_host_verify, peer_CN, strnlen(peer_CN, DNS_MAX_CNAME_LEN)) != 0) {
tlog(TLOG_INFO, "server %s CN is invalid, peer CN: %s, expect CN: %s", server_info->ip, peer_CN,
tls_host_verify);
goto errout;
}
if (_dns_client_verify_common_name(server_info, cert, peer_CN) != 0) {
goto errout;
}
pubkey = X509_get_X509_PUBKEY(cert);

View File

@@ -634,6 +634,11 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
}
}
/* if server is domain name, then verify domain */
if (server->tls_host_verify[0] == '\0' && check_is_ipaddr(server->server) != 0) {
safe_strncpy(server->tls_host_verify, server->server, DNS_MAX_CNAME_LEN);
}
/* add new server */
server->type = type;
server->port = port;