From dkg at fifthhorseman.net Fri Dec 18 15:00:17 2015 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 18 Dec 2015 10:00:17 -0500 Subject: [getdns-users] [PATCH] define _DEFAULT_SOURCE as well as _BSD_SOURCE for glibc version 2.20 and up Message-ID: <1450450817-8942-1-git-send-email-dkg@fifthhorseman.net> in recent versions of feature_test_macros(7), it says of _BSD_SOURCE: Since glibc 2.20, this macro is deprecated. It now has the same effect as defining _DEFAULT_SOURCE, but generates a compile-time warning (unless _DEFAULT_SOURCE is also defined). Use _DEFAULT_SOURCE instead. To allow code that requires _BSD_SOURCE in glibc 2.19 and earlier and _DEFAULT_SOURCE in glibc 2.20 and later to compile without warnings, define both _BSD_SOURCE and _DEFAULT_SOURCE. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5e6d663..fe086ba 100644 --- a/configure.ac +++ b/configure.ac @@ -98,7 +98,7 @@ AX_CHECK_COMPILE_FLAG([-xc99],[CFLAGS="$CFLAGS -xc99"],[],[]) AX_CHECK_COMPILE_FLAG([-Wall],[CFLAGS="$CFLAGS -Wall"],[],[]) case "$host_os" in - linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE" + linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE" ;; solaris* ) CFLAGS="$CFLAGS -D__EXTENSIONS__" # for strdup() from ;; -- 2.6.4 From dkg at fifthhorseman.net Tue Dec 22 06:03:03 2015 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Tue, 22 Dec 2015 01:03:03 -0500 Subject: [getdns-users] public key pinning and tls_authentication models Message-ID: <87mvt3rpew.fsf@alice.fifthhorseman.net> hi all-- I just submitted: https://github.com/getdnsapi/getdns/pull/130 This allows the user to require that the certificate offered by the TLS-enabled DNS server use an X.509 certificate with a public key that matches one of a list of pins. It's a large-ish changeset overall, but I've tried to order the patches in a series so that they're easy to read sequentially with clear steps from one to the next. As i wrote in the github pull request: ----------- Configuration is done per-upstream, with an additional member of the upstream object, tls_pubkey_pinset (by analogy with tls_auth_name). this is a list of dicts, each of which describes a public key pin, which looks like this: { "address_data": , "address_type": , "tls_port": 853, "tls_pubkey_pinset": [ { "digest": , "value": }, { "digest": , "value": } ] } The series includes a new argument for getdns_query -K to specify pins. All pins are applied to all upstreams. For example: getdns_query -K 'pin-sha256="foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9S="' -l L -m '@185.49.141.38~getdnsapi.net' google.com ------------- There are still a couple missing pieces, though. In particular, the interaction between getdns_context_get_tls_authentication() and the dicts that comprise the list of upstreams seems complicated and confusing. We could make it so that your authentication choices are limited to either NONE or HOSTNAME or PUBKEY_PINSET, but what do we do if the user specifies a tls_auth_name combined with a PUBKEY_PINSET ? it seems like we're giving users extra ways to create internally-incompatible configurations, and the API has a hard enough time already with nuanced error reporting. At the same time, i realize that it might be useful for some users to be able to suggest a hostname or a public key pinset opportunistically, just to see what would happen without getting in the way of functionality. One way to do this is to drop getdns_context_get_tls_authentication() entirely. I'm calling this the "upstream-dict" model of tls authentication: * an upstream configured with tls_auth_name will do hostname verification checking; * an upstream configured with tls_pubkey_pinset will do public key pinset matching; * and an upstream configured without either of these will not be able to do strict TLS. A user who wants to do opportunistic "verification" can specify a non-TLS transport, which will enable all of these strict modes to become advisory-only. I think this is the simplest model we can offer that is internally consistent, and i think it's less confusing to the user than requiring them to set an explicit tls_authentication mode on the context object that happens to match the values in each upstream dict. There is some question about whether there is a legitimate use case for wanting to do "only TLS", but in an opportunistic mode -- that is, without fallback to a cleartext transport. I'll call this "blinded-tls". The proposed tls-authentication-in-the-upstream-dict model doesn't support blinded-tls explicitly. if we decide we do want to support blinded-tls, we could add a function getdns_context_allow_opportunistic_tls() that makes this explicitly possible. This is semantically equivalent to having two possible values for getdns_tls_authentication_t : OPPORTUNISTIC and STRICT, which we could map to the current values of NONE and HOSTNAME and hope we get away with a dirty tweak of the library's API :) By default, a context would report STRICT if it has only TLS transports, and OPPORTUNISTIC if it has non-TLS transports. If the context has only TLS transports, and the user sets OPPORTUNISTIC, that would be "blinded-tls". I'm not sure what we should do if the user sets STRICT but has non-TLS transports available, though. Perhaps that would be an error in the configuration? Again, it seems better to me to field an API that has fewer ways that a user can get themselves into an unusable state, which is why i'm leaning toward the pure "upstream-dict" model. What do folks think about this? What are the advantages of retaining the current getdns_context_{set,get}_tls_authentication() approach (other than API stability)? --dkg PS fwiw, no package in the debian archive is currently using g_c_{s,g}et_tls_authentication -- this is the kind of API change that we could probably drop without a lot of pain if we wanted to: https://codesearch.debian.net/results/getdns_context_%5Bsg%5Det_tls_authentication/page_0 From willem at nlnetlabs.nl Tue Dec 22 09:25:21 2015 From: willem at nlnetlabs.nl (Willem Toorop) Date: Tue, 22 Dec 2015 10:25:21 +0100 Subject: [getdns-users] public key pinning and tls_authentication models In-Reply-To: <87mvt3rpew.fsf@alice.fifthhorseman.net> References: <87mvt3rpew.fsf@alice.fifthhorseman.net> Message-ID: <56791701.40501@nlnetlabs.nl> Hey! Fantastic work. Thank you! Sara, could you review too? I believe we introduced getdns_context_get_tls_authentication() as a quick way to allow for opportunistic TLS. So renaming the define GETDNS_AUTHENTICATION_NONE into OPPORTUNISTIC and HOSTNAME in STRICT would be in line with its original intent I think. Indicating what credentials (hostname or pubkey hashes) to use for authentication makes complete sense to me too. Question: If you specify a pinset in an upstream with STRICT authentication, would your cert still need to be authenticated against the CA store? Cheers, -- Willem Op 22-12-15 om 07:03 schreef Daniel Kahn Gillmor: > hi all-- > > I just submitted: > > https://github.com/getdnsapi/getdns/pull/130 > > This allows the user to require that the certificate offered by the > TLS-enabled DNS server use an X.509 certificate with a public key that > matches one of a list of pins. > > It's a large-ish changeset overall, but I've tried to order the patches > in a series so that they're easy to read sequentially with clear steps > from one to the next. > > As i wrote in the github pull request: > > > ----------- > > Configuration is done per-upstream, with an additional member of the > upstream object, tls_pubkey_pinset (by analogy with tls_auth_name). > > this is a list of dicts, each of which describes a public key pin, which > looks like this: > > { > "address_data": , > "address_type": , > "tls_port": 853, > "tls_pubkey_pinset": > [ > { > "digest": , > "value": > }, > { > "digest": , > "value": > } > ] > } > > The series includes a new argument for getdns_query -K to specify > pins. All pins are applied to all upstreams. For example: > > getdns_query -K 'pin-sha256="foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9S="' -l L -m '@185.49.141.38~getdnsapi.net' google.com > > ------------- > > There are still a couple missing pieces, though. In particular, the > interaction between getdns_context_get_tls_authentication() and the > dicts that comprise the list of upstreams seems complicated and > confusing. > > We could make it so that your authentication choices are limited to > either NONE or HOSTNAME or PUBKEY_PINSET, but what do we do if the user > specifies a tls_auth_name combined with a PUBKEY_PINSET ? it seems like > we're giving users extra ways to create internally-incompatible > configurations, and the API has a hard enough time already with nuanced > error reporting. > > At the same time, i realize that it might be useful for some users to be > able to suggest a hostname or a public key pinset opportunistically, > just to see what would happen without getting in the way of > functionality. > > One way to do this is to drop getdns_context_get_tls_authentication() > entirely. I'm calling this the "upstream-dict" model of tls > authentication: > > * an upstream configured with tls_auth_name will do hostname > verification checking; > > * an upstream configured with tls_pubkey_pinset will do public key > pinset matching; > > * and an upstream configured without either of these will not be able > to do strict TLS. > > A user who wants to do opportunistic "verification" can specify a > non-TLS transport, which will enable all of these strict modes to become > advisory-only. > > I think this is the simplest model we can offer that is internally > consistent, and i think it's less confusing to the user than requiring > them to set an explicit tls_authentication mode on the context object > that happens to match the values in each upstream dict. > > There is some question about whether there is a legitimate use case for > wanting to do "only TLS", but in an opportunistic mode -- that is, > without fallback to a cleartext transport. I'll call this "blinded-tls". > The proposed tls-authentication-in-the-upstream-dict model doesn't > support blinded-tls explicitly. > > if we decide we do want to support blinded-tls, we could add a function > getdns_context_allow_opportunistic_tls() that makes this explicitly > possible. This is semantically equivalent to having two possible values > for getdns_tls_authentication_t : OPPORTUNISTIC and STRICT, which we > could map to the current values of NONE and HOSTNAME and hope we get > away with a dirty tweak of the library's API :) > > By default, a context would report STRICT if it has only TLS transports, > and OPPORTUNISTIC if it has non-TLS transports. If the context has only > TLS transports, and the user sets OPPORTUNISTIC, that would be > "blinded-tls". I'm not sure what we should do if the user sets STRICT > but has non-TLS transports available, though. Perhaps that would be an > error in the configuration? > > Again, it seems better to me to field an API that has fewer ways that a > user can get themselves into an unusable state, which is why i'm leaning > toward the pure "upstream-dict" model. > > What do folks think about this? What are the advantages of retaining > the current getdns_context_{set,get}_tls_authentication() approach > (other than API stability)? > > --dkg > > PS fwiw, no package in the debian archive is currently using > g_c_{s,g}et_tls_authentication -- this is the kind of API change that > we could probably drop without a lot of pain if we wanted to: > > https://codesearch.debian.net/results/getdns_context_%5Bsg%5Det_tls_authentication/page_0 > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users > From dkg at fifthhorseman.net Tue Dec 22 14:23:55 2015 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Tue, 22 Dec 2015 09:23:55 -0500 Subject: [getdns-users] public key pinning and tls_authentication models In-Reply-To: <56791701.40501@nlnetlabs.nl> References: <87mvt3rpew.fsf@alice.fifthhorseman.net> <56791701.40501@nlnetlabs.nl> Message-ID: <87wps6imtg.fsf@alice.fifthhorseman.net> On Tue 2015-12-22 04:25:21 -0500, Willem Toorop wrote: > I believe we introduced getdns_context_get_tls_authentication() as a > quick way to allow for opportunistic TLS. So renaming the define > GETDNS_AUTHENTICATION_NONE into OPPORTUNISTIC and HOSTNAME in STRICT > would be in line with its original intent I think. Indicating what > credentials (hostname or pubkey hashes) to use for authentication makes > complete sense to me too. great, that only leaves the question of what we should do with a configuration that asks for STRICT but allows fallback to non-TLS -- we could either ignore the non-TLS upstreams, or fail the request entirely to indicate that they're not getting what they asked for. > Question: If you specify a pinset in an upstream with STRICT > authentication, would your cert still need to be authenticated against > the CA store? At the moment, yes, the code says that if you've specified HOSTNAME then you need to have a hostname :) I didn't want to change those semantics without making sure people were OK with that. I can work on an additional patch that makes this change, if it seems plausible. --dkg From dkg at fifthhorseman.net Tue Dec 22 22:08:55 2015 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Tue, 22 Dec 2015 17:08:55 -0500 Subject: [getdns-users] public key pinning and tls_authentication models In-Reply-To: <87mvt3rpew.fsf@alice.fifthhorseman.net> References: <87mvt3rpew.fsf@alice.fifthhorseman.net> Message-ID: <87io3qnnk8.fsf@alice.fifthhorseman.net> On Tue 2015-12-22 01:03:03 -0500, Daniel Kahn Gillmor wrote: > There are still a couple missing pieces, though. In particular, the > interaction between getdns_context_get_tls_authentication() and the > dicts that comprise the list of upstreams seems complicated and > confusing. After some discussion with Sara, I've just pushed 3 more patches to the feature/pubkey-pinning branch as a way to address this concern without making any particularly dirty API changes. What i've done is i've renamed GETDNS_TLS_AUTHENTICATION_HOSTNAME to GETDNS_TLS_AUTHENTICATION_REQUIRED. The semantics are the same as before, but now the authentication will be based on either member of the upstream dict: tls_auth_name or tls_pubkey_pinset (or both, if both are present). GETDNS_TLS_AUTHENTICATION_HOSTNAME is retained as an alias to GETDNS_TLS_AUTHENTICATION_REQUIRED so that we don't break the API here, and these changes now make it possible to do a strongly-authenticated query using only a pinset. Additionally, Sara and i had a really fruitful discussion about what we would do if we were willing to make backward-incompatible API changes to how we handle DNS privacy to align with the Yokohama discussion (with an SONAME bump, of course); i'll start a new feature/privacy-api-overhaul branch based on top of feature/pubkey-pinning to document that thinking, so that it's available for consideration whenever an SONAME bump is acceptable. --dkg From willem at nlnetlabs.nl Thu Dec 24 17:07:58 2015 From: willem at nlnetlabs.nl (Willem Toorop) Date: Thu, 24 Dec 2015 18:07:58 +0100 Subject: [getdns-users] getdns 0.9.0 release candidate Message-ID: <567C266E.8090606@nlnetlabs.nl> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Dear All, We have a candidate for the special Christmas and New Years eve release, version 0.9.0rc1 of getdns. This release brings the implementation on par with the December 2015 version of the specification and has (almost) all of the still remaining functionality from the specification implemented. This includes respecting the given dns root servers in recursive resolution modus and TSIG authentication. Other new features and noteworthy improvements are: - Functions to convert getdns_dicts representing resource records to and from wire- and zone file format. Also zone files can be read into a getdns_list of getdns_dicts representing the resource records in that zone file. These lists can then conventiently be used with (for example) getdns_context_set_dns_root_servers() and getdns_context_set_dnssec_trust_anchors(). - TCP Fast Open support whenever available on the platform (including Mac-OS X (new)). - Client side edns-tcp-keepalice support - Pinning of upstream certificate's public keys with pinsets (with TLS transport) - Initial support for Windows Besides these new functionalities, a few bugs have been fixed. For a complete overview see the ChangeLog below. Please review this candidate carefully. If no issues arise the actual release will follow Thursday the 31th of December 2015. Marry Christmas! link: https://getdnsapi.net/dist/getdns-0.9.0rc1.tar.gz md5 : b5525667b35a0a1b013abe5c49b2b2c1 sha1: 5fe50d706949da22d8c0635b4345ad1a98c4872e pgp : https://getdnsapi.net/dist/getdns-0.9.0rc1.tar.gz.asc ChangeLog ========= * Update of unofficial extension to the API that supports stub mode TLS verification. GETDNS_AUTHENTICATION_ is replaced by GETDNS_AUTHENTICATION_REQUIRED (but remains available as an alias). Upstreams can now be configured with either a hostname or a SPKI pinset for TLS authentication (or both). If the GETDNS_AUTHENTICATION_REQUIRED option is used at least one piece of authentication information must be configured for each upstream, and all the configured authentication information for an upstream must validate. * Remove STARTTLS implementation (no change to SPEC) * Enable TCP Fast Open when possible. Add OSX support for TFO. * Rename return_call_debugging to return_call_reporting * Bugfix: configure problem with getdns-0.5.1 on OpenBSD Thanks Claus Assmann. * pkg-config support. Thanks Neil Cook. * Functions to convert from RR dicts to wireformat and text format and vice versa. Including a function that builds a getdns_list of RR dicts from a zonefile. * Use the with the getdns_context_set_dns_root_servers() function provided root servers in recursing resolution modus. * getdns_query option (-f) to read a DNSSEC trust anchor from file. * getdns_query option (-R) to read a "root hints" file. * Bugfix: Detect and prevent duplicate NSEC(3)s to be returned with dnssec_return_validation_chain. * Bugfix: Remove duplicate RRs from RRsets when DNSSEC verifying * Client side edns-tcp-keepalive support * TSIG support * Verify upstream TLS pubkeys with pinsets; A getdns_query option (-K) to attach pinsets to getdns_contexts. Thanks Daniel Kahn Gillmor * Initial support for Windows. Thanks Gowri Visweswaran -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWfCZuAAoJEOX4+CEvd6SYVh0P/3iHig6/kwccluUFzL/p8TYj x0wSD4TMt/vQlfgJfRwj3RGDVJWNsGgyo4dEb2u8yLm+hiKf6kqt4tx9P8NI/pZF eNskXiLaVgsRRgHGJ2ZaGz358tRIwDIhcfuwuBUpx7+8bdiJuBCoGBQFoFUWA/Ds e9vEztKUsT9a+Juk8l8RgY8IK+INGxWh48h0ABXwkBwggGd8itTMihkNfYW3RhoI x5WgPxa1umyLyrp7sPfdQjwQ537EusHU4PuUUl5qWbjw3hysddyAEaLqrCeorjOd SmA/mta7xCWI2UMiBH7ivPPb+s5SKZGqfprNDx8XXthuNWDUoZVa/rGoe+5wSBlX C+G65Ink7BzKJt9nLhE6fgoeVB5q75MgtSrbXtw3uKsMT4diqaYKlr0Ood5qGCpB C/TCou28NUBbX1oH+QC215s67bMdoGVuQ5sDshqZm2G0oYzvRCP15lDNH8Nibq8I v1uz5my5+Y0ZwFoEG7uN900K1rZ4Y2rQX1gX91F1sLzpYPm5/B+NzgpsySpMaXXh WevFL2z65sDH1jgYQCmP+7zVuMYl8fXA8Lel0mZJa1VZREO0UmTogk+/BkLV+aMt XQFUeOJPha4K+p6bOr/aFvfQhgj0alJjGubeVGkRcDqEmQ9SOIt4wXUf3mZXr4zP x23DrWzMlOpHSi/0jVLX =mQii -----END PGP SIGNATURE----- From willem at nlnetlabs.nl Thu Dec 31 13:46:26 2015 From: willem at nlnetlabs.nl (Willem Toorop) Date: Thu, 31 Dec 2015 14:46:26 +0100 Subject: [getdns-users] getdns 0.9.0 released Message-ID: <568531B2.3060603@nlnetlabs.nl> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Dear All, We have a special New Year's Eve release, version 0.9.0 of getdns. This release brings the implementation on par with the December 2015 version of the specification and has (almost) all of the still remaining functionality from the specification implemented. These include: * Respecting the given dns root servers in recursive resolution modus See this in action with getdns_query, for example with the root servers of the Yeti DNS Project (https://yeti-dns.org/): getdns_query -f yeti.key -R yeti.hints getdnsapi.net A \ +dnssec_return_status Where yeti.key came from: https://github.com/BII-Lab/Yeti-Project/raw/master/domain/KSK.pub and yeti.hints came from: https://github.com/BII-Lab/Yeti-Project/raw/master/domain/named.cache * TSIG authentication. Specification of upstreams with getdns_query has been extended to configure a TSIG name and secret. From the getdns_query help text: getdns_query [