mirror of https://github.com/getdnsapi/getdns.git
Add TLS 1.3 test.
Add a new item tls_version to call_reporting, containing the OpenSSL version string for the name of the protocol used for the connection. The test does a normal lookup, but first sets the cipher list to TLS1.3 only ciphers. This will cause a Bad Context error at search time, so we can tell if the underlying OpenSSL library lacks TLS 1.3. The check the call reporting for a TLS version of "TLSv1.3".
This commit is contained in:
parent
62ad159f15
commit
0291e205fd
|
@ -211,6 +211,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;
|
||||
net_req->debug_tls_peer_cert.size = 0;
|
||||
net_req->debug_tls_peer_cert.data = NULL;
|
||||
net_req->debug_tls_version = NULL;
|
||||
net_req->debug_udp = 0;
|
||||
|
||||
/* Scheduling, touch only via _getdns_netreq_change_state!
|
||||
|
|
14
src/stub.c
14
src/stub.c
|
@ -1687,12 +1687,14 @@ upstream_write_cb(void *userarg)
|
|||
remove_from_write_queue(upstream, netreq);
|
||||
|
||||
if (netreq->owner->return_call_reporting &&
|
||||
netreq->upstream->tls_obj &&
|
||||
netreq->debug_tls_peer_cert.data == NULL &&
|
||||
(cert = SSL_get_peer_certificate(netreq->upstream->tls_obj))) {
|
||||
netreq->debug_tls_peer_cert.size = i2d_X509(
|
||||
cert, &netreq->debug_tls_peer_cert.data);
|
||||
X509_free(cert);
|
||||
netreq->upstream->tls_obj) {
|
||||
if (netreq->debug_tls_peer_cert.data == NULL &&
|
||||
(cert = SSL_get_peer_certificate(netreq->upstream->tls_obj))) {
|
||||
netreq->debug_tls_peer_cert.size = i2d_X509(
|
||||
cert, &netreq->debug_tls_peer_cert.data);
|
||||
X509_free(cert);
|
||||
}
|
||||
netreq->debug_tls_version = SSL_get_version(netreq->upstream->tls_obj);
|
||||
}
|
||||
/* Need this because auth status is reset on connection close */
|
||||
netreq->debug_tls_auth_status = netreq->upstream->tls_auth_state;
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
|
||||
#define EDNS0_PADDING_CODE 12
|
||||
|
||||
static const char TLS13_CIPHER_SUITE[] =
|
||||
"TLS13-AES-256-GCM-SHA384:"
|
||||
"TLS13-CHACHA20-POLY1305-SHA256:"
|
||||
"TLS13-AES-128-GCM-SHA256:"
|
||||
"TLS13-AES-128-CCM-8-SHA256:"
|
||||
"TLS13-AES-128-CCM-SHA256";
|
||||
|
||||
#define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""
|
||||
|
||||
/* Plugin exit values */
|
||||
|
@ -298,6 +305,7 @@ static void usage()
|
|||
" Check server support for EDNS0 padding in TLS\n"
|
||||
" Special blocksize values are 0 = off,\n"
|
||||
" 1 = sensible default.\n"
|
||||
" tls-1.3 Check whether server supports TLS 1.3\n"
|
||||
"\n"
|
||||
"Enabling monitoring mode ensures output messages and exit statuses conform\n"
|
||||
"to the requirements of monitoring plugins (www.monitoring-plugins.org).\n",
|
||||
|
@ -386,7 +394,8 @@ static exit_value search(const struct test_info_s *test_info,
|
|||
const char *name,
|
||||
uint16_t type,
|
||||
getdns_dict *extensions,
|
||||
getdns_dict **response)
|
||||
getdns_dict **response,
|
||||
getdns_return_t *getdns_return)
|
||||
{
|
||||
getdns_return_t ret;
|
||||
getdns_dict *search_extensions =
|
||||
|
@ -394,6 +403,8 @@ static exit_value search(const struct test_info_s *test_info,
|
|||
|
||||
/* We always turn on the return_call_reporting extension. */
|
||||
if ((ret = getdns_dict_set_int(search_extensions, "return_call_reporting", GETDNS_EXTENSION_TRUE)) != GETDNS_RETURN_GOOD) {
|
||||
if (getdns_return)
|
||||
*getdns_return = ret;
|
||||
fprintf(test_info->errout,
|
||||
"Cannot set return call reporting: %s (%d)",
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
|
@ -417,11 +428,15 @@ static exit_value search(const struct test_info_s *test_info,
|
|||
if (!extensions)
|
||||
getdns_dict_destroy(search_extensions);
|
||||
if (ret != GETDNS_RETURN_GOOD) {
|
||||
fprintf(test_info->errout,
|
||||
"Error resolving '%s': %s (%d)",
|
||||
name,
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
if (getdns_return) {
|
||||
*getdns_return = ret;
|
||||
} else {
|
||||
fprintf(test_info->errout,
|
||||
"Error resolving '%s': %s (%d)",
|
||||
name,
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
}
|
||||
return EXIT_CRITICAL;
|
||||
}
|
||||
|
||||
|
@ -431,6 +446,8 @@ static exit_value search(const struct test_info_s *test_info,
|
|||
getdns_pretty_print_dict(*response));
|
||||
}
|
||||
|
||||
if (getdns_return)
|
||||
*getdns_return = ret;
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
|
@ -694,7 +711,7 @@ static exit_value search_check(const struct test_info_s *test_info,
|
|||
exit_value xit;
|
||||
getdns_dict *resp;
|
||||
|
||||
if ((xit = search(test_info, lookup_name, lookup_type, NULL, &resp)) != EXIT_OK)
|
||||
if ((xit = search(test_info, lookup_name, lookup_type, NULL, &resp, NULL)) != EXIT_OK)
|
||||
return xit;
|
||||
|
||||
if ((xit = check_result(test_info, resp)) != EXIT_OK)
|
||||
|
@ -1170,7 +1187,8 @@ static exit_value test_dnssec_validate(const struct test_info_s *test_info,
|
|||
"dnssec-failed.org",
|
||||
GETDNS_RRTYPE_A,
|
||||
NULL,
|
||||
&response)) != EXIT_OK)
|
||||
&response,
|
||||
NULL)) != EXIT_OK)
|
||||
return xit;
|
||||
|
||||
uint32_t error_id, rcode;
|
||||
|
@ -1209,7 +1227,8 @@ static exit_value test_dnssec_validate(const struct test_info_s *test_info,
|
|||
"dnssec-failed.org",
|
||||
GETDNS_RRTYPE_A,
|
||||
extensions,
|
||||
&response2)) != EXIT_OK)
|
||||
&response2,
|
||||
NULL)) != EXIT_OK)
|
||||
return xit;
|
||||
|
||||
getdns_dict_destroy(extensions);
|
||||
|
@ -1238,6 +1257,100 @@ static exit_value test_dnssec_validate(const struct test_info_s *test_info,
|
|||
return EXIT_OK;
|
||||
}
|
||||
|
||||
static exit_value test_tls13(const struct test_info_s *test_info,
|
||||
char ** av)
|
||||
{
|
||||
exit_value xit;
|
||||
getdns_return_t ret;
|
||||
|
||||
if (*av) {
|
||||
fputs("tls-1.3 takes no arguments", test_info->errout);
|
||||
return EXIT_USAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set cipher list to TLS 1.3-only ciphers. If we are using
|
||||
* an OpenSSL version that doesn't support TLS 1.3 this will cause
|
||||
* a Bad Context error on the lookup.
|
||||
*/
|
||||
if ((ret = getdns_context_set_tls_cipher_list(test_info->context, TLS13_CIPHER_SUITE)) != GETDNS_RETURN_GOOD) {
|
||||
fprintf(test_info->errout,
|
||||
"Cannot set TLS 1.3 cipher list: %s (%d)",
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
}
|
||||
|
||||
getdns_dict *response;
|
||||
|
||||
if ((xit = search(test_info,
|
||||
DEFAULT_LOOKUP_NAME,
|
||||
DEFAULT_LOOKUP_TYPE,
|
||||
NULL,
|
||||
&response,
|
||||
&ret)) != EXIT_OK) {
|
||||
if (xit == EXIT_CRITICAL) {
|
||||
if (ret == GETDNS_RETURN_BAD_CONTEXT) {
|
||||
fputs("Your version of OpenSSL does not support TLS 1.3 ciphers. You need at least OpenSSL 1.1.1.",
|
||||
test_info->errout);
|
||||
return EXIT_UNKNOWN;
|
||||
} else {
|
||||
fputs("Cannot establish TLS 1.3 connection.",
|
||||
test_info->errout);
|
||||
return EXIT_CRITICAL;
|
||||
}
|
||||
} else {
|
||||
return xit;
|
||||
}
|
||||
}
|
||||
|
||||
if ((xit = get_report_info(test_info, response, NULL, NULL, NULL)) != EXIT_OK)
|
||||
return xit;
|
||||
|
||||
getdns_list *l;
|
||||
|
||||
if ((ret = getdns_dict_get_list(response, "call_reporting", &l)) != GETDNS_RETURN_GOOD) {
|
||||
fprintf(test_info->errout,
|
||||
"Cannot get call report: %s (%d)",
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
return EXIT_UNKNOWN;
|
||||
}
|
||||
|
||||
getdns_dict *d;
|
||||
|
||||
if ((ret = getdns_list_get_dict(l, 0, &d)) != GETDNS_RETURN_GOOD) {
|
||||
fprintf(test_info->errout,
|
||||
"Cannot get call report first item: %s (%d)",
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
return EXIT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Search is forced TLS, so tls_version flag must exist. */
|
||||
getdns_bindata *version;
|
||||
|
||||
if ((ret = getdns_dict_get_bindata(d, "tls_version", &version)) != GETDNS_RETURN_GOOD) {
|
||||
fprintf(test_info->errout,
|
||||
"Cannot get TLS version: %s (%d)",
|
||||
getdns_get_errorstr_by_id(ret),
|
||||
ret);
|
||||
return EXIT_UNKNOWN;
|
||||
}
|
||||
|
||||
const char TLS_1_3_SIG[] = "TLSv1.3";
|
||||
|
||||
if (strncmp((const char *)version->data, TLS_1_3_SIG, sizeof(TLS_1_3_SIG) - 1) != 0) {
|
||||
fputs("Server does not support TLS 1.3", test_info->errout);
|
||||
return EXIT_CRITICAL;
|
||||
}
|
||||
|
||||
if ((xit = check_result(test_info, response)) != EXIT_OK)
|
||||
return xit;
|
||||
|
||||
fputs("Server supports TLS 1.3", test_info->errout);
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
static struct test_funcs_s
|
||||
{
|
||||
const char *name;
|
||||
|
@ -1254,6 +1367,7 @@ static struct test_funcs_s
|
|||
{ "tls-padding", true, false, test_padding },
|
||||
{ "keepalive", false, true, test_keepalive },
|
||||
{ "dnssec-validate", false, false, test_dnssec_validate },
|
||||
{ "tls-1.3", true, false, test_tls13 },
|
||||
{ NULL, false, false, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@ typedef struct getdns_network_req
|
|||
uint64_t debug_end_time;
|
||||
getdns_auth_state_t debug_tls_auth_status;
|
||||
getdns_bindata debug_tls_peer_cert;
|
||||
const char *debug_tls_version;
|
||||
size_t debug_udp;
|
||||
|
||||
/* When more space is needed for the wire_data response than is
|
||||
|
|
|
@ -920,6 +920,12 @@ _getdns_create_call_reporting_dict(
|
|||
getdns_dict_destroy(netreq_debug);
|
||||
return NULL;
|
||||
}
|
||||
if (getdns_dict_util_set_string(netreq_debug, "tls_version",
|
||||
netreq->debug_tls_version)){
|
||||
|
||||
getdns_dict_destroy(netreq_debug);
|
||||
return NULL;
|
||||
}
|
||||
if (getdns_dict_set_bindata(netreq_debug, "tls_peer_cert",
|
||||
&netreq->debug_tls_peer_cert)) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue