mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'develop' into feature/abstract-tls
This commit is contained in:
commit
3fe0c94357
38
ChangeLog
38
ChangeLog
|
@ -1,4 +1,40 @@
|
|||
* 2018-0?-??: Version 1.4.3
|
||||
* 2019-01-??: Version 1.5.1
|
||||
* Issue #415: Filter out #defines etc. when creating
|
||||
symbols file. Thanks Zero King
|
||||
* Be consistent and always fail connection setup if setting ciphers/curves/
|
||||
TLS version/cipher suites fails.
|
||||
|
||||
* 2018-12-21: Version 1.5.0
|
||||
* RFE getdnsapi/stubby#121 log re-instantiating TLS
|
||||
upstreams (because they reached tls_backoff_time) at
|
||||
log level 4 (WARNING)
|
||||
* GETDNS_RESPSTATUS_NO_NAME for NODATA answers too
|
||||
* ZONEMD rr-type
|
||||
* getdns_query queries for addresses when a query name
|
||||
without a type is given.
|
||||
* RFE #408: Fetching of trust anchors will be retried
|
||||
after failure, after a certain backoff time. The time
|
||||
can be configured with
|
||||
getdns_context_set_trust_anchors_backoff_time().
|
||||
* RFE #408: A "dnssec" extension that requires DNSSEC
|
||||
verification. When this extension is set, Indeterminate
|
||||
DNSSEC status will not be returned.
|
||||
* Issue #410: Unspecified ownership of get_api_information()
|
||||
* Fix for DNSSEC bug in finding most specific key when
|
||||
trust anchor proves non-existance of one of the labels
|
||||
along the authentication chain other than the non-
|
||||
existance of a DS record on a zonecut.
|
||||
* Enhancement getdnsapi/stubby#56 & getdnsapi/stubby#130:
|
||||
Configurable minimum and maximum TLS versions with
|
||||
getdns_context_set_tls_min_version() and
|
||||
getdns_context_set_tls_max_version() functions and
|
||||
tls_min_version and tls_max_version configuration parameters
|
||||
for upstreams.
|
||||
* Configurable TLS1.3 ciphersuites with the
|
||||
getdns_context_set_tls_ciphersuites() function and
|
||||
tls_ciphersuites config parameter for upstreams.
|
||||
* Bugfix in upstream string configurations: tls_cipher_list and
|
||||
tls_curve_list
|
||||
* Bugfix finding signer for validating NSEC and NSEC3s, which
|
||||
caused trouble with the partly tracing DNSSEC from the root
|
||||
up, introduced in 1.4.2. Thanks Philip Homburg
|
||||
|
|
|
@ -165,7 +165,7 @@ distclean:
|
|||
rm -f m4/ltoptions.m4
|
||||
rm -f m4/ltsugar.m4
|
||||
rm -f m4/ltversion.m4
|
||||
rm -f $(distdir).tar.gz $(distdir).tar.gz.sha256
|
||||
rm -f $(distdir).tar.gz $(distdir).tar.gz.sha256 $(distdir).tar.gz.sha1
|
||||
rm -f $(distdir).tar.gz.md5 $(distdir).tar.gz.asc
|
||||
|
||||
megaclean:
|
||||
|
@ -177,11 +177,14 @@ autoclean: megaclean
|
|||
|
||||
dist: $(distdir).tar.gz
|
||||
|
||||
pub: $(distdir).tar.gz.sha256 $(distdir).tar.gz.md5 $(distdir).tar.gz.asc
|
||||
pub: $(distdir).tar.gz.sha256 $(distdir).tar.gz.md5 $(distdir).tar.gz.asc $(distdir).tar.gz.sha1
|
||||
|
||||
$(distdir).tar.gz.sha256: $(distdir).tar.gz
|
||||
openssl sha256 $(distdir).tar.gz >$@
|
||||
|
||||
$(distdir).tar.gz.sha1: $(distdir).tar.gz
|
||||
openssl sha1 $(distdir).tar.gz >$@
|
||||
|
||||
$(distdir).tar.gz.md5: $(distdir).tar.gz
|
||||
openssl md5 $(distdir).tar.gz >$@
|
||||
|
||||
|
|
84
configure.ac
84
configure.ac
|
@ -37,7 +37,7 @@ sinclude(./m4/ac_lib_nettle.m4)
|
|||
sinclude(./m4/ax_check_compile_flag.m4)
|
||||
sinclude(./m4/pkg.m4)
|
||||
|
||||
AC_INIT([getdns], [1.4.2], [team@getdnsapi.net], [getdns], [https://getdnsapi.net])
|
||||
AC_INIT([getdns], [1.5.0], [team@getdnsapi.net], [getdns], [https://getdnsapi.net])
|
||||
|
||||
# Autoconf 2.70 will have set up runstatedir. 2.69 is frequently (Debian)
|
||||
# patched to do the same, but frequently (MacOS) not. So add a with option
|
||||
|
@ -64,13 +64,13 @@ AC_ARG_WITH([current-date],
|
|||
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
|
||||
|
||||
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
|
||||
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x01040200])
|
||||
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x01050000])
|
||||
AC_SUBST(API_VERSION, ["December 2015"])
|
||||
AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00])
|
||||
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
|
||||
|
||||
AC_DEFINE_UNQUOTED([STUBBY_PACKAGE], ["stubby"], [Stubby package])
|
||||
AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.3$STUBBY_RELEASE_CANDIDATE"], [Stubby package string])
|
||||
AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.4$STUBBY_RELEASE_CANDIDATE"], [Stubby package string])
|
||||
|
||||
# Library version
|
||||
# ---------------
|
||||
|
@ -106,8 +106,9 @@ AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.3$STUBBY_RELEASE_CANDIDATE"],
|
|||
# getdns-1.3.0 had libversion 9:0:3
|
||||
# getdns-1.4.0 had libversion 10:0:0
|
||||
# getdns-1.4.1 had libversion 10:1:0
|
||||
# getdns-1.4.2 has libversion 10:2:0
|
||||
GETDNS_LIBVERSION=10:2:0
|
||||
# getdns-1.4.2 had libversion 10:2:0
|
||||
# getdns-1.5.0 has libversion 11:0:1
|
||||
GETDNS_LIBVERSION=11:0:1
|
||||
|
||||
AC_SUBST(GETDNS_COMPILATION_COMMENT)
|
||||
AC_SUBST(GETDNS_LIBVERSION)
|
||||
|
@ -401,44 +402,45 @@ yes)
|
|||
esac
|
||||
|
||||
USE_NSS="no"
|
||||
AC_ARG_WITH([nss], AC_HELP_STRING([--with-nss=path],
|
||||
[use libnss instead of openssl, installed at path.]),
|
||||
[
|
||||
USE_NSS="yes"
|
||||
AC_DEFINE(HAVE_NSS, 1, [Use libnss for crypto])
|
||||
if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include/nss3"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
CPPFLAGS="-I$withval/include/nspr4 $CPPFLAGS"
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include/nss3"
|
||||
CPPFLAGS="-I/usr/include/nspr4 $CPPFLAGS"
|
||||
fi
|
||||
LIBS="$LIBS -lnss3 -lnspr4"
|
||||
SSLLIB=""
|
||||
]
|
||||
)
|
||||
dnl AC_ARG_WITH([nss], AC_HELP_STRING([--with-nss=path],
|
||||
dnl [use libnss instead of openssl, installed at path.]),
|
||||
dnl [
|
||||
dnl USE_NSS="yes"
|
||||
dnl AC_DEFINE(HAVE_NSS, 1, [Use libnss for crypto])
|
||||
dnl if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
dnl CPPFLAGS="$CPPFLAGS -I$withval/include/nss3"
|
||||
dnl LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
dnl ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
dnl CPPFLAGS="-I$withval/include/nspr4 $CPPFLAGS"
|
||||
dnl else
|
||||
dnl CPPFLAGS="$CPPFLAGS -I/usr/include/nss3"
|
||||
dnl CPPFLAGS="-I/usr/include/nspr4 $CPPFLAGS"
|
||||
dnl fi
|
||||
dnl LIBS="$LIBS -lnss3 -lnspr4"
|
||||
dnl SSLLIB=""
|
||||
dnl ]
|
||||
dnl )
|
||||
|
||||
# libnettle
|
||||
USE_NETTLE="no"
|
||||
AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path],
|
||||
[use libnettle as crypto library, installed at path.]),
|
||||
[
|
||||
USE_NETTLE="yes"
|
||||
AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto])
|
||||
AC_CHECK_HEADERS([nettle/dsa-compat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include/nettle"
|
||||
fi
|
||||
LIBS="$LIBS -lhogweed -lnettle -lgmp"
|
||||
SSLLIB=""
|
||||
]
|
||||
)
|
||||
dnl AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path],
|
||||
dnl [use libnettle as crypto library, installed at path.]),
|
||||
dnl [
|
||||
dnl USE_NETTLE="yes"
|
||||
dnl AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto])
|
||||
dnl AC_CHECK_HEADERS([nettle/dsa-compat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
dnl if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
dnl CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
|
||||
dnl LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
dnl ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
dnl else
|
||||
dnl CPPFLAGS="$CPPFLAGS -I/usr/include/nettle"
|
||||
dnl fi
|
||||
dnl LIBS="$LIBS -lhogweed -lnettle -lgmp"
|
||||
dnl SSLLIB=""
|
||||
dnl ]
|
||||
dnl )
|
||||
|
||||
# Which TLS and crypto libs to use.
|
||||
AC_ARG_WITH([gnutls],
|
||||
[AS_HELP_STRING([--with-gnutls],
|
||||
|
@ -497,7 +499,7 @@ fi
|
|||
AC_CHECK_HEADERS([openssl/conf.h openssl/ssl.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/bn.h openssl/rsa.h openssl/dsa.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_min_proto_version OpenSSL_version_num OpenSSL_version SSL_CTX_dane_enable SSL_dane_enable SSL_dane_tlsa_add X509_check_host X509_get_notAfter X509_get0_notAfter SSL_CTX_set_ciphersuites SSL_set_ciphersuites OPENSSL_init_crypto DSA_set0_pqg DSA_set0_key RSA_set0_key])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify OpenSSL_version_num OpenSSL_version SSL_CTX_dane_enable SSL_dane_enable SSL_dane_tlsa_add X509_check_host X509_get_notAfter X509_get0_notAfter SSL_CTX_set_ciphersuites SSL_set_ciphersuites OPENSSL_init_crypto DSA_set0_pqg DSA_set0_key RSA_set0_key])
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set1_curves_list,SSL_set1_curves_list,SSL_set_min_proto_version,SSL_get_min_proto_version], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
|
|
242
src/anchor.c
242
src/anchor.c
|
@ -523,10 +523,8 @@ static const char tas_write_xml_p7s_buf[] =
|
|||
"\r\n";
|
||||
|
||||
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
static inline const char * rt_str(uint16_t rt)
|
||||
{ return rt == GETDNS_RRTYPE_A ? "A" : rt == GETDNS_RRTYPE_AAAA ? "AAAA" : "?"; }
|
||||
#endif
|
||||
|
||||
static int tas_busy(tas_connection *a)
|
||||
{
|
||||
|
@ -573,7 +571,8 @@ static void tas_success(getdns_context *context, tas_connection *a)
|
|||
tas_cleanup(context, a);
|
||||
tas_cleanup(context, other);
|
||||
|
||||
DEBUG_ANCHOR("Successfully fetched new trust anchors\n");
|
||||
_getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
|
||||
, "Successfully fetched new trust anchors\n");
|
||||
context->trust_anchors_source = GETDNS_TASRC_XML;
|
||||
_getdns_ta_notify_dnsreqs(context);
|
||||
}
|
||||
|
@ -581,20 +580,26 @@ static void tas_success(getdns_context *context, tas_connection *a)
|
|||
static void tas_fail(getdns_context *context, tas_connection *a)
|
||||
{
|
||||
tas_connection *other = &context->a == a ? &context->aaaa : &context->a;
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
uint16_t rt = &context->a == a ? GETDNS_RRTYPE_A : GETDNS_RRTYPE_AAAA;
|
||||
uint16_t ort = rt == GETDNS_RRTYPE_A ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A;
|
||||
#endif
|
||||
|
||||
tas_cleanup(context, a);
|
||||
|
||||
if (!tas_busy(other)) {
|
||||
DEBUG_ANCHOR("Fatal error fetching trust anchor: "
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Fatal error fetching trust anchor: "
|
||||
"%s connection failed too\n", rt_str(rt));
|
||||
context->trust_anchors_source = GETDNS_TASRC_FAILED;
|
||||
context->trust_anchors_backoff_expiry =
|
||||
_getdns_get_now_ms() + context->trust_anchors_backoff_time;
|
||||
_getdns_ta_notify_dnsreqs(context);
|
||||
} else
|
||||
DEBUG_ANCHOR("%s connection failed, waiting for %s\n"
|
||||
, rt_str(rt), rt_str(ort));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "%s connection failed, waiting for %s\n"
|
||||
, rt_str(rt)
|
||||
, rt_str( rt == GETDNS_RRTYPE_A
|
||||
? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A));
|
||||
}
|
||||
|
||||
static void tas_connect(getdns_context *context, tas_connection *a);
|
||||
|
@ -626,7 +631,9 @@ static void tas_timeout_cb(void *userarg)
|
|||
a = &context->a;
|
||||
else a = &context->aaaa;
|
||||
|
||||
DEBUG_ANCHOR("Trust anchor fetch timeout\n");
|
||||
_getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "Trust anchor fetch timeout\n");
|
||||
|
||||
GETDNS_CLEAR_EVENT(a->loop, &a->event);
|
||||
tas_next(context, a);
|
||||
}
|
||||
|
@ -642,7 +649,9 @@ static void tas_reconnect_cb(void *userarg)
|
|||
a = &context->a;
|
||||
else a = &context->aaaa;
|
||||
|
||||
DEBUG_ANCHOR("Waiting for second document timeout. Reconnecting...\n");
|
||||
_getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "Waiting for second document timeout. Reconnecting...\n");
|
||||
|
||||
GETDNS_CLEAR_EVENT(a->loop, &a->event);
|
||||
close(a->fd);
|
||||
a->fd = -1;
|
||||
|
@ -657,8 +666,6 @@ static void tas_read_cb(void *userarg);
|
|||
static void tas_write_cb(void *userarg);
|
||||
static void tas_doc_read(getdns_context *context, tas_connection *a)
|
||||
{
|
||||
DEBUG_ANCHOR("doc (size: %d)\n", (int)a->tcp.read_buf_len);
|
||||
|
||||
assert(a->tcp.read_pos == a->tcp.read_buf + a->tcp.read_buf_len);
|
||||
assert(context);
|
||||
|
||||
|
@ -687,18 +694,20 @@ static void tas_doc_read(getdns_context *context, tas_connection *a)
|
|||
|
||||
if ((r = getdns_context_get_trust_anchors_verify_CA(
|
||||
context, (const char **)&verify_CA.data)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify"
|
||||
" CA: \"%s\"\n", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get trust anchor verify CA: "
|
||||
"\"%s\"\n", getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if (!(verify_CA.size = strlen((const char *)verify_CA.data)))
|
||||
; /* pass */
|
||||
|
||||
else if ((r = getdns_context_get_trust_anchors_verify_email(
|
||||
context, &verify_email)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify"
|
||||
" email address: \"%s\"\n", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get trust anchor verify email: "
|
||||
"\"%s\"\n", getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if (!(tas = _getdns_tas_validate(&context->mf, &a->xml, &p7s_bd,
|
||||
&verify_CA, verify_email, &now_ms, tas, &tas_len)))
|
||||
|
@ -823,7 +832,11 @@ static void tas_read_cb(void *userarg)
|
|||
DEBUG_ANCHOR("i: %d, n: %d, doc_len: %d\n"
|
||||
, (int)i, (int)n, doc_len);
|
||||
if (!doc)
|
||||
DEBUG_ANCHOR("Memory error");
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR
|
||||
, GETDNS_LOG_ERR
|
||||
, "Memory error while reading "
|
||||
"trust anchor\n");
|
||||
else {
|
||||
ssize_t surplus = n - i;
|
||||
|
||||
|
@ -870,7 +883,11 @@ static void tas_read_cb(void *userarg)
|
|||
} else if (_getdns_socketerror_wants_retry())
|
||||
return;
|
||||
|
||||
DEBUG_ANCHOR("Read error: %d %s\n", (int)n, _getdns_errnostr());
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error while receiving trust anchor: %s\n"
|
||||
, _getdns_errnostr());
|
||||
|
||||
GETDNS_CLEAR_EVENT(a->loop, &a->event);
|
||||
tas_next(context, a);
|
||||
}
|
||||
|
@ -920,7 +937,9 @@ static void tas_write_cb(void *userarg)
|
|||
} else if (_getdns_socketerror_wants_retry())
|
||||
return;
|
||||
|
||||
DEBUG_ANCHOR("Write error: %s\n", _getdns_errnostr());
|
||||
_getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error while sending to trust anchor site: %s\n"
|
||||
, _getdns_errnostr());
|
||||
GETDNS_CLEAR_EVENT(a->loop, &a->event);
|
||||
tas_next(context, a);
|
||||
}
|
||||
|
@ -959,9 +978,7 @@ static getdns_return_t _getdns_get_tas_url_hostname(
|
|||
|
||||
static void tas_connect(getdns_context *context, tas_connection *a)
|
||||
{
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char a_buf[40];
|
||||
#endif
|
||||
int r;
|
||||
|
||||
#ifdef HAVE_FCNTL
|
||||
|
@ -977,15 +994,19 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
tas_next(context, a);
|
||||
return;
|
||||
}
|
||||
DEBUG_ANCHOR("Initiating connection to %s\n"
|
||||
, inet_ntop(( a->req->request_type == GETDNS_RRTYPE_A
|
||||
? AF_INET : AF_INET6)
|
||||
, a->rr->rr_i.rr_type + 10, a_buf, sizeof(a_buf)));
|
||||
|
||||
_getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "Setting op connection to: %s\n"
|
||||
, inet_ntop( ( a->req->request_type == GETDNS_RRTYPE_A
|
||||
? AF_INET : AF_INET6)
|
||||
, a->rr->rr_i.rr_type + 10
|
||||
, a_buf, sizeof(a_buf)));
|
||||
|
||||
if ((a->fd = socket(( a->req->request_type == GETDNS_RRTYPE_A
|
||||
? AF_INET : AF_INET6), SOCK_STREAM, IPPROTO_TCP)) == -1) {
|
||||
DEBUG_ANCHOR("Error creating socket: %s\n",
|
||||
_getdns_errnostr());
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error creating socket: %s\n", _getdns_errnostr());
|
||||
tas_next(context, a);
|
||||
return;
|
||||
}
|
||||
|
@ -1036,9 +1057,11 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
}
|
||||
if ((R = _getdns_get_tas_url_hostname(
|
||||
context, tas_hostname, &path))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get hostname from trust anchor "
|
||||
"url: \"%s\"\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
goto error;
|
||||
}
|
||||
hostname_len = strlen(tas_hostname);
|
||||
|
@ -1046,8 +1069,10 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
tas_hostname[--hostname_len] = '\0';
|
||||
path_len = strlen(path);
|
||||
if (path_len < 4) {
|
||||
DEBUG_ANCHOR("ERROR %s(): path of tas_url \"%s\" too "
|
||||
"small\n", __FUNC__, path);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Trust anchor path \"%s\" too small\n"
|
||||
, path);
|
||||
goto error;
|
||||
}
|
||||
if (a->state == TAS_RETRY_GET_PS7) {
|
||||
|
@ -1060,8 +1085,10 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
fmt = tas_write_xml_p7s_buf;
|
||||
}
|
||||
if (!(write_buf = GETDNS_XMALLOC(context->mf, char, buf_sz))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not allocate write "
|
||||
"buffer\n", __FUNC__);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot allocate write buffer for "
|
||||
"sending to trust anchor host\n");
|
||||
goto error;
|
||||
}
|
||||
if (a->state == TAS_RETRY_GET_PS7) {
|
||||
|
@ -1095,8 +1122,10 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
DEBUG_ANCHOR("Scheduled write with event\n");
|
||||
return;
|
||||
} else
|
||||
DEBUG_ANCHOR("Connect error: %s\n", _getdns_errnostr());
|
||||
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error connecting to trust anchor host: %s\n "
|
||||
, _getdns_errnostr());
|
||||
error:
|
||||
tas_next(context, a);
|
||||
}
|
||||
|
@ -1110,7 +1139,10 @@ static void tas_happy_eyeballs_cb(void *userarg)
|
|||
if (tas_fetching(&context->aaaa))
|
||||
return;
|
||||
else {
|
||||
DEBUG_ANCHOR("AAAA came too late, clearing Happy Eyeballs timer\n");
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "Too late reception of AAAA for trust anchor "
|
||||
"host for Happy Eyeballs\n");
|
||||
GETDNS_CLEAR_EVENT(context->a.loop, &context->a.event);
|
||||
tas_connect(context, &context->a);
|
||||
}
|
||||
|
@ -1129,28 +1161,31 @@ static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq)
|
|||
&a->rrset_spc, a->req->response, a->req->response_len);
|
||||
|
||||
if (!a->rrset) {
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char tas_hostname[256] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%s lookup for %s returned no response\n"
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "%s lookup for %s returned no response\n"
|
||||
, rt_str(a->req->request_type), tas_hostname);
|
||||
#endif
|
||||
|
||||
} else if (a->req->response_len < dnsreq->name_len + 12 ||
|
||||
!_getdns_dname_equal(a->req->response + 12, dnsreq->name) ||
|
||||
a->rrset->rr_type != a->req->request_type) {
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char tas_hostname[256] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%s lookup for %s returned wrong response\n"
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "%s lookup for %s returned wrong response\n"
|
||||
, rt_str(a->req->request_type), tas_hostname);
|
||||
#endif
|
||||
|
||||
} else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset))) {
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char tas_hostname[256] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%s lookup for %s returned no addresses\n"
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "%s lookup for %s returned no addresses\n"
|
||||
, rt_str(a->req->request_type), tas_hostname);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
tas_connection *other = a == &context->a ? &context->aaaa
|
||||
: &context->a;
|
||||
|
@ -1160,8 +1195,9 @@ static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq)
|
|||
; /* pass */
|
||||
|
||||
else if (a == &context->a && tas_busy(other)) {
|
||||
DEBUG_ANCHOR("Postponing connection initiation: "
|
||||
"Happy Eyeballs\n");
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "Waiting 25ms for AAAA to arrive\n");
|
||||
GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 25,
|
||||
getdns_eventloop_event_init(&a->event,
|
||||
a->req->owner, NULL, NULL, tas_happy_eyeballs_cb));
|
||||
|
@ -1178,7 +1214,8 @@ static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq)
|
|||
tas_fail(context, a);
|
||||
}
|
||||
|
||||
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
||||
void _getdns_start_fetching_ta(
|
||||
getdns_context *context, getdns_eventloop *loop, uint64_t *now_ms)
|
||||
{
|
||||
getdns_return_t r;
|
||||
size_t scheduled;
|
||||
|
@ -1187,38 +1224,47 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
const char *verify_email;
|
||||
|
||||
if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get hostname from trust anchor url: "
|
||||
"\"%s\"\n", getdns_get_errorstr_by_id(r));
|
||||
return;
|
||||
|
||||
} else if ((r = getdns_context_get_trust_anchors_verify_CA(
|
||||
context, &verify_CA))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get verify CA"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get trust anchor verify CA: \"%s\"\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
return;
|
||||
|
||||
} else if (!verify_CA || !*verify_CA) {
|
||||
DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely "
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
|
||||
, "Trust anchor verification explicitly "
|
||||
"disabled by empty verify CA\n");
|
||||
return;
|
||||
|
||||
} else if ((r = getdns_context_get_trust_anchors_verify_email(
|
||||
context, &verify_email))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get verify email address"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Cannot get trust anchor verify email: \"%s\"\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
return;
|
||||
|
||||
} else if (!verify_email || !*verify_email) {
|
||||
DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely "
|
||||
"disabled by empty verify email address\n");
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
|
||||
, "Trust anchor verification explicitly "
|
||||
"disabled by empty verify email\n");
|
||||
return;
|
||||
|
||||
} else if (!_getdns_context_can_write_appdata(context)) {
|
||||
DEBUG_ANCHOR("NOTICE %s(): Not fetching TA, because "
|
||||
"non writeable appdata directory\n", __FUNC__);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "Not fetching TA, because "
|
||||
"non writeable appdata directory\n");
|
||||
return;
|
||||
}
|
||||
DEBUG_ANCHOR("Hostname: %s\n", tas_hostname);
|
||||
|
@ -1226,35 +1272,44 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
loop == &context->sync_eventloop.loop ? "" : "a");
|
||||
|
||||
scheduled = 0;
|
||||
#if 1
|
||||
context->a.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context, loop,
|
||||
tas_hostname, GETDNS_RRTYPE_A,
|
||||
no_dnssec_checking_disabled_opportunistic,
|
||||
context, &context->a.req, NULL, _tas_hostname_lookup_cb))) {
|
||||
DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n"
|
||||
, tas_hostname, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "Error scheduling A lookup for %s: %s\n"
|
||||
, tas_hostname, getdns_get_errorstr_by_id(r));
|
||||
} else
|
||||
scheduled += 1;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
context->aaaa.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context, loop,
|
||||
tas_hostname, GETDNS_RRTYPE_AAAA,
|
||||
no_dnssec_checking_disabled_opportunistic,
|
||||
context, &context->aaaa.req, NULL, _tas_hostname_lookup_cb))) {
|
||||
DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n"
|
||||
, tas_hostname, getdns_get_errorstr_by_id(r));
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "Error scheduling AAAA lookup for %s: %s\n"
|
||||
, tas_hostname, getdns_get_errorstr_by_id(r));
|
||||
} else
|
||||
scheduled += 1;
|
||||
#endif
|
||||
|
||||
if (!scheduled) {
|
||||
DEBUG_ANCHOR("Fatal error fetching trust anchor: Unable to "
|
||||
"schedule address requests for %s\n"
|
||||
, tas_hostname);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING
|
||||
, "Error scheduling address lookups for %s\n"
|
||||
, tas_hostname);
|
||||
|
||||
context->trust_anchors_source = GETDNS_TASRC_FAILED;
|
||||
if (now_ms) {
|
||||
if (*now_ms == 0) *now_ms = _getdns_get_now_ms();
|
||||
context->trust_anchors_backoff_expiry =
|
||||
*now_ms + context->trust_anchors_backoff_time;
|
||||
} else
|
||||
context->trust_anchors_backoff_expiry =
|
||||
_getdns_get_now_ms() + context->trust_anchors_backoff_time;
|
||||
_getdns_ta_notify_dnsreqs(context);
|
||||
} else
|
||||
context->trust_anchors_source = GETDNS_TASRC_FETCHING;
|
||||
|
@ -1371,7 +1426,10 @@ static void _getdns_context_read_root_ksk(getdns_context *context)
|
|||
buf_sz *= 2;
|
||||
}
|
||||
if (!(buf = GETDNS_XMALLOC(context->mf, uint8_t, buf_sz))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error allocating memory to read "
|
||||
"root.key\n");
|
||||
break;;
|
||||
}
|
||||
ptr = buf;
|
||||
|
@ -1456,8 +1514,10 @@ _getdns_context_update_root_ksk(
|
|||
break;
|
||||
}
|
||||
if (str_buf != str_spc) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Buffer size determination "
|
||||
"error\n", __FUNC__);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error determining buffer size for root "
|
||||
"KSK\n");
|
||||
if (str_buf)
|
||||
GETDNS_FREE(context->mf, str_buf);
|
||||
|
||||
|
@ -1465,11 +1525,13 @@ _getdns_context_update_root_ksk(
|
|||
}
|
||||
if (!(str_pos = str_buf = GETDNS_XMALLOC( context->mf, char,
|
||||
(str_sz = sizeof(str_spc) - remaining) + 1))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
|
||||
, "Error allocating memory to read "
|
||||
"root KSK\n");
|
||||
return;
|
||||
}
|
||||
remaining = str_sz + 1;
|
||||
DEBUG_ANCHOR("Retrying with buf size: %d\n", remaining);
|
||||
};
|
||||
|
||||
/* Write presentation format DNSKEY rrset to "root.key" file */
|
||||
|
@ -1544,17 +1606,21 @@ _getdns_context_update_root_ksk(
|
|||
break;
|
||||
}
|
||||
if (!ta) {
|
||||
DEBUG_ANCHOR("NOTICE %s(): Key with id %d "
|
||||
"*not* found in TA.\n"
|
||||
"\"root-anchors.xml\" need "
|
||||
"updating.\n", __FUNC__
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR
|
||||
, GETDNS_LOG_NOTICE
|
||||
, "Key with id %d not found in TA; "
|
||||
"\"root-anchors.xml\" needs to be "
|
||||
"updated.\n"
|
||||
, context->root_ksk.ids[i]);
|
||||
context->trust_anchors_source =
|
||||
GETDNS_TASRC_XML_UPDATE;
|
||||
break;
|
||||
}
|
||||
DEBUG_ANCHOR("DEBUG %s(): Key with id %d found in TA\n"
|
||||
, __FUNC__, context->root_ksk.ids[i]);
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG
|
||||
, "Key with id %d found in TA\n"
|
||||
, context->root_ksk.ids[i]);
|
||||
}
|
||||
}
|
||||
if (str_buf && str_buf != str_spc)
|
||||
|
|
|
@ -64,7 +64,8 @@ uint16_t _getdns_parse_xml_trust_anchors_buf(gldns_buffer *gbuf, uint64_t *now_m
|
|||
**/
|
||||
void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms);
|
||||
|
||||
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop);
|
||||
void _getdns_start_fetching_ta(
|
||||
getdns_context *context, getdns_eventloop *loop, uint64_t *now_ms);
|
||||
|
||||
#define MAX_KSKS 16
|
||||
#define RRSIG_RDATA_LEN 16
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define KEYSZ 32
|
||||
#define IVSZ 8
|
||||
|
@ -71,6 +74,72 @@ static struct {
|
|||
|
||||
static inline void _rs_rekey(u_char *dat, size_t datlen);
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
fallback_gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fallback for getentropy in case libc returns failure */
|
||||
static int
|
||||
fallback_getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
# ifdef HAVE_FCNTL
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
#endif
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (fallback_gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
|
@ -114,14 +183,14 @@ _rs_stir(void)
|
|||
u_char rnd[KEYSZ + IVSZ];
|
||||
|
||||
if (getentropy(rnd, sizeof rnd) == -1) {
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
raise(SIGKILL);
|
||||
raise(SIGKILL);
|
||||
#else
|
||||
#ifdef GETDNS_ON_WINDOWS
|
||||
DebugBreak();
|
||||
#endif
|
||||
exit(9); /* windows */
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!rs)
|
||||
|
@ -131,9 +200,6 @@ _rs_stir(void)
|
|||
explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
|
||||
|
||||
/* invalidate rs_buf */
|
||||
#ifdef GETDNS_ON_WINDOWS
|
||||
_Analysis_assume_(rs != NULL);
|
||||
#endif
|
||||
rs->rs_have = 0;
|
||||
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
|
||||
|
||||
|
@ -145,15 +211,7 @@ _rs_stir_if_needed(size_t len)
|
|||
{
|
||||
#ifndef MAP_INHERIT_ZERO
|
||||
static pid_t _rs_pid = 0;
|
||||
#ifdef GETDNS_ON_WINDOWS
|
||||
/*
|
||||
* TODO: if compiling for the Windows Runtime, use GetCurrentProcessId(),
|
||||
* but this requires linking with kernel32.lib
|
||||
*/
|
||||
pid_t pid = _getpid();
|
||||
#else
|
||||
pid_t pid = getpid();
|
||||
#endif
|
||||
|
||||
/* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
|
||||
if (_rs_pid == 0 || _rs_pid != pid) {
|
||||
|
@ -164,9 +222,6 @@ _rs_stir_if_needed(size_t len)
|
|||
#endif
|
||||
if (!rs || rs->rs_count <= len)
|
||||
_rs_stir();
|
||||
#ifdef GETDNS_ON_WINDOWS
|
||||
_Analysis_assume_(rs != NULL);
|
||||
#endif
|
||||
if (rs->rs_count <= len)
|
||||
rs->rs_count = 0;
|
||||
else
|
||||
|
|
|
@ -39,7 +39,7 @@ arc4random_uniform(uint32_t upper_bound)
|
|||
return 0;
|
||||
|
||||
/* 2**32 % x == (2**32 - x) % x */
|
||||
min = ((uint32_t)(-(int32_t)upper_bound)) % upper_bound;
|
||||
min = -upper_bound % upper_bound;
|
||||
|
||||
/*
|
||||
* This could theoretically loop forever but each retry has
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: getentropy_linux.c,v 1.45 2018/03/13 22:53:28 bcook Exp $ */
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
|
@ -15,17 +15,13 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
#define WITH_DL_ITERATE_PHDR 1
|
||||
#ifdef WITH_DL_ITERATE_PHDR
|
||||
#define _GNU_SOURCE 1
|
||||
/* #define _POSIX_C_SOURCE 199309L */
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#define _GNU_SOURCE 1
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -43,9 +39,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#ifdef WITH_DL_ITERATE_PHDR
|
||||
#include <link.h>
|
||||
#endif
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
@ -67,6 +60,9 @@
|
|||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#include <sys/vfs.h>
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define REPEAT 5
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
@ -82,7 +78,6 @@
|
|||
#if defined(HAVE_SSL)
|
||||
#define CRYPTO_SHA512_CTX SHA512_CTX
|
||||
#define CRYPTO_SHA512_INIT(x) SHA512_Init(x)
|
||||
#define CRYPTO_SHA512_UPDATE(c, x, l) (SHA512_Update((c), (char *)(x), (l)))
|
||||
#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c)
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
|
@ -90,7 +85,6 @@
|
|||
#elif defined(HAVE_NETTLE)
|
||||
#define CRYPTO_SHA512_CTX struct sha512_ctx
|
||||
#define CRYPTO_SHA512_INIT(x) sha512_init(x)
|
||||
#define CRYPTO_SHA512_UPDATE(c, x, l) (sha512_update((c), (l), (uint8_t *)(x)))
|
||||
#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
|
||||
#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
|
||||
|
@ -99,8 +93,11 @@
|
|||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
static int getentropy_getrandom(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
|
@ -108,9 +105,6 @@ static int getentropy_urandom(void *buf, size_t len);
|
|||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
#ifdef WITH_DL_ITERATE_PHDR
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
#endif
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
|
@ -119,21 +113,18 @@ getentropy(void *buf, size_t len)
|
|||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
/*
|
||||
* Try descriptor-less getrandom(), in non-blocking mode.
|
||||
*
|
||||
* The design of Linux getrandom is broken. It has an
|
||||
* uninitialized phase coupled with blocking behaviour, which
|
||||
* is unacceptable from within a library at boot time without
|
||||
* possible recovery. See http://bugs.python.org/issue26839#msg267745
|
||||
* Try descriptor-less getrandom()
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (errno != ENOSYS)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -187,7 +178,7 @@ getentropy(void *buf, size_t len)
|
|||
* - Do the best under the circumstances....
|
||||
*
|
||||
* This code path exists to bring light to the issue that Linux
|
||||
* still does not provide a failsafe API for entropy collection.
|
||||
* does not provide a failsafe API for entropy collection.
|
||||
*
|
||||
* We hope this demonstrates that Linux should either retain their
|
||||
* sysctl ABI, or consider providing a new failsafe API which
|
||||
|
@ -217,11 +208,11 @@ gotdata(char *buf, size_t len)
|
|||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
|
@ -230,7 +221,7 @@ getentropy_getrandom(void *buf, size_t len)
|
|||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
|
||||
ret = syscall(SYS_getrandom, buf, len, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret != (int)len)
|
||||
|
@ -278,7 +269,7 @@ start:
|
|||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
|
@ -291,11 +282,11 @@ start:
|
|||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SYS__sysctl
|
||||
|
@ -326,11 +317,11 @@ getentropy_sysctl(void *buf, size_t len)
|
|||
}
|
||||
sysctlfailed:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
static const int cl[] = {
|
||||
static int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC,
|
||||
|
@ -355,18 +346,6 @@ static const int cl[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef WITH_DL_ITERATE_PHDR
|
||||
static int
|
||||
getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
CRYPTO_SHA512_CTX *ctx = data;
|
||||
(void)size;
|
||||
|
||||
CRYPTO_SHA512_UPDATE(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
|
@ -403,10 +382,6 @@ getentropy_fallback(void *buf, size_t len)
|
|||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
#ifdef WITH_DL_ITERATE_PHDR
|
||||
dl_iterate_phdr(getentropy_phdr, &ctx);
|
||||
#endif
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
|
@ -426,6 +401,9 @@ getentropy_fallback(void *buf, size_t len)
|
|||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
|
@ -550,34 +528,33 @@ getentropy_fallback(void *buf, size_t len)
|
|||
HD(cnt);
|
||||
}
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#ifdef AT_RANDOM
|
||||
# ifdef AT_RANDOM
|
||||
/* Not as random as you think but we take what we are given */
|
||||
p = (char *) getauxval(AT_RANDOM);
|
||||
if (p)
|
||||
HR(p, 16);
|
||||
#endif
|
||||
#ifdef AT_SYSINFO_EHDR
|
||||
# endif
|
||||
# ifdef AT_SYSINFO_EHDR
|
||||
p = (char *) getauxval(AT_SYSINFO_EHDR);
|
||||
if (p)
|
||||
HR(p, pgs);
|
||||
#endif
|
||||
#ifdef AT_BASE
|
||||
# endif
|
||||
# ifdef AT_BASE
|
||||
p = (char *) getauxval(AT_BASE);
|
||||
if (p)
|
||||
HD(p);
|
||||
#endif
|
||||
#endif
|
||||
# endif
|
||||
#endif /* HAVE_GETAUXVAL */
|
||||
|
||||
CRYPTO_SHA512_FINAL(results, &ctx);
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
memset(&ctx, 0, sizeof ctx);
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,10 @@ static struct const_info consts_info[] = {
|
|||
{ 632, "GETDNS_CONTEXT_CODE_TLS_CA_FILE", GETDNS_CONTEXT_CODE_TLS_CA_FILE_TEXT },
|
||||
{ 633, "GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST", GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST_TEXT },
|
||||
{ 634, "GETDNS_CONTEXT_CODE_TLS_CURVES_LIST", GETDNS_CONTEXT_CODE_TLS_CURVES_LIST_TEXT },
|
||||
{ 635, "GETDNS_CONTEXT_CODE_TLS_CIPHERSUITES", GETDNS_CONTEXT_CODE_TLS_CIPHERSUITES_TEXT },
|
||||
{ 636, "GETDNS_CONTEXT_CODE_TLS_MIN_VERSION", GETDNS_CONTEXT_CODE_TLS_MIN_VERSION_TEXT },
|
||||
{ 637, "GETDNS_CONTEXT_CODE_TLS_MAX_VERSION", GETDNS_CONTEXT_CODE_TLS_MAX_VERSION_TEXT },
|
||||
{ 638, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_BACKOFF_TIME_TEXT },
|
||||
{ 699, "GETDNS_CONTEXT_CODE_MAX_BACKOFF_VALUE", GETDNS_CONTEXT_CODE_MAX_BACKOFF_VALUE_TEXT },
|
||||
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
||||
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
||||
|
@ -115,7 +119,16 @@ static struct const_info consts_info[] = {
|
|||
{ 1202, "GETDNS_TRANSPORT_TLS", GETDNS_TRANSPORT_TLS_TEXT },
|
||||
{ 1300, "GETDNS_AUTHENTICATION_NONE", GETDNS_AUTHENTICATION_NONE_TEXT },
|
||||
{ 1301, "GETDNS_AUTHENTICATION_REQUIRED", GETDNS_AUTHENTICATION_REQUIRED_TEXT },
|
||||
{ 4096, "GETDNS_LOG_UPSTREAM_STATS", GETDNS_LOG_UPSTREAM_STATS_TEXT },
|
||||
{ 1400, "GETDNS_SSL3", GETDNS_SSL3_TEXT },
|
||||
{ 1401, "GETDNS_TLS1", GETDNS_TLS1_TEXT },
|
||||
{ 1402, "GETDNS_TLS1_1", GETDNS_TLS1_1_TEXT },
|
||||
{ 1403, "GETDNS_TLS1_2", GETDNS_TLS1_2_TEXT },
|
||||
{ 1404, "GETDNS_TLS1_3", GETDNS_TLS1_3_TEXT },
|
||||
{ 8192, "GETDNS_LOG_SYS_STUB", GETDNS_LOG_SYS_STUB_TEXT },
|
||||
{ 12288, "GETDNS_LOG_UPSTREAM_STATS", GETDNS_LOG_UPSTREAM_STATS_TEXT },
|
||||
{ 16384, "GETDNS_LOG_SYS_RECURSING", GETDNS_LOG_SYS_RECURSING_TEXT },
|
||||
{ 24576, "GETDNS_LOG_SYS_RESOLVING", GETDNS_LOG_SYS_RESOLVING_TEXT },
|
||||
{ 32768, "GETDNS_LOG_SYS_ANCHOR", GETDNS_LOG_SYS_ANCHOR_TEXT },
|
||||
};
|
||||
|
||||
static int const_info_cmp(const void *a, const void *b)
|
||||
|
@ -190,10 +203,14 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CA_FILE", 632 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CA_PATH", 631 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CIPHERSUITES", 635 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST", 633 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CURVES_LIST", 634 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_MAX_VERSION", 637 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_MIN_VERSION", 636 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_BACKOFF_TIME", 638 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL", 625 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", 626 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", 627 },
|
||||
|
@ -212,7 +229,11 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_LOG_ERR", 3 },
|
||||
{ "GETDNS_LOG_INFO", 6 },
|
||||
{ "GETDNS_LOG_NOTICE", 5 },
|
||||
{ "GETDNS_LOG_UPSTREAM_STATS", 4096 },
|
||||
{ "GETDNS_LOG_SYS_ANCHOR", 32768 },
|
||||
{ "GETDNS_LOG_SYS_RECURSING", 16384 },
|
||||
{ "GETDNS_LOG_SYS_RESOLVING", 24576 },
|
||||
{ "GETDNS_LOG_SYS_STUB", 8192 },
|
||||
{ "GETDNS_LOG_UPSTREAM_STATS", 12288 },
|
||||
{ "GETDNS_LOG_WARNING", 4 },
|
||||
{ "GETDNS_NAMESPACE_DNS", 500 },
|
||||
{ "GETDNS_NAMESPACE_LOCALNAMES", 501 },
|
||||
|
@ -279,6 +300,7 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_RRCLASS_IN", 1 },
|
||||
{ "GETDNS_RRCLASS_NONE", 254 },
|
||||
{ "GETDNS_RRTYPE_A", 1 },
|
||||
{ "GETDNS_RRTYPE_A6", 38 },
|
||||
{ "GETDNS_RRTYPE_AAAA", 28 },
|
||||
{ "GETDNS_RRTYPE_AFSDB", 18 },
|
||||
{ "GETDNS_RRTYPE_ANY", 255 },
|
||||
|
@ -299,6 +321,8 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_RRTYPE_DOA", 259 },
|
||||
{ "GETDNS_RRTYPE_DS", 43 },
|
||||
{ "GETDNS_RRTYPE_EID", 31 },
|
||||
{ "GETDNS_RRTYPE_EUI48", 108 },
|
||||
{ "GETDNS_RRTYPE_EUI64", 109 },
|
||||
{ "GETDNS_RRTYPE_GID", 102 },
|
||||
{ "GETDNS_RRTYPE_GPOS", 27 },
|
||||
{ "GETDNS_RRTYPE_HINFO", 13 },
|
||||
|
@ -308,6 +332,8 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_RRTYPE_IXFR", 251 },
|
||||
{ "GETDNS_RRTYPE_KEY", 25 },
|
||||
{ "GETDNS_RRTYPE_KX", 36 },
|
||||
{ "GETDNS_RRTYPE_L32", 105 },
|
||||
{ "GETDNS_RRTYPE_L64", 106 },
|
||||
{ "GETDNS_RRTYPE_LOC", 29 },
|
||||
{ "GETDNS_RRTYPE_LP", 107 },
|
||||
{ "GETDNS_RRTYPE_MAILA", 254 },
|
||||
|
@ -327,6 +353,8 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_RRTYPE_NSAP", 22 },
|
||||
{ "GETDNS_RRTYPE_NSAP_PTR", 23 },
|
||||
{ "GETDNS_RRTYPE_NSEC", 47 },
|
||||
{ "GETDNS_RRTYPE_NSEC3", 50 },
|
||||
{ "GETDNS_RRTYPE_NSEC3PARAM", 51 },
|
||||
{ "GETDNS_RRTYPE_NULL", 10 },
|
||||
{ "GETDNS_RRTYPE_NXT", 30 },
|
||||
{ "GETDNS_RRTYPE_OPENPGPKEY", 61 },
|
||||
|
@ -355,6 +383,13 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_RRTYPE_UNSPEC", 103 },
|
||||
{ "GETDNS_RRTYPE_URI", 256 },
|
||||
{ "GETDNS_RRTYPE_WKS", 11 },
|
||||
{ "GETDNS_RRTYPE_X25", 19 },
|
||||
{ "GETDNS_RRTYPE_ZONEMD", 63 },
|
||||
{ "GETDNS_SSL3", 1400 },
|
||||
{ "GETDNS_TLS1", 1401 },
|
||||
{ "GETDNS_TLS1_1", 1402 },
|
||||
{ "GETDNS_TLS1_2", 1403 },
|
||||
{ "GETDNS_TLS1_3", 1404 },
|
||||
{ "GETDNS_TRANSPORT_TCP", 1201 },
|
||||
{ "GETDNS_TRANSPORT_TCP_ONLY", 542 },
|
||||
{ "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", 543 },
|
||||
|
|
1052
src/context.c
1052
src/context.c
File diff suppressed because it is too large
Load Diff
|
@ -128,7 +128,7 @@ const getdns_tsig_info *_getdns_get_tsig_info(getdns_tsig_algo tsig_alg);
|
|||
|
||||
/* for doing public key pinning of TLS-capable upstreams: */
|
||||
typedef struct sha256_pin {
|
||||
char pin[SHA256_DIGEST_LENGTH];
|
||||
uint8_t pin[SHA256_DIGEST_LENGTH];
|
||||
struct sha256_pin *next;
|
||||
} sha256_pin_t;
|
||||
|
||||
|
@ -207,9 +207,15 @@ typedef struct getdns_upstream {
|
|||
getdns_tls_hs_state_t tls_hs_state;
|
||||
getdns_auth_state_t tls_auth_state;
|
||||
unsigned tls_fallback_ok : 1;
|
||||
|
||||
/* TLS settings */
|
||||
char *tls_cipher_list;
|
||||
char *tls_ciphersuites;
|
||||
char *tls_curves_list;
|
||||
/* Auth credentials*/
|
||||
getdns_tls_version_t tls_min_version;
|
||||
getdns_tls_version_t tls_max_version;
|
||||
|
||||
/* Auth credentials */
|
||||
char tls_auth_name[256];
|
||||
sha256_pin_t *tls_pubkey_pinset;
|
||||
|
||||
|
@ -264,7 +270,7 @@ typedef struct getdns_upstreams {
|
|||
size_t count;
|
||||
size_t current_udp;
|
||||
size_t current_stateful;
|
||||
uint16_t max_backoff_value;
|
||||
uint16_t max_backoff_value;
|
||||
uint16_t tls_backoff_time;
|
||||
uint16_t tls_connection_retries;
|
||||
getdns_log_config log;
|
||||
|
@ -342,6 +348,8 @@ struct getdns_context {
|
|||
char *trust_anchors_url;
|
||||
char *trust_anchors_verify_CA;
|
||||
char *trust_anchors_verify_email;
|
||||
uint64_t trust_anchors_backoff_time;
|
||||
uint64_t trust_anchors_backoff_expiry;
|
||||
|
||||
_getdns_ksks root_ksk;
|
||||
|
||||
|
@ -351,7 +359,10 @@ struct getdns_context {
|
|||
char *tls_ca_path;
|
||||
char *tls_ca_file;
|
||||
char *tls_cipher_list;
|
||||
char *tls_ciphersuites;
|
||||
char *tls_curves_list;
|
||||
getdns_tls_version_t tls_min_version;
|
||||
getdns_tls_version_t tls_max_version;
|
||||
|
||||
getdns_upstreams *upstreams;
|
||||
uint16_t limit_outstanding_queries;
|
||||
|
@ -359,7 +370,7 @@ struct getdns_context {
|
|||
getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/
|
||||
getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/
|
||||
uint8_t round_robin_upstreams;
|
||||
uint16_t max_backoff_value;
|
||||
uint16_t max_backoff_value;
|
||||
uint16_t tls_backoff_time;
|
||||
uint16_t tls_connection_retries;
|
||||
|
||||
|
@ -434,6 +445,7 @@ struct getdns_context {
|
|||
getdns_dict *header;
|
||||
getdns_dict *add_opt_parameters;
|
||||
unsigned add_warning_for_bad_dns : 1;
|
||||
unsigned dnssec : 1;
|
||||
unsigned dnssec_return_all_statuses : 1;
|
||||
unsigned dnssec_return_full_validation_chain : 1;
|
||||
unsigned dnssec_return_only_secure : 1;
|
||||
|
@ -491,11 +503,38 @@ struct getdns_context {
|
|||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
}; /* getdns_context */
|
||||
|
||||
void _getdns_upstream_log(getdns_upstream *upstream, uint64_t system,
|
||||
getdns_loglevel_type level, const char *fmt, ...);
|
||||
static inline int _getdns_check_log(const getdns_log_config *log,
|
||||
uint64_t system, getdns_loglevel_type level)
|
||||
{ assert(log)
|
||||
; return log->func && (log->system & system) && level <= log->level; }
|
||||
|
||||
void _getdns_context_log(getdns_context *context, uint64_t system,
|
||||
getdns_loglevel_type level, const char *fmt, ...);
|
||||
static inline void _getdns_log(const getdns_log_config *log,
|
||||
uint64_t system, getdns_loglevel_type level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!_getdns_check_log(log, system, level))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
log->func(log->userarg, system, level, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static inline void _getdns_upstream_log(const getdns_upstream *up,
|
||||
uint64_t system, getdns_loglevel_type level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!up || !up->upstreams
|
||||
|| !_getdns_check_log(&up->upstreams->log, system, level))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
up->upstreams->log.func(
|
||||
up->upstreams->log.userarg, system, level, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
/** internal functions **/
|
||||
|
@ -552,8 +591,9 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
|||
|
||||
void _getdns_upstream_shutdown(getdns_upstream *upstream);
|
||||
|
||||
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn);
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
FILE *_getdns_context_get_priv_fp(
|
||||
const getdns_context *context, const char *fn);
|
||||
uint8_t *_getdns_context_get_priv_file(const getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
|
||||
|
||||
int _getdns_context_write_priv_file(getdns_context *context,
|
||||
|
|
|
@ -434,7 +434,7 @@ getdns_dict_create_with_memory_functions(void *(*malloc)(size_t),
|
|||
|
||||
/*-------------------------- getdns_dict_create_with_context */
|
||||
struct getdns_dict *
|
||||
getdns_dict_create_with_context(struct getdns_context *context)
|
||||
getdns_dict_create_with_context(const getdns_context *context)
|
||||
{
|
||||
if (context)
|
||||
return getdns_dict_create_with_extended_memory_functions(
|
||||
|
@ -655,7 +655,8 @@ getdns_dict_set_bindata(
|
|||
|
||||
/*---------------------------------------- getdns_dict_set_bindata */
|
||||
getdns_return_t
|
||||
getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value)
|
||||
getdns_dict_util_set_string(getdns_dict *dict,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
getdns_item *item;
|
||||
getdns_bindata *newbindata;
|
||||
|
@ -1078,9 +1079,12 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
|
|||
strcmp(item->node.key, "transport") == 0 ||
|
||||
strcmp(item->node.key, "resolution_type") == 0 ||
|
||||
strcmp(item->node.key, "tls_authentication") == 0 ||
|
||||
strcmp(item->node.key, "tls_min_version") == 0 ||
|
||||
strcmp(item->node.key, "tls_max_version") == 0 ||
|
||||
|
||||
/* extensions */
|
||||
strcmp(item->node.key, "add_warning_for_bad_dns") == 0 ||
|
||||
strcmp(item->node.key, "dnssec") == 0 ||
|
||||
strcmp(item->node.key, "dnssec_return_all_statuses") == 0 ||
|
||||
strcmp(item->node.key, "dnssec_return_full_validation_chain") == 0 ||
|
||||
strcmp(item->node.key, "dnssec_return_only_secure") == 0 ||
|
||||
|
|
106
src/dnssec.c
106
src/dnssec.c
|
@ -523,7 +523,7 @@ static void val_chain_sched(chain_head *head, const uint8_t *dname);
|
|||
static void val_chain_sched_ds(chain_head *head, const uint8_t *dname);
|
||||
static void val_chain_sched_signer(chain_head *head, _getdns_rrsig_iter *rrsig);
|
||||
|
||||
static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
|
||||
static chain_head *add_rrset2val_chain(const struct mem_funcs *mf,
|
||||
chain_head **chain_p, _getdns_rrset *rrset, getdns_network_req *netreq)
|
||||
{
|
||||
chain_head *head;
|
||||
|
@ -788,7 +788,7 @@ static int is_synthesized_cname(_getdns_rrset *cname)
|
|||
* When a SOA query was successful, a query for DS will follow for that
|
||||
* owner name.
|
||||
*/
|
||||
static void add_pkt2val_chain(struct mem_funcs *mf,
|
||||
static void add_pkt2val_chain(const struct mem_funcs *mf,
|
||||
chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
|
||||
getdns_network_req *netreq)
|
||||
{
|
||||
|
@ -850,7 +850,7 @@ static void add_pkt2val_chain(struct mem_funcs *mf,
|
|||
* checked eventually.
|
||||
* But only if we know the question of course...
|
||||
*/
|
||||
static void add_question2val_chain(struct mem_funcs *mf,
|
||||
static void add_question2val_chain(const struct mem_funcs *mf,
|
||||
chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
|
||||
const uint8_t *qname, uint16_t qtype, uint16_t qclass,
|
||||
getdns_network_req *netreq)
|
||||
|
@ -1364,8 +1364,9 @@ static int _rr_iter_rdata_cmp(const void *a, const void *b)
|
|||
* nc_name will be set to the next closer (within rrset->name).
|
||||
*/
|
||||
#define VAL_RRSET_SPC_SZ 256
|
||||
static int _getdns_verify_rrsig(struct mem_funcs *mf,
|
||||
_getdns_rrset *rrset, _getdns_rrsig_iter *rrsig, _getdns_rrtype_iter *key, const uint8_t **nc_name)
|
||||
static int _getdns_verify_rrsig(const struct mem_funcs *mf,
|
||||
_getdns_rrset *rrset, _getdns_rrsig_iter *rrsig, _getdns_rrtype_iter *key,
|
||||
const uint8_t **nc_name)
|
||||
{
|
||||
int r;
|
||||
int to_skip;
|
||||
|
@ -1683,8 +1684,9 @@ static int check_dates(time_t now, int32_t skew, int32_t exp, int32_t inc)
|
|||
/* Returns whether dnskey signed rrset. If the rrset was a valid wildcard
|
||||
* expansion, nc_name will point to the next closer part of the name in rrset.
|
||||
*/
|
||||
static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
_getdns_rrtype_iter *dnskey, _getdns_rrset *rrset, const uint8_t **nc_name)
|
||||
static int dnskey_signed_rrset(const struct mem_funcs *mf, time_t now,
|
||||
uint32_t skew, _getdns_rrtype_iter *dnskey, _getdns_rrset *rrset,
|
||||
const uint8_t **nc_name)
|
||||
{
|
||||
_getdns_rrsig_iter rrsig_spc, *rrsig;
|
||||
_getdns_rdf_iter rdf_spc, *rdf;
|
||||
|
@ -1752,7 +1754,7 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
|
|||
}
|
||||
|
||||
/* Returns whether a dnskey for keyset signed a non wildcard rrset. */
|
||||
static int a_key_signed_rrset_no_wc(struct mem_funcs *mf, time_t now,
|
||||
static int a_key_signed_rrset_no_wc(const struct mem_funcs *mf, time_t now,
|
||||
uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset)
|
||||
{
|
||||
_getdns_rrtype_iter dnskey_spc, *dnskey;
|
||||
|
@ -1780,13 +1782,13 @@ static int a_key_signed_rrset_no_wc(struct mem_funcs *mf, time_t now,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int find_nsec_covering_name(
|
||||
struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey,
|
||||
static int find_nsec_covering_name(const struct mem_funcs *mf,
|
||||
time_t now, uint32_t skew, _getdns_rrset *dnskey,
|
||||
_getdns_rrset *rrset, const uint8_t *name, int *opt_out);
|
||||
|
||||
/* Returns whether a dnskey for keyset signed rrset. */
|
||||
static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
_getdns_rrset *keyset, _getdns_rrset *rrset)
|
||||
static int a_key_signed_rrset(const struct mem_funcs *mf, time_t now,
|
||||
uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset)
|
||||
{
|
||||
_getdns_rrtype_iter dnskey_spc, *dnskey;
|
||||
const uint8_t *nc_name; /* Initialized by dnskey_signed_rrset() */
|
||||
|
@ -1827,7 +1829,7 @@ static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
|
|||
/* Returns whether a DS in ds_set matches a dnskey in dnskey_set which in turn
|
||||
* signed the dnskey set.
|
||||
*/
|
||||
static int ds_authenticates_keys(struct mem_funcs *mf,
|
||||
static int ds_authenticates_keys(const struct mem_funcs *mf,
|
||||
time_t now, uint32_t skew, _getdns_rrset *ds_set, _getdns_rrset *dnskey_set)
|
||||
{
|
||||
_getdns_rrtype_iter dnskey_spc, *dnskey;
|
||||
|
@ -2112,8 +2114,8 @@ static int nsec3_covers_name(
|
|||
}
|
||||
}
|
||||
|
||||
static int find_nsec_covering_name(
|
||||
struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey,
|
||||
static int find_nsec_covering_name(const struct mem_funcs *mf, time_t now,
|
||||
uint32_t skew, _getdns_rrset *dnskey,
|
||||
_getdns_rrset *rrset, const uint8_t *name, int *opt_out)
|
||||
{
|
||||
_getdns_rrset_iter i_spc, *i;
|
||||
|
@ -2215,7 +2217,7 @@ static int find_nsec_covering_name(
|
|||
}
|
||||
|
||||
static int nsec3_find_next_closer(
|
||||
struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
const struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
_getdns_rrset *dnskey, _getdns_rrset *rrset,
|
||||
const uint8_t *nc_name, int *opt_out)
|
||||
{
|
||||
|
@ -2267,7 +2269,7 @@ static int nsec3_find_next_closer(
|
|||
* verifying key: it returns keytag + NSEC3_ITERATION_COUNT_HIGH (0x20000)
|
||||
*/
|
||||
static int key_proves_nonexistance(
|
||||
struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
const struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
_getdns_rrset *keyset, _getdns_rrset *rrset, int *opt_out)
|
||||
{
|
||||
_getdns_rrset nsec_rrset, *cover, *ce;
|
||||
|
@ -2571,7 +2573,7 @@ static int key_proves_nonexistance(
|
|||
* non-existence of a DS along the path is proofed, and SECURE otherwise.
|
||||
*/
|
||||
static int chain_node_get_trusted_keys(
|
||||
struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
const struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
chain_node *node, _getdns_rrset *ta, _getdns_rrset **keys)
|
||||
{
|
||||
int s, keytag;
|
||||
|
@ -2606,7 +2608,7 @@ static int chain_node_get_trusted_keys(
|
|||
*keys = ta;
|
||||
return GETDNS_DNSSEC_SECURE;
|
||||
}
|
||||
/* ta is parent's ZSK */
|
||||
/* ta is parent's ZSK proving insecurity below this node? */
|
||||
if ((keytag = key_proves_nonexistance(
|
||||
mf, now, skew, ta, &node->ds, &opt_out))) {
|
||||
node->ds_signer = keytag;
|
||||
|
@ -2621,12 +2623,18 @@ static int chain_node_get_trusted_keys(
|
|||
* key_proves_nonexistance() will set opt_out also for
|
||||
* these conditions.
|
||||
*/
|
||||
return opt_out ? GETDNS_DNSSEC_INSECURE
|
||||
: GETDNS_DNSSEC_SECURE;
|
||||
}
|
||||
if ((keytag = a_key_signed_rrset_no_wc(
|
||||
if (opt_out)
|
||||
return GETDNS_DNSSEC_INSECURE;
|
||||
|
||||
/* If this is not an insecurity proof,
|
||||
* continue searching one label up.
|
||||
*/
|
||||
|
||||
/* ta is parent's ZSK authenticating DS? */
|
||||
} else if ((keytag = a_key_signed_rrset_no_wc(
|
||||
mf, now, skew, ta, &node->ds))) {
|
||||
node->ds_signer = keytag;
|
||||
/* DS should authenticate the DNSKEY rrset now */
|
||||
if ((keytag = ds_authenticates_keys(
|
||||
mf, now, skew, &node->ds, &node->dnskey))) {
|
||||
*keys = &node->dnskey;
|
||||
|
@ -2635,6 +2643,7 @@ static int chain_node_get_trusted_keys(
|
|||
? GETDNS_DNSSEC_INSECURE
|
||||
: GETDNS_DNSSEC_SECURE;
|
||||
}
|
||||
/* DS without DNSKEY rrset == BOGUS */
|
||||
return GETDNS_DNSSEC_BOGUS;
|
||||
}
|
||||
} else
|
||||
|
@ -2707,7 +2716,7 @@ static int chain_node_get_trusted_keys(
|
|||
* For this first a secure keyset is looked up, with which the keyset is
|
||||
* evaluated.
|
||||
*/
|
||||
static int chain_head_validate_with_ta(struct mem_funcs *mf,
|
||||
static int chain_head_validate_with_ta(const struct mem_funcs *mf,
|
||||
time_t now, uint32_t skew, chain_head *head, _getdns_rrset *ta)
|
||||
{
|
||||
_getdns_rrset *keys;
|
||||
|
@ -2794,8 +2803,8 @@ static int chain_head_validate_with_ta(struct mem_funcs *mf,
|
|||
/* The DNSSEC status of the rrset in head is evaluated by trying the trust
|
||||
* anchors in tas in turn. The best outcome counts.
|
||||
*/
|
||||
static int chain_head_validate(struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||
chain_head *head, _getdns_rrset_iter *tas)
|
||||
static int chain_head_validate(const struct mem_funcs *mf, time_t now,
|
||||
uint32_t skew, chain_head *head, _getdns_rrset_iter *tas)
|
||||
{
|
||||
_getdns_rrset_iter *i;
|
||||
_getdns_rrset *ta, dnskey_ta, ds_ta;
|
||||
|
@ -2944,7 +2953,7 @@ static void chain_clear_netreq_dnssec_status(chain_head *chain)
|
|||
* processing each head in turn. The worst outcome is the dnssec status for
|
||||
* the whole.
|
||||
*/
|
||||
static int chain_validate_dnssec(struct mem_funcs *mf,
|
||||
static int chain_validate_dnssec(const struct mem_funcs *mf,
|
||||
time_t now, uint32_t skew, chain_head *chain, _getdns_rrset_iter *tas)
|
||||
{
|
||||
int s = GETDNS_DNSSEC_INDETERMINATE, t;
|
||||
|
@ -3280,7 +3289,6 @@ static void check_chain_complete(chain_head *chain)
|
|||
|
||||
} else if (_getdns_bogus(dnsreq)) {
|
||||
_getdns_rrsig_iter rrsig_spc;
|
||||
DEBUG_ANCHOR("Request was bogus!\n");
|
||||
|
||||
if ((head = chain) && (node = _to_the_root(head->parent))
|
||||
/* The root DNSKEY rrset */
|
||||
|
@ -3293,13 +3301,15 @@ static void check_chain_complete(chain_head *chain)
|
|||
&& _getdns_rrsig_iter_init(&rrsig_spc, &node->dnskey)
|
||||
){
|
||||
|
||||
DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
|
||||
_getdns_log( &context->log
|
||||
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_NOTICE
|
||||
, "root DNSKEY set was bogus!\n");
|
||||
if (!dnsreq->waiting_for_ta) {
|
||||
uint64_t now = 0;
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
dnsreq->waiting_for_ta = 1;
|
||||
_getdns_context_equip_with_anchor(
|
||||
context, &now);
|
||||
context, &now_ms);
|
||||
|
||||
if (context->trust_anchors_source
|
||||
== GETDNS_TASRC_XML) {
|
||||
|
@ -3307,9 +3317,19 @@ static void check_chain_complete(chain_head *chain)
|
|||
check_chain_complete(chain);
|
||||
return;
|
||||
}
|
||||
_getdns_start_fetching_ta(
|
||||
context, dnsreq->loop);
|
||||
|
||||
if (context->trust_anchors_source ==
|
||||
GETDNS_TASRC_FAILED
|
||||
&& 0 == _getdns_ms_until_expiry2(
|
||||
context->trust_anchors_backoff_expiry,
|
||||
&now_ms)) {
|
||||
context->trust_anchors_source =
|
||||
GETDNS_TASRC_NONE;
|
||||
}
|
||||
if (context->trust_anchors_source
|
||||
!= GETDNS_TASRC_FAILED) {
|
||||
_getdns_start_fetching_ta(
|
||||
context, dnsreq->loop, &now_ms);
|
||||
}
|
||||
if (dnsreq->waiting_for_ta &&
|
||||
context->trust_anchors_source
|
||||
== GETDNS_TASRC_FETCHING) {
|
||||
|
@ -3464,7 +3484,7 @@ void _getdns_ta_notify_dnsreqs(getdns_context *context)
|
|||
getdns_network_req *netreq, **netreq_p;
|
||||
int r = GETDNS_RETURN_GOOD;
|
||||
|
||||
(void) _getdns_context_prepare_for_resolution(context);
|
||||
(void) _getdns_context_prepare_for_resolution(context);
|
||||
|
||||
*dnsreq_p = dnsreq->ta_notify;
|
||||
for ( netreq_p = dnsreq->netreqs
|
||||
|
@ -3589,7 +3609,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
|||
*****************************************************************************/
|
||||
|
||||
|
||||
static int wire_validate_dnssec(struct mem_funcs *mf,
|
||||
static int wire_validate_dnssec(const struct mem_funcs *mf,
|
||||
time_t now, uint32_t skew, uint8_t *to_val, size_t to_val_len,
|
||||
uint8_t *support, size_t support_len, uint8_t *tas, size_t tas_len)
|
||||
{
|
||||
|
@ -3671,9 +3691,9 @@ static int wire_validate_dnssec(struct mem_funcs *mf,
|
|||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_validate_dnssec2(getdns_list *records_to_validate,
|
||||
getdns_list *support_records,
|
||||
getdns_list *trust_anchors,
|
||||
getdns_validate_dnssec2(const getdns_list *records_to_validate,
|
||||
const getdns_list *support_records,
|
||||
const getdns_list *trust_anchors,
|
||||
time_t now, uint32_t skew)
|
||||
{
|
||||
uint8_t to_val_buf[4096], *to_val,
|
||||
|
@ -3685,7 +3705,7 @@ getdns_validate_dnssec2(getdns_list *records_to_validate,
|
|||
tas_len = sizeof(tas_buf);
|
||||
|
||||
int r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
struct mem_funcs *mf;
|
||||
const struct mem_funcs *mf;
|
||||
|
||||
size_t i;
|
||||
getdns_dict *reply;
|
||||
|
@ -3766,9 +3786,9 @@ exit_free_support:
|
|||
|
||||
|
||||
getdns_return_t
|
||||
getdns_validate_dnssec(getdns_list *records_to_validate,
|
||||
getdns_list *support_records,
|
||||
getdns_list *trust_anchors)
|
||||
getdns_validate_dnssec(const getdns_list *records_to_validate,
|
||||
const getdns_list *support_records,
|
||||
const getdns_list *trust_anchors)
|
||||
{
|
||||
return getdns_validate_dnssec2(records_to_validate, support_records,
|
||||
trust_anchors, time(NULL), 0);
|
||||
|
|
|
@ -218,12 +218,14 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
&& !dns_req->avoid_dnssec_roadblocks
|
||||
&& (dns_req->dnssec_return_status ||
|
||||
dns_req->dnssec_return_only_secure ||
|
||||
dns_req->dnssec ||
|
||||
dns_req->dnssec_return_all_statuses
|
||||
))
|
||||
#endif
|
||||
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& (dns_req->dnssec_return_status ||
|
||||
dns_req->dnssec_return_only_secure ||
|
||||
dns_req->dnssec ||
|
||||
dns_req->dnssec_return_all_statuses)
|
||||
&& _getdns_bogus(dns_req))
|
||||
)) {
|
||||
|
@ -241,7 +243,6 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
#if defined(REQ_DEBUG) && REQ_DEBUG
|
||||
debug_req("getting validation chain for ", *dns_req->netreqs);
|
||||
#endif
|
||||
DEBUG_ANCHOR("Valchain lookup\n");
|
||||
_getdns_get_validation_chain(dns_req);
|
||||
} else
|
||||
_getdns_call_user_callback(
|
||||
|
@ -423,6 +424,7 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
|||
if ( context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
|| dns_req->dnssec_return_status
|
||||
|| dns_req->dnssec_return_only_secure
|
||||
|| dns_req->dnssec
|
||||
|| dns_req->dnssec_return_all_statuses
|
||||
|| dns_req->dnssec_return_validation_chain) {
|
||||
#endif
|
||||
|
@ -492,7 +494,7 @@ extformatcmp(const void *a, const void *b)
|
|||
|
||||
/*---------------------------------------- validate_extensions */
|
||||
static getdns_return_t
|
||||
validate_extensions(struct getdns_dict * extensions)
|
||||
validate_extensions(const getdns_dict * extensions)
|
||||
{
|
||||
/**
|
||||
* this is a comprehensive list of extensions and their data types
|
||||
|
@ -503,6 +505,7 @@ validate_extensions(struct getdns_dict * extensions)
|
|||
static getdns_extension_format extformats[] = {
|
||||
{"add_opt_parameters" , t_dict, 1},
|
||||
{"add_warning_for_bad_dns" , t_int , 1},
|
||||
{"dnssec" , t_int , 1},
|
||||
{"dnssec_return_all_statuses" , t_int , 1},
|
||||
{"dnssec_return_full_validation_chain", t_int , 1},
|
||||
{"dnssec_return_only_secure" , t_int , 1},
|
||||
|
@ -555,7 +558,7 @@ validate_extensions(struct getdns_dict * extensions)
|
|||
|
||||
static getdns_return_t
|
||||
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
void *userarg, getdns_network_req **return_netreq_p,
|
||||
getdns_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces)
|
||||
{
|
||||
|
@ -591,13 +594,18 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
_getdns_context_track_outbound_request(req);
|
||||
|
||||
if (req->dnssec_extension_set) {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_FAILED
|
||||
&& _getdns_ms_until_expiry2(
|
||||
context->trust_anchors_backoff_expiry, &now_ms) == 0) {
|
||||
context->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||
}
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_XML_UPDATE)
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
_getdns_start_fetching_ta(context, loop, &now_ms);
|
||||
|
||||
else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_context_equip_with_anchor(context, &now_ms);
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
_getdns_start_fetching_ta(context, loop, &now_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -706,7 +714,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
getdns_return_t
|
||||
_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
void *userarg, getdns_network_req **netreq_p,
|
||||
getdns_callback_t callback, internal_cb_t internal_cb)
|
||||
{
|
||||
|
@ -718,33 +726,33 @@ _getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
getdns_return_t
|
||||
_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
const char *name, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
getdns_dict *my_extensions = extensions;
|
||||
getdns_dict *my_extensions = NULL;
|
||||
getdns_return_t r;
|
||||
uint32_t value;
|
||||
getdns_network_req *netreq = NULL;
|
||||
|
||||
if (!my_extensions) {
|
||||
if (!extensions) {
|
||||
if (!(my_extensions=getdns_dict_create_with_context(context)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
} else if (
|
||||
getdns_dict_get_int(my_extensions, "return_both_v4_and_v6", &value)
|
||||
getdns_dict_get_int(extensions, "return_both_v4_and_v6", &value)
|
||||
&& (r = _getdns_dict_copy(extensions, &my_extensions)))
|
||||
return r;
|
||||
|
||||
if (my_extensions != extensions && (r = getdns_dict_set_int(
|
||||
if (my_extensions && (r = getdns_dict_set_int(
|
||||
my_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE)))
|
||||
return r;
|
||||
|
||||
r = getdns_general_ns(context, loop,
|
||||
name, GETDNS_RRTYPE_AAAA, my_extensions,
|
||||
name, GETDNS_RRTYPE_AAAA, my_extensions ? my_extensions : extensions,
|
||||
userarg, &netreq, callback, NULL, 1);
|
||||
if (netreq && transaction_id)
|
||||
*transaction_id = netreq->owner->trans_id;
|
||||
|
||||
if (my_extensions != extensions)
|
||||
if (my_extensions)
|
||||
getdns_dict_destroy(my_extensions);
|
||||
|
||||
return r;
|
||||
|
@ -752,7 +760,7 @@ _getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
getdns_return_t
|
||||
_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
getdns_dict *address, getdns_dict *extensions, void *userarg,
|
||||
const getdns_dict *address, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
struct getdns_bindata *address_data;
|
||||
|
@ -842,7 +850,7 @@ _getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
getdns_return_t
|
||||
_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
const char *name, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
getdns_return_t r;
|
||||
|
@ -859,7 +867,7 @@ _getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_general(getdns_context *context,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t * transaction_id,
|
||||
getdns_callback_t callbackfn)
|
||||
{
|
||||
|
@ -881,7 +889,7 @@ getdns_general(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_address(getdns_context *context,
|
||||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
const char *name, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
@ -896,7 +904,7 @@ getdns_address(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_hostname(getdns_context *context,
|
||||
getdns_dict *address, getdns_dict *extensions, void *userarg,
|
||||
const getdns_dict *address, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
@ -910,7 +918,7 @@ getdns_hostname(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_service(getdns_context *context,
|
||||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
const char *name, const getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
|
|
@ -63,25 +63,25 @@ int _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms);
|
|||
|
||||
getdns_return_t
|
||||
_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
void *userarg, getdns_network_req **netreq_p,
|
||||
getdns_callback_t callbackfn, internal_cb_t internal_cb);
|
||||
|
||||
getdns_return_t
|
||||
_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions,
|
||||
const char *name, const getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
getdns_callback_t callbackfn);
|
||||
|
||||
getdns_return_t
|
||||
_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
getdns_dict *address, getdns_dict *extensions,
|
||||
const getdns_dict *address, const getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
getdns_callback_t callbackfn);
|
||||
|
||||
getdns_return_t
|
||||
_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions,
|
||||
const char *name, const getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
getdns_callback_t callbackfn);
|
||||
|
||||
|
|
|
@ -416,6 +416,7 @@ typedef enum getdns_callback_type_t {
|
|||
#define GETDNS_RRTYPE_CDNSKEY 60
|
||||
#define GETDNS_RRTYPE_OPENPGPKEY 61
|
||||
#define GETDNS_RRTYPE_CSYNC 62
|
||||
#define GETDNS_RRTYPE_ZONEMD 63
|
||||
#define GETDNS_RRTYPE_SPF 99
|
||||
#define GETDNS_RRTYPE_UINFO 100
|
||||
#define GETDNS_RRTYPE_UID 101
|
||||
|
@ -743,7 +744,7 @@ getdns_list *getdns_list_create();
|
|||
* used to create and initialize the list.
|
||||
* @return pointer to an allocated list, NULL if insufficient memory
|
||||
*/
|
||||
getdns_list *getdns_list_create_with_context(getdns_context *context);
|
||||
getdns_list *getdns_list_create_with_context(const getdns_context *context);
|
||||
|
||||
/**
|
||||
* create a new list with no items, creating and initializing it with the
|
||||
|
@ -863,7 +864,7 @@ getdns_dict *getdns_dict_create();
|
|||
* used to create and initialize the dict.
|
||||
* @return pointer to an allocated dict, NULL if insufficient memory
|
||||
*/
|
||||
getdns_dict *getdns_dict_create_with_context(getdns_context *context);
|
||||
getdns_dict *getdns_dict_create_with_context(const getdns_context *context);
|
||||
|
||||
/**
|
||||
* create a new dict with no items, creating and initializing it with the
|
||||
|
@ -1030,9 +1031,9 @@ getdns_return_t
|
|||
getdns_general(getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn);
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn);
|
||||
|
||||
/**
|
||||
* retrieve address assigned to a DNS name
|
||||
|
@ -1048,9 +1049,9 @@ getdns_general(getdns_context *context,
|
|||
getdns_return_t
|
||||
getdns_address(getdns_context *context,
|
||||
const char *name,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn);
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn);
|
||||
|
||||
/**
|
||||
* retrieve hostname assigned to an IP address
|
||||
|
@ -1065,10 +1066,10 @@ getdns_address(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_hostname(getdns_context *context,
|
||||
getdns_dict *address,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *address,
|
||||
const getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn);
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn);
|
||||
|
||||
/**
|
||||
* retrieve a service assigned to a DNS name
|
||||
|
@ -1084,9 +1085,9 @@ getdns_hostname(getdns_context *context,
|
|||
getdns_return_t
|
||||
getdns_service(getdns_context *context,
|
||||
const char *name,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn);
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn);
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
@ -1201,7 +1202,7 @@ getdns_return_t
|
|||
getdns_general_sync(getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
getdns_dict **response);
|
||||
|
||||
/**
|
||||
|
@ -1216,7 +1217,7 @@ getdns_general_sync(getdns_context *context,
|
|||
getdns_return_t
|
||||
getdns_address_sync(getdns_context *context,
|
||||
const char *name,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
getdns_dict **response);
|
||||
|
||||
/**
|
||||
|
@ -1230,8 +1231,8 @@ getdns_address_sync(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_hostname_sync(getdns_context *context,
|
||||
getdns_dict *address,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *address,
|
||||
const getdns_dict *extensions,
|
||||
getdns_dict **response);
|
||||
|
||||
/**
|
||||
|
@ -1246,7 +1247,7 @@ getdns_hostname_sync(getdns_context *context,
|
|||
getdns_return_t
|
||||
getdns_service_sync(getdns_context *context,
|
||||
const char *name,
|
||||
getdns_dict *extensions,
|
||||
const getdns_dict *extensions,
|
||||
getdns_dict **response);
|
||||
|
||||
/** @}
|
||||
|
@ -1341,9 +1342,8 @@ char *getdns_convert_alabel_to_ulabel(const char *alabel);
|
|||
* depending on the validation status.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_validate_dnssec(getdns_list *to_validate,
|
||||
getdns_list *support_records,
|
||||
getdns_list *trust_anchors);
|
||||
getdns_validate_dnssec(const getdns_list *to_validate,
|
||||
const getdns_list *support_records, const getdns_list *trust_anchors);
|
||||
|
||||
/**
|
||||
* Get the default list of trust anchor records that is used by the library
|
||||
|
@ -1444,7 +1444,7 @@ getdns_context_set_resolution_type(getdns_context *context,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_namespaces(getdns_context *context,
|
||||
size_t namespace_count, getdns_namespace_t *namespaces);
|
||||
size_t namespace_count, const getdns_namespace_t *namespaces);
|
||||
|
||||
/**
|
||||
* Specifies what transport are used for DNS lookups. The default is
|
||||
|
@ -1812,9 +1812,11 @@ getdns_context_set_extended_memory_functions(getdns_context *context,
|
|||
* GETDNS_RESOLUTION_STUB.
|
||||
* - all_context (a dict) with names for all the other settings in
|
||||
* context.
|
||||
* The application is responsible for cleaning up the returned dictionary
|
||||
* object with getdns_dict_destroy.
|
||||
*/
|
||||
getdns_dict*
|
||||
getdns_context_get_api_information(getdns_context* context);
|
||||
getdns_context_get_api_information(const getdns_context *context);
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
|
|
@ -102,6 +102,15 @@ extern "C" {
|
|||
#define GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST_TEXT "Change related to getdns_context_set_tls_cipher_list"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CURVES_LIST 634
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CURVES_LIST_TEXT "Change related to getdns_context_set_tls_curves_list"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CIPHERSUITES 635
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CIPHERSUITES_TEXT "Change related to getdns_context_set_tls_ciphersuites"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_MIN_VERSION 636
|
||||
#define GETDNS_CONTEXT_CODE_TLS_MIN_VERSION_TEXT "Change related to getdns_context_set_tls_min_version"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_MAX_VERSION 637
|
||||
#define GETDNS_CONTEXT_CODE_TLS_MAX_VERSION_TEXT "Change related to getdns_context_set_tls_max_version"
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_BACKOFF_TIME 638
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_trust_anchors_backoff_time"
|
||||
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
@ -352,7 +361,7 @@ struct getdns_eventloop_vmt {
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or eventloop were NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_eventloop(getdns_context* context,
|
||||
getdns_context_set_eventloop(getdns_context *context,
|
||||
getdns_eventloop *eventloop);
|
||||
|
||||
/**
|
||||
|
@ -368,7 +377,7 @@ getdns_context_set_eventloop(getdns_context* context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or evenloop were NULL
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_eventloop(getdns_context* context,
|
||||
getdns_context_get_eventloop(const getdns_context *context,
|
||||
getdns_eventloop **eventloop);
|
||||
|
||||
/**
|
||||
|
@ -548,8 +557,18 @@ typedef enum getdns_loglevel_type {
|
|||
#define GETDNS_LOG_INFO_TEXT "Informational message"
|
||||
#define GETDNS_LOG_DEBUG_TEXT "Debug-level message"
|
||||
|
||||
#define GETDNS_LOG_UPSTREAM_STATS 4096
|
||||
#define GETDNS_LOG_UPSTREAM_STATS 0x3000
|
||||
#define GETDNS_LOG_UPSTREAM_STATS_TEXT "Log messages about upstream statistics"
|
||||
#define GETDNS_LOG_SYS_STUB 0x2000
|
||||
#define GETDNS_LOG_SYS_STUB_TEXT "Log messages about stub resolving"
|
||||
#define GETDNS_LOG_SYS_RECURSING 0x4000
|
||||
#define GETDNS_LOG_SYS_RECURSING_TEXT "Log messages about recursive resolving"
|
||||
#define GETDNS_LOG_SYS_RESOLVING 0x6000
|
||||
#define GETDNS_LOG_SYS_RESOLVING_TEXT "Log messages about resolving"
|
||||
#define GETDNS_LOG_SYS_ANCHOR 0x8000
|
||||
#define GETDNS_LOG_SYS_ANCHOR_TEXT "Log messages about fetching trust anchors"
|
||||
|
||||
|
||||
|
||||
typedef void (*getdns_logfunc_type) (void *userarg, uint64_t log_systems,
|
||||
getdns_loglevel_type, const char *, va_list ap);
|
||||
|
@ -694,6 +713,22 @@ getdns_return_t
|
|||
getdns_context_set_trust_anchors_verify_email(
|
||||
getdns_context *context, const char *verify_email);
|
||||
|
||||
/**
|
||||
* Configure the amount of milliseconds the trust anchors should not be tried
|
||||
* to be fetched after failure. Default is 2500 which is two and a half seconds.
|
||||
* Setting the trust anchors backoff time will cause fetching to be retried
|
||||
* immediatly.
|
||||
* @see getdns_context_get_trust_anchors_backoff_time
|
||||
* @param context The context to configure
|
||||
* @param value Number of milliseconds before fetch trust anchors
|
||||
* will be retried.
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchors_backoff_time(
|
||||
getdns_context *context, uint64_t value);
|
||||
|
||||
/**
|
||||
* Initialized the context's upstream recursive servers and suffixes
|
||||
* with the values from the given resolv.conf file.
|
||||
|
@ -755,6 +790,18 @@ getdns_return_t
|
|||
getdns_context_set_tls_cipher_list(
|
||||
getdns_context *context, const char *cipher_list);
|
||||
|
||||
/**
|
||||
* Configure the available TLS1.3 ciphersuites for authenticated TLS upstreams.
|
||||
* @see getdns_context_get_tls_ciphersuites
|
||||
* @param[in] context The context to configure
|
||||
* @param[in] ciphersuites The cipher list
|
||||
* @return GETDNS_RETURN_GOOD when successful
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_ciphersuites(
|
||||
getdns_context *context, const char *ciphersuites);
|
||||
|
||||
/**
|
||||
* Sets the supported curves TLS upstreams.
|
||||
* @see getdns_context_get_tls_curves_list
|
||||
|
@ -768,6 +815,80 @@ getdns_return_t
|
|||
getdns_context_set_tls_curves_list(
|
||||
getdns_context *context, const char *curves_list);
|
||||
|
||||
typedef enum getdns_tls_version_t {
|
||||
GETDNS_SSL3 = 1400,
|
||||
GETDNS_TLS1 = 1401,
|
||||
GETDNS_TLS1_1 = 1402,
|
||||
GETDNS_TLS1_2 = 1403,
|
||||
GETDNS_TLS1_3 = 1404
|
||||
} getdns_tls_version_t;
|
||||
|
||||
#define GETDNS_SSL3_TEXT "See getdns_context_(set|get)_tls_(min|max)_version()"
|
||||
#define GETDNS_TLS1_TEXT "See getdns_context_(set|get)_tls_(min|max)_version()"
|
||||
#define GETDNS_TLS1_1_TEXT "See getdns_context_(set|get)_tls_(min|max)_version()"
|
||||
#define GETDNS_TLS1_2_TEXT "See getdns_context_(set|get)_tls_(min|max)_version()"
|
||||
#define GETDNS_TLS1_3_TEXT "See getdns_context_(set|get)_tls_(min|max)_version()"
|
||||
|
||||
/**
|
||||
* Configure context for minimum supported TLS version.
|
||||
* @see getdns_context_set_tls_max_version
|
||||
* @see getdns_context_get_tls_min_version
|
||||
* @param context The context to configure
|
||||
* @param min_version is one of GETDNS_SSL3, GETDNS_TLS1, GETDNS_TLS1_1,
|
||||
* GETDNS_TLS1_2, GETDNS_TLS1_3
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null or value has an
|
||||
* invalid value.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_min_version(
|
||||
getdns_context *context, getdns_tls_version_t min_version);
|
||||
|
||||
/**
|
||||
* Get configured minimum supported TLS version.
|
||||
* @see getdns_context_get_tls_max_version
|
||||
* @see getdns_context_set_tls_min_version
|
||||
* @param context The context to configure
|
||||
* @param min_version is one of GETDNS_SSL3, GETDNS_TLS1, GETDNS_TLS1_1,
|
||||
* GETDNS_TLS1_2, GETDNS_TLS1_3
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null or value has an
|
||||
* invalid value.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_min_version(
|
||||
const getdns_context *context, getdns_tls_version_t *min_version);
|
||||
|
||||
/**
|
||||
* Configure context for maximum supported TLS version.
|
||||
* @see getdns_context_set_tls_min_version
|
||||
* @see getdns_context_get_tls_max_version
|
||||
* @param context The context to configure
|
||||
* @param max_version is one of GETDNS_SSL3, GETDNS_TLS1, GETDNS_TLS1_1,
|
||||
* GETDNS_TLS1_2, GETDNS_TLS1_3
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null or value has an
|
||||
* invalid value.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_max_version(
|
||||
getdns_context *context, getdns_tls_version_t max_version);
|
||||
|
||||
/**
|
||||
* Get configured maximum supported TLS version.
|
||||
* @see getdns_context_get_tls_min_version
|
||||
* @see getdns_context_set_tls_max_version
|
||||
* @param context The context to configure
|
||||
* @param max_version is one of GETDNS_SSL3, GETDNS_TLS1, GETDNS_TLS1_1,
|
||||
* GETDNS_TLS1_2, GETDNS_TLS1_3
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null or value has an
|
||||
* invalid value.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_max_version(
|
||||
const getdns_context *context, getdns_tls_version_t *max_version);
|
||||
|
||||
/**
|
||||
* Get the current resolution type setting from this context.
|
||||
* @see getdns_context_set_resolution_type
|
||||
|
@ -779,8 +900,8 @@ getdns_context_set_tls_curves_list(
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_resolution_type(getdns_context *context,
|
||||
getdns_resolution_t* value);
|
||||
getdns_context_get_resolution_type(const getdns_context *context,
|
||||
getdns_resolution_t *value);
|
||||
|
||||
/**
|
||||
* Get a copy of the namespaces list setting from this context.
|
||||
|
@ -794,8 +915,8 @@ getdns_context_get_resolution_type(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_namespaces(getdns_context *context,
|
||||
size_t* namespace_count, getdns_namespace_t **namespaces);
|
||||
getdns_context_get_namespaces(const getdns_context *context,
|
||||
size_t *namespace_count, getdns_namespace_t **namespaces);
|
||||
|
||||
/**
|
||||
* Get what transports are used for DNS lookups.
|
||||
|
@ -808,8 +929,8 @@ getdns_context_get_namespaces(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_dns_transport(getdns_context *context,
|
||||
getdns_transport_t* value);
|
||||
getdns_context_get_dns_transport(const getdns_context *context,
|
||||
getdns_transport_t *value);
|
||||
|
||||
/**
|
||||
* Get a copy of the transports list setting from this context.
|
||||
|
@ -824,8 +945,8 @@ getdns_context_get_dns_transport(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_dns_transport_list(getdns_context *context,
|
||||
size_t* transport_count, getdns_transport_list_t **transports);
|
||||
getdns_context_get_dns_transport_list(const getdns_context *context,
|
||||
size_t *transport_count, getdns_transport_list_t **transports);
|
||||
|
||||
/**
|
||||
* Get the current limit for outstanding queries setting from this context.
|
||||
|
@ -836,8 +957,8 @@ getdns_context_get_dns_transport_list(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or limit was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
||||
uint16_t* limit);
|
||||
getdns_context_get_limit_outstanding_queries(const getdns_context *context,
|
||||
uint16_t *limit);
|
||||
|
||||
/**
|
||||
* Get the current number of milliseconds the API will wait for request
|
||||
|
@ -850,7 +971,7 @@ getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or limit was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_timeout(getdns_context *context, uint64_t* timeout);
|
||||
getdns_context_get_timeout(const getdns_context *context, uint64_t *timeout);
|
||||
|
||||
/**
|
||||
* Get the current number of milliseconds the API will leave an idle TCP or TLS
|
||||
|
@ -864,7 +985,8 @@ getdns_context_get_timeout(getdns_context *context, uint64_t* timeout);
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or timeout was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_idle_timeout(getdns_context *context, uint64_t* timeout);
|
||||
getdns_context_get_idle_timeout(
|
||||
const getdns_context *context, uint64_t *timeout);
|
||||
|
||||
/**
|
||||
* Get the setting that says whether or not DNS queries follow redirects.
|
||||
|
@ -876,8 +998,8 @@ getdns_context_get_idle_timeout(getdns_context *context, uint64_t* timeout);
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_follow_redirects(getdns_context *context,
|
||||
getdns_redirects_t* value);
|
||||
getdns_context_get_follow_redirects(const getdns_context *context,
|
||||
getdns_redirects_t *value);
|
||||
|
||||
/**
|
||||
* Get a copy of the list of addresses in use for looking up top-level domains
|
||||
|
@ -894,7 +1016,7 @@ getdns_context_get_follow_redirects(getdns_context *context,
|
|||
* @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_dns_root_servers(getdns_context *context,
|
||||
getdns_context_get_dns_root_servers(const getdns_context *context,
|
||||
getdns_list **addresses);
|
||||
|
||||
/**
|
||||
|
@ -912,8 +1034,8 @@ getdns_context_get_dns_root_servers(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_append_name(getdns_context *context,
|
||||
getdns_append_name_t* value);
|
||||
getdns_context_get_append_name(const getdns_context *context,
|
||||
getdns_append_name_t *value);
|
||||
|
||||
/**
|
||||
* Get a copy of the list of suffixes to be appended based on the value off the
|
||||
|
@ -929,7 +1051,7 @@ getdns_context_get_append_name(getdns_context *context,
|
|||
* @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_suffix(getdns_context *context, getdns_list **value);
|
||||
getdns_context_get_suffix(const getdns_context *context, getdns_list **value);
|
||||
|
||||
/**
|
||||
* Get a copy of the list of DNSSEC trust anchors in use by context.
|
||||
|
@ -944,7 +1066,7 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value);
|
|||
* @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_dnssec_trust_anchors(getdns_context *context,
|
||||
getdns_context_get_dnssec_trust_anchors(const getdns_context *context,
|
||||
getdns_list **value);
|
||||
|
||||
/**
|
||||
|
@ -958,8 +1080,8 @@ getdns_context_get_dnssec_trust_anchors(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_dnssec_allowed_skew(getdns_context *context,
|
||||
uint32_t* value);
|
||||
getdns_context_get_dnssec_allowed_skew(const getdns_context *context,
|
||||
uint32_t *value);
|
||||
|
||||
/**
|
||||
* Get a copy of the list of upstream that will be targeted in stub resolution
|
||||
|
@ -975,7 +1097,7 @@ getdns_context_get_dnssec_allowed_skew(getdns_context *context,
|
|||
* @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_upstream_recursive_servers(getdns_context *context,
|
||||
getdns_context_get_upstream_recursive_servers(const getdns_context *context,
|
||||
getdns_list **upstream_list);
|
||||
|
||||
/**
|
||||
|
@ -990,8 +1112,8 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context,
|
||||
uint16_t* value);
|
||||
getdns_context_get_edns_maximum_udp_payload_size(const getdns_context *context,
|
||||
uint16_t *value);
|
||||
|
||||
/**
|
||||
* Get the rcode advertised in an EDNS0 OPT record setting from context
|
||||
|
@ -1002,8 +1124,8 @@ getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_extended_rcode(getdns_context *context,
|
||||
uint8_t* value);
|
||||
getdns_context_get_edns_extended_rcode(const getdns_context *context,
|
||||
uint8_t *value);
|
||||
|
||||
/**
|
||||
* Get the version advertised in an EDNS0 OPT record setting from context
|
||||
|
@ -1014,7 +1136,7 @@ getdns_context_get_edns_extended_rcode(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_version(getdns_context *context, uint8_t* value);
|
||||
getdns_context_get_edns_version(const getdns_context *context, uint8_t *value);
|
||||
|
||||
/**
|
||||
* Get the DO bit advertised in an EDNS0 OPT record setting from context
|
||||
|
@ -1026,7 +1148,7 @@ getdns_context_get_edns_version(getdns_context *context, uint8_t* value);
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value);
|
||||
getdns_context_get_edns_do_bit(const getdns_context *context, uint8_t *value);
|
||||
|
||||
/**
|
||||
* Get whether queries with this context will have the EDNS Client Subnet
|
||||
|
@ -1039,7 +1161,8 @@ getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value);
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* value);
|
||||
getdns_context_get_edns_client_subnet_private(const getdns_context *context,
|
||||
uint8_t *value);
|
||||
|
||||
/**
|
||||
* Get the blocksize that will be used to pad outgoing queries over TLS.
|
||||
|
@ -1051,7 +1174,8 @@ getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t*
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_query_padding_blocksize(getdns_context *context, uint16_t* value);
|
||||
getdns_context_get_tls_query_padding_blocksize(
|
||||
const getdns_context *context, uint16_t *value);
|
||||
|
||||
/**
|
||||
* Get whether the upstream needs to be authenticated with DNS over TLS.
|
||||
|
@ -1069,8 +1193,8 @@ getdns_context_get_tls_query_padding_blocksize(getdns_context *context, uint16_t
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_authentication(getdns_context *context,
|
||||
getdns_tls_authentication_t* value);
|
||||
getdns_context_get_tls_authentication(const getdns_context *context,
|
||||
getdns_tls_authentication_t *value);
|
||||
|
||||
/**
|
||||
* Get whether the context is configured to round robin queries over the available
|
||||
|
@ -1082,8 +1206,8 @@ getdns_context_get_tls_authentication(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_round_robin_upstreams(getdns_context *context,
|
||||
uint8_t* value);
|
||||
getdns_context_get_round_robin_upstreams(const getdns_context *context,
|
||||
uint8_t *value);
|
||||
|
||||
/**
|
||||
* Get the amount of seconds a TLS connection should not be tried with
|
||||
|
@ -1097,8 +1221,8 @@ getdns_context_get_round_robin_upstreams(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_backoff_time(getdns_context *context,
|
||||
uint16_t* value);
|
||||
getdns_context_get_tls_backoff_time(const getdns_context *context,
|
||||
uint16_t *value);
|
||||
|
||||
/**
|
||||
* Get the number of times getdns retries to setup DNS over TLS with a
|
||||
|
@ -1112,8 +1236,8 @@ getdns_context_get_tls_backoff_time(getdns_context *context,
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_connection_retries(getdns_context *context,
|
||||
uint16_t* value);
|
||||
getdns_context_get_tls_connection_retries(const getdns_context *context,
|
||||
uint16_t *value);
|
||||
|
||||
/**
|
||||
* Get the currently registered callback function and user defined argument
|
||||
|
@ -1130,7 +1254,8 @@ getdns_context_get_tls_connection_retries(getdns_context *context,
|
|||
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
||||
getdns_context_get_update_callback(const getdns_context *context,
|
||||
void **userarg,
|
||||
void (**value) (getdns_context *, getdns_context_code_t, void *));
|
||||
|
||||
|
||||
|
@ -1184,7 +1309,7 @@ getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchors_url(
|
||||
getdns_context *context, const char **url);
|
||||
const getdns_context *context, const char **url);
|
||||
|
||||
/**
|
||||
* Gets the public certificate for the Certificate Authority with which to
|
||||
|
@ -1203,7 +1328,7 @@ getdns_context_get_trust_anchors_url(
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchors_verify_CA(
|
||||
getdns_context *context, const char **verify_CA);
|
||||
const getdns_context *context, const char **verify_CA);
|
||||
|
||||
/**
|
||||
* Gets the email address for the Subject of the signer's certificate from the
|
||||
|
@ -1220,7 +1345,21 @@ getdns_context_get_trust_anchors_verify_CA(
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchors_verify_email(
|
||||
getdns_context *context, const char **verify_email);
|
||||
const getdns_context *context, const char **verify_email);
|
||||
|
||||
/**
|
||||
* Get the amount of milliseconds the trust anchors will not be tried to be
|
||||
* fetched after failure.
|
||||
* @see getdns_context_set_trust_anchors_backoff_time
|
||||
* @param context The context to configure
|
||||
* @param value Number of milliseconds before fetch trust anchors
|
||||
* will be retried.
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchors_backoff_time(
|
||||
const getdns_context *context, uint64_t *value);
|
||||
|
||||
/**
|
||||
* Get the value with which the context's upstream recursive servers
|
||||
|
@ -1233,7 +1372,8 @@ getdns_context_get_trust_anchors_verify_email(
|
|||
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf);
|
||||
getdns_context_get_resolvconf(
|
||||
const getdns_context *context, const char **resolvconf);
|
||||
|
||||
/**
|
||||
* Get the value with which the context's GETDNS_NAMESPACE_LOCALNAMES namespace
|
||||
|
@ -1246,7 +1386,8 @@ getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf);
|
|||
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_hosts(getdns_context *context, const char **hosts);
|
||||
getdns_context_get_hosts(
|
||||
const getdns_context *context, const char **hosts);
|
||||
|
||||
/**
|
||||
* Get the location of the directory for CA certificates for verification
|
||||
|
@ -1260,7 +1401,8 @@ getdns_context_get_hosts(getdns_context *context, const char **hosts);
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path);
|
||||
getdns_context_get_tls_ca_path(
|
||||
const getdns_context *context, const char **tls_ca_path);
|
||||
|
||||
/**
|
||||
* Get the file location with CA certificates for verification purposes.
|
||||
|
@ -1273,7 +1415,8 @@ getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path
|
|||
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file);
|
||||
getdns_context_get_tls_ca_file(
|
||||
const getdns_context *context, const char **tls_ca_file);
|
||||
|
||||
/**
|
||||
* Get the list of available ciphers for authenticated TLS upstreams.
|
||||
|
@ -1285,7 +1428,20 @@ getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_cipher_list(
|
||||
getdns_context *context, const char **cipher_list);
|
||||
const getdns_context *context, const char **cipher_list);
|
||||
|
||||
/**
|
||||
* Get the configured available TLS1.3 ciphersuited for authenticated TLS
|
||||
* upstreams.
|
||||
* @see getdns_context_set_tls_ciphersuites
|
||||
* @param[in] context The context configure
|
||||
* @param[out] ciphersuites The cipher list
|
||||
* @return GETDNS_RETURN_GOOD when successful
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_ciphersuites(
|
||||
const getdns_context *context, const char **ciphersuites);
|
||||
|
||||
/**
|
||||
* Get the supported curves list if one has been set earlier.
|
||||
|
@ -1300,7 +1456,7 @@ getdns_context_get_tls_cipher_list(
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_curves_list(
|
||||
getdns_context *context, const char **curves_list);
|
||||
const getdns_context *context, const char **curves_list);
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
@ -1388,7 +1544,8 @@ const char *getdns_get_errorstr_by_id(uint16_t err);
|
|||
* @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value);
|
||||
getdns_dict_util_set_string(
|
||||
getdns_dict *dict, const char *name, const char *value);
|
||||
|
||||
/**
|
||||
* Get the string associated with the speicifed name. The string should not
|
||||
|
@ -1401,7 +1558,8 @@ getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value);
|
|||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result);
|
||||
getdns_dict_util_get_string(
|
||||
const getdns_dict * dict, const char *name, char **result);
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
@ -1442,9 +1600,9 @@ getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result);
|
|||
* return code.
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_validate_dnssec2(getdns_list *to_validate,
|
||||
getdns_list *support_records,
|
||||
getdns_list *trust_anchors,
|
||||
getdns_validate_dnssec2(const getdns_list *to_validate,
|
||||
const getdns_list *support_records,
|
||||
const getdns_list *trust_anchors,
|
||||
time_t validation_time, uint32_t skew);
|
||||
|
||||
|
||||
|
@ -1487,9 +1645,9 @@ getdns_validate_dnssec2(getdns_list *to_validate,
|
|||
* @param str the pinning string to parse
|
||||
* @return a dict created from ctx, or NULL if the string did not match.
|
||||
*/
|
||||
getdns_dict* getdns_pubkey_pin_create_from_string(
|
||||
getdns_context* context,
|
||||
const char* str);
|
||||
getdns_dict *getdns_pubkey_pin_create_from_string(
|
||||
const getdns_context *context,
|
||||
const char *str);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1506,8 +1664,8 @@ getdns_dict* getdns_pubkey_pin_create_from_string(
|
|||
* @return GETDNS_RETURN_GOOD if the pinset passes the sanity check.
|
||||
*/
|
||||
getdns_return_t getdns_pubkey_pinset_sanity_check(
|
||||
const getdns_list* pinset,
|
||||
getdns_list* errorlist);
|
||||
const getdns_list *pinset,
|
||||
getdns_list *errorlist);
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
@ -2155,7 +2313,7 @@ getdns_context_set_listen_addresses(
|
|||
*/
|
||||
getdns_return_t
|
||||
getdns_reply(getdns_context *context,
|
||||
getdns_dict *reply, getdns_transaction_t request_id);
|
||||
const getdns_dict *reply, getdns_transaction_t request_id);
|
||||
|
||||
|
||||
/** @}
|
||||
|
@ -2179,7 +2337,7 @@ getdns_return_t getdns_strerror(getdns_return_t err, char *buf, size_t buflen);
|
|||
* WARNING! Do not use this function. This function will be removed in
|
||||
* future versions of getdns.
|
||||
*/
|
||||
getdns_return_t getdns_context_process_async(getdns_context* context);
|
||||
getdns_return_t getdns_context_process_async(getdns_context *context);
|
||||
|
||||
/**
|
||||
* Return the number of pending requests and the point of time of the next
|
||||
|
@ -2187,8 +2345,8 @@ getdns_return_t getdns_context_process_async(getdns_context* context);
|
|||
* WARNING! Do not use this function. This function will be removed in
|
||||
* future versions of getdns.
|
||||
*/
|
||||
uint32_t getdns_context_get_num_pending_requests(getdns_context* context,
|
||||
struct timeval* next_timeout);
|
||||
uint32_t getdns_context_get_num_pending_requests(const getdns_context *context,
|
||||
struct timeval *next_timeout);
|
||||
|
||||
/**
|
||||
* Detach the eventloop from the context. Resets the context with the default
|
||||
|
@ -2213,7 +2371,7 @@ getdns_context_detach_eventloop(getdns_context *context);
|
|||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if context is NULL
|
||||
*/
|
||||
getdns_return_t getdns_context_set_use_threads(getdns_context* context,
|
||||
getdns_return_t getdns_context_set_use_threads(getdns_context *context,
|
||||
int use_threads);
|
||||
|
||||
/** @}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Meant to be run from this directory
|
||||
rm -fr gldns
|
||||
mkdir gldns
|
||||
svn co http://unbound.net/svn/trunk/sldns/
|
||||
svn co https://nlnetlabs.nl/svn/unbound/trunk/sldns/
|
||||
mv gbuffer.h sbuffer.h
|
||||
mv gbuffer.c sbuffer.c
|
||||
for f in sldns/*.[ch]
|
||||
|
|
|
@ -130,7 +130,7 @@ struct gldns_buffer
|
|||
/** If the buffer is fixed it cannot be resized */
|
||||
unsigned _fixed : 1;
|
||||
|
||||
/** If the buffer is vfixed, no more than capacity bytes willl be
|
||||
/** If the buffer is vfixed, no more than capacity bytes will be
|
||||
* written to _data, however the _position counter will be updated
|
||||
* with the amount that would have been written in consecutive
|
||||
* writes. This allows for a modus operandi in which a sequence is
|
||||
|
@ -160,7 +160,7 @@ gldns_buffer_invariant(gldns_buffer *buffer)
|
|||
assert(buffer != NULL);
|
||||
assert(buffer->_position <= buffer->_limit || buffer->_vfixed);
|
||||
assert(buffer->_limit <= buffer->_capacity);
|
||||
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0));
|
||||
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0 && buffer->_limit == 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ then
|
|||
mv sbuffer.h gbuffer.h
|
||||
mv sbuffer.c gbuffer.c
|
||||
else
|
||||
svn co http://unbound.net/svn/trunk/sldns/
|
||||
for f in sldns/*.[ch]
|
||||
svn co https://nlnetlabs.nl/svn/unbound/trunk/sldns/
|
||||
for f in ldns/*.[ch]
|
||||
do
|
||||
sed -e 's/sldns_/gldns_/g' \
|
||||
-e 's/LDNS_/GLDNS_/g' \
|
||||
|
|
|
@ -58,7 +58,7 @@ time_t gldns_mktime_from_utc(const struct tm *tm);
|
|||
* The function interprets time as the number of seconds since epoch
|
||||
* with respect to now using serial arithmetics (rfc1982).
|
||||
* That number of seconds is then converted to broken-out time information.
|
||||
* This is especially useful when converting the inception and expiration
|
||||
* This is especially usefull when converting the inception and expiration
|
||||
* fields of RRSIG records.
|
||||
*
|
||||
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
|
||||
|
|
|
@ -150,6 +150,9 @@ static const gldns_rdf_type type_openpgpkey_wireformat[] = {
|
|||
static const gldns_rdf_type type_csync_wireformat[] = {
|
||||
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT16, GLDNS_RDF_TYPE_NSEC
|
||||
};
|
||||
static const gldns_rdf_type type_zonemd_wireformat[] = {
|
||||
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_HEX
|
||||
};
|
||||
/* nsec3 is some vars, followed by same type of data of nsec */
|
||||
static const gldns_rdf_type type_nsec3_wireformat[] = {
|
||||
/* GLDNS_RDF_TYPE_NSEC3_VARS, GLDNS_RDF_TYPE_NSEC3_NEXT_OWNER, GLDNS_RDF_TYPE_NSEC*/
|
||||
|
@ -341,12 +344,9 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
|
|||
{GLDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 52 */
|
||||
{GLDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
/*53 */
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 53 */
|
||||
{GLDNS_RR_TYPE_SMIMEA, "SMIMEA", 4, 4, type_tlsa_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 54 */
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 55
|
||||
* Hip ends with 0 or more Rendezvous Servers represented as dname's.
|
||||
|
@ -375,7 +375,8 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
|
|||
{GLDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 62 */
|
||||
{GLDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 63 */
|
||||
{GLDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
|
|
|
@ -182,9 +182,7 @@ enum gldns_enum_rr_type
|
|||
GLDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
|
||||
GLDNS_RR_TYPE_NSEC3PARAMS = 51,
|
||||
GLDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
|
||||
GLDNS_RR_TYPE_SMIMEA = 53, /* draft-ietf-dane-smime, TLSA-like but may
|
||||
be extended */
|
||||
|
||||
GLDNS_RR_TYPE_SMIMEA = 53, /* RFC 8162 */
|
||||
GLDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
|
||||
|
||||
/** draft-reid-dnsext-zs */
|
||||
|
@ -197,6 +195,7 @@ enum gldns_enum_rr_type
|
|||
GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
|
||||
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
|
||||
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
|
||||
GLDNS_RR_TYPE_ZONEMD = 63, /* draft-wessels-dns-zone-digest */
|
||||
|
||||
GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, NLnet Labs
|
||||
* Copyright (c) 2018-2019, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -53,14 +53,18 @@
|
|||
#define HAVE_TLS_CTX_CURVES_LIST 0
|
||||
#define HAVE_TLS_CONN_CURVES_LIST 0
|
||||
|
||||
typedef struct getdns_log_config getdns_log_config;
|
||||
|
||||
typedef struct _getdns_tls_context {
|
||||
struct mem_funcs* mfs;
|
||||
char* cipher_list;
|
||||
char* cipher_suites;
|
||||
char* curve_list;
|
||||
bool min_proto_1_2;
|
||||
gnutls_protocol_t min_tls;
|
||||
gnutls_protocol_t max_tls;
|
||||
char* ca_trust_file;
|
||||
char* ca_trust_path;
|
||||
const getdns_log_config* log;
|
||||
} _getdns_tls_context;
|
||||
|
||||
typedef struct _getdns_tls_connection {
|
||||
|
@ -70,10 +74,14 @@ typedef struct _getdns_tls_connection {
|
|||
_getdns_tls_context* ctx;
|
||||
struct mem_funcs* mfs;
|
||||
char* cipher_list;
|
||||
char* cipher_suites;
|
||||
char* curve_list;
|
||||
gnutls_protocol_t min_tls;
|
||||
gnutls_protocol_t max_tls;
|
||||
dane_query_t dane_query;
|
||||
dane_state_t dane_state;
|
||||
char* tlsa;
|
||||
const getdns_log_config* log;
|
||||
} _getdns_tls_connection;
|
||||
|
||||
typedef struct _getdns_tls_session {
|
||||
|
|
144
src/gnutls/tls.c
144
src/gnutls/tls.c
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, NLnet Labs
|
||||
* Copyright (c) 2018-2019, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,17 +43,27 @@
|
|||
/*
|
||||
* Cipher suites recommended in RFC7525.
|
||||
*
|
||||
* The following string generates a list with the same ciphers that are
|
||||
* The following strings generate a list with the same ciphers that are
|
||||
* generated by the equivalent string in the OpenSSL version of this file.
|
||||
*/
|
||||
char const * const _getdns_tls_context_default_cipher_list =
|
||||
"NONE:+AES-256-GCM:+AES-128-GCM:+CHACHA20-POLY1305:"
|
||||
"+ECDHE-RSA:+ECDHE-ECDSA:+SIGN-RSA-SHA384:+AEAD:"
|
||||
"+COMP-ALL:+VERS-TLS-ALL:+CURVE-ALL";
|
||||
static char const * const _getdns_tls_context_default_cipher_list =
|
||||
"+ECDHE-RSA:+ECDHE-ECDSA:+AEAD";
|
||||
|
||||
static char const * const _getdns_tls_context_default_cipher_suites =
|
||||
"+AES-256-GCM:+AES-128-GCM:+CHACHA20-POLY1305";
|
||||
|
||||
static char const * const _getdns_tls_connection_opportunistic_cipher_list =
|
||||
"NORMAL";
|
||||
|
||||
static char const * const _getdns_tls_priorities[] = {
|
||||
NULL, /* No protocol */
|
||||
"+VERS-TLS1.0", /* SSL3 */
|
||||
"+VERS-TLS1.0", /* TLS1.0 */
|
||||
"+VERS-TLS1.1", /* TLS1.1 */
|
||||
"+VERS-TLS1.2", /* TLS1.2 */
|
||||
"+VERS-TLS1.3", /* TLS1.3 */
|
||||
};
|
||||
|
||||
static char* getdns_strdup(struct mem_funcs* mfs, const char* s)
|
||||
{
|
||||
char* res;
|
||||
|
@ -92,6 +102,13 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
|
|||
char* pri = NULL;
|
||||
int res;
|
||||
|
||||
pri = getdns_priappend(conn->mfs, pri, "NONE:+COMP-ALL:+SIGN-RSA-SHA384");
|
||||
|
||||
if (conn->cipher_suites)
|
||||
pri = getdns_priappend(conn->mfs, pri, conn->cipher_suites);
|
||||
else if (conn->ctx->cipher_suites)
|
||||
pri = getdns_priappend(conn->mfs, pri, conn->ctx->cipher_suites);
|
||||
|
||||
if (conn->cipher_list)
|
||||
pri = getdns_priappend(conn->mfs, pri, conn->cipher_list);
|
||||
else if (conn->ctx->cipher_list)
|
||||
|
@ -101,12 +118,39 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
|
|||
pri = getdns_priappend(conn->mfs, pri, conn->curve_list);
|
||||
else if (conn->ctx->curve_list)
|
||||
pri = getdns_priappend(conn->mfs, pri, conn->ctx->curve_list);
|
||||
else
|
||||
pri = getdns_priappend(conn->mfs, pri, "+CURVE-ALL");
|
||||
|
||||
if (pri)
|
||||
gnutls_protocol_t min = conn->min_tls;
|
||||
gnutls_protocol_t max = conn->max_tls;
|
||||
if (!min) min = conn->ctx->min_tls;
|
||||
if (!max) max = conn->ctx->max_tls;
|
||||
|
||||
if (!min && !max) {
|
||||
pri = getdns_priappend(conn->mfs, pri, "+VERS-TLS-ALL");
|
||||
} else {
|
||||
if (!max) max = GNUTLS_TLS_VERSION_MAX;
|
||||
|
||||
for (gnutls_protocol_t i = min; i <= max; ++i)
|
||||
pri = getdns_priappend(conn->mfs, pri, _getdns_tls_priorities[i]);
|
||||
}
|
||||
|
||||
if (pri) {
|
||||
res = gnutls_priority_set_direct(conn->tls, pri, NULL);
|
||||
if (res != GNUTLS_E_SUCCESS) {
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
, pri
|
||||
, gnutls_strerror(res));
|
||||
}
|
||||
}
|
||||
else
|
||||
res = gnutls_set_default_priority(conn->tls);
|
||||
GETDNS_FREE(*conn->mfs, pri);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -142,6 +186,17 @@ static getdns_return_t get_gnu_mac_algorithm(int algorithm, gnutls_mac_algorithm
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static gnutls_protocol_t _getdns_tls_version2gnutls_version(getdns_tls_version_t v)
|
||||
{
|
||||
switch (v) {
|
||||
case GETDNS_SSL3 : return GNUTLS_SSL3;
|
||||
case GETDNS_TLS1 : return GNUTLS_TLS1;
|
||||
case GETDNS_TLS1_1: return GNUTLS_TLS1_1;
|
||||
case GETDNS_TLS1_2: return GNUTLS_TLS1_2;
|
||||
default : return GNUTLS_TLS_VERSION_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static _getdns_tls_x509* _getdns_tls_x509_new(struct mem_funcs* mfs, gnutls_datum_t cert)
|
||||
{
|
||||
_getdns_tls_x509* res;
|
||||
|
@ -158,7 +213,7 @@ void _getdns_tls_init()
|
|||
gnutls_global_init();
|
||||
}
|
||||
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs)
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log)
|
||||
{
|
||||
_getdns_tls_context* res;
|
||||
|
||||
|
@ -166,10 +221,11 @@ _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs)
|
|||
return NULL;
|
||||
|
||||
res->mfs = mfs;
|
||||
res->min_proto_1_2 = false;
|
||||
res->cipher_list = res->curve_list = NULL;
|
||||
res->cipher_list = res->cipher_suites = res->curve_list = NULL;
|
||||
res->min_tls = res->max_tls = 0;
|
||||
res->ca_trust_file = NULL;
|
||||
res->ca_trust_path = NULL;
|
||||
res->log = log;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -182,6 +238,7 @@ getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_cont
|
|||
GETDNS_FREE(*mfs, ctx->ca_trust_path);
|
||||
GETDNS_FREE(*mfs, ctx->ca_trust_file);
|
||||
GETDNS_FREE(*mfs, ctx->curve_list);
|
||||
GETDNS_FREE(*mfs, ctx->cipher_suites);
|
||||
GETDNS_FREE(*mfs, ctx->cipher_list);
|
||||
GETDNS_FREE(*mfs, ctx);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
@ -192,12 +249,18 @@ void _getdns_tls_context_pinset_init(_getdns_tls_context* ctx)
|
|||
(void) ctx;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_min_proto_1_2(_getdns_tls_context* ctx)
|
||||
getdns_return_t _getdns_tls_context_set_min_max_tls_version(_getdns_tls_context* ctx, getdns_tls_version_t min, getdns_tls_version_t max)
|
||||
{
|
||||
if (!ctx)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
ctx->min_proto_1_2 = true;
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
ctx->min_tls = _getdns_tls_version2gnutls_version(min);
|
||||
ctx->max_tls = _getdns_tls_version2gnutls_version(max);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
const char* _getdns_tls_context_get_default_cipher_list()
|
||||
{
|
||||
return _getdns_tls_context_default_cipher_list;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_cipher_list(_getdns_tls_context* ctx, const char* list)
|
||||
|
@ -213,6 +276,24 @@ getdns_return_t _getdns_tls_context_set_cipher_list(_getdns_tls_context* ctx, co
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
const char* _getdns_tls_context_get_default_cipher_suites()
|
||||
{
|
||||
return _getdns_tls_context_default_cipher_suites;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_cipher_suites(_getdns_tls_context* ctx, const char* list)
|
||||
{
|
||||
if (!ctx)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (!list)
|
||||
list = _getdns_tls_context_default_cipher_suites;
|
||||
|
||||
GETDNS_FREE(*ctx->mfs, ctx->cipher_suites);
|
||||
ctx->cipher_suites = getdns_strdup(ctx->mfs, list);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_curves_list(_getdns_tls_context* ctx, const char* list)
|
||||
{
|
||||
if (!ctx)
|
||||
|
@ -235,7 +316,7 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd)
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd, const getdns_log_config* log)
|
||||
{
|
||||
_getdns_tls_connection* res;
|
||||
|
||||
|
@ -250,11 +331,12 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
|
|||
res->mfs = mfs;
|
||||
res->cred = NULL;
|
||||
res->tls = NULL;
|
||||
res->cipher_list = NULL;
|
||||
res->curve_list = NULL;
|
||||
res->cipher_list = res->cipher_suites = res->curve_list = NULL;
|
||||
res->min_tls = res->max_tls = 0;
|
||||
res->dane_state = NULL;
|
||||
res->dane_query = NULL;
|
||||
res->tlsa = NULL;
|
||||
res->log = log;
|
||||
|
||||
if (gnutls_certificate_allocate_credentials(&res->cred) != GNUTLS_E_SUCCESS)
|
||||
goto failed;
|
||||
|
@ -270,8 +352,10 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
|
|||
|
||||
if (gnutls_init(&res->tls, GNUTLS_CLIENT | GNUTLS_NONBLOCK) != GNUTLS_E_SUCCESS)
|
||||
goto failed;
|
||||
if (set_connection_ciphers(res) != GNUTLS_E_SUCCESS)
|
||||
if (set_connection_ciphers(res) != GNUTLS_E_SUCCESS) {
|
||||
|
||||
goto failed;
|
||||
}
|
||||
if (gnutls_credentials_set(res->tls, GNUTLS_CRD_CERTIFICATE, res->cred) != GNUTLS_E_SUCCESS)
|
||||
goto failed;
|
||||
if (dane_state_init(&res->dane_state, DANE_F_IGNORE_DNSSEC) != DANE_E_SUCCESS)
|
||||
|
@ -300,6 +384,7 @@ getdns_return_t _getdns_tls_connection_free(struct mem_funcs* mfs, _getdns_tls_c
|
|||
gnutls_certificate_free_credentials(conn->cred);
|
||||
GETDNS_FREE(*mfs, conn->tlsa);
|
||||
GETDNS_FREE(*mfs, conn->curve_list);
|
||||
GETDNS_FREE(*mfs, conn->cipher_suites);
|
||||
GETDNS_FREE(*mfs, conn->cipher_list);
|
||||
GETDNS_FREE(*mfs, conn);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
@ -321,6 +406,15 @@ getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_min_max_tls_version(_getdns_tls_connection* conn, getdns_tls_version_t min, getdns_tls_version_t max)
|
||||
{
|
||||
if (!conn)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
conn->min_tls = _getdns_tls_version2gnutls_version(min);
|
||||
conn->max_tls = _getdns_tls_version2gnutls_version(max);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_list(_getdns_tls_connection* conn, const char* list)
|
||||
{
|
||||
if (!conn || !conn->tls)
|
||||
|
@ -337,6 +431,19 @@ getdns_return_t _getdns_tls_connection_set_cipher_list(_getdns_tls_connection* c
|
|||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_suites(_getdns_tls_connection* conn, const char* list)
|
||||
{
|
||||
if (!conn || !conn->tls)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
GETDNS_FREE(*conn->mfs, conn->cipher_list);
|
||||
conn->cipher_suites = getdns_strdup(conn->mfs, list);
|
||||
if (set_connection_ciphers(conn) == GNUTLS_E_SUCCESS)
|
||||
return GETDNS_RETURN_GOOD;
|
||||
else
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_curves_list(_getdns_tls_connection* conn, const char* list)
|
||||
{
|
||||
if (!conn || !conn->tls)
|
||||
|
@ -400,9 +507,6 @@ getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn
|
|||
|
||||
r = gnutls_handshake(conn->tls);
|
||||
if (r == GNUTLS_E_SUCCESS) {
|
||||
if (conn->ctx->min_proto_1_2 &&
|
||||
gnutls_protocol_get_version(conn->tls) < GNUTLS_TLS1_2)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -36,9 +36,13 @@ getdns_context_get_tls_backoff_time
|
|||
getdns_context_get_tls_ca_file
|
||||
getdns_context_get_tls_ca_path
|
||||
getdns_context_get_tls_cipher_list
|
||||
getdns_context_get_tls_ciphersuites
|
||||
getdns_context_get_tls_connection_retries
|
||||
getdns_context_get_tls_curves_list
|
||||
getdns_context_get_tls_max_version
|
||||
getdns_context_get_tls_min_version
|
||||
getdns_context_get_tls_query_padding_blocksize
|
||||
getdns_context_get_trust_anchors_backoff_time
|
||||
getdns_context_get_trust_anchors_url
|
||||
getdns_context_get_trust_anchors_verify_CA
|
||||
getdns_context_get_trust_anchors_verify_email
|
||||
|
@ -80,9 +84,13 @@ getdns_context_set_tls_backoff_time
|
|||
getdns_context_set_tls_ca_file
|
||||
getdns_context_set_tls_ca_path
|
||||
getdns_context_set_tls_cipher_list
|
||||
getdns_context_set_tls_ciphersuites
|
||||
getdns_context_set_tls_connection_retries
|
||||
getdns_context_set_tls_curves_list
|
||||
getdns_context_set_tls_max_version
|
||||
getdns_context_set_tls_min_version
|
||||
getdns_context_set_tls_query_padding_blocksize
|
||||
getdns_context_set_trust_anchors_backoff_time
|
||||
getdns_context_set_trust_anchors_url
|
||||
getdns_context_set_trust_anchors_verify_CA
|
||||
getdns_context_set_trust_anchors_verify_email
|
||||
|
|
|
@ -418,7 +418,7 @@ getdns_list_create_with_memory_functions(void *(*malloc)(size_t),
|
|||
|
||||
/*-------------------------- getdns_list_create_with_context */
|
||||
struct getdns_list *
|
||||
getdns_list_create_with_context(struct getdns_context *context)
|
||||
getdns_list_create_with_context(const getdns_context *context)
|
||||
{
|
||||
if (context)
|
||||
return getdns_list_create_with_extended_memory_functions(
|
||||
|
|
|
@ -14,7 +14,7 @@ cat > const-info.c << END_OF_HEAD
|
|||
static struct const_info consts_info[] = {
|
||||
{ -1, NULL, "/* <unknown getdns value> */" },
|
||||
END_OF_HEAD
|
||||
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%7d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%7d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%7d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns_extra.h.in getdns/getdns.h.in const-info.h| sed 's/,,/,/g' >> const-info.c
|
||||
gawk --non-decimal-data '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%7d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z0-9_]+[ ]+(0[xX][0-9a-fA-F]+|[0-9]+)/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%7d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%7d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns_extra.h.in getdns/getdns.h.in const-info.h| sed 's/,,/,/g' >> const-info.c
|
||||
cat >> const-info.c << END_OF_TAIL
|
||||
};
|
||||
|
||||
|
@ -49,7 +49,7 @@ getdns_get_errorstr_by_id(uint16_t err)
|
|||
|
||||
static struct const_name_info consts_name_info[] = {
|
||||
END_OF_TAIL
|
||||
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in const-info.h| sed 's/,,/,/g' >> const-info.c
|
||||
gawk --non-decimal-data '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+(0[xX][0-9a-fA-F]+|[0-9]+)/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in const-info.h| sed 's/,,/,/g' >> const-info.c
|
||||
cat >> const-info.c << END_OF_TAIL
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
write_symbols() {
|
||||
OUTPUT=$1
|
||||
shift
|
||||
grep 'getdns_[0-9a-zA-Z_]*(' $* | grep -v '^#' | grep -v 'INLINE' | grep -v 'getdns_extra\.h\.in: \* if' \
|
||||
grep -h 'getdns_[0-9a-zA-Z_]*(' $* | grep -v '^#' | grep -v 'INLINE' | grep -v '^ \* if' \
|
||||
| sed -e 's/(.*$//g' -e 's/^.*getdns_/getdns_/g' | LC_ALL=C sort | uniq > $OUTPUT
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/md5.h>
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
# include <openssl/conf.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
|
@ -38,6 +41,16 @@
|
|||
#ifdef USE_GOST
|
||||
|
||||
/** store GOST engine reference loaded into OpenSSL library */
|
||||
#ifdef OPENSSL_NO_ENGINE
|
||||
int
|
||||
gldns_key_EVP_load_gost_id(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void gldns_key_EVP_unload_gost(void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
ENGINE* gldns_gost_engine = NULL;
|
||||
|
||||
int
|
||||
|
@ -97,6 +110,7 @@ void gldns_key_EVP_unload_gost(void)
|
|||
gldns_gost_engine = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* ifndef OPENSSL_NO_ENGINE */
|
||||
#endif /* USE_GOST */
|
||||
|
||||
DSA *
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#include "pubkey-pinning-internal.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
#define X509_STORE_CTX_get0_untrusted(store) store->untrusted
|
||||
#endif
|
||||
|
||||
|
@ -106,7 +106,7 @@ _get_ssl_getdns_upstream_idx(X509_STORE *store)
|
|||
{
|
||||
static volatile int idx = -1;
|
||||
if (idx < 0) {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
#else
|
||||
X509_STORE_lock(store);
|
||||
|
@ -114,7 +114,7 @@ _get_ssl_getdns_upstream_idx(X509_STORE *store)
|
|||
if (idx < 0)
|
||||
idx = SSL_get_ex_new_index(0, "associated getdns upstream",
|
||||
NULL,NULL,NULL);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
#else
|
||||
X509_STORE_unlock(store);
|
||||
|
@ -123,27 +123,6 @@ _get_ssl_getdns_upstream_idx(X509_STORE *store)
|
|||
return idx;
|
||||
}
|
||||
|
||||
getdns_upstream*
|
||||
_getdns_upstream_from_x509_store(X509_STORE_CTX *store)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
int uidx = _get_ssl_getdns_upstream_idx();
|
||||
#else
|
||||
int uidx = _get_ssl_getdns_upstream_idx(X509_STORE_CTX_get0_store(store));
|
||||
#endif
|
||||
int sslidx = SSL_get_ex_data_X509_STORE_CTX_idx();
|
||||
const SSL *ssl;
|
||||
|
||||
/* all *_get_ex_data() should return NULL on failure anyway */
|
||||
ssl = X509_STORE_CTX_get_ex_data(store, sslidx);
|
||||
if (ssl)
|
||||
return (getdns_upstream*) SSL_get_ex_data(ssl, uidx);
|
||||
else
|
||||
return NULL;
|
||||
/* TODO: if we want more details about errors somehow, we
|
||||
* might call ERR_get_error (see CRYPTO_set_ex_data(3ssl))*/
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_associate_upstream_with_connection(_getdns_tls_connection *conn,
|
||||
getdns_upstream *upstream)
|
||||
|
@ -151,7 +130,7 @@ _getdns_associate_upstream_with_connection(_getdns_tls_connection *conn,
|
|||
if (!conn || !conn->ssl)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
int uidx = _get_ssl_getdns_upstream_idx();
|
||||
#else
|
||||
int uidx = _get_ssl_getdns_upstream_idx(SSL_CTX_get_cert_store(SSL_get_SSL_CTX(conn->ssl)));
|
||||
|
@ -164,91 +143,4 @@ _getdns_associate_upstream_with_connection(_getdns_tls_connection *conn,
|
|||
* might call ERR_get_error (see CRYPTO_set_ex_data(3ssl))*/
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_verify_pinset_match(const sha256_pin_t *pinset,
|
||||
X509_STORE_CTX *store)
|
||||
{
|
||||
getdns_return_t ret = GETDNS_RETURN_GENERIC_ERROR;
|
||||
X509 *x, *prev = NULL;
|
||||
int i, len;
|
||||
unsigned char raw[4096];
|
||||
unsigned char *next;
|
||||
unsigned char buf[sizeof(pinset->pin)];
|
||||
const sha256_pin_t *p;
|
||||
|
||||
if (pinset == NULL || store == NULL)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
/* start at the base of the chain (the end-entity cert) and
|
||||
* make sure that some valid element of the chain does match
|
||||
* the pinset. */
|
||||
|
||||
/* Testing with OpenSSL 1.0.1e-1 on debian indicates that
|
||||
* store->untrusted holds the chain offered by the server in
|
||||
* the order that the server offers it. If the server offers
|
||||
* bogus certificates (that is, matching and valid certs that
|
||||
* belong to private keys that the server does not control),
|
||||
* the the verification will succeed (including this pinset
|
||||
* check), but the handshake will fail outside of this
|
||||
* verification. */
|
||||
|
||||
/* TODO: how do we handle raw public keys? */
|
||||
|
||||
for (i = 0; i < sk_X509_num(X509_STORE_CTX_get0_untrusted(store)); i++, prev = x) {
|
||||
|
||||
x = sk_X509_value(X509_STORE_CTX_get0_untrusted(store), i);
|
||||
#if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
DEBUG_STUB("%s %-35s: Name of cert: %d ",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i);
|
||||
X509_NAME_print_ex_fp(stderr, X509_get_subject_name(x), 1, XN_FLAG_ONELINE);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
if (i > 0) {
|
||||
/* we ensure that "prev" is signed by "x" */
|
||||
EVP_PKEY *pkey = X509_get_pubkey(x);
|
||||
int verified;
|
||||
if (!pkey) {
|
||||
DEBUG_STUB("%s %-35s: Could not get pubkey from cert %d (%p)\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)x);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
verified = X509_verify(prev, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!verified) {
|
||||
DEBUG_STUB("%s %-35s: cert %d (%p) was not signed by cert %d\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i-1, (void*)prev, i);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* digest the cert with sha256 */
|
||||
len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL);
|
||||
if (len > (int)sizeof(raw)) {
|
||||
DEBUG_STUB("%s %-35s: Pubkey %d is larger than %"PRIsz" octets\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, sizeof(raw));
|
||||
continue;
|
||||
}
|
||||
next = raw;
|
||||
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next);
|
||||
if (next - raw != len) {
|
||||
DEBUG_STUB("%s %-35s: Pubkey %d claimed it needed %d octets, really needed %"PRIsz"\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, len, next - raw);
|
||||
continue;
|
||||
}
|
||||
SHA256(raw, len, buf);
|
||||
|
||||
/* compare it */
|
||||
for (p = pinset; p; p = p->next)
|
||||
if (0 == memcmp(buf, p->pin, sizeof(p->pin))) {
|
||||
DEBUG_STUB("%s %-35s: Pubkey %d matched pin %p (%"PRIsz")\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p, sizeof(p->pin));
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} else
|
||||
DEBUG_STUB("%s %-35s: Pubkey %d did not match pin %p\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* pubkey-pinning.c */
|
||||
|
|
|
@ -36,16 +36,7 @@
|
|||
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/* internal functions for associating X.509 verification processes in
|
||||
* OpenSSL with getdns_upstream objects. */
|
||||
|
||||
getdns_upstream*
|
||||
_getdns_upstream_from_x509_store(X509_STORE_CTX *store);
|
||||
|
||||
|
||||
getdns_return_t
|
||||
_getdns_verify_pinset_match(const sha256_pin_t *pinset,
|
||||
X509_STORE_CTX *store);
|
||||
getdns_return_t _getdns_decode_base64(const char* str, uint8_t* res, size_t res_size);
|
||||
|
||||
#endif
|
||||
/* pubkey-pinning-internal.h */
|
||||
|
|
|
@ -55,13 +55,16 @@
|
|||
#define GETDNS_TLS_MAX_DIGEST_LENGTH (EVP_MAX_MD_SIZE)
|
||||
|
||||
typedef struct sha256_pin sha256_pin_t;
|
||||
typedef struct getdns_log_config getdns_log_config;
|
||||
|
||||
typedef struct _getdns_tls_context {
|
||||
SSL_CTX* ssl;
|
||||
const getdns_log_config* log;
|
||||
} _getdns_tls_context;
|
||||
|
||||
typedef struct _getdns_tls_connection {
|
||||
SSL* ssl;
|
||||
const getdns_log_config* log;
|
||||
#if defined(USE_DANESSL)
|
||||
const char* auth_name;
|
||||
sha256_pin_t* pinset;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "context.h"
|
||||
#include "const-info.h"
|
||||
|
||||
#ifdef USE_DANESSL
|
||||
# include "ssl_dane/danessl.h"
|
||||
|
@ -62,33 +63,20 @@
|
|||
#endif
|
||||
|
||||
/* Cipher suites recommended in RFC7525. */
|
||||
char const * const _getdns_tls_context_default_cipher_list =
|
||||
"TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:"
|
||||
"TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20";
|
||||
static char const * const _getdns_tls_context_default_cipher_list =
|
||||
#ifndef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
"TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:"
|
||||
"TLS13-CHACHA20-POLY1305-SHA256:"
|
||||
#endif
|
||||
"EECDH+AESGCM:EECDH+CHACHA20";
|
||||
|
||||
static char const * const _getdns_tls_context_default_cipher_suites =
|
||||
"TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:"
|
||||
"TLS_CHACHA20_POLY1305_SHA256";
|
||||
|
||||
static char const * const _getdns_tls_connection_opportunistic_cipher_list =
|
||||
"DEFAULT";
|
||||
|
||||
#if defined(USE_DANESSL) && defined(STUB_DEBUG) && STUB_DEBUG
|
||||
static void _stub_debug_print_openssl_errors(void)
|
||||
{
|
||||
unsigned long err;
|
||||
char buffer[1024];
|
||||
const char *file;
|
||||
const char *data;
|
||||
int line;
|
||||
int flags;
|
||||
|
||||
while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
|
||||
ERR_error_string_n(err, buffer, sizeof(buffer));
|
||||
if (flags & ERR_TXT_STRING)
|
||||
DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d:%s\n", buffer, file, line, data);
|
||||
else
|
||||
DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d\n", buffer, file, line);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _getdns_tls_verify_always_ok(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
|
@ -156,23 +144,63 @@ static const EVP_MD* get_digester(int algorithm)
|
|||
return digester;
|
||||
}
|
||||
|
||||
#if HAVE_DECL_SSL_SET_MIN_PROTO_VERSION
|
||||
static int _getdns_tls_version2openssl_version(getdns_tls_version_t v)
|
||||
{
|
||||
switch (v) {
|
||||
# ifdef SSL3_VERSION
|
||||
case GETDNS_SSL3 : return SSL3_VERSION;
|
||||
# endif
|
||||
# ifdef TLS1_VERSION
|
||||
case GETDNS_TLS1 : return TLS1_VERSION;
|
||||
# endif
|
||||
# ifdef TLS1_1_VERSION
|
||||
case GETDNS_TLS1_1: return TLS1_1_VERSION;
|
||||
# endif
|
||||
# ifdef TLS1_2_VERSION
|
||||
case GETDNS_TLS1_2: return TLS1_2_VERSION;
|
||||
# endif
|
||||
# ifdef TLS1_3_VERSION
|
||||
case GETDNS_TLS1_3: return TLS1_3_VERSION;
|
||||
# endif
|
||||
default :
|
||||
# if defined(TLS_MAX_VERSION)
|
||||
return TLS_MAX_VERSION;
|
||||
# elif defined(TLS1_3_VERSION)
|
||||
return TLS1_3_VERSION;
|
||||
# elif defined(TLS1_2_VERSION)
|
||||
return TLS1_2_VERSION;
|
||||
# elif defined(TLS1_1_VERSION)
|
||||
return TLS1_1_VERSION;
|
||||
# elif defined(TLS1_VERSION)
|
||||
return TLS1_VERSION;
|
||||
# elif defined(SSL3_VERSION)
|
||||
return SSL3_VERSION;
|
||||
# else
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* For windows, the CA trust store is not read by openssl.
|
||||
Add code to open the trust store using wincrypt API and add
|
||||
the root certs into openssl trust store */
|
||||
static int
|
||||
add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
|
||||
add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx, const getdns_log_config* log)
|
||||
{
|
||||
HCERTSTORE hSystemStore;
|
||||
PCCERT_CONTEXT pTargetCert = NULL;
|
||||
|
||||
DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__,
|
||||
"Adding Windows certificates from system root store to CA store");
|
||||
_getdns_log(log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_DEBUG
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS,
|
||||
, "Adding Windows certificates from system root store to CA store")
|
||||
;
|
||||
|
||||
/* load just once per context lifetime for this version of getdns
|
||||
TODO: dynamically update CA trust changes as they are available */
|
||||
if (!tls_ctx)
|
||||
return 0;
|
||||
assert(tls_ctx);
|
||||
|
||||
/* Call wincrypt's CertOpenStore to open the CA root store. */
|
||||
|
||||
|
@ -185,19 +213,27 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
|
|||
1 << 16,
|
||||
L"root")) == 0)
|
||||
{
|
||||
_getdns_log(log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS
|
||||
, "Could not CertOpenStore()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
X509_STORE* store = SSL_CTX_get_cert_store(tls_ctx);
|
||||
if (!store)
|
||||
if (!store) {
|
||||
_getdns_log(log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS
|
||||
, "Could not SSL_CTX_get_cert_store()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* failure if the CA store is empty or the call fails */
|
||||
if ((pTargetCert = CertEnumCertificatesInStore(
|
||||
hSystemStore, pTargetCert)) == 0) {
|
||||
DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__,
|
||||
"CA certificate store for Windows is empty.");
|
||||
return 0;
|
||||
hSystemStore, pTargetCert)) == 0) {
|
||||
_getdns_log(log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_NOTICE
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS
|
||||
, "CA certificate store for Windows is empty.");
|
||||
return 0;
|
||||
}
|
||||
/* iterate over the windows cert store and add to openssl store */
|
||||
do
|
||||
|
@ -207,9 +243,13 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
|
|||
pTargetCert->cbCertEncoded);
|
||||
if (!cert1) {
|
||||
/* return error if a cert fails */
|
||||
DEBUG_STUB("%s %-35s: %s %d:%s\n", STUB_DEBUG_SETUP_TLS, __FUNC__,
|
||||
"Unable to parse certificate in memory",
|
||||
ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
|
||||
_getdns_log(log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR,
|
||||
, "%s: %s %d:%s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Unable to parse certificate in memory"
|
||||
, ERR_get_error()
|
||||
, ERR_error_string(ERR_get_error(), NULL));
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
|
@ -221,9 +261,16 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
|
|||
* certificate is already in the store. */
|
||||
if(ERR_GET_LIB(error) != ERR_LIB_X509 ||
|
||||
ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
|
||||
DEBUG_STUB("%s %-35s: %s %d:%s\n", STUB_DEBUG_SETUP_TLS, __FUNC__,
|
||||
"Error adding certificate", ERR_get_error(),
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
_getdns_log(log
|
||||
, GETDNS_LOG_SYS_STUB
|
||||
, GETDNS_LOG_ERR
|
||||
, "%s: %s %d:%s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error adding certificate"
|
||||
, ERR_get_error()
|
||||
, ERR_error_string( ERR_get_error()
|
||||
, NULL)
|
||||
);
|
||||
X509_free(cert1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -238,12 +285,18 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
|
|||
CertFreeCertificateContext(pTargetCert);
|
||||
if (hSystemStore)
|
||||
{
|
||||
if (!CertCloseStore(
|
||||
hSystemStore, 0))
|
||||
if (!CertCloseStore(hSystemStore, 0)) {
|
||||
_getdns_log(log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS
|
||||
, "Could not CertCloseStore()");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__,
|
||||
"Completed adding Windows certificates to CA store successfully");
|
||||
_getdns_log(log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_INFO
|
||||
, "%s: %s\n", STUB_DEBUG_SETUP_TLS
|
||||
, "Completed adding Windows certificates to CA store successfully")
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -265,13 +318,15 @@ void _getdns_tls_init()
|
|||
#endif
|
||||
}
|
||||
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs)
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log)
|
||||
{
|
||||
_getdns_tls_context* res;
|
||||
|
||||
if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_context)))
|
||||
return NULL;
|
||||
|
||||
res->log = log;
|
||||
|
||||
/* Create client context, use TLS v1.2 only for now */
|
||||
# ifdef HAVE_TLS_CLIENT_METHOD
|
||||
res->ssl = SSL_CTX_new(TLS_client_method());
|
||||
|
@ -279,6 +334,15 @@ _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs)
|
|||
res->ssl = SSL_CTX_new(TLSv1_2_client_method());
|
||||
# endif
|
||||
if(res->ssl == NULL) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error creating TLS context"
|
||||
, ssl_err);
|
||||
GETDNS_FREE(*mfs, res);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -297,35 +361,90 @@ getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_cont
|
|||
void _getdns_tls_context_pinset_init(_getdns_tls_context* ctx)
|
||||
{
|
||||
int osr;
|
||||
(void) osr;
|
||||
|
||||
#if defined(HAVE_SSL_CTX_DANE_ENABLE)
|
||||
osr = SSL_CTX_dane_enable(ctx->ssl);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: SSL_CTX_dane_enable() -> %d\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
#elif defined(USE_DANESSL)
|
||||
osr = DANESSL_CTX_init(ctx->ssl);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_CTX_init() -> %d\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
#else
|
||||
#error Must have either DANE SSL or OpenSSL v1.1.
|
||||
#endif
|
||||
if (!osr) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_WARNING
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Could not enable DANE on TLX context"
|
||||
, ssl_err);
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_min_proto_1_2(_getdns_tls_context* ctx)
|
||||
getdns_return_t _getdns_tls_context_set_min_max_tls_version(_getdns_tls_context* ctx, getdns_tls_version_t min, getdns_tls_version_t max)
|
||||
{
|
||||
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
||||
#if HAVE_DECL_SSL_SET_MIN_PROTO_VERSION
|
||||
char ssl_err[256];
|
||||
int min_ssl = _getdns_tls_version2openssl_version(min);
|
||||
int max_ssl = _getdns_tls_version2openssl_version(max);
|
||||
|
||||
if (!ctx || !ctx->ssl)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
if (!SSL_CTX_set_min_proto_version(ctx->ssl, TLS1_2_VERSION))
|
||||
if (min && !SSL_CTX_set_min_proto_version(ctx->ssl, min_ssl)) {
|
||||
struct const_info* ci = _getdns_get_const_info(min);
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS context with "
|
||||
"minimum TLS version"
|
||||
, ci->name
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
if (max && !SSL_CTX_set_max_proto_version(ctx->ssl, max_ssl)) {
|
||||
struct const_info* ci = _getdns_get_const_info(min);
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS context with "
|
||||
"minimum TLS version"
|
||||
, ci->name
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
#else
|
||||
/*
|
||||
* We've used TLSv1_2_client_method() creating the context, so
|
||||
* error if they asked for anything other than TLS 1.2 or better.
|
||||
*/
|
||||
(void) ctx;
|
||||
if ((!min || min == GETDNS_TLS1_2) && !max)
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support setting of minimum or maximum "
|
||||
"TLS versions");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* _getdns_tls_context_get_default_cipher_list()
|
||||
{
|
||||
return _getdns_tls_context_default_cipher_list;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_cipher_list(_getdns_tls_context* ctx, const char* list)
|
||||
{
|
||||
if (!ctx || !ctx->ssl)
|
||||
|
@ -334,8 +453,60 @@ getdns_return_t _getdns_tls_context_set_cipher_list(_getdns_tls_context* ctx, co
|
|||
if (!list)
|
||||
list = _getdns_tls_context_default_cipher_list;
|
||||
|
||||
if (!SSL_CTX_set_cipher_list(ctx->ssl, list))
|
||||
if (!SSL_CTX_set_cipher_list(ctx->ssl, list)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS context with "
|
||||
"cipher list"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
const char* _getdns_tls_context_get_default_cipher_suites()
|
||||
{
|
||||
return _getdns_tls_context_default_cipher_suites;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_context_set_cipher_suites(_getdns_tls_context* ctx, const char* list)
|
||||
{
|
||||
if (!ctx || !ctx->ssl)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
if (!list)
|
||||
list = _getdns_tls_context_default_cipher_suites;
|
||||
|
||||
if (!SSL_CTX_set_ciphersuites(ctx->ssl, list)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS context with "
|
||||
"cipher suites"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
#else
|
||||
if (list) {
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support configuring cipher suites");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
@ -345,10 +516,29 @@ getdns_return_t _getdns_tls_context_set_curves_list(_getdns_tls_context* ctx, co
|
|||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
#if HAVE_TLS_CTX_CURVES_LIST
|
||||
if (list &&
|
||||
!SSL_CTX_set1_curves_list(ctx->ssl, list))
|
||||
!SSL_CTX_set1_curves_list(ctx->ssl, list)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS context with "
|
||||
"curves list"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
#else
|
||||
(void) list;
|
||||
if (list) {
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support configuring curves list");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
@ -357,20 +547,53 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
|
|||
{
|
||||
if (!ctx || !ctx->ssl)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
if ((file || path) &&
|
||||
SSL_CTX_load_verify_locations(ctx->ssl, file, path))
|
||||
if (file || path) {
|
||||
if (!SSL_CTX_load_verify_locations(ctx->ssl, file, path)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err
|
||||
, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB
|
||||
, GETDNS_LOG_WARNING
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Could not load verify locations"
|
||||
, ssl_err);
|
||||
} else {
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB
|
||||
, GETDNS_LOG_DEBUG
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Verify locations loaded");
|
||||
}
|
||||
return GETDNS_RETURN_GOOD; /* pass */
|
||||
}
|
||||
#ifndef USE_WINSOCK
|
||||
else if (SSL_CTX_set_default_verify_paths(ctx->ssl))
|
||||
return GETDNS_RETURN_GOOD;
|
||||
else {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err
|
||||
, sizeof(ssl_err));
|
||||
_getdns_log(ctx->log
|
||||
, GETDNS_LOG_SYS_STUB
|
||||
, GETDNS_LOG_WARNING
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Could not load default verify locations"
|
||||
, ssl_err);
|
||||
}
|
||||
#else
|
||||
else if (add_WIN_cacerts_to_openssl_store(ctx->ssl))
|
||||
else if (add_WIN_cacerts_to_openssl_store(ctx->ssl, ctx->log))
|
||||
return GETDNS_RETURN_GOOD;
|
||||
#endif /* USE_WINSOCK */
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd)
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd, const getdns_log_config* log)
|
||||
{
|
||||
_getdns_tls_connection* res;
|
||||
|
||||
|
@ -392,6 +615,8 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
|
|||
return NULL;
|
||||
}
|
||||
|
||||
res->log = log;
|
||||
|
||||
/* Connection is a client. */
|
||||
SSL_set_connect_state(res->ssl);
|
||||
|
||||
|
@ -415,9 +640,6 @@ getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn)
|
|||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
#ifdef USE_DANESSL
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
_stub_debug_print_openssl_errors();
|
||||
# endif
|
||||
DANESSL_cleanup(conn->ssl);
|
||||
#endif
|
||||
|
||||
|
@ -428,6 +650,64 @@ getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn)
|
|||
}
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_min_max_tls_version(_getdns_tls_connection* conn, getdns_tls_version_t min, getdns_tls_version_t max)
|
||||
{
|
||||
#if HAVE_DECL_SSL_SET_MIN_PROTO_VERSION
|
||||
char ssl_err[256];
|
||||
int min_ssl = _getdns_tls_version2openssl_version(min);
|
||||
int max_ssl = _getdns_tls_version2openssl_version(max);
|
||||
|
||||
if (!conn || !conn->ssl)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
if (min && !SSL_set_min_proto_version(conn->ssl, min_ssl)) {
|
||||
struct const_info* ci = _getdns_get_const_info(min);
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
"minimum TLS version"
|
||||
, ci->name
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
if (max && !SSL_set_max_proto_version(conn->ssl, max_ssl)) {
|
||||
struct const_info* ci = _getdns_get_const_info(min);
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
"minimum TLS version"
|
||||
, ci->name
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
#else
|
||||
/*
|
||||
* We've used TLSv1_2_client_method() creating the context, so
|
||||
* error if they asked for anything other than TLS 1.2 or better.
|
||||
*/
|
||||
(void) conn;
|
||||
if ((!min || min == GETDNS_TLS1_2) && !max)
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support setting of minimum or maximum "
|
||||
"TLS versions");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_list(_getdns_tls_connection* conn, const char* list)
|
||||
{
|
||||
if (!conn || !conn->ssl)
|
||||
|
@ -436,8 +716,53 @@ getdns_return_t _getdns_tls_connection_set_cipher_list(_getdns_tls_connection* c
|
|||
if (!list)
|
||||
list = _getdns_tls_connection_opportunistic_cipher_list;
|
||||
|
||||
if (!SSL_set_cipher_list(conn->ssl, list))
|
||||
if (!SSL_set_cipher_list(conn->ssl, list)) {
|
||||
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
"cipher list"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_suites(_getdns_tls_connection* conn, const char* list)
|
||||
{
|
||||
if (!conn || !conn->ssl || !list)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
#ifdef HAVE_SSL_SET_CIPHERSUITES
|
||||
if (!SSL_set_ciphersuites(conn->ssl, list)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
"cipher suites"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
#else
|
||||
if (list) {
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support configuring cipher suites");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
@ -447,10 +772,29 @@ getdns_return_t _getdns_tls_connection_set_curves_list(_getdns_tls_connection* c
|
|||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
#if HAVE_TLS_CONN_CURVES_LIST
|
||||
if (list &&
|
||||
!SSL_set1_curves_list(conn->ssl, list))
|
||||
!SSL_set1_curves_list(conn->ssl, list)) {
|
||||
char ssl_err[256];
|
||||
ERR_error_string_n( ERR_get_error()
|
||||
, ssl_err, sizeof(ssl_err));
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s (%s)\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "Error configuring TLS connection with "
|
||||
"curves list"
|
||||
, ssl_err);
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
#else
|
||||
(void) list;
|
||||
if (list) {
|
||||
_getdns_log(conn->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, "%s: %s\n"
|
||||
, STUB_DEBUG_SETUP_TLS
|
||||
, "This version of OpenSSL does not "
|
||||
"support configuring curves list");
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,23 @@ int fake_dsa = 0;
|
|||
/** fake SHA1 support for unit tests */
|
||||
int fake_sha1 = 0;
|
||||
|
||||
/**
|
||||
* Output a libcrypto openssl error to the logfile.
|
||||
* @param str: string to add to it.
|
||||
* @param e: the error to output, error number from ERR_get_error().
|
||||
*/
|
||||
static void
|
||||
log_crypto_error(const char* str, unsigned long e)
|
||||
{
|
||||
char buf[128];
|
||||
/* or use ERR_error_string if ERR_error_string_n is not avail TODO */
|
||||
ERR_error_string_n(e, buf, sizeof(buf));
|
||||
/* buf now contains */
|
||||
/* error:[error code]:[library name]:[function name]:[reason string] */
|
||||
log_err("%s crypto %s", str, buf);
|
||||
(void) str; /* In case log_err() does nothing. */
|
||||
}
|
||||
|
||||
/* return size of digest if supported, or 0 otherwise */
|
||||
size_t
|
||||
nsec3_hash_algo_size_supported(int id)
|
||||
|
@ -96,7 +113,13 @@ secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
|||
{
|
||||
switch(algo) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!sldns_digest_evp(buf, len, res, EVP_sha1()))
|
||||
log_crypto_error("could not digest with EVP_sha1",
|
||||
ERR_get_error());
|
||||
#else
|
||||
(void)SHA1(buf, len, res);
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -106,7 +129,13 @@ secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
|||
void
|
||||
secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!sldns_digest_evp(buf, len, res, EVP_sha256()))
|
||||
log_crypto_error("could not digest with EVP_sha256",
|
||||
ERR_get_error());
|
||||
#else
|
||||
(void)SHA256(buf, len, res);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,12 +194,24 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
|||
switch(algo) {
|
||||
#if defined(HAVE_EVP_SHA1) && defined(USE_SHA1)
|
||||
case LDNS_SHA1:
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!sldns_digest_evp(buf, len, res, EVP_sha1()))
|
||||
log_crypto_error("could not digest with EVP_sha1",
|
||||
ERR_get_error());
|
||||
#else
|
||||
(void)SHA1(buf, len, res);
|
||||
#endif
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
case LDNS_SHA256:
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!sldns_digest_evp(buf, len, res, EVP_sha256()))
|
||||
log_crypto_error("could not digest with EVP_sha256",
|
||||
ERR_get_error());
|
||||
#else
|
||||
(void)SHA256(buf, len, res);
|
||||
#endif
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
|
@ -181,7 +222,13 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
|||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_SHA384:
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!sldns_digest_evp(buf, len, res, EVP_sha384()))
|
||||
log_crypto_error("could not digest with EVP_sha384",
|
||||
ERR_get_error());
|
||||
#else
|
||||
(void)SHA384(buf, len, res);
|
||||
#endif
|
||||
return 1;
|
||||
#endif
|
||||
default:
|
||||
|
@ -248,22 +295,6 @@ dnskey_algo_id_is_supported(int id)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a libcrypto openssl error to the logfile.
|
||||
* @param str: string to add to it.
|
||||
* @param e: the error to output, error number from ERR_get_error().
|
||||
*/
|
||||
static void
|
||||
log_crypto_error(const char* str, unsigned long e)
|
||||
{
|
||||
char buf[128];
|
||||
/* or use ERR_error_string if ERR_error_string_n is not avail TODO */
|
||||
ERR_error_string_n(e, buf, sizeof(buf));
|
||||
/* buf now contains */
|
||||
/* error:[error code]:[library name]:[function name]:[reason string] */
|
||||
log_err("%s crypto %s", str, buf);
|
||||
}
|
||||
|
||||
#ifdef USE_DSA
|
||||
/**
|
||||
* Setup DSA key digest in DER encoding ...
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <string.h>
|
||||
#include "context.h"
|
||||
#include "util-internal.h"
|
||||
#include "gldns/parseutil.h"
|
||||
|
||||
#include "pubkey-pinning.h"
|
||||
#include "pubkey-pinning-internal.h"
|
||||
|
@ -85,14 +86,13 @@ static const getdns_bindata sha256 = {
|
|||
It is the caller's responsibility to call getdns_dict_destroy when
|
||||
it is no longer needed.
|
||||
*/
|
||||
getdns_dict* getdns_pubkey_pin_create_from_string(
|
||||
getdns_context* context,
|
||||
const char* str)
|
||||
getdns_dict *getdns_pubkey_pin_create_from_string(
|
||||
const getdns_context *context, const char *str)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t buf[SHA256_DIGEST_LENGTH];
|
||||
getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf };
|
||||
getdns_dict* out = NULL;
|
||||
getdns_dict *out = NULL;
|
||||
|
||||
/* we only do sha256 right now, make sure this is well-formed */
|
||||
if (!str || strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH))
|
||||
|
@ -253,7 +253,7 @@ _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list,
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_get_pubkey_pinset_list(getdns_context *ctx,
|
||||
_getdns_get_pubkey_pinset_list(const getdns_context *ctx,
|
||||
const sha256_pin_t *pinset_in,
|
||||
getdns_list **pinset_list)
|
||||
{
|
||||
|
@ -289,5 +289,3 @@ _getdns_get_pubkey_pinset_list(getdns_context *ctx,
|
|||
getdns_list_destroy(out);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* pubkey-pinning.c */
|
||||
|
|
|
@ -34,17 +34,11 @@
|
|||
#ifndef PUBKEY_PINNING_H_
|
||||
#define PUBKEY_PINNING_H_
|
||||
|
||||
/* getdns_pubkey_pin_create_from_string() is implemented in pubkey-pinning.c */
|
||||
#include "getdns/getdns_extra.h"
|
||||
|
||||
#include "tls.h"
|
||||
|
||||
/**
|
||||
** Internal functions, implemented in pubkey-pinning-internal.c.
|
||||
**/
|
||||
getdns_return_t _getdns_decode_base64(const char* str, uint8_t* res, size_t res_size);
|
||||
|
||||
/**
|
||||
** Public interface.
|
||||
**/
|
||||
|
||||
/* create and populate a pinset linked list from a getdns_list pinset */
|
||||
getdns_return_t
|
||||
_getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list,
|
||||
|
@ -54,7 +48,7 @@ _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list,
|
|||
|
||||
/* create a getdns_list version of the pinset */
|
||||
getdns_return_t
|
||||
_getdns_get_pubkey_pinset_list(getdns_context *ctx,
|
||||
_getdns_get_pubkey_pinset_list(const getdns_context *ctx,
|
||||
const sha256_pin_t *pinset_in,
|
||||
getdns_list **pinset_list);
|
||||
|
||||
|
@ -62,7 +56,5 @@ getdns_return_t
|
|||
_getdns_associate_upstream_with_connection(_getdns_tls_connection *conn,
|
||||
getdns_upstream *upstream);
|
||||
|
||||
getdns_dict* getdns_pubkey_pin_create_from_string(getdns_context* context, const char* str);
|
||||
|
||||
#endif
|
||||
/* pubkey-pinning.h */
|
||||
|
|
|
@ -93,7 +93,7 @@ getdns_dict *no_dnssec_checking_disabled_opportunistic
|
|||
= &no_dnssec_checking_disabled_opportunistic_spc;
|
||||
|
||||
static int
|
||||
is_extension_set(getdns_dict *extensions, const char *name, int default_value)
|
||||
is_extension_set(const getdns_dict *extensions, const char *name, int default_value)
|
||||
{
|
||||
getdns_return_t r;
|
||||
uint32_t value;
|
||||
|
@ -168,7 +168,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
int with_opt, int edns_maximum_udp_payload_size,
|
||||
uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
|
||||
uint16_t opt_options_size, size_t noptions, getdns_list *options,
|
||||
size_t wire_data_sz, size_t max_query_sz, getdns_dict *extensions)
|
||||
size_t wire_data_sz, size_t max_query_sz, const getdns_dict *extensions)
|
||||
{
|
||||
uint8_t *buf;
|
||||
getdns_dict *option;
|
||||
|
@ -475,6 +475,9 @@ _getdns_network_req_add_tsig(getdns_network_req *req)
|
|||
void
|
||||
_getdns_network_validate_tsig(getdns_network_req *req)
|
||||
{
|
||||
#if defined(HAVE_NSS) || defined(HAVE_NETTLE)
|
||||
(void)req;
|
||||
#else
|
||||
_getdns_rr_iter rr_spc, *rr;
|
||||
_getdns_rdf_iter rdf_spc, *rdf;
|
||||
const uint8_t *request_mac;
|
||||
|
@ -618,6 +621,7 @@ _getdns_network_validate_tsig(getdns_network_req *req)
|
|||
gldns_write_uint16(req->response, gldns_read_uint16(req->query));
|
||||
gldns_write_uint16(req->response + 10,
|
||||
gldns_read_uint16(req->response + 10) + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -649,9 +653,12 @@ static const uint8_t no_suffixes[] = { 1, 0 };
|
|||
/* create a new dns req to be submitted */
|
||||
getdns_dns_req *
|
||||
_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
uint64_t *now_ms)
|
||||
{
|
||||
int dnssec = is_extension_set(
|
||||
extensions, "dnssec",
|
||||
context->dnssec);
|
||||
int dnssec_return_status = is_extension_set(
|
||||
extensions, "dnssec_return_status",
|
||||
context->dnssec_return_status);
|
||||
|
@ -678,7 +685,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
|| is_extension_set(extensions, "dnssec_roadblock_avoidance",
|
||||
context->dnssec_roadblock_avoidance);
|
||||
#endif
|
||||
int dnssec_extension_set = dnssec_return_status
|
||||
int dnssec_extension_set = dnssec || dnssec_return_status
|
||||
|| dnssec_return_only_secure || dnssec_return_all_statuses
|
||||
|| dnssec_return_validation_chain
|
||||
|| dnssec_return_full_validation_chain
|
||||
|
@ -726,6 +733,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
int opportunistic = 0;
|
||||
|
||||
if (extensions == no_dnssec_checking_disabled_opportunistic) {
|
||||
dnssec = 0;
|
||||
dnssec_return_status = 0;
|
||||
dnssec_return_only_secure = 0;
|
||||
dnssec_return_all_statuses = 0;
|
||||
|
@ -906,6 +914,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->context = context;
|
||||
result->loop = loop;
|
||||
result->trans_id = (uint64_t) (intptr_t) result;
|
||||
result->dnssec = dnssec;
|
||||
result->dnssec_return_status = dnssec_return_status;
|
||||
result->dnssec_return_only_secure = dnssec_return_only_secure;
|
||||
result->dnssec_return_all_statuses = dnssec_return_all_statuses;
|
||||
|
|
|
@ -613,6 +613,11 @@ static _getdns_rdata_def csync_rdata[] = {
|
|||
{ "serial" , GETDNS_RDF_I4 , NULL },
|
||||
{ "flags" , GETDNS_RDF_I2 , NULL },
|
||||
{ "type_bit_maps" , GETDNS_RDF_X , NULL }};
|
||||
static _getdns_rdata_def zonemd_rdata[] = {
|
||||
{ "serial" , GETDNS_RDF_I4 , NULL },
|
||||
{ "digest_type" , GETDNS_RDF_I1 , NULL },
|
||||
{ "reserved" , GETDNS_RDF_I1 , NULL },
|
||||
{ "digest" , GETDNS_RDF_X , NULL }};
|
||||
static _getdns_rdata_def spf_rdata[] = {
|
||||
{ "text" , GETDNS_RDF_S_M , NULL }};
|
||||
static _getdns_rdata_def nid_rdata[] = {
|
||||
|
@ -723,9 +728,9 @@ static _getdns_rr_def _getdns_rr_defs[] = {
|
|||
{ "TALINK", talink_rdata, ALEN( talink_rdata) },
|
||||
{ "CDS", ds_rdata, ALEN( ds_rdata) },
|
||||
{ "CDNSKEY", dnskey_rdata, ALEN( dnskey_rdata) },
|
||||
{ "OPENPGPKEY", openpgpkey_rdata, ALEN(openpgpkey_rdata) }, /* 61 - */
|
||||
{ "CSYNC", csync_rdata, ALEN( csync_rdata) }, /* - 62 */
|
||||
{ NULL, NULL, 0 },
|
||||
{ "OPENPGPKEY", openpgpkey_rdata, ALEN(openpgpkey_rdata) },
|
||||
{ "CSYNC", csync_rdata, ALEN( csync_rdata) },
|
||||
{ "ZONEMD", zonemd_rdata, ALEN( zonemd_rdata) }, /* - 63 */
|
||||
{ NULL, NULL, 0 },
|
||||
{ NULL, NULL, 0 },
|
||||
{ NULL, NULL, 0 },
|
||||
|
|
|
@ -287,8 +287,8 @@ _getdns_cancel_reply(getdns_context *context, connection *conn)
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_reply(
|
||||
getdns_context *context, getdns_dict *reply, getdns_transaction_t request_id)
|
||||
getdns_reply(getdns_context *context,
|
||||
const getdns_dict *reply, getdns_transaction_t request_id)
|
||||
{
|
||||
/* TODO: Check request_id at context->outbound_requests */
|
||||
connection *conn = (connection *)(intptr_t)request_id;
|
||||
|
|
56
src/stub.c
56
src/stub.c
|
@ -822,19 +822,45 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
|||
getdns_context *context = dnsreq->context;
|
||||
if (context->tls_ctx == NULL)
|
||||
return NULL;
|
||||
_getdns_tls_connection* tls = _getdns_tls_connection_new(&context->my_mf, context->tls_ctx, fd);
|
||||
_getdns_tls_connection* tls = _getdns_tls_connection_new(&context->my_mf, context->tls_ctx, fd, &upstream->upstreams->log);
|
||||
if(!tls)
|
||||
return NULL;
|
||||
#if HAVE_TLS_CONN_CURVES_LIST
|
||||
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
|
||||
if (upstream->tls_curves_list)
|
||||
_getdns_tls_connection_set_curves_list(tls, upstream->tls_curves_list);
|
||||
#endif
|
||||
r = _getdns_tls_connection_set_curves_list(tls, upstream->tls_curves_list);
|
||||
if (!r && upstream->tls_ciphersuites)
|
||||
r = _getdns_tls_connection_set_cipher_suites(tls, upstream->tls_ciphersuites);
|
||||
if (!r)
|
||||
r = _getdns_tls_connection_set_min_max_tls_version(tls, upstream->tls_min_version, upstream->tls_max_version);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
if (upstream->tls_fallback_ok)
|
||||
r = _getdns_tls_connection_set_cipher_list(tls, NULL);
|
||||
else if (upstream->tls_cipher_list)
|
||||
r = _getdns_tls_connection_set_cipher_list(tls, upstream->tls_cipher_list);
|
||||
}
|
||||
|
||||
/* make sure we'll be able to find the context again when we need it */
|
||||
if (_getdns_associate_upstream_with_connection(tls, upstream) != GETDNS_RETURN_GOOD) {
|
||||
_getdns_tls_connection_free(&context->my_mf, tls);
|
||||
if (!r)
|
||||
r = _getdns_associate_upstream_with_connection(tls, upstream);
|
||||
|
||||
if (r) {
|
||||
_getdns_tls_connection_free(&upstream->upstreams->mf, tls);
|
||||
upstream->tls_auth_state = r;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (upstream->tls_fallback_ok) {
|
||||
DEBUG_STUB("%s %-35s: WARNING: Using Opportunistic TLS (fallback allowed)!\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
||||
} else {
|
||||
DEBUG_STUB("%s %-35s: Using Strict TLS \n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
||||
}
|
||||
|
||||
/* NOTE: this code will fallback on a given upstream, without trying
|
||||
authentication on other upstreams first. This is non-optimal and but avoids
|
||||
multiple TLS handshakes before getting a usable connection. */
|
||||
|
@ -874,16 +900,6 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
|||
upstream->tls_fallback_ok = 1;
|
||||
}
|
||||
}
|
||||
if (upstream->tls_fallback_ok) {
|
||||
_getdns_tls_connection_set_cipher_list(tls, NULL);
|
||||
DEBUG_STUB("%s %-35s: WARNING: Using Opportunistic TLS (fallback allowed)!\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
||||
} else {
|
||||
if (upstream->tls_cipher_list)
|
||||
_getdns_tls_connection_set_cipher_list(tls, upstream->tls_cipher_list);
|
||||
DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS,
|
||||
__FUNC__);
|
||||
}
|
||||
|
||||
_getdns_tls_connection_set_host_pinset(tls, upstream->tls_auth_name, upstream->tls_pubkey_pinset);
|
||||
|
||||
|
@ -1811,7 +1827,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
|||
if (upstreams->upstreams[i].conn_state == GETDNS_CONN_BACKOFF &&
|
||||
upstreams->upstreams[i].conn_retry_time < now) {
|
||||
upstreams->upstreams[i].conn_state = GETDNS_CONN_CLOSED;
|
||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_NOTICE,
|
||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
|
||||
"%-40s : Upstream : Re-instating %s for this upstream\n",
|
||||
upstreams->upstreams[i].addr_str,
|
||||
upstreams->upstreams[i].transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP");
|
||||
|
@ -2070,9 +2086,9 @@ upstream_find_for_netreq(getdns_network_req *netreq)
|
|||
return fd;
|
||||
}
|
||||
/* Handle better, will give generic error*/
|
||||
DEBUG_STUB("%s %-35s: MSG: %p No valid upstream! \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq);
|
||||
_getdns_context_log(netreq->owner->context, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||
" *FAILURE* no valid transports or upstreams available!\n");
|
||||
_getdns_log(&netreq->owner->context->log
|
||||
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
|
||||
, " *FAILURE* no valid transports or upstreams available!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
10
src/sync.c
10
src/sync.c
|
@ -164,7 +164,7 @@ getdns_sync_cb(getdns_context *context, getdns_callback_type_t callback_type,
|
|||
|
||||
getdns_return_t
|
||||
getdns_general_sync(getdns_context *context, const char *name,
|
||||
uint16_t request_type, getdns_dict *extensions, getdns_dict **response)
|
||||
uint16_t request_type, const getdns_dict *extensions, getdns_dict **response)
|
||||
{
|
||||
getdns_sync_data data;
|
||||
getdns_return_t r;
|
||||
|
@ -190,7 +190,7 @@ getdns_general_sync(getdns_context *context, const char *name,
|
|||
|
||||
getdns_return_t
|
||||
getdns_address_sync(getdns_context *context, const char *name,
|
||||
getdns_dict *extensions, getdns_dict **response)
|
||||
const getdns_dict *extensions, getdns_dict **response)
|
||||
{
|
||||
getdns_sync_data data;
|
||||
getdns_return_t r;
|
||||
|
@ -215,8 +215,8 @@ getdns_address_sync(getdns_context *context, const char *name,
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_hostname_sync(getdns_context *context, getdns_dict *address,
|
||||
getdns_dict *extensions, getdns_dict **response)
|
||||
getdns_hostname_sync(getdns_context *context, const getdns_dict *address,
|
||||
const getdns_dict *extensions, getdns_dict **response)
|
||||
{
|
||||
getdns_sync_data data;
|
||||
getdns_return_t r;
|
||||
|
@ -242,7 +242,7 @@ getdns_hostname_sync(getdns_context *context, getdns_dict *address,
|
|||
|
||||
getdns_return_t
|
||||
getdns_service_sync(getdns_context *context, const char *name,
|
||||
getdns_dict *extensions, getdns_dict **response)
|
||||
const getdns_dict *extensions, getdns_dict **response)
|
||||
{
|
||||
getdns_sync_data data;
|
||||
getdns_return_t r;
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
{
|
||||
/*
|
||||
* name = "localhost" name should be resolved from host file
|
||||
* expect: NOERROR/NODATA response:
|
||||
* expect: NOERROR response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* rcode = 0
|
||||
* ancount = 1 (number of records in ANSWER section)
|
||||
|
@ -192,7 +192,7 @@
|
|||
CONTEXT_CREATE(TRUE);
|
||||
EVENT_BASE_CREATE;
|
||||
|
||||
ASSERT_RC(getdns_address(context, "localhost", NULL,
|
||||
ASSERT_RC(getdns_address(context, "localhost.", NULL,
|
||||
&fn_ref, &transaction_id, callbackfn),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
|
||||
CONTEXT_CREATE(TRUE);
|
||||
|
||||
ASSERT_RC(getdns_address_sync(context, "localhost", NULL, &response),
|
||||
ASSERT_RC(getdns_address_sync(context, "localhost.", NULL, &response),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
|
||||
|
||||
EXTRACT_LOCAL_RESPONSE;
|
||||
|
@ -147,7 +147,7 @@
|
|||
/*
|
||||
* name = "willem.getdnsapi.net" need to replace this with domain from unbound zone
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_DATA
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
@ -162,6 +162,7 @@
|
|||
EXTRACT_RESPONSE;
|
||||
|
||||
assert_noerror(&ex_response);
|
||||
assert_nodata(&ex_response);
|
||||
//assert_soa_in_authority(&ex_response);
|
||||
|
||||
CONTEXT_DESTROY;
|
||||
|
|
|
@ -70,6 +70,7 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
|
|||
* If it is absent, do not try to decompose the replies_tree, because the
|
||||
* answer most likely came not from DNS.
|
||||
*/
|
||||
ex_response->response = response;
|
||||
have_answer_type = getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type) ==
|
||||
GETDNS_RETURN_GOOD;
|
||||
|
||||
|
@ -159,10 +160,15 @@ void extract_local_response(struct getdns_dict *response, struct extracted_respo
|
|||
void assert_noerror(struct extracted_response *ex_response)
|
||||
{
|
||||
uint32_t rcode;
|
||||
uint32_t ancount = 0;
|
||||
|
||||
ASSERT_RC(ex_response->status, GETDNS_RESPSTATUS_GOOD, "Unexpected value for \"status\"");
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->header, "rcode", &rcode), GETDNS_RETURN_GOOD, "Failed to extract \"rcode\"");
|
||||
ck_assert_msg(rcode == 0, "Expected rcode == 0, got %d", rcode);
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"ancount\"");
|
||||
|
||||
ASSERT_RC(ex_response->status, ((ancount > 0) ? GETDNS_RESPSTATUS_GOOD : GETDNS_RESPSTATUS_NO_NAME), "Unexpected value for \"status\"");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,6 +187,8 @@ void assert_nodata(struct extracted_response *ex_response)
|
|||
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length");
|
||||
ck_assert_msg(length == 0, "Expected \"answer\" length == 0, got %d", length);
|
||||
|
||||
ASSERT_RC(ex_response->status, GETDNS_RESPSTATUS_NO_NAME, "Unexpected value for \"status\"");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -233,11 +241,14 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int
|
|||
*/
|
||||
void assert_address_in_just_address_answers(struct extracted_response *ex_response)
|
||||
{
|
||||
size_t length;
|
||||
size_t length = 0;
|
||||
char *resp_str = "";
|
||||
ASSERT_RC(getdns_list_get_length(ex_response->just_address_answers, &length),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length");
|
||||
|
||||
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d", length);
|
||||
|
||||
if (length == 0) resp_str = getdns_pretty_print_dict(ex_response->response);
|
||||
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d\n%s", length, resp_str);
|
||||
if (length == 0) free(resp_str);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
struct extracted_response {
|
||||
uint32_t top_answer_type;
|
||||
struct getdns_dict *response;
|
||||
struct getdns_bindata *top_canonical_name;
|
||||
struct getdns_list *just_address_answers;
|
||||
struct getdns_list *replies_full;
|
||||
|
|
|
@ -264,8 +264,6 @@
|
|||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
|
||||
ASSERT_RC(getdns_context_set_edns_maximum_udp_payload_size(context, 512),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_maximum_udp_payload_size()");
|
||||
ASSERT_RC(getdns_context_set_timeout(context, 2000),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_maximum_udp_payload_size()");
|
||||
ASSERT_RC(getdns_general_sync(context, "large.getdnsapi.net", GETDNS_RRTYPE_TXT, extensions, &response),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()");
|
||||
|
||||
|
@ -292,17 +290,14 @@
|
|||
struct getdns_dict *extensions = getdns_dict_create();
|
||||
|
||||
/*
|
||||
* Not all servers in the path to large.getdnsapi.net seem to support
|
||||
* TCP consistently. Many (root) servers are anycasted which decreases
|
||||
* reliability of TCP availability (as we've seen in practice).
|
||||
* To mitigate we provide our own root server for which we are sure that
|
||||
* it supports TCP. The .net authoritative server are still out of our
|
||||
* control tough. But because they are managed by a single party I
|
||||
* suspect them to be a bit more reliable.
|
||||
* Not all root servers seem to support TCP reliably. To mitigate,
|
||||
* we put our faith in k.root-servers.net.
|
||||
*/
|
||||
struct getdns_list *root_servers = getdns_list_create();
|
||||
struct getdns_list *root_servers2 = getdns_list_create();
|
||||
struct getdns_bindata nlnetlabs_root = { 4, (void *)"\xB9\x31\x8D\x25" };
|
||||
struct getdns_bindata k4_root = { 4, (void *)"\xC1\x00\x0E\x81" };
|
||||
struct getdns_bindata k6_root = { 16, (void *)
|
||||
"\x20\x01\x07\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" };
|
||||
struct getdns_bindata *answer = NULL;
|
||||
|
||||
uint32_t status;
|
||||
|
@ -319,7 +314,9 @@
|
|||
/* Re-do over TCP */
|
||||
ASSERT_RC(getdns_dict_set_int(extensions,"return_call_reporting", GETDNS_EXTENSION_TRUE),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
|
||||
ASSERT_RC(getdns_list_set_bindata(root_servers, 0, &nlnetlabs_root),
|
||||
ASSERT_RC(getdns_list_set_bindata(root_servers, 0, &k6_root),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_list_set_bindata()");
|
||||
ASSERT_RC(getdns_list_set_bindata(root_servers, 1, &k4_root),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_list_set_bindata()");
|
||||
|
||||
ASSERT_RC(getdns_context_set_dns_root_servers(context, root_servers),
|
||||
|
@ -328,8 +325,13 @@
|
|||
GETDNS_RETURN_GOOD, "Return code from getdns_context_get_dns_root_servers()");
|
||||
ASSERT_RC(getdns_list_get_bindata(root_servers2, 0, &answer),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_bindata()");
|
||||
ck_assert_msg(strncmp((char *)answer->data, (char *)nlnetlabs_root.data, 4) == 0,
|
||||
"Expected answer data to be 185.49.141.37");
|
||||
ck_assert_msg(strncmp((char *)answer->data, (char *)k6_root.data, 16) == 0,
|
||||
"Expected answer data to be 2001:7fd::1");
|
||||
ASSERT_RC(getdns_list_get_bindata(root_servers2, 1, &answer),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_bindata()");
|
||||
ck_assert_msg(strncmp((char *)answer->data, (char *)k4_root.data, 4) == 0,
|
||||
"Expected answer data to be 193.0.14.129");
|
||||
|
||||
ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
|
||||
ASSERT_RC(getdns_context_set_edns_maximum_udp_payload_size(context, 512),
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
* name = "google.com"
|
||||
* request_type = 0 (minimum valid RRTYPE)
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
@ -180,7 +180,7 @@
|
|||
* name = "google.com"
|
||||
* request_type = 65279 (maximum unassigned RRTYPE)
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
@ -322,7 +322,7 @@
|
|||
* name = "willem.getdnsapi.net" and unbound zone
|
||||
* request_type = GETDNS_RRTYPE_MX
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
* name = "google.com"
|
||||
* request_type = 0 (minimum valid RRTYPE)
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
@ -155,7 +155,7 @@
|
|||
* name = "google.com"
|
||||
* request_type = 65279 (maximum unassigned RRTYPE)
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
@ -269,7 +269,7 @@
|
|||
* name = "willem.getdnsapi.net" an unbound zone (as in no MX)
|
||||
* request_type = GETDNS_RRTYPE_MX
|
||||
* expect: NOERROR/NODATA response:
|
||||
* status = GETDNS_RESPSTATUS_GOOD
|
||||
* status = GETDNS_RESPSTATUS_NO_NAME
|
||||
* rcode = 0
|
||||
* ancount = 0 (number of records in ANSWER section)
|
||||
*/
|
||||
|
|
|
@ -10,8 +10,8 @@ then
|
|||
else
|
||||
HAVE_SSL_HN_AUTH=0
|
||||
fi
|
||||
SERVER_IP="8.8.8.8"
|
||||
SERVER_IPv6="2001:4860:4860::8888"
|
||||
SERVER_IP="64.6.64.6"
|
||||
SERVER_IPv6="2620:74:1b::1:1"
|
||||
|
||||
SERVER_IP_TSIG="185.49.141.37^"
|
||||
SERVER_IPv6_TSIG="2a04:b900:0:100::37^"
|
||||
|
@ -134,7 +134,7 @@ for (( ii = 0; ii < 1; ii++)); do
|
|||
|
||||
if [[ $HAVE_SSL_HN_AUTH = 1 ]]
|
||||
then
|
||||
NUM_GOOD_QUERIES=9
|
||||
NUM_GOOD_QUERIES=8
|
||||
GOOD_QUERIES=(
|
||||
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
||||
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||
|
@ -143,18 +143,18 @@ for (( ii = 0; ii < 1; ii++)); do
|
|||
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP}" "L" "S"
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||
"-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S")
|
||||
# "-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||
else
|
||||
NUM_GOOD_QUERIES=7
|
||||
NUM_GOOD_QUERIES=6
|
||||
GOOD_QUERIES=(
|
||||
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
||||
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||
"-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S")
|
||||
# "-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||
fi
|
||||
#"-s -A getdnsapi.net -l L -m @${TLS_SERVER_SS_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_SS_KEY}\"" "L" "S"
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
export SRCDIR=`dirname $0`
|
||||
. `dirname $0`/setup-env.sh
|
||||
|
||||
# pass a single test name as the first parameter (without .tpgk extension)
|
||||
ONE_TEST=$1
|
||||
# pass a single test name as the first parameter
|
||||
ONE_TEST=${1%/}
|
||||
ONE_TEST=${ONE_TEST%.tpkg}
|
||||
shift
|
||||
|
||||
"${TPKG}" $* exe ${SRCDIR}/${ONE_TEST}.tpkg
|
||||
|
|
72
src/tls.h
72
src/tls.h
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, NLnet Labs
|
||||
* Copyright (c) 2018-2019, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -57,10 +57,11 @@ void _getdns_tls_init();
|
|||
/**
|
||||
* Create a new TLS context.
|
||||
*
|
||||
* @param mfs point to getdns memory functions.
|
||||
* @param mfs pointer to getdns memory functions.
|
||||
* @paam log pointer to context log config.
|
||||
* @return pointer to new context or NULL on error.
|
||||
*/
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs);
|
||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log);
|
||||
|
||||
/**
|
||||
* Free a TLS context.
|
||||
|
@ -80,15 +81,25 @@ getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_cont
|
|||
void _getdns_tls_context_pinset_init(_getdns_tls_context* ctx);
|
||||
|
||||
/**
|
||||
* Set TLS 1.2 as minimum TLS version.
|
||||
* Set minimum and maximum TLS versions.
|
||||
* If max or min are 0, that boundary is not set.
|
||||
*
|
||||
* @param ctx the context.
|
||||
* @param min the minimum TLS version.
|
||||
* @param max the maximum TLS version.
|
||||
* @return GETDNS_RETURN_GOOD on success.
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER on bad context pointer.
|
||||
* @return GETDNS_RETURN_NOT_IMPLEMENTED if not implemented.
|
||||
* @return GETDNS_RETURN_BAD_CONTEXT on failure.
|
||||
*/
|
||||
getdns_return_t _getdns_tls_context_set_min_proto_1_2(_getdns_tls_context* ctx);
|
||||
getdns_return_t _getdns_tls_context_set_min_max_tls_version(_getdns_tls_context* ctx, getdns_tls_version_t min, getdns_tls_version_t max);
|
||||
|
||||
/**
|
||||
* Get the default context cipher list.
|
||||
*
|
||||
* @return the default context cipher list.
|
||||
*/
|
||||
const char* _getdns_tls_context_get_default_cipher_list();
|
||||
|
||||
/**
|
||||
* Set list of allowed ciphers.
|
||||
|
@ -101,6 +112,24 @@ getdns_return_t _getdns_tls_context_set_min_proto_1_2(_getdns_tls_context* ctx);
|
|||
*/
|
||||
getdns_return_t _getdns_tls_context_set_cipher_list(_getdns_tls_context* ctx, const char* list);
|
||||
|
||||
/**
|
||||
* Get the default context cipher suites.
|
||||
*
|
||||
* @return the default context cipher suites.
|
||||
*/
|
||||
const char* _getdns_tls_context_get_default_cipher_suites();
|
||||
|
||||
/**
|
||||
* Set list of allowed cipher suites.
|
||||
*
|
||||
* @param ctx the context.
|
||||
* @param list the list of cipher suites. NULL for default setting.
|
||||
* @return GETDNS_RETURN_GOOD on success.
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER on bad context pointer.
|
||||
* @return GETDNS_RETURN_BAD_CONTEXT on failure.
|
||||
*/
|
||||
getdns_return_t _getdns_tls_context_set_cipher_suites(_getdns_tls_context* ctx, const char* list);
|
||||
|
||||
/**
|
||||
* Set list of allowed curves.
|
||||
*
|
||||
|
@ -134,9 +163,10 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
|
|||
* @param mfs pointer to getdns memory functions.
|
||||
* @param ctx the context.
|
||||
* @param fd the file descriptor to associate with the connection.
|
||||
* @paam log pointer to connection log config.
|
||||
* @return pointer to new connection or NULL on error.
|
||||
*/
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd);
|
||||
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd, const getdns_log_config* log);
|
||||
|
||||
/**
|
||||
* Free a TLS connection.
|
||||
|
@ -160,6 +190,20 @@ getdns_return_t _getdns_tls_connection_free(struct mem_funcs* mfs, _getdns_tls_c
|
|||
*/
|
||||
getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn);
|
||||
|
||||
/**
|
||||
* Set minimum and maximum TLS versions for this connection.
|
||||
* If max or min are 0, that boundary is not set.
|
||||
*
|
||||
* @param conn the connection.
|
||||
* @param min the minimum TLS version.
|
||||
* @param max the maximum TLS version.
|
||||
* @return GETDNS_RETURN_GOOD on success.
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER on bad context pointer.
|
||||
* @return GETDNS_RETURN_NOT_IMPLEMENTED if not implemented.
|
||||
* @return GETDNS_RETURN_BAD_CONTEXT on failure.
|
||||
*/
|
||||
getdns_return_t _getdns_tls_connection_set_min_max_tls_version(_getdns_tls_connection* conn, getdns_tls_version_t min, getdns_tls_version_t max);
|
||||
|
||||
/**
|
||||
* Set list of allowed ciphers on this connection.
|
||||
*
|
||||
|
@ -171,6 +215,17 @@ getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn);
|
|||
*/
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_list(_getdns_tls_connection* conn, const char* list);
|
||||
|
||||
/**
|
||||
* Set list of allowed cipher suites on this connection.
|
||||
*
|
||||
* @param conn the connection.
|
||||
* @param list the list of cipher suites. NULL for default setting.
|
||||
* @return GETDNS_RETURN_GOOD on success.
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER on bad context pointer.
|
||||
* @return GETDNS_RETURN_BAD_CONTEXT on failure.
|
||||
*/
|
||||
getdns_return_t _getdns_tls_connection_set_cipher_suites(_getdns_tls_connection* conn, const char* list);
|
||||
|
||||
/**
|
||||
* Set list of allowed curves on this connection.
|
||||
*
|
||||
|
@ -407,9 +462,4 @@ void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf);
|
|||
*/
|
||||
void _getdns_tls_cookie_sha256(uint32_t secret, void* addr, size_t addrlen, unsigned char* buf, size_t* buflen);
|
||||
|
||||
/**
|
||||
* Default context cipher list.
|
||||
*/
|
||||
const char* const _getdns_tls_context_default_cipher_list;
|
||||
|
||||
#endif /* _GETDNS_TLS_H */
|
||||
|
|
|
@ -183,6 +183,7 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\ntsig spec: [<algorithm>:]<name>:<secret in Base64>\n");
|
||||
fprintf(out, "\nextensions:\n");
|
||||
fprintf(out, "\t+add_warning_for_bad_dns\n");
|
||||
fprintf(out, "\t+dnssec\n");
|
||||
fprintf(out, "\t+dnssec_return_status\n");
|
||||
fprintf(out, "\t+dnssec_return_only_secure\n");
|
||||
fprintf(out, "\t+dnssec_return_all_statuses\n");
|
||||
|
@ -580,11 +581,15 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
size_t upstream_count = 0;
|
||||
FILE *fh;
|
||||
int int_value;
|
||||
int got_rrtype = 0;
|
||||
int got_calltype = 0;
|
||||
int got_qname = 0;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = argv[i];
|
||||
if ((t = get_rrtype(arg)) >= 0) {
|
||||
request_type = t;
|
||||
got_rrtype = 1;
|
||||
continue;
|
||||
|
||||
} else if (arg[0] == '+') {
|
||||
|
@ -653,6 +658,7 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
continue;
|
||||
|
||||
} else if (arg[0] != '-') {
|
||||
got_qname = 1;
|
||||
name = arg;
|
||||
continue;
|
||||
}
|
||||
|
@ -666,6 +672,7 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
break;
|
||||
case 'A':
|
||||
calltype = ADDRESS;
|
||||
got_calltype = 1;
|
||||
break;
|
||||
case 'b':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
|
@ -739,9 +746,11 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
break;
|
||||
case 'G':
|
||||
calltype = GENERAL;
|
||||
got_calltype = 1;
|
||||
break;
|
||||
case 'H':
|
||||
calltype = HOSTNAME;
|
||||
got_calltype = 1;
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(stdout, argv[0]);
|
||||
|
@ -870,6 +879,7 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
break;
|
||||
case 'S':
|
||||
calltype = SERVICE;
|
||||
got_calltype = 1;
|
||||
break;
|
||||
case 't':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
|
@ -1093,6 +1103,9 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
}
|
||||
next: ;
|
||||
}
|
||||
if (!got_calltype && !got_rrtype && got_qname) {
|
||||
calltype = ADDRESS;
|
||||
}
|
||||
if (r)
|
||||
return r;
|
||||
if (pubkey_pinset && upstream_count) {
|
||||
|
|
|
@ -299,6 +299,7 @@ typedef struct getdns_dns_req {
|
|||
unsigned suffix_appended : 1;
|
||||
|
||||
/* request extensions */
|
||||
unsigned dnssec : 1;
|
||||
unsigned dnssec_return_status : 1;
|
||||
unsigned dnssec_return_only_secure : 1;
|
||||
unsigned dnssec_return_all_statuses : 1;
|
||||
|
@ -431,7 +432,8 @@ extern getdns_dict *no_dnssec_checking_disabled_opportunistic;
|
|||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions, uint64_t *now_ms);
|
||||
const char *name, uint16_t request_type, const getdns_dict *extensions,
|
||||
uint64_t *now_ms);
|
||||
|
||||
void _getdns_dns_req_free(getdns_dns_req * req);
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@
|
|||
|
||||
|
||||
getdns_return_t
|
||||
getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result)
|
||||
getdns_dict_util_get_string(const getdns_dict *dict,
|
||||
const char *name, char **result)
|
||||
{
|
||||
struct getdns_bindata *bindata = NULL;
|
||||
if (!result) {
|
||||
|
@ -710,7 +711,7 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
|
|||
else goto error;
|
||||
|
||||
/* other stuff
|
||||
* Note that spec doesn't explicitely mention these.
|
||||
* Note that spec doesn't explicitly mention these.
|
||||
* They are only showcased in the response dict example */
|
||||
if (getdns_dict_set_int(result, "answer_type", GETDNS_NAMETYPE_DNS))
|
||||
goto error;
|
||||
|
@ -1119,9 +1120,11 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
int rrsigs_in_answer = 0;
|
||||
getdns_dict *reply;
|
||||
getdns_bindata *canonical_name = NULL;
|
||||
int nreplies = 0, nanswers = 0, nsecure = 0, ninsecure = 0, nbogus = 0;
|
||||
int nreplies = 0, nanswers = 0;
|
||||
int nsecure = 0, ninsecure = 0, nindeterminate = 0, nbogus = 0;
|
||||
getdns_dict *netreq_debug;
|
||||
_srvs srvs = { 0, 0, NULL };
|
||||
_getdns_rrset_spc answer_spc;
|
||||
|
||||
/* info (bools) about dns_req */
|
||||
int dnssec_return_status;
|
||||
|
@ -1133,7 +1136,8 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
if (!(result = getdns_dict_create_with_context(context)))
|
||||
return NULL;
|
||||
|
||||
dnssec_return_status = completed_request->dnssec_return_status ||
|
||||
dnssec_return_status = completed_request->dnssec ||
|
||||
completed_request->dnssec_return_status ||
|
||||
completed_request->dnssec_return_only_secure ||
|
||||
completed_request->dnssec_return_all_statuses
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
|
@ -1192,16 +1196,18 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
_getdns_network_validate_tsig(netreq);
|
||||
|
||||
nreplies++;
|
||||
if (netreq->dnssec_status == GETDNS_DNSSEC_SECURE)
|
||||
nsecure++;
|
||||
else if (netreq->dnssec_status != GETDNS_DNSSEC_BOGUS)
|
||||
ninsecure++;
|
||||
|
||||
if (dnssec_return_status &&
|
||||
netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||
nbogus++;
|
||||
|
||||
|
||||
switch (netreq->dnssec_status) {
|
||||
case GETDNS_DNSSEC_SECURE : nsecure++;
|
||||
break;
|
||||
case GETDNS_DNSSEC_INSECURE : ninsecure++;
|
||||
break;
|
||||
case GETDNS_DNSSEC_INDETERMINATE: nindeterminate++;
|
||||
ninsecure++;
|
||||
break;
|
||||
case GETDNS_DNSSEC_BOGUS : if (dnssec_return_status)
|
||||
nbogus++;
|
||||
break;
|
||||
}
|
||||
if (! completed_request->dnssec_return_all_statuses &&
|
||||
! completed_request->dnssec_return_validation_chain) {
|
||||
if (dnssec_return_status &&
|
||||
|
@ -1210,6 +1216,9 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
else if (completed_request->dnssec_return_only_secure
|
||||
&& netreq->dnssec_status != GETDNS_DNSSEC_SECURE)
|
||||
continue;
|
||||
else if (completed_request->dnssec &&
|
||||
netreq->dnssec_status == GETDNS_DNSSEC_INDETERMINATE)
|
||||
continue;
|
||||
else if (netreq->tsig_status == GETDNS_DNSSEC_BOGUS)
|
||||
continue;
|
||||
}
|
||||
|
@ -1227,8 +1236,8 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
/* TODO: Check instead if canonical_name for request_type
|
||||
* is in the answer section.
|
||||
*/
|
||||
if (GLDNS_RCODE_NOERROR ==
|
||||
GLDNS_RCODE_WIRE(netreq->response))
|
||||
if (_getdns_rrset_answer(&answer_spc, netreq->response
|
||||
, netreq->response_len))
|
||||
nanswers++;
|
||||
|
||||
if (dnssec_return_status ||
|
||||
|
@ -1287,9 +1296,14 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
if (getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
|
||||
completed_request->request_timed_out ||
|
||||
nreplies == 0 ? GETDNS_RESPSTATUS_ALL_TIMEOUT :
|
||||
completed_request->dnssec_return_only_secure && nsecure == 0 && ninsecure > 0
|
||||
( completed_request->dnssec
|
||||
&& nsecure == 0 && nindeterminate ) > 0
|
||||
? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
|
||||
completed_request->dnssec_return_only_secure && nsecure == 0 && nbogus > 0
|
||||
( completed_request->dnssec_return_only_secure
|
||||
&& nsecure == 0 && ninsecure ) > 0
|
||||
? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
|
||||
( completed_request->dnssec_return_only_secure
|
||||
|| completed_request->dnssec ) && nsecure == 0 && nbogus > 0
|
||||
? GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS :
|
||||
nanswers == 0 ? GETDNS_RESPSTATUS_NO_NAME
|
||||
: GETDNS_RESPSTATUS_GOOD))
|
||||
|
@ -1442,7 +1456,7 @@ _getdns_validate_dname(const char* dname) {
|
|||
} /* _getdns_validate_dname */
|
||||
|
||||
|
||||
static void _getdns_reply2wire_buf(gldns_buffer *buf, getdns_dict *reply)
|
||||
static void _getdns_reply2wire_buf(gldns_buffer *buf, const getdns_dict *reply)
|
||||
{
|
||||
getdns_dict *rr_dict, *q_dict, *h_dict;
|
||||
getdns_list *section;
|
||||
|
@ -1498,7 +1512,7 @@ static void _getdns_reply2wire_buf(gldns_buffer *buf, getdns_dict *reply)
|
|||
}
|
||||
}
|
||||
|
||||
static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l)
|
||||
static void _getdns_list2wire_buf(gldns_buffer *buf, const getdns_list *l)
|
||||
{
|
||||
getdns_dict *rr_dict;
|
||||
size_t i, pkt_start;
|
||||
|
@ -1536,8 +1550,8 @@ static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l)
|
|||
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
|
||||
}
|
||||
|
||||
uint8_t *_getdns_list2wire(
|
||||
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf)
|
||||
uint8_t *_getdns_list2wire(const getdns_list *l,
|
||||
uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
|
||||
{
|
||||
gldns_buffer gbuf;
|
||||
size_t sz;
|
||||
|
@ -1557,8 +1571,8 @@ uint8_t *_getdns_list2wire(
|
|||
return buf;
|
||||
}
|
||||
|
||||
uint8_t *_getdns_reply2wire(
|
||||
getdns_dict *r, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf)
|
||||
uint8_t *_getdns_reply2wire(const getdns_dict *r,
|
||||
uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
|
||||
{
|
||||
gldns_buffer gbuf;
|
||||
size_t sz;
|
||||
|
@ -1578,7 +1592,7 @@ uint8_t *_getdns_reply2wire(
|
|||
return buf;
|
||||
}
|
||||
|
||||
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l)
|
||||
void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l)
|
||||
{
|
||||
_getdns_rr_iter rr_spc, *rr;
|
||||
getdns_dict *rr_dict;
|
||||
|
|
|
@ -147,17 +147,18 @@ _getdns_rr_iter2rr_dict_canonical(
|
|||
struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl);
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct getdns_dict *_getdns_create_getdns_response(struct getdns_dns_req *completed_request);
|
||||
struct getdns_dict *_getdns_create_getdns_response(
|
||||
struct getdns_dns_req *completed_request);
|
||||
|
||||
getdns_return_t _getdns_validate_dname(const char* dname);
|
||||
|
||||
uint8_t *_getdns_list2wire(
|
||||
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf);
|
||||
uint8_t *_getdns_list2wire(const getdns_list *l,
|
||||
uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf);
|
||||
|
||||
uint8_t *_getdns_reply2wire(
|
||||
getdns_dict *r, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf);
|
||||
uint8_t *_getdns_reply2wire(const getdns_dict *r,
|
||||
uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf);
|
||||
|
||||
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l);
|
||||
void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,7 +143,7 @@ int rbtree_find_less_equal(rbtree_type *rbtree, const void *key,
|
|||
* @param rbtree: tree
|
||||
* @return: smallest element or NULL if tree empty.
|
||||
*/
|
||||
rbnode_type *rbtree_first(rbtree_type *rbtree);
|
||||
rbnode_type *rbtree_first(const rbtree_type *rbtree);
|
||||
|
||||
/**
|
||||
* Returns last (largest) node in the tree
|
||||
|
|
|
@ -546,7 +546,7 @@ rbtree_find_less_equal(rbtree_type *rbtree, const void *key,
|
|||
*
|
||||
*/
|
||||
rbnode_type *
|
||||
rbtree_first (rbtree_type *rbtree)
|
||||
rbtree_first (const rbtree_type *rbtree)
|
||||
{
|
||||
rbnode_type *node;
|
||||
|
||||
|
|
Loading…
Reference in New Issue