tls: support certificate verify.

This commit is contained in:
Nick Peng
2020-04-30 22:51:42 +08:00
parent 304e94bc6f
commit 54801e1ed6
12 changed files with 114 additions and 8 deletions

View File

@@ -107,6 +107,7 @@ struct dns_server_info {
SSL *ssl;
SSL_CTX *ssl_ctx;
SSL_SESSION *ssl_session;
char skip_check_cert;
dns_server_status status;
struct dns_server_buff send_buff;
@@ -714,6 +715,39 @@ static char *_dns_client_server_get_spki(struct dns_server_info *server_info, in
return spki;
}
static int _dns_client_set_trusted_cert(SSL_CTX *ssl_ctx)
{
char *cafile = NULL;
char *capath = NULL;
int cert_path_set = 0;
if (dns_conf_ca_file[0]) {
cafile = dns_conf_ca_file;
}
if (dns_conf_ca_path[0]) {
capath = dns_conf_ca_path;
}
if (cafile == NULL && capath == NULL) {
if (SSL_CTX_set_default_verify_paths(ssl_ctx)) {
cafile = "/etc/ssl/certs/ca-certificates.crt";
capath = "/etc/ssl/certs";
} else {
cert_path_set = 1;
}
}
if (cert_path_set == 0) {
if (!SSL_CTX_load_verify_locations(ssl_ctx, cafile, capath)) {
tlog(TLOG_WARN, "load certificate from %s:%s failed.", cafile, capath);
return -1;
}
}
return 0;
}
/* add dns server information */
static int _dns_client_server_add(char *server_ip, char *server_host, int port, dns_server_type_t server_type,
struct client_dns_server_flags *flags)
@@ -724,6 +758,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
int ttl = 0;
char port_s[8];
int sock_type;
char skip_check_cert = 0;
switch (server_type) {
case DNS_SERVER_UDP: {
@@ -748,11 +783,13 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
}
}
sock_type = SOCK_STREAM;
skip_check_cert = flag_https->skip_check_cert;
} break;
case DNS_SERVER_TLS: {
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
spki_data_len = flag_tls->spi_len;
sock_type = SOCK_STREAM;
skip_check_cert = flag_tls->skip_check_cert;
} break;
case DNS_SERVER_TCP:
sock_type = SOCK_STREAM;
@@ -798,6 +835,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
server_info->status = DNS_SERVER_STATUS_INIT;
server_info->ttl = ttl;
server_info->ttl_range = 0;
server_info->skip_check_cert = skip_check_cert;
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
/* exclude this server from default group */
@@ -815,6 +853,11 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
#else
server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
#endif
if (_dns_client_set_trusted_cert(server_info->ssl_ctx) != 0) {
tlog(TLOG_WARN, "disable check certificate for %s.", server_info->ip);
server_info->skip_check_cert = 1;
}
if (server_info->ssl_ctx == NULL) {
tlog(TLOG_ERROR, "init ssl failed.");
goto errout;
@@ -2078,6 +2121,14 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
return -1;
}
if (server_info->skip_check_cert == 0) {
long res = SSL_get_verify_result(server_info->ssl);
if (res != X509_V_OK) {
tlog(TLOG_WARN, "peer server certificate verify failed.");
goto errout;
}
}
cert_name = X509_get_subject_name(cert);
if (cert_name == NULL) {
tlog(TLOG_ERROR, "get subject name failed.");
@@ -2094,7 +2145,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
/* check tls host */
tls_host_verify = _dns_client_server_get_tls_host_verify(server_info);
if (tls_host_verify) {
if (_dns_client_tls_matchName(peer_CN, tls_host_verify, strnlen(tls_host_verify, DNS_MAX_CNAME_LEN)) != 0) {
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;

View File

@@ -70,6 +70,7 @@ struct client_dns_server_flag_tls {
int spi_len;
char hostname[DNS_MAX_CNAME_LEN];
char tls_host_verify[DNS_MAX_CNAME_LEN];
char skip_check_cert;
};
struct client_dns_server_flag_https {
@@ -79,6 +80,7 @@ struct client_dns_server_flag_https {
char httphost[DNS_MAX_CNAME_LEN];
char path[DNS_MAX_CNAME_LEN];
char tls_host_verify[DNS_MAX_CNAME_LEN];
char skip_check_cert;
};
struct client_dns_server_flags {

View File

@@ -68,6 +68,10 @@ char dns_conf_log_file[DNS_MAX_PATH];
size_t dns_conf_log_size = 1024 * 1024;
int dns_conf_log_num = 8;
/* CA file */
char dns_conf_ca_file[DNS_MAX_PATH];
char dns_conf_ca_path[DNS_MAX_PATH];
/* auditing */
int dns_conf_audit_enable = 0;
int dns_conf_audit_log_SOA;
@@ -246,6 +250,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
{"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */
{"host-name", required_argument, NULL, 'h'}, /* host name */
{"http-host", required_argument, NULL, 'H'}, /* http host */
{"no-check-certificate", no_argument, NULL, 'N'}, /* do not check certificate */
{"tls-host-verify", required_argument, NULL, 'V' }, /* verify tls hostname */
{"group", required_argument, NULL, 'g'}, /* add to group */
{"exclude-default-group", no_argument, NULL, 'E'}, /* ecluse this from default group */
@@ -340,6 +345,10 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
safe_strncpy(server->tls_host_verify, optarg, DNS_MAX_CNAME_LEN);
break;
}
case 'N': {
server->skip_check_cert = 1;
break;
}
default:
break;
}
@@ -1370,6 +1379,8 @@ static struct config_item _config_item[] = {
CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL),
CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL),
CONF_CUSTOM("domain-rules", _conf_domain_rules, NULL),
CONF_STRING("ca-file", (char *)&dns_conf_ca_file, DNS_MAX_PATH),
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
CONF_CUSTOM("conf-file", config_addtional_file, NULL),
CONF_END(),
};

View File

@@ -145,6 +145,7 @@ struct dns_servers {
unsigned int server_flag;
int ttl;
dns_server_type_t type;
char skip_check_cert;
char spki[DNS_MAX_SPKI_LEN];
char hostname[DNS_MAX_CNAME_LEN];
char httphost[DNS_MAX_CNAME_LEN];
@@ -211,6 +212,9 @@ extern char dns_conf_log_file[DNS_MAX_PATH];
extern size_t dns_conf_log_size;
extern int dns_conf_log_num;
extern char dns_conf_ca_file[DNS_MAX_PATH];
extern char dns_conf_ca_path[DNS_MAX_PATH];
extern struct dns_domain_check_order dns_conf_check_order;
extern struct dns_server_groups dns_conf_server_groups[DNS_NAX_GROUP_NUMBER];

View File

@@ -1026,7 +1026,7 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
uint32_t addrkey;
char ip_str[PING_MAX_HOSTLEN];
int port = -1;
FAST_PING_TYPE ping_type;
FAST_PING_TYPE ping_type = FAST_PING_END;
unsigned int seed;
int ret = 0;

View File

@@ -160,6 +160,7 @@ static int _smartdns_add_servers(void)
safe_strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost));
safe_strncpy(flag_http->tls_host_verify, dns_conf_servers[i].tls_host_verify,
sizeof(flag_http->tls_host_verify));
flag_http->skip_check_cert = dns_conf_servers[i].skip_check_cert;
} break;
case DNS_SERVER_TLS: {
struct client_dns_server_flag_tls *flag_tls = &flags.tls;
@@ -167,6 +168,8 @@ static int _smartdns_add_servers(void)
safe_strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname));
safe_strncpy(flag_tls->tls_host_verify, dns_conf_servers[i].tls_host_verify,
sizeof(flag_tls->tls_host_verify));
flag_tls->skip_check_cert = dns_conf_servers[i].skip_check_cert;
} break;
case DNS_SERVER_TCP:
break;