From 540735a956e169eb025be435dbfd6a62d6c403f8 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 4 Jan 2018 15:58:09 +0100 Subject: [PATCH 001/303] Check pins with DANE functions when available --- configure.ac | 2 +- src/context.c | 5 +++ src/stub.c | 102 ++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 97 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 9bc7f66a..f18d6c88 100644 --- a/configure.ac +++ b/configure.ac @@ -408,7 +408,7 @@ fi AC_CHECK_HEADERS([openssl/conf.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]) +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]) AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ AC_INCLUDES_DEFAULT #ifdef HAVE_OPENSSL_ERR_H diff --git a/src/context.c b/src/context.c index c8f14363..9f3d19ef 100644 --- a/src/context.c +++ b/src/context.c @@ -3622,6 +3622,11 @@ _getdns_context_prepare_for_resolution(getdns_context *context) if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) return GETDNS_RETURN_BAD_CONTEXT; } +# ifdef HAVE_SSL_CTX_DANE_ENABLE + int osr = SSL_CTX_dane_enable(context->tls_ctx); + DEBUG_STUB("%s %-35s: DEBUG: SSL_CTX_dane_enable() -> %d\n" + , STUB_DEBUG_SETUP_TLS, __FUNC__, osr); +# endif #else /* HAVE_TLS_v1_2 */ if (tls_only_is_in_transports_list(context) == 1) return GETDNS_RETURN_BAD_CONTEXT; diff --git a/src/stub.c b/src/stub.c index 07f22fcd..9e783035 100644 --- a/src/stub.c +++ b/src/stub.c @@ -827,7 +827,16 @@ tls_requested(getdns_network_req *netreq) 1 : 0; } -int + +#ifdef HAVE_SSL_DANE_ENABLE + +static int +_getdns_tls_verify_always_ok(int preverify_ok, X509_STORE_CTX *ctx) +{ (void)preverify_ok; (void)ctx; return 1; } + +#else + +static int tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { getdns_upstream *upstream; @@ -837,11 +846,11 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) return 0; int err = X509_STORE_CTX_get_error(ctx); -#if defined(STUB_DEBUG) && STUB_DEBUG +# if defined(STUB_DEBUG) && STUB_DEBUG DEBUG_STUB("%s %-35s: FD: %d Verify result: (%d) \"%s\"\n", STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err, X509_verify_cert_error_string(err)); -#endif +# endif if (!preverify_ok && !upstream->tls_fallback_ok) _getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR, "%-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n", @@ -849,14 +858,14 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) X509_verify_cert_error_string(err)); /* First deal with the hostname authentication done by OpenSSL. */ -#ifdef X509_V_ERR_HOSTNAME_MISMATCH -# if defined(STUB_DEBUG) && STUB_DEBUG +# ifdef X509_V_ERR_HOSTNAME_MISMATCH +# if defined(STUB_DEBUG) && STUB_DEBUG /*Report if error is hostname mismatch*/ if (err == X509_V_ERR_HOSTNAME_MISMATCH && upstream->tls_fallback_ok) DEBUG_STUB("%s %-35s: FD: %d WARNING: Proceeding even though hostname validation failed!\n", STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd); -# endif -#else +# endif +# else /* if we weren't built against OpenSSL with hostname matching we * could not have matched the hostname, so this would be an automatic * tls_auth_fail if there is a hostname provided*/ @@ -864,7 +873,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) upstream->tls_auth_state = GETDNS_AUTH_FAILED; preverify_ok = 0; } -#endif +# endif /* Now deal with the pinset validation*/ if (upstream->tls_pubkey_pinset) @@ -910,6 +919,8 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) return (upstream->tls_fallback_ok) ? 1 : preverify_ok; } +#endif /* HAVE_SSL_DANE_ENABLE */ + static SSL* tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream) { @@ -992,7 +1003,30 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream) DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS, __FUNC__); } +#ifdef HAVE_SSL_DANE_ENABLE + int osr = SSL_dane_enable(ssl, *upstream->tls_auth_name ? upstream->tls_auth_name : NULL); + DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_enable(\"%s\") -> %d\n" + , STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->tls_auth_name, osr); + SSL_set_verify(ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok); + sha256_pin_t *pin_p; + size_t n_pins = 0; + for (pin_p = upstream->tls_pubkey_pinset; pin_p; pin_p = pin_p->next) { + osr = SSL_dane_tlsa_add(ssl, 2, 1, 1, + (unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH); + DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_tlsa_add() -> %d\n" + , STUB_DEBUG_SETUP_TLS, __FUNC__, osr); + if (osr > 0) + ++n_pins; + osr = SSL_dane_tlsa_add(ssl, 3, 1, 1, + (unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH); + DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_tlsa_add() -> %d\n" + , STUB_DEBUG_SETUP_TLS, __FUNC__, osr); + if (osr > 0) + ++n_pins; + } +#else SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_callback); +#endif SSL_set_connect_state(ssl); (void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); @@ -1048,16 +1082,62 @@ tls_do_handshake(getdns_upstream *upstream) return STUB_SETUP_ERROR; } } - upstream->tls_hs_state = GETDNS_HS_DONE; - upstream->conn_state = GETDNS_CONN_OPEN; - upstream->conn_completed++; /* A re-used session is not verified so need to fix up state in that case */ if (SSL_session_reused(upstream->tls_obj)) upstream->tls_auth_state = upstream->last_tls_auth_state; + + else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) { + X509 *peer_cert = SSL_get_peer_certificate(upstream->tls_obj); + long verify_result = SSL_get_verify_result(upstream->tls_obj); + + upstream->tls_auth_state = peer_cert && verify_result == X509_V_OK + ? GETDNS_AUTH_OK : GETDNS_AUTH_FAILED; + X509_free(peer_cert); + + if (!peer_cert) + _getdns_upstream_log(upstream, + GETDNS_LOG_UPSTREAM_STATS, + ( upstream->tls_fallback_ok + ? GETDNS_LOG_INFO : GETDNS_LOG_ERR), + "%-40s : Verify failed : Transport=TLS - %s - " + "Remote did not offer certificate\n", + upstream->addr_str, + ( upstream->tls_fallback_ok + ? "Allowed because of Opportunistic profile" + : "*Failure*" )); + + else if (verify_result != X509_V_OK) + _getdns_upstream_log(upstream, + GETDNS_LOG_UPSTREAM_STATS, + ( upstream->tls_fallback_ok + ? GETDNS_LOG_INFO : GETDNS_LOG_ERR), + "%-40s : Verify failed : Transport=TLS - %s - " + "(%d) \"%s\"\n", upstream->addr_str, + ( upstream->tls_fallback_ok + ? "Allowed because of Opportunistic profile" + : "*Failure*" ), verify_result, + X509_verify_cert_error_string(verify_result)); + else + _getdns_upstream_log(upstream, + GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, + "%-40s : Verify passed : Transport=TLS - %s - " + "(%d) \"%s\"\n", upstream->addr_str, + ( upstream->tls_fallback_ok + ? "Allowed because of Opportunistic profile" + : "*Failure*" ), verify_result, + X509_verify_cert_error_string(verify_result)); + + if (upstream->tls_auth_state == GETDNS_AUTH_FAILED + && !upstream->tls_fallback_ok) + return STUB_SETUP_ERROR; + } DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %s. Session is %s.\n", STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, _getdns_auth_str(upstream->tls_auth_state), SSL_session_reused(upstream->tls_obj) ?"re-used":"new"); + upstream->tls_hs_state = GETDNS_HS_DONE; + upstream->conn_state = GETDNS_CONN_OPEN; + upstream->conn_completed++; if (upstream->tls_session != NULL) SSL_SESSION_free(upstream->tls_session); upstream->tls_session = SSL_get1_session(upstream->tls_obj); From 2471f43dead872fa4ae8eb2194720286d9d3c7aa Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 4 Jan 2018 16:15:50 +0100 Subject: [PATCH 002/303] Less logging with successful authenticated upstreams --- src/stub.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/stub.c b/src/stub.c index 9e783035..cb773190 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1120,12 +1120,8 @@ tls_do_handshake(getdns_upstream *upstream) else _getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, - "%-40s : Verify passed : Transport=TLS - %s - " - "(%d) \"%s\"\n", upstream->addr_str, - ( upstream->tls_fallback_ok - ? "Allowed because of Opportunistic profile" - : "*Failure*" ), verify_result, - X509_verify_cert_error_string(verify_result)); + "%-40s : Verify passed : Transport=TLS\n", + upstream->addr_str); if (upstream->tls_auth_state == GETDNS_AUTH_FAILED && !upstream->tls_fallback_ok) From 608189710ca9d5e81d68b15363811fc142e48eaa Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 4 Jan 2018 16:35:22 +0100 Subject: [PATCH 003/303] Log printing in getdns_query --- src/tools/getdns_query.c | 159 ++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 96 deletions(-) diff --git a/src/tools/getdns_query.c b/src/tools/getdns_query.c index 713783fc..e963fc35 100644 --- a/src/tools/getdns_query.c +++ b/src/tools/getdns_query.c @@ -57,19 +57,7 @@ getdns_return_t getdns_yaml2dict(const char *, getdns_dict **dict); #define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\"" static int verbosity = 0; -static int i_am_stubby = 0; -static const char *default_stubby_config = -"{ resolution_type: GETDNS_RESOLUTION_STUB" -", dns_transport_list: [ GETDNS_TRANSPORT_TLS, GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP ]" -", idle_timeout: 10000" -", listen_addresses: [ 127.0.0.1@53, 0::1@53 ]" -", tls_query_padding_blocksize: 1" -", edns_client_subnet_private : 1" -"}"; static int clear_listen_list_on_arg = 0; -#ifndef GETDNS_ON_WINDOWS -static int run_in_foreground = 1; -#endif static int quiet = 0; static int batch_mode = 0; static char *query_file = NULL; @@ -95,6 +83,8 @@ static int check_dnssec = 0; static char *resolvconf = NULL; #endif static int print_api_info = 0, print_trust_anchors = 0; +static int log_level = 0; +static uint64_t log_systems = 0xFFFFFFFFFFFFFFFF; static int get_rrtype(const char *t) { @@ -179,19 +169,14 @@ print_usage(FILE *out, const char *progname) { fprintf(out, "usage: %s [