From linus at nordberg.se Wed Feb 10 19:44:28 2016 From: linus at nordberg.se (Linus Nordberg) Date: Wed, 10 Feb 2016 20:44:28 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension Message-ID: <878u2sqrj7.fsf@localhost> Hi list, I've been trying to use the "dnssec_return_validation_chain" extension, so far without luck. I define luck as seeing a "validation_chain" section in a reply. I have verified that my context has proper trust anchor(s). It'd be great to be able to run some example code, C or Python, to rule out local problems at my end. My ultimate goal with this exercise is to understand what to pass in the support_records argument to getdns_validate_dnssec(). The rationale behind this is https://getdnsapi.net/pipermail/users/2015-May/000032.html which says --8<---------------cut here---------------start------------->8--- - bundle_of_support_records must be a list of DS's RR-dicts and DNSKEY RR-dicts with companion RRSIG-RR-dicts that lead up from one of the trust_anchors to the RR-dicts to validate. ... If you would do a query with the "dnssec_return_validation_chain" extension, you can use the "validation_chain" key in the response dict as the bundle_of_support_records parameter ro getdns_validate_dnssec. --8<---------------cut here---------------end--------------->8--- Thanks, Linus From melinda.shore at nomountain.net Wed Feb 10 19:50:16 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Wed, 10 Feb 2016 10:50:16 -0900 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <878u2sqrj7.fsf@localhost> References: <878u2sqrj7.fsf@localhost> Message-ID: <56BB9478.50903@nomountain.net> Hi, Linus: I believe there are examples in the test subdirectory, but here's a Python example: import getdns from pprint import pprint c = getdns.Context() ext = { 'dnssec_return_validation_chain': getdns.EXTENSION_TRUE } r = c.address('getdnsapi.net', extensions=ext) pprint(r.validation_chain) Melinda From linus at nordberg.se Wed Feb 10 20:19:13 2016 From: linus at nordberg.se (Linus Nordberg) Date: Wed, 10 Feb 2016 21:19:13 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <56BB9478.50903@nomountain.net> (Melinda Shore's message of "Wed, 10 Feb 2016 10:50:16 -0900") References: <878u2sqrj7.fsf@localhost> <56BB9478.50903@nomountain.net> Message-ID: <87y4aspbcu.fsf@localhost> Melinda Shore wrote Wed, 10 Feb 2016 10:50:16 -0900: | I believe there are examples in the test subdirectory, but | here's a Python example: Oh, I was looking in 'replies_tree'! I should've read and understood the spec. :) "This set comes as validation_chain (a list) at the top level of the response object." Thanks! From melinda.shore at nomountain.net Wed Feb 10 21:00:07 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Wed, 10 Feb 2016 12:00:07 -0900 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <87y4aspbcu.fsf@localhost> References: <878u2sqrj7.fsf@localhost> <56BB9478.50903@nomountain.net> <87y4aspbcu.fsf@localhost> Message-ID: <56BBA4D7.9010300@nomountain.net> On 2/10/16 11:19 AM, Linus Nordberg wrote: > Oh, I was looking in 'replies_tree'! Yes, the structure of the returned data isn't particularly transparent, so I often find myself jumping into the Python interpreter and running it interactively to poke around. The main thing to remember is that in the result, the "replies_full" member contains the entire set of returned data, so you can do things like r.replies_full.keys() and go forward from there. Also, dir(r) (assuming that "r" contains the query results). Melinda From willem at nlnetlabs.nl Thu Feb 11 09:15:28 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Thu, 11 Feb 2016 10:15:28 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <878u2sqrj7.fsf@localhost> References: <878u2sqrj7.fsf@localhost> Message-ID: <56BC5130.8050400@nlnetlabs.nl> Hi Linus, Rereading that message you are referring, I realise that a lot has been improved since may 2015. The dnssec_return_validation_chain extension currently works perfectly inn all possible circumstances. The chain will also contain proofs for insecure zones. The record_to_validate parameter to getdns_validate_dnssec() may now also contain a list of reply dicts to validate actual DNS packets. This allows to also validate proof of denial of existence or insecure NXDOMAINs etc. The getdns_query program (did you compile the binary with --with-getdns_query ?) contains example usage of getdns_validate_dnssec and will revalidate the answer with getdns_validate_dnssec() when the dnssec_return_validation_chain was used. This happens in function validate_chain on line 537 of getdns_query.c. It basically boils down to: getdns_return_t validate_chain(getdns_dict *response) { getdns_status r = GETDNS_RETURN_GENERIC_ERROR; getdns_list *trust_anchor; getdns_list *validation_chain; getdns_list *replies_tree; /* Get the trust anchors ... */ if (getdns_context_get_dnssec_trust_anchors( context, &trust_anchor)) trust_anchor = getdns_root_trust_anchor(NULL); if (!trust_anchor) fprintf(stderr, "No trust anchor to validate with.\n"); /* ... get the validation chain ... */ else if ((r = getdns_dict_get_list( response, "validation_chain", &validation_chain))) fprintf(stderr, "Could not get validation chain\n"); /* .. get the replies tree .. */ else if (r = getdns_dict_get_list( response, "replies_tree", &replies_tree))) fprintf(stderr, "Could not get replies tree\n"); /* .. and validate. */ else switch(getdns_validate_dnssec( replies_tree, validation_chain, trust_anchors)) { case GETDNS_DNSSEC_SECURE : printf("Replies are secure\n"); return GETDNS_RETURN_GOOD; case GETDNS_DNSSEC_INDETERMINATE: case GETDNS_DNSSEC_INSECURE: printf("Replies are insecure\n"); return GETDNS_RETURN_GOOD; case GETDNS_DNSSEC_BOGUS : printf("Replies are bogus\n"); return GETDNS_RETURN_GOOD; default : /* Not possible to get here */ fprintf( stderr , "Unkown dnssec status\n"); return GETDNS_RETURN_GENERIC_ERROR; } return r; } Op 10-02-16 om 20:44 schreef Linus Nordberg: > Hi list, > > I've been trying to use the "dnssec_return_validation_chain" extension, > so far without luck. I define luck as seeing a "validation_chain" > section in a reply. I have verified that my context has proper trust > anchor(s). > > It'd be great to be able to run some example code, C or Python, to rule > out local problems at my end. > > My ultimate goal with this exercise is to understand what to pass in the > support_records argument to getdns_validate_dnssec(). The rationale > behind this is > https://getdnsapi.net/pipermail/users/2015-May/000032.html which says > > --8<---------------cut here---------------start------------->8--- > - bundle_of_support_records must be a list of DS's RR-dicts and DNSKEY > RR-dicts with companion RRSIG-RR-dicts that lead up from one of the > trust_anchors to the RR-dicts to validate. > ... > If you would do a query with the "dnssec_return_validation_chain" > extension, you can use the "validation_chain" key in the response dict > as the bundle_of_support_records parameter ro getdns_validate_dnssec. > --8<---------------cut here---------------end--------------->8--- > > Thanks, > Linus > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users > From willem at nlnetlabs.nl Thu Feb 11 09:25:24 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Thu, 11 Feb 2016 10:25:24 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <56BC5130.8050400@nlnetlabs.nl> References: <878u2sqrj7.fsf@localhost> <56BC5130.8050400@nlnetlabs.nl> Message-ID: <56BC5384.50502@nlnetlabs.nl> I know you're interested to validate resource records at specified moments. I'll try to expose a "non-API" version of the getdns_validate_dnssec() function with that extra parameter in the upcoming release. I.e. getdns_return_t getdns_validate_dnssec2( getdns_list *to_validate, getdns_list *bundle_of_support_records, getdns_list *trust_anchor_records, time_t moment ); OK? -- Willem Op 11-02-16 om 10:15 schreef Willem Toorop: > Hi Linus, > > Rereading that message you are referring, I realise that a lot has been > improved since may 2015. > > The dnssec_return_validation_chain extension currently works perfectly > inn all possible circumstances. The chain will also contain proofs for > insecure zones. > > The record_to_validate parameter to getdns_validate_dnssec() may now > also contain a list of reply dicts to validate actual DNS packets. This > allows to also validate proof of denial of existence or insecure > NXDOMAINs etc. > > The getdns_query program (did you compile the binary with > --with-getdns_query ?) contains example usage of getdns_validate_dnssec > and will revalidate the answer with getdns_validate_dnssec() when the > dnssec_return_validation_chain was used. This happens in function > validate_chain on line 537 of getdns_query.c. > > It basically boils down to: > > getdns_return_t validate_chain(getdns_dict *response) > { > getdns_status r = GETDNS_RETURN_GENERIC_ERROR; > getdns_list *trust_anchor; > getdns_list *validation_chain; > getdns_list *replies_tree; > > /* Get the trust anchors ... > */ > if (getdns_context_get_dnssec_trust_anchors( > context, &trust_anchor)) > trust_anchor = getdns_root_trust_anchor(NULL); > > if (!trust_anchor) > fprintf(stderr, "No trust anchor to validate with.\n"); > > /* ... get the validation chain ... > */ > else if ((r = getdns_dict_get_list( > response, "validation_chain", &validation_chain))) > fprintf(stderr, "Could not get validation chain\n"); > > > /* .. get the replies tree .. > */ > else if (r = getdns_dict_get_list( > response, "replies_tree", &replies_tree))) > fprintf(stderr, "Could not get replies tree\n"); > > /* .. and validate. > */ > else switch(getdns_validate_dnssec( > replies_tree, validation_chain, trust_anchors)) { > > case GETDNS_DNSSEC_SECURE : printf("Replies are secure\n"); > return GETDNS_RETURN_GOOD; > > case GETDNS_DNSSEC_INDETERMINATE: > case GETDNS_DNSSEC_INSECURE: printf("Replies are insecure\n"); > return GETDNS_RETURN_GOOD; > > case GETDNS_DNSSEC_BOGUS : printf("Replies are bogus\n"); > return GETDNS_RETURN_GOOD; > > default : /* Not possible to get here */ > fprintf( stderr > , "Unkown dnssec status\n"); > return GETDNS_RETURN_GENERIC_ERROR; > } > return r; > } > > Op 10-02-16 om 20:44 schreef Linus Nordberg: >> Hi list, >> >> I've been trying to use the "dnssec_return_validation_chain" extension, >> so far without luck. I define luck as seeing a "validation_chain" >> section in a reply. I have verified that my context has proper trust >> anchor(s). >> >> It'd be great to be able to run some example code, C or Python, to rule >> out local problems at my end. >> >> My ultimate goal with this exercise is to understand what to pass in the >> support_records argument to getdns_validate_dnssec(). The rationale >> behind this is >> https://getdnsapi.net/pipermail/users/2015-May/000032.html which says >> >> --8<---------------cut here---------------start------------->8--- >> - bundle_of_support_records must be a list of DS's RR-dicts and DNSKEY >> RR-dicts with companion RRSIG-RR-dicts that lead up from one of the >> trust_anchors to the RR-dicts to validate. >> ... >> If you would do a query with the "dnssec_return_validation_chain" >> extension, you can use the "validation_chain" key in the response dict >> as the bundle_of_support_records parameter ro getdns_validate_dnssec. >> --8<---------------cut here---------------end--------------->8--- >> >> Thanks, >> Linus >> _______________________________________________ >> Users mailing list >> Users at getdnsapi.net >> http://getdnsapi.net/mailman/listinfo/users >> > > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users > From linus at nordberg.se Thu Feb 11 11:13:01 2016 From: linus at nordberg.se (Linus Nordberg) Date: Thu, 11 Feb 2016 12:13:01 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <56BC5130.8050400@nlnetlabs.nl> (Willem Toorop's message of "Thu, 11 Feb 2016 10:15:28 +0100") References: <878u2sqrj7.fsf@localhost> <56BC5130.8050400@nlnetlabs.nl> Message-ID: <87bn7no5z6.fsf@localhost> Willem Toorop wrote Thu, 11 Feb 2016 10:15:28 +0100: | The dnssec_return_validation_chain extension currently works perfectly | inn all possible circumstances. The chain will also contain proofs for | insecure zones. | | The record_to_validate parameter to getdns_validate_dnssec() may now | also contain a list of reply dicts to validate actual DNS packets. This | allows to also validate proof of denial of existence or insecure | NXDOMAINs etc. Thanks for the update! | The getdns_query program (did you compile the binary with | --with-getdns_query ?) contains example usage of getdns_validate_dnssec | and will revalidate the answer with getdns_validate_dnssec() when the | dnssec_return_validation_chain was used. This happens in function | validate_chain on line 537 of getdns_query.c. I had failed to notice the src/test directory. This is very useful. From linus at nordberg.se Thu Feb 11 12:15:48 2016 From: linus at nordberg.se (Linus Nordberg) Date: Thu, 11 Feb 2016 13:15:48 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <56BC5384.50502@nlnetlabs.nl> (Willem Toorop's message of "Thu, 11 Feb 2016 10:25:24 +0100") References: <878u2sqrj7.fsf@localhost> <56BC5130.8050400@nlnetlabs.nl> <56BC5384.50502@nlnetlabs.nl> Message-ID: <877fibo32j.fsf@localhost> Hi Willem, Thanks for bringing this up. I'm a bit undereducated on the matter of DNSSEC so please bear with me for being a bit daft here. The tl;dr reads "Sounds great! Can I haz a public wire-format-input entry-point as well?". For background and details, read on. My immediate use for a function validating a (single) DS RR is to be able to thwart spamming of an experimental DNSSEC Transparency log. In short, the log will accept submissions of a DS RR (from a limited number of zones) if accompanied by a valid chain consisting of RRSIG, DNSKEY and DS RR's. The log will store the DS and chain RRs together with a timestamp for later retrieval by any log client. (Current thinking is that the DS RR and the timestamp (but not the chain) will be covered by a signature issued by the log but this might change.) I've so far expected the time of submission of a DS RR to be close in time of observation in the DNS but I've lately come to think that this might not be such a good idea. I'd very much like old DS records to be submitted as well. The next use for a validation function would be log monitors. Their job is to poll logs for new entries and look at the data with the goal of finding proof of misissuance. Imagine f.ex. that you ran a monitor looking for DS records for getdnsapi.net which raised the alarm whenever it saw one, so that you could decide if that issuance was ordered by someone with control over the domain or if it was .net or . acting unauthorized. This is expected to happen not only close in time to the publication of the DS record in the DNS but also a long time after that. Since the log stores and on request hands out the full chain (up to and including one of potentially several configured trust anchors, but typically the DNSSEC root), this shouldn't be a problem using your suggested function. All a monitor would have to do is to use the timestamp from the log entry as the 'moment' argument. While perhaps not strictly necessary, I think this will be useful especially for spam mitigation -- a log could choose to refuse records that are deemed too old for being interesting and stop someone trying to fill up the log by submitting a gazillion of old DS records they've stored. Last, to my request for a validation function accepting RR's in wire format. Since all RR's to and from the log will be sent in DNS wire format, it'd be more conventient if I could use that with the getdns_validate_dnssec() function (or its variant with 'moment'). As it is now, I have to first turn the wire format into getdns_dict's and then put them in getdns_list's. What do you think? On a side note, it'd be great to have you and other DNS and DNSSEC experts participating in the transparency discussions over at [1]. [1] https://lists.sunet.se/listinfo/dnssec-transparency Willem Toorop wrote Thu, 11 Feb 2016 10:25:24 +0100: | I know you're interested to validate resource records at specified | moments. I'll try to expose a "non-API" version of the | getdns_validate_dnssec() function with that extra parameter in the | upcoming release. I.e. | | getdns_return_t getdns_validate_dnssec2( | getdns_list *to_validate, | getdns_list *bundle_of_support_records, | getdns_list *trust_anchor_records, | time_t moment | ); | | OK? | | -- Willem | | Op 11-02-16 om 10:15 schreef Willem Toorop: | > Hi Linus, | > | > Rereading that message you are referring, I realise that a lot has been | > improved since may 2015. | > | > The dnssec_return_validation_chain extension currently works perfectly | > inn all possible circumstances. The chain will also contain proofs for | > insecure zones. | > | > The record_to_validate parameter to getdns_validate_dnssec() may now | > also contain a list of reply dicts to validate actual DNS packets. This | > allows to also validate proof of denial of existence or insecure | > NXDOMAINs etc. | > | > The getdns_query program (did you compile the binary with | > --with-getdns_query ?) contains example usage of getdns_validate_dnssec | > and will revalidate the answer with getdns_validate_dnssec() when the | > dnssec_return_validation_chain was used. This happens in function | > validate_chain on line 537 of getdns_query.c. | > | > It basically boils down to: | > | > getdns_return_t validate_chain(getdns_dict *response) | > { | > getdns_status r = GETDNS_RETURN_GENERIC_ERROR; | > getdns_list *trust_anchor; | > getdns_list *validation_chain; | > getdns_list *replies_tree; | > | > /* Get the trust anchors ... | > */ | > if (getdns_context_get_dnssec_trust_anchors( | > context, &trust_anchor)) | > trust_anchor = getdns_root_trust_anchor(NULL); | > | > if (!trust_anchor) | > fprintf(stderr, "No trust anchor to validate with.\n"); | > | > /* ... get the validation chain ... | > */ | > else if ((r = getdns_dict_get_list( | > response, "validation_chain", &validation_chain))) | > fprintf(stderr, "Could not get validation chain\n"); | > | > | > /* .. get the replies tree .. | > */ | > else if (r = getdns_dict_get_list( | > response, "replies_tree", &replies_tree))) | > fprintf(stderr, "Could not get replies tree\n"); | > | > /* .. and validate. | > */ | > else switch(getdns_validate_dnssec( | > replies_tree, validation_chain, trust_anchors)) { | > | > case GETDNS_DNSSEC_SECURE : printf("Replies are secure\n"); | > return GETDNS_RETURN_GOOD; | > | > case GETDNS_DNSSEC_INDETERMINATE: | > case GETDNS_DNSSEC_INSECURE: printf("Replies are insecure\n"); | > return GETDNS_RETURN_GOOD; | > | > case GETDNS_DNSSEC_BOGUS : printf("Replies are bogus\n"); | > return GETDNS_RETURN_GOOD; | > | > default : /* Not possible to get here */ | > fprintf( stderr | > , "Unkown dnssec status\n"); | > return GETDNS_RETURN_GENERIC_ERROR; | > } | > return r; | > } | > | > Op 10-02-16 om 20:44 schreef Linus Nordberg: | >> Hi list, | >> | >> I've been trying to use the "dnssec_return_validation_chain" extension, | >> so far without luck. I define luck as seeing a "validation_chain" | >> section in a reply. I have verified that my context has proper trust | >> anchor(s). | >> | >> It'd be great to be able to run some example code, C or Python, to rule | >> out local problems at my end. | >> | >> My ultimate goal with this exercise is to understand what to pass in the | >> support_records argument to getdns_validate_dnssec(). The rationale | >> behind this is | >> https://getdnsapi.net/pipermail/users/2015-May/000032.html which says | >> | >> --8<---------------cut here---------------start------------->8--- | >> - bundle_of_support_records must be a list of DS's RR-dicts and DNSKEY | >> RR-dicts with companion RRSIG-RR-dicts that lead up from one of the | >> trust_anchors to the RR-dicts to validate. | >> ... | >> If you would do a query with the "dnssec_return_validation_chain" | >> extension, you can use the "validation_chain" key in the response dict | >> as the bundle_of_support_records parameter ro getdns_validate_dnssec. | >> --8<---------------cut here---------------end--------------->8--- | >> | >> Thanks, | >> Linus | >> _______________________________________________ | >> Users mailing list | >> Users at getdnsapi.net | >> http://getdnsapi.net/mailman/listinfo/users>> | > | > _______________________________________________ | > Users mailing list | > Users at getdnsapi.net | > http://getdnsapi.net/mailman/listinfo/users> | | _______________________________________________ | Users mailing list | Users at getdnsapi.net | http://getdnsapi.net/mailman/listinfo/users From rick at openfortress.nl Thu Feb 25 09:20:50 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 25 Feb 2016 10:20:50 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? Message-ID: <56CEC772.8020607@openfortress.nl> Hello, I'm looking into GetDNS, curious about a new player on the landscape, and have a few beginner's questions, if I may. I noticed it is "not by DNS folk for DNS folk", so as a "DNS person" I may be not be the targeted audience. Still: 1. The documentation mentions STUB mode in a number of places, but does not accurately define it. I found that it means dropping the Unbound dependency; but does that mean that it won't perform DNSSEC validation, or just that it won't cache, or...? How is this impacting the experience from the GenDNS API? 2. I was looking into GetDNS as an possible alternative for libunbound (and got a bit confused because they're both from NLNet Labs) and if I'm getting it correctly, then GetDNS is meant to be wrapped for script-style languages, but given the string-indexed dictionary structures returned it strikes me as more complex to use in a C program than libunbound; or am I missing something? 3. Part of my wondering is that I don't know if GetDNS does DNSSEC for itself, or delegates these duties to libunbound. Finally, if I was making an easy API to DNS then I would have created"DNS objects"that hold a path ("lookup SRV, take out port and protocol, lookup TLSA record") to a piece of data in DNS, to which they "subscribe" by holding it in memory and renewing it just before TTL expiration if not yet removed (deleted or GC'd). I would have the object send notifications to all listeners (such as "validated certificate" objects) if anything changed to the DNS data during a refresh, including to its validity in terms of DNSSEC. But that's just thinking out loud. Thanks, -Rick From allison.mankin at gmail.com Thu Feb 25 16:42:08 2016 From: allison.mankin at gmail.com (Allison Mankin) Date: Thu, 25 Feb 2016 11:42:08 -0500 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? Message-ID: Hello, Rick, Taking your comments/questions one by one: 0. We really intend a conjunction, not a disjunction, with the point about DNS folk and we encourage DNS folks actively. Case in point, our participation in the IETF's hackathons with getdns. 1. That's a valid issue about the STUB mode definition. Our getdns implementation started with the spec, which is a consensus document, and over time, we have enhanced STUB mode so that it is fully capable of performing DNSSEC validation without revising the spec enough to capture this. In stub-only mode, the stub can validate DNSSEC, but it doesn't perform all the functions of the caching recursive resolver. getdns uses libunbound when it is in recursive mode, but not when it is a validating stub. There's a great discussion of validating stub, with lots of detail, that Willem Toorop presented at vBSDcon in September 2015, that I think would make this all very clear to you: https://www.youtube.com/watch?v=73M7h56Dsas 2. Release 0.9 added excellent helpers to make getdns easier to work with from C. They were described in the email about the release, and you can find them in the 0.9 ChangeLog on github (Hey others on the core team: let's make this info clearer on the website too). Melinda Shore blogged about this too, but I'm not finding a link to the blog right now, perhaps due to insufficient caffeine today. 3. As noted in 1), getdns in stub-only mode readily does DNSSEC validation for itself on the end-system. Interesting point about the API. I hope others will comment in detail. Thank you for writing. We're glad to continue discussion. Allison (getdns Team Coordinator) Hello, I'm looking into GetDNS, curious about a new player on the landscape, > and have a few beginner's questions, if I may. I noticed it is "not by > DNS folk for DNS folk", so as a "DNS person" I may be not be the > targeted audience. Still: > > 1. The documentation mentions STUB mode in a number of places, but does > not accurately define it. I found that it means dropping the Unbound > dependency; but does that mean that it won't perform DNSSEC validation, > or just that it won't cache, or...? How is this impacting the > experience from the GenDNS API? > 2. I was looking into GetDNS as an possible alternative for libunbound > (and got a bit confused because they're both from NLNet Labs) and if I'm > getting it correctly, then GetDNS is meant to be wrapped for > script-style languages, but given the string-indexed dictionary > structures returned it strikes me as more complex to use in a C program > than libunbound; or am I missing something? > 3. Part of my wondering is that I don't know if GetDNS does DNSSEC for > itself, or delegates these duties to libunbound. > > Finally, if I was making an easy API to DNS then I would have > created"DNS objects"that hold a path ("lookup SRV, take out port and > protocol, lookup TLSA record") to a piece of data in DNS, to which they > "subscribe" by holding it in memory and renewing it just before TTL > expiration if not yet removed (deleted or GC'd). I would have the > object send notifications to all listeners (such as "validated > certificate" objects) if anything changed to the DNS data during a > refresh, including to its validity in terms of DNSSEC. But that's just > thinking out loud. > > Thanks, > -Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: From rick at openfortress.nl Thu Feb 25 17:53:56 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 25 Feb 2016 18:53:56 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: References: Message-ID: <56CF3FB4.5090602@openfortress.nl> Hi Allison, Thank you very much. Willem's talk starts off by clearly positioning GetDNS as a secure stub resolver, possibly at the OS level; this probably is the main statement to make, and I wasn't quite clear based on the website. One aspect of that is the overlap with libunbound, and the absense of a comparison of which/why/when between the two. Is that helpful feedback? > Interesting point about the API. I hope others will comment in detail. > Maybe it helps to give a few advanced DNS use cases then. Of course, where I wrote "object" you are welcome to read "callback function registration". The change notifications of live network state (after TTL expiration) is what it is about. It's like caching, but application-driven. A model that works particularly well I think is LDAP's "SyncRepl" mechanism [RFC 4533], where you send a search and annotate it with "oh, and if you have updates then let me know please, I'll stay connected". If that conceptual model would be possible, leading to callbacks when RRsets are changed, or their security status, then it could greatly simplify heavy-weight use of DNS. As an example, I wrote a DNSKEY-uploader-to-parent script that scrutinises timing information on DSs and DNSKEYs or their absense, in order to do nothing too hastily. The code is rock-solid but needs to do a lot of administration of DNS-based timing and absense/presence of records. There is a general underlying concept, I think; I'm now working on a similarly robust RESTful API to OpenDNSSEC, and I find myself turning to pydns with the same zeal for detail. The reason I am now looking into GetDNS is for my TLS Pool [1]; a daemon that takes TLS out of applications, to separate private keys from application logic (or "frivolity" if you like). Of course I'm looking at DANE, but is it best used if only done at the start of a session? My preference would be to register for changes to the chain that leads to my TLSA record throughout the lifetime of a TLS connection (which may be long, for instance when using LDAP or IMAP). Another part of my InternetWide.org work is an interest in realm crossover for Kerberos [2] (and proper embedding of Kerberos in TLS [3]). During this "impromptu" crossover, public keys are used, and it would be very interesting if it would be possible to reverse automatically when TLSA records are pulled from DNS. Making such things easy, not necessarily through an object API but at least facilitating that sort of object, could IMHO be a great asset to the usefulness of DNSSEC, DANE and other improvements for online security. Sorry for the infodump, I hadn't expected such an open response to my API remark! But don't get me started, there's more where that came from :) Cheers, -Rick [1] https://github.com/arpa2/tlspool [2] http://internetwide.org/blog/2015/04/22/id-2-byoid.html [3] http://internetwide.org/blog/2015/11/24/somethings-cooking-3.html > Thank you for writing. We're glad to continue discussion. > > Allison > > (getdns Team Coordinator) > > Hello, > > I'm looking into GetDNS, curious about a new player on the landscape, > From melinda.shore at nomountain.net Thu Feb 25 18:30:01 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Thu, 25 Feb 2016 09:30:01 -0900 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CEC772.8020607@openfortress.nl> References: <56CEC772.8020607@openfortress.nl> Message-ID: <56CF4829.2060804@nomountain.net> On 2/25/16 12:20 AM, Rick van Rein wrote: > 2. I was looking into GetDNS as an possible alternative for libunbound > (and got a bit confused because they're both from NLNet Labs) and if I'm > getting it correctly, then GetDNS is meant to be wrapped for > script-style languages, but given the string-indexed dictionary > structures returned it strikes me as more complex to use in a C program > than libunbound; or am I missing something? Hi, Rick: Yes, there's no question that the original data structure design was extremely clunky for C programmers. This was recognized fairly early on, so Willem came up with a really nice alternative syntax for accessing deeply-nested data, for both read and write. It resembles JSON pointers and Unix filesystem paths and saves writing a ton of repetitive code. I wrote up a blog post on it, here: http://melindashore.blogspot.com/2016/02/enhanced-getdns-data-access.html Melinda From rick at openfortress.nl Thu Feb 25 19:10:17 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 25 Feb 2016 20:10:17 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF4829.2060804@nomountain.net> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> Message-ID: <56CF5199.1080503@openfortress.nl> Hello Melinda, Thanks for your blog reference, I helped to gain a better understanding of the use of GetDNS from C. I'm hesitant to embrace it, to be honest. Where Willem Toorop emphasis the ease of extension in his YouTube talk, I see dynamicity as a two-sided sword when security is at play. IMHO, static typing is a very powerful tool in reducing programming errors, and scriptish data structures such as a dictionary or list are not helpful in that respect. I have to weigh pros and cons; it's not a heavenly match the way you describe it. Functional language strike a very interesting middle ground in this arena; they can often be statically typed, but with refinements that are not possible in procedural languages. Both C and JavaScript/Lua end up holding a shorter end of the stick, albeit the opposite end :) The "easy" code that you show using snprintf() hurts my skull with thoughts of buffer overflows. They can be managed, but it takes mental effort that would not otherwise be required; this means it is still an awkward API for C, at least to me. A lesser concern is "wasting" compute cycles on dynamicity; but I know that this is being pedantic and is not a serious hold-back. I now understand better what GetDNS tries to do to be more C-ish, but to me it still feels like a bit of a twist. -Rick From melinda.shore at nomountain.net Thu Feb 25 20:13:03 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Thu, 25 Feb 2016 11:13:03 -0900 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF5199.1080503@openfortress.nl> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> <56CF5199.1080503@openfortress.nl> Message-ID: <56CF604F.6070903@nomountain.net> On 2/25/16 10:10 AM, Rick van Rein wrote: > The "easy" code that you show using snprintf() hurts my skull with > thoughts of buffer overflows. They can be managed, but it takes > mental effort that would not otherwise be required; this means it is > still an awkward API for C, at least to me. Well, I think nearly any C API that deals with DNS data is going to have similar issues given the nature of what's returned from a DNS query. Easing the pain of doing validation and so on, on the other hand, is a big security win, as that's something that's entirely too easy for an implementer to get wrong. It's all about the tradeoffs. But you may want to check out the Python bindings. The data are standard Python dicts and lists and the callback function is a standard Python callable, so working with those is not any different from any other sort of Python programming and it's easy to adhere to a more functional style. You'll need to have libgetdns installed, along with the Python development tools (usually "python-dev" and "python3-dev" on most Linux distributions). Melinda From rick at openfortress.nl Thu Feb 25 20:22:27 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 25 Feb 2016 21:22:27 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF604F.6070903@nomountain.net> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> <56CF5199.1080503@openfortress.nl> <56CF604F.6070903@nomountain.net> Message-ID: <56CF6283.3070305@openfortress.nl> Hi Melinda, > It's all about the tradeoffs. Oh yes, nothing I said is black & white; I'm merely expressing the concerns that I have with this API design approach and the way it exports potential problems that are otherwise internalised. This is why I proposed the API was more on the hand of scripts than of C programs. > But you may want to check out the Python bindings. Oh yes, for Python I am already 80% convinced; having used pydns :) It's strictly the embedding in C that leaves me concerned -- and that is related to the sort of programs I like to write in C: software that checks all return values and repairs any trouble. Then, exported dynamicity becomes a concern. > The data are > standard Python dicts and lists and the callback function is a > standard Python callable, so working with those is not any different > from any other sort of Python programming and it's easy to adhere > to a more functional style. As expected, work well done. NLNet Labs are heroes. Thanks, -Rick From melinda.shore at nomountain.net Thu Feb 25 21:57:23 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Thu, 25 Feb 2016 12:57:23 -0900 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF6283.3070305@openfortress.nl> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> <56CF5199.1080503@openfortress.nl> <56CF604F.6070903@nomountain.net> <56CF6283.3070305@openfortress.nl> Message-ID: <56CF78C3.5070200@nomountain.net> On 2/25/16 11:22 AM, Rick van Rein wrote: > As expected, work well done. NLNet Labs are heroes. Indeed they are, but the Python bindings are mine. Melinda From rick at openfortress.nl Thu Feb 25 21:57:40 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 25 Feb 2016 22:57:40 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF78C3.5070200@nomountain.net> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> <56CF5199.1080503@openfortress.nl> <56CF604F.6070903@nomountain.net> <56CF6283.3070305@openfortress.nl> <56CF78C3.5070200@nomountain.net> Message-ID: <56CF78D4.3090209@openfortress.nl> Hah! > Indeed they are, but the Python bindings are mine. Then you are a heroine too ;-) -Rick From willem at nlnetlabs.nl Fri Feb 26 09:13:49 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Fri, 26 Feb 2016 10:13:49 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CEC772.8020607@openfortress.nl> References: <56CEC772.8020607@openfortress.nl> Message-ID: <56D0174D.9060806@nlnetlabs.nl> Op 25-02-16 om 10:20 schreef Rick van Rein: > Finally, if I was making an easy API to DNS then I would have > created"DNS objects"that hold a path ("lookup SRV, take out port and > protocol, lookup TLSA record") to a piece of data in DNS, to which they > "subscribe" by holding it in memory and renewing it just before TTL > expiration if not yet removed (deleted or GC'd). I would have the > object send notifications to all listeners (such as "validated > certificate" objects) if anything changed to the DNS data during a > refresh, including to its validity in terms of DNSSEC. But that's just > thinking out loud. Hey Rick! A subscription service for DNS information (or on a DNS cache even), taking into account DNS redirects (by SRV, CNAME, MX, NS, or whatever). I like that idea a lot! This would work perfectly well with the whole eventloop approach that getdns embraces too. It would also be in line with the "small cache for the sub resolver (for DS/DNSKEY (or their denial of existence) only in first instance)" feature that we have on our wishlist. This would be a great hackathon project for the IETF95 too. Too many fun & interesting things to do, too little time... :( Maybe we could discuss API prototypes for such an API if your in the neighbourhood sometime? -- Willem > > > Thanks, > -Rick > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users > From willem at nlnetlabs.nl Fri Feb 26 09:20:10 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Fri, 26 Feb 2016 10:20:10 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56CF4829.2060804@nomountain.net> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> Message-ID: <56D018CA.8070706@nlnetlabs.nl> Op 25-02-16 om 19:30 schreef Melinda Shore: > On 2/25/16 12:20 AM, Rick van Rein wrote: >> 2. I was looking into GetDNS as an possible alternative for libunbound >> (and got a bit confused because they're both from NLNet Labs) and if I'm >> getting it correctly, then GetDNS is meant to be wrapped for >> script-style languages, but given the string-indexed dictionary >> structures returned it strikes me as more complex to use in a C program >> than libunbound; or am I missing something? > > Hi, Rick: > > Yes, there's no question that the original data structure > design was extremely clunky for C programmers. This was > recognized fairly early on, so Willem came up with a Uh-hum... so Philip Homburg suggested to use expressions in the lookup strings to get to more deeply nested information for the first time during the IETF in Prague I believe. JSON pointer syntax was suggested by Joe Hildebrand. > really nice alternative syntax for accessing deeply-nested > data, for both read and write. It resembles JSON pointers > and Unix filesystem paths and saves writing a ton of repetitive > code. I wrote up a blog post on it, here: > > http://melindashore.blogspot.com/2016/02/enhanced-getdns-data-access.html > > Melinda > > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users From rick at openfortress.nl Fri Feb 26 09:46:55 2016 From: rick at openfortress.nl (Rick van Rein) Date: Fri, 26 Feb 2016 10:46:55 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56D0174D.9060806@nlnetlabs.nl> References: <56CEC772.8020607@openfortress.nl> <56D0174D.9060806@nlnetlabs.nl> Message-ID: <56D01F0F.4060407@openfortress.nl> Hi Willem, > A subscription service for DNS information (or on a DNS cache even), > taking into account DNS redirects (by SRV, CNAME, MX, NS, or whatever). > I like that idea a lot! This would work perfectly well with the whole > eventloop approach that getdns embraces too. > > It would also be in line with the "small cache for the sub resolver (for > DS/DNSKEY (or their denial of existence) only in first instance)" > feature that we have on our wishlist. Whoa, enthousiasm ;-) Then let me add a few other things I've been missing in the DNS landscape... First, I think SCTP as a transport for DNS is a no-brainer, at least between authoritatives (but possibly also for local/befriended clients): * reliable delivery: slaves never miss a NOTIFY from their master * out-of-order delivery: data up to 64k can overtake (as with UDP) * optional ordering: mimic TCP style when data exceeds 64k (AXFR, IXFR) * SCTP is relatively expensive to setup, but fine for known relations * potentially use added streams for extra info (I/AXFR, zones serviced) For the work I've been doing at SURFnet I've really wished my client software could subscribe to NOTIFYs over SCTP, as though they were a slave DNS server themselves. This is not stub functionality I suppose, although it gets really close. It can speed up closed loops OpenDNSSEC -> DNS -> monitoring -> OpenDNSESC and take out the guesses. Note how the entire DNS system becomes instant-upgrade among friends; this can really facilitate DNS as a secure backbone, even if it is just used internally. (SCTP for all DNS is probably going to be too hefty.) Finally, much of our work in assuring DNSSEC to be correctly implemented came down to TTL computations (you may have seen https://dnssec.surfnet.nl/?p=771 which was truly painful to compose) and IMHO additional management data from DNS could be useful: I call it "minDNS,maxDNS" to indicate separate DNS supply streams with the data common to all DNS caches in the World, and the union of all information that might be in a DNS cache anywhere in the World. All the TTL administration that we've been doing to make DNSSEC rock solid crystalises to this sort of information base: minDNS,maxDNS. This would be the work of an authoritative server, unless clients could follow the published state and receieve reliable NOTIFYs as though they were authoritatives themselves. (Using SCTP, that would be possible, and separate streams may be used for minDNS and maxDNS.) > This would be a great hackathon project for the IETF95 too. I will probably be there... > Too many fun & interesting things to do, too little time... :( I'm afraid I can have a very bad impact on that :-D > Maybe we could discuss API prototypes for such an API if your in the > neighbourhood sometime? Gladly! I liked the word "enumerator" but didn't find it yet. And I have some strong ideas about static structures in APIs too (just made an ASN.1 DER parser fulfilling that same ideal, while staying generic, and we could maybe look for something like that to make GetDNS taste more like a C library, https://github.com/vanrein/quick-der#quick-and-easy-der-a-library-for-parsing-asn1 ) Cheers, -Rick From willem at nlnetlabs.nl Fri Feb 26 10:15:59 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Fri, 26 Feb 2016 11:15:59 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: <56D01F0F.4060407@openfortress.nl> References: <56CEC772.8020607@openfortress.nl> <56D0174D.9060806@nlnetlabs.nl> <56D01F0F.4060407@openfortress.nl> Message-ID: <56D025DF.8070709@nlnetlabs.nl> Op 26-02-16 om 10:46 schreef Rick van Rein: > Hi Willem, > >> A subscription service for DNS information (or on a DNS cache even), >> taking into account DNS redirects (by SRV, CNAME, MX, NS, or whatever). >> I like that idea a lot! This would work perfectly well with the whole >> eventloop approach that getdns embraces too. >> >> It would also be in line with the "small cache for the sub resolver (for >> DS/DNSKEY (or their denial of existence) only in first instance)" >> feature that we have on our wishlist. > > Whoa, enthousiasm ;-) > > > Then let me add a few other things I've been missing in the DNS landscape... > > First, I think SCTP as a transport for DNS is a no-brainer, at least > between authoritatives (but possibly also for local/befriended clients): > > * reliable delivery: slaves never miss a NOTIFY from their master > * out-of-order delivery: data up to 64k can overtake (as with UDP) > * optional ordering: mimic TCP style when data exceeds 64k (AXFR, IXFR) > * SCTP is relatively expensive to setup, but fine for known relations > * potentially use added streams for extra info (I/AXFR, zones serviced) > > For the work I've been doing at SURFnet I've really wished my client > software could subscribe to NOTIFYs over SCTP, as though they were a > slave DNS server themselves. This is not stub functionality I suppose, > although it gets really close. It can speed up closed loops > OpenDNSSEC -> DNS -> monitoring -> OpenDNSESC and take out the guesses. > Note how the entire DNS system becomes instant-upgrade among friends; > this can really facilitate DNS as a secure backbone, even if it is just > used internally. (SCTP for all DNS is probably going to be too hefty.) > > Finally, much of our work in assuring DNSSEC to be correctly implemented > came down to TTL computations (you may have seen https://dnssec.surfnet.nl/?p=771 > which was truly painful to compose) and IMHO additional management data > from DNS could be useful: I call it "minDNS,maxDNS" to indicate separate > DNS supply streams with the data common to all DNS caches in the World, and > the union of all information that might be in a DNS cache anywhere in the > World. All the TTL administration that we've been doing to make DNSSEC > rock solid crystalises to this sort of information base: minDNS,maxDNS. > This would be the work of an authoritative server, unless clients could > follow the published state and receieve reliable NOTIFYs as though they > were authoritatives themselves. (Using SCTP, that would be possible, and > separate streams may be used for minDNS and maxDNS.) Interesting stuff! I'm afraid I have to chew on this a bit more to properly appreciate it tough, sorry ;) > >> This would be a great hackathon project for the IETF95 too. > > I will probably be there... Good! Make sure to sign up for the hackathon and join the DNSSEC team if you do! > >> Too many fun & interesting things to do, too little time... :( > > I'm afraid I can have a very bad impact on that :-D > >> Maybe we could discuss API prototypes for such an API if your in the >> neighbourhood sometime? > > Gladly! I liked the word "enumerator" but didn't find it yet. And I have > some strong ideas about static structures in APIs too (just made an ASN.1 > DER parser fulfilling that same ideal, while staying generic, and we could > maybe look for something like that to make GetDNS taste more like a C library, > https://github.com/vanrein/quick-der#quick-and-easy-der-a-library-for-parsing-asn1 > ) Aha... iterators and such things. We have those sort of structures under the hood too. Have a look at https://github.com/getdnsapi/getdns/blob/develop/src/rr-iter.h for example (documentation is lagging behind a bit, sorry...). Cheers, -- Willem > > Cheers, > -Rick > _______________________________________________ > Users mailing list > Users at getdnsapi.net > http://getdnsapi.net/mailman/listinfo/users > From willem at nlnetlabs.nl Fri Feb 26 11:16:38 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Fri, 26 Feb 2016 12:16:38 +0100 Subject: [getdns-users] Example using the "dnssec_return_validation_chain" extension In-Reply-To: <877fibo32j.fsf@localhost> References: <878u2sqrj7.fsf@localhost> <56BC5130.8050400@nlnetlabs.nl> <56BC5384.50502@nlnetlabs.nl> <877fibo32j.fsf@localhost> Message-ID: <56D03416.9060200@nlnetlabs.nl> Op 11-02-16 om 13:15 schreef Linus Nordberg: > Hi Willem, > > Thanks for bringing this up. I'm a bit undereducated on the matter of > DNSSEC so please bear with me for being a bit daft here. > > The tl;dr reads "Sounds great! Can I haz a public wire-format-input > entry-point as well?". For background and details, read on. > > > My immediate use for a function validating a (single) DS RR is to be > able to thwart spamming of an experimental DNSSEC Transparency log. In > short, the log will accept submissions of a DS RR (from a limited number > of zones) if accompanied by a valid chain consisting of RRSIG, DNSKEY > and DS RR's. The log will store the DS and chain RRs together with a > timestamp for later retrieval by any log client. (Current thinking is > that the DS RR and the timestamp (but not the chain) will be covered by > a signature issued by the log but this might change.) > > I've so far expected the time of submission of a DS RR to be close in > time of observation in the DNS but I've lately come to think that this > might not be such a good idea. I'd very much like old DS records to be > submitted as well. > > > The next use for a validation function would be log monitors. Their job > is to poll logs for new entries and look at the data with the goal of > finding proof of misissuance. Imagine f.ex. that you ran a monitor > looking for DS records for getdnsapi.net which raised the alarm whenever > it saw one, so that you could decide if that issuance was ordered by > someone with control over the domain or if it was .net or . acting > unauthorized. > > This is expected to happen not only close in time to the publication of > the DS record in the DNS but also a long time after that. Since the log > stores and on request hands out the full chain (up to and including one > of potentially several configured trust anchors, but typically the > DNSSEC root), this shouldn't be a problem using your suggested > function. All a monitor would have to do is to use the timestamp from > the log entry as the 'moment' argument. > > While perhaps not strictly necessary, I think this will be useful > especially for spam mitigation -- a log could choose to refuse records > that are deemed too old for being interesting and stop someone trying to > fill up the log by submitting a gazillion of old DS records they've > stored. > > > Last, to my request for a validation function accepting RR's in wire > format. Since all RR's to and from the log will be sent in DNS wire > format, it'd be more conventient if I could use that with the > getdns_validate_dnssec() function (or its variant with 'moment'). As it > is now, I have to first turn the wire format into getdns_dict's and then > put them in getdns_list's. What do you think? Hi Linus, Although currently the returned getdns_dicts are indeed data structures, constructed from the wire format data *before* being returned; it is (and has long be) my intention to postpone parsing that wire format until you actually access it. So for example this usage of an access function to read the AD bit: getdns_dict_get_int(response, "/replies_tree/0/header/ad", &ad); would then internally be equivalent with *ret = response->replies[0][2] & 0x20 ? 1 : 0; So in that sense you may as well consider those "conversion" functions (at least for the big wire format blobs, like complete replies) more like a "create a getdns handle" sort of function. The response dicts that getdns returns b.t.w. offer direct access to the wire format data via the "replies_full" key at the packet level, and the "rdata_raw" keys [1] at the individual resource record level. Also the owner "name" data is returned in wire format just like all of the rdata fields. Getdns doesn't do too much conversion really; It just helps with determining the position, type and boundaries of RRs and rdata fields in the underlying wire format data. That said; We do have a "wire format" validate_dnssec function under the hood: ( https://github.com/getdnsapi/getdns/blob/develop/src/dnssec.c#L3281 ) static int wire_validate_dnssec(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) The to_val, to_val_len should be a DNS packet to validate. The support/support_len and tas/tas_len are also given in DNS packet format; but handled as a list as RR's (doesn't matter in which section) and the headers and the query count are completely ignored. This was convenient implementation wise, because the support packet is then laid out as answers along the branches of the internal chain structure. ( see https://github.com/getdnsapi/getdns/blob/develop/src/dnssec.c#L79 for a good description of the operation and the data structures involved ) I consider this function a bit too low level and too dangerous for public use though. I suppose we could expose the symbol in some form if you really want, but it doesn't seem too much of an effort to convert from wire format to a getdns_list. I.e. for example with the well documented wire2rr_dict_scan ;) : /** * Convert wireformat resource record in a getdns rr_dict representation. * * @param wire A pointer to the pointer of the wireformat buffer. * On return this pointer is moved to after first read * in resource record. * @param wire_sz On input the size of the wire buffer * On output the size is decreased with the length * of the wireformat resource record. * @return rr_dict The returned rr_dict * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t getdns_wire2rr_dict_scan( const uint8_t **wire, size_t *wire_sz, getdns_dict **rr_dict); Suppose (uint8_t *) buf is a buffer containing a list of RRs and (size_t) buf_len is its size; then to convert it to a getdns_list: getdns_list *support_rrs = getdns_list_create(); getdns_dict *rr_dict; getdns_return_t r; size_t n_rrs; n_rrs = 0; while (buf_len > 0) { r = getdns_wire2rr_dict_scan(&buf, &buf_len, &rr_dict); if (r) break; r = getdns_list_set_dict(support_rrs, n_rrs, rr_dict); getdns_dict_destroy(rr_dict); if (r) break; n_rrs++; } We could expose this as getdns_return_t getdns_wire_rrs2list(uint8_t *wire, size_t wire_len, getdns_list **list); But I also like to keep the API as small as possible and don't want to expose a lot of helper functions that you could have easily recreated with the existing functions as well. Cheers & regards, -- Willem [1] be carefull with those "rdata_raw" keys though because they will contain compression pointers! > > > On a side note, it'd be great to have you and other DNS and DNSSEC > experts participating in the transparency discussions over at [1]. > > [1] https://lists.sunet.se/listinfo/dnssec-transparency > > > Willem Toorop wrote > Thu, 11 Feb 2016 10:25:24 +0100: > > | I know you're interested to validate resource records at specified > | moments. I'll try to expose a "non-API" version of the > | getdns_validate_dnssec() function with that extra parameter in the > | upcoming release. I.e. > | > | getdns_return_t getdns_validate_dnssec2( > | getdns_list *to_validate, > | getdns_list *bundle_of_support_records, > | getdns_list *trust_anchor_records, > | time_t moment > | ); > | > | OK? > | > | -- Willem > | > | Op 11-02-16 om 10:15 schreef Willem Toorop: > | > Hi Linus, > | > > | > Rereading that message you are referring, I realise that a lot has been > | > improved since may 2015. > | > > | > The dnssec_return_validation_chain extension currently works perfectly > | > inn all possible circumstances. The chain will also contain proofs for > | > insecure zones. > | > > | > The record_to_validate parameter to getdns_validate_dnssec() may now > | > also contain a list of reply dicts to validate actual DNS packets. This > | > allows to also validate proof of denial of existence or insecure > | > NXDOMAINs etc. > | > > | > The getdns_query program (did you compile the binary with > | > --with-getdns_query ?) contains example usage of getdns_validate_dnssec > | > and will revalidate the answer with getdns_validate_dnssec() when the > | > dnssec_return_validation_chain was used. This happens in function > | > validate_chain on line 537 of getdns_query.c. > | > > | > It basically boils down to: > | > > | > getdns_return_t validate_chain(getdns_dict *response) > | > { > | > getdns_status r = GETDNS_RETURN_GENERIC_ERROR; > | > getdns_list *trust_anchor; > | > getdns_list *validation_chain; > | > getdns_list *replies_tree; > | > > | > /* Get the trust anchors ... > | > */ > | > if (getdns_context_get_dnssec_trust_anchors( > | > context, &trust_anchor)) > | > trust_anchor = getdns_root_trust_anchor(NULL); > | > > | > if (!trust_anchor) > | > fprintf(stderr, "No trust anchor to validate with.\n"); > | > > | > /* ... get the validation chain ... > | > */ > | > else if ((r = getdns_dict_get_list( > | > response, "validation_chain", &validation_chain))) > | > fprintf(stderr, "Could not get validation chain\n"); > | > > | > > | > /* .. get the replies tree .. > | > */ > | > else if (r = getdns_dict_get_list( > | > response, "replies_tree", &replies_tree))) > | > fprintf(stderr, "Could not get replies tree\n"); > | > > | > /* .. and validate. > | > */ > | > else switch(getdns_validate_dnssec( > | > replies_tree, validation_chain, trust_anchors)) { > | > > | > case GETDNS_DNSSEC_SECURE : printf("Replies are secure\n"); > | > return GETDNS_RETURN_GOOD; > | > > | > case GETDNS_DNSSEC_INDETERMINATE: > | > case GETDNS_DNSSEC_INSECURE: printf("Replies are insecure\n"); > | > return GETDNS_RETURN_GOOD; > | > > | > case GETDNS_DNSSEC_BOGUS : printf("Replies are bogus\n"); > | > return GETDNS_RETURN_GOOD; > | > > | > default : /* Not possible to get here */ > | > fprintf( stderr > | > , "Unkown dnssec status\n"); > | > return GETDNS_RETURN_GENERIC_ERROR; > | > } > | > return r; > | > } > | > > | > Op 10-02-16 om 20:44 schreef Linus Nordberg: > | >> Hi list, > | >> > | >> I've been trying to use the "dnssec_return_validation_chain" extension, > | >> so far without luck. I define luck as seeing a "validation_chain" > | >> section in a reply. I have verified that my context has proper trust > | >> anchor(s). > | >> > | >> It'd be great to be able to run some example code, C or Python, to rule > | >> out local problems at my end. > | >> > | >> My ultimate goal with this exercise is to understand what to pass in the > | >> support_records argument to getdns_validate_dnssec(). The rationale > | >> behind this is > | >> https://getdnsapi.net/pipermail/users/2015-May/000032.html which says > | >> > | >> --8<---------------cut here---------------start------------->8--- > | >> - bundle_of_support_records must be a list of DS's RR-dicts and DNSKEY > | >> RR-dicts with companion RRSIG-RR-dicts that lead up from one of the > | >> trust_anchors to the RR-dicts to validate. > | >> ... > | >> If you would do a query with the "dnssec_return_validation_chain" > | >> extension, you can use the "validation_chain" key in the response dict > | >> as the bundle_of_support_records parameter ro getdns_validate_dnssec. > | >> --8<---------------cut here---------------end--------------->8--- > | >> > | >> Thanks, > | >> Linus > | >> _______________________________________________ > | >> Users mailing list > | >> Users at getdnsapi.net > | >> http://getdnsapi.net/mailman/listinfo/users>> > | > > | > _______________________________________________ > | > Users mailing list > | > Users at getdnsapi.net > | > http://getdnsapi.net/mailman/listinfo/users> > | > | _______________________________________________ > | Users mailing list > | Users at getdnsapi.net > | http://getdnsapi.net/mailman/listinfo/users > From pch-getdns at u-1.phicoh.com Fri Feb 26 13:01:23 2016 From: pch-getdns at u-1.phicoh.com (Philip Homburg) Date: Fri, 26 Feb 2016 14:01:23 +0100 Subject: [getdns-users] STUB mode, does it validate DNSSEC security? In-Reply-To: Your message of "Fri, 26 Feb 2016 10:20:10 +0100 ." <56D018CA.8070706@nlnetlabs.nl> References: <56CEC772.8020607@openfortress.nl> <56CF4829.2060804@nomountain.net> <56D018CA.8070706@nlnetlabs.nl> Message-ID: In your letter dated Fri, 26 Feb 2016 10:20:10 +0100 you wrote: >Op 25-02-16 om 19:30 schreef Melinda Shore: >> On 2/25/16 12:20 AM, Rick van Rein wrote: >>> 2. I was looking into GetDNS as an possible alternative for libunbound >>> (and got a bit confused because they're both from NLNet Labs) and if I'm >>> getting it correctly, then GetDNS is meant to be wrapped for >>> script-style languages, but given the string-indexed dictionary >>> structures returned it strikes me as more complex to use in a C program >>> than libunbound; or am I missing something? >> >> Hi, Rick: >> >> Yes, there's no question that the original data structure >> design was extremely clunky for C programmers. This was >> recognized fairly early on, so Willem came up with a > >Uh-hum... so Philip Homburg suggested to use expressions in the lookup >strings to get to more deeply nested information for the first time >during the IETF in Prague I believe. JSON pointer syntax was suggested >by Joe Hildebrand. As a long time C programmer with some experience with python, etc. it is very clear that getdns is completely different from normal C APIs. However, for DNS this approach seems to be a good fit. It takes some getting used to. It helps if you have already experience dealing with JSON, etc. Typically, DNS involves variable length strings anyhow, so getdns doesn't seem to be worse from that point of view. Always using snprintf, strlcpy, strlcat should be enough there. While writing some code that uses getdns I realized that having to manually navigate the result structure one step at the time was not very nice. So I suggested to Willem to add some syntax to refer to deeper fields directly. I didn't know that there was already an official JSON pointer syntax. That reminds me that I have to update my code to actually use this feature :-) From robert.groenenberg at broadforward.com Thu Feb 25 14:37:32 2016 From: robert.groenenberg at broadforward.com (Robert Groenenberg) Date: Thu, 25 Feb 2016 15:37:32 +0100 Subject: [getdns-api] Memory leaks in getdns_context_get_api_information() Message-ID: <56CF11AC.3010907@broadforward.com> Hi, While testing my application, which uses getdns 0.9.0, I found two small memory leaks related to getdns_context_get_api_information(), but probably I'm missing something... I destroy the returned dict from getdns_context_get_api_information(), but according to valgrind there are two leaks. The first (context.c:2948) refers to the dns transport list, the second to the namespaces list. Apparently these are not freed as part of the getdns_dict_destroy(). Am I forgetting to destroy something? res = getdns_context_create(&ctxt, 0); if (res == GETDNS_RETURN_GOOD) { dict = *getdns_context_get_api_information*(ctxt); if (dict != NULL) { if ((res = *getdns_dict_get_bindata*(dict, "/version_string", &version)) == GETDNS_RETURN_GOOD)) { trace_mod(TRACE_INFO, "Using getdns library version %.*s", version->size, version->data); } *getdns_dict_destroy*(dict); dict = NULL; } else { trace_mod(BF_TRACE_ERROR, "Failed to initialise getdns library: %s (%d)", getdns_get_errorstr_by_id(res), res); retval = FAILURE; } /* Cleanup */ *getdns_context_destroy*(ctxt); ctxt = NULL; } > ==11484== 216 (56 direct, 160 indirect) bytes in 1 blocks are > definitely lost in loss record 637 of 686 > ==11484== at 0x4A08455: malloc (vg_replace_malloc.c:299) > ==11484== by 0x224B6F86: > getdns_list_create_with_extended_memory_functions (list.c:380) > ==11484== by 0x224C5F15: _get_context_settings (context.c:2948) > ==11484== by 0x224C5F15: *getdns_context_get_api_information > *(context.c:2986) > ==11484== by 0x22191724: mf_am_init (enum_init.c:136) > ==11484== by 0x4366F0: mf_am_process_init (mf_am.c:837) > ==11484== by 0x43B23A: mf_core_init (mf_core.c:487) > ==11484== by 0x40FB31: main (mf_main.c:422) > ==11484== > ==11484== 216 (56 direct, 160 indirect) bytes in 1 blocks are > definitely lost in loss record 638 of 686 > ==11484== at 0x4A08455: malloc (vg_replace_malloc.c:299) > ==11484== by 0x224B6F86: > getdns_list_create_with_extended_memory_functions (list.c:380) > ==11484== by 0x224C5DE2: _get_context_settings (context.c:2960) > ==11484== by 0x224C5DE2: *getdns_context_get_api_information* > (context.c:2986) > ==11484== by 0x22191724: mf_am_init (enum_init.c:136) > ==11484== by 0x4366F0: mf_am_process_init (mf_am.c:837) > ==11484== by 0x43B23A: mf_core_init (mf_core.c:487) > ==11484== by 0x40FB31: main (mf_main.c:422) Thanks, Robert -------------- next part -------------- An HTML attachment was scrubbed... URL: From willem at nlnetlabs.nl Fri Feb 26 11:28:16 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Fri, 26 Feb 2016 12:28:16 +0100 Subject: [getdns-api] Memory leaks in getdns_context_get_api_information() In-Reply-To: <56CF11AC.3010907@broadforward.com> References: <56CF11AC.3010907@broadforward.com> Message-ID: <56D036D0.90505@nlnetlabs.nl> Thank you Robert! Good catch. I've committed a fix: https://github.com/getdnsapi/getdns/commit/6fd05675aa96337b164bd7e9e480cc30f7eb9897 Best regards, -- Willem Op 25-02-16 om 15:37 schreef Robert Groenenberg: > Hi, > > While testing my application, which uses getdns 0.9.0, I found two small > memory leaks related to getdns_context_get_api_information(), but > probably I'm missing something... > > I destroy the returned dict from getdns_context_get_api_information(), > but according to valgrind there are two leaks. The first > (context.c:2948) refers to the dns transport list, the second to the > namespaces list. Apparently these are not freed as part of the > getdns_dict_destroy(). > > Am I forgetting to destroy something? > > res = getdns_context_create(&ctxt, 0); > if (res == GETDNS_RETURN_GOOD) > { > dict = *getdns_context_get_api_information*(ctxt); > if (dict != NULL) > { > if ((res = *getdns_dict_get_bindata*(dict, > "/version_string", > &version)) == > GETDNS_RETURN_GOOD)) > { > trace_mod(TRACE_INFO, > "Using getdns library version %.*s", > version->size, version->data); > } > *getdns_dict_destroy*(dict); > dict = NULL; > } > else > { > trace_mod(BF_TRACE_ERROR, > "Failed to initialise getdns library: %s (%d)", > getdns_get_errorstr_by_id(res), res); > retval = FAILURE; > } > > /* Cleanup */ > *getdns_context_destroy*(ctxt); > ctxt = NULL; > } > >> ==11484== 216 (56 direct, 160 indirect) bytes in 1 blocks are >> definitely lost in loss record 637 of 686 >> ==11484== at 0x4A08455: malloc (vg_replace_malloc.c:299) >> ==11484== by 0x224B6F86: >> getdns_list_create_with_extended_memory_functions (list.c:380) >> ==11484== by 0x224C5F15: _get_context_settings (context.c:2948) >> ==11484== by 0x224C5F15: *getdns_context_get_api_information >> *(context.c:2986) >> ==11484== by 0x22191724: mf_am_init (enum_init.c:136) >> ==11484== by 0x4366F0: mf_am_process_init (mf_am.c:837) >> ==11484== by 0x43B23A: mf_core_init (mf_core.c:487) >> ==11484== by 0x40FB31: main (mf_main.c:422) >> ==11484== >> ==11484== 216 (56 direct, 160 indirect) bytes in 1 blocks are >> definitely lost in loss record 638 of 686 >> ==11484== at 0x4A08455: malloc (vg_replace_malloc.c:299) >> ==11484== by 0x224B6F86: >> getdns_list_create_with_extended_memory_functions (list.c:380) >> ==11484== by 0x224C5DE2: _get_context_settings (context.c:2960) >> ==11484== by 0x224C5DE2: *getdns_context_get_api_information* >> (context.c:2986) >> ==11484== by 0x22191724: mf_am_init (enum_init.c:136) >> ==11484== by 0x4366F0: mf_am_process_init (mf_am.c:837) >> ==11484== by 0x43B23A: mf_core_init (mf_core.c:487) >> ==11484== by 0x40FB31: main (mf_main.c:422) > > Thanks, > Robert > > > _______________________________________________ > spec mailing list > spec at getdnsapi.net >