dns_client: add verify subject alt name
This commit is contained in:
@@ -1622,9 +1622,10 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
|||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
int qtype = 0;
|
int qtype = 0;
|
||||||
int qclass = 0;
|
int qclass = 0;
|
||||||
char domain[DNS_MAX_CNAME_LEN];
|
char domain[DNS_MAX_CNAME_LEN] = {0};
|
||||||
int rr_count = 0;
|
int rr_count = 0;
|
||||||
struct dns_rrs *rrs = NULL;
|
struct dns_rrs *rrs = NULL;
|
||||||
unsigned char packet_buff[DNS_PACKSIZE];
|
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));
|
dns_get_OPT_payload_size(packet));
|
||||||
|
|
||||||
/* get question */
|
/* get question */
|
||||||
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
|
for (j = 0; j < DNS_RRS_END && domain[0] == '\0'; j++) {
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
rrs = dns_get_rrs_start(packet, (dns_rr_type)j, &rr_count);
|
||||||
dns_get_domain(rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
tlog(TLOG_DEBUG, "domain: %s qtype: %d qclass: %d\n", domain, qtype, qclass);
|
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) {
|
if (dns_get_OPT_payload_size(packet) > 0) {
|
||||||
@@ -2741,6 +2745,61 @@ errout:
|
|||||||
return -1;
|
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)
|
static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
||||||
{
|
{
|
||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
@@ -2754,7 +2813,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
|||||||
unsigned char *key_sha256 = NULL;
|
unsigned char *key_sha256 = NULL;
|
||||||
char *spki = NULL;
|
char *spki = NULL;
|
||||||
int spki_len = 0;
|
int spki_len = 0;
|
||||||
char *tls_host_verify = NULL;
|
|
||||||
if (server_info->ssl == NULL) {
|
if (server_info->ssl == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2773,7 +2832,8 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
|||||||
pthread_mutex_unlock(&server_info->lock);
|
pthread_mutex_unlock(&server_info->lock);
|
||||||
peer_CN[0] = '\0';
|
peer_CN[0] = '\0';
|
||||||
_dns_client_tls_get_cert_CN(cert, peer_CN, sizeof(peer_CN));
|
_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);
|
tlog(TLOG_WARN, "peer CN: %s", peer_CN);
|
||||||
goto errout;
|
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);
|
tlog(TLOG_DEBUG, "peer CN: %s", peer_CN);
|
||||||
/* check tls host */
|
|
||||||
tls_host_verify = _dns_client_server_get_tls_host_verify(server_info);
|
if (_dns_client_verify_common_name(server_info, cert, peer_CN) != 0) {
|
||||||
if (tls_host_verify) {
|
goto errout;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey = X509_get_X509_PUBKEY(cert);
|
pubkey = X509_get_X509_PUBKEY(cert);
|
||||||
|
|||||||
@@ -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 */
|
/* add new server */
|
||||||
server->type = type;
|
server->type = type;
|
||||||
server->port = port;
|
server->port = port;
|
||||||
|
|||||||
Reference in New Issue
Block a user