On 10/03/2012 04:45 PM, Nikos Mavrogiannopoulos wrote:
> On Wed, Oct 3, 2012 at 2:35 PM, W.C.A. Wijngaards <[email protected]> wrote:
> 
>>> Is there some portable way to obtain a DNSSEC trust anchor in a
>>> system? It seems that unlike the other functions which set a
>>> default
>> portable?  I cannot help you with this, perhaps authors of those
>> systems can provide you with their answers.
> 
> I think this shouldn't be left on the unbound application developer.
> Similarly to ub_ctx_hosts() and ub_ctx_resolvconf() there should be an
> option to try some sensible defaults. E.g. try to find the unbound
> root.key file, then try the bind one, and so on. Then patches for the
> various unsupported systems will come to unbound from developers
> working with them. Otherwise this discovery phase will be duplicated
> on every project using unbound, and possibly with varying success.

One option, I think the closest to "platform-independent" would be distributing
the key with the library (like NSS does with builtin certs). Then you can use
ub_ctx_add_ta (see attached sample). Obvious drawback is that you have issue new
version if root key changes or implement key management on your own.

Alternatively, probe for default locations of the key file, then fallback to key
distributed with the library. Also, you could add unbound-anchor to the
distributed archive and run it in a post-install script.

Notes on unbound and defaults:

- I suggest to avoid using forwarder (ub_ctx_set_fwd) as most commonly deployed
recursive DNS resolvers at ISPs will fail for DNSSEC (usually due to DS
records). Instead use libunbound as full recursive resolver. It will take few
queries to get its cache heated, but it's rather quick unless you go over a very
slow network like Tor.
- Attempting to use ub_ctx_hosts() with the default locations on the other hand
might be a good idea in preserving user's mappings for local machines, etc.
- Some distros like Fedora, RHEL and clones distribute unbound with root
anchors, some like Debian/Ubuntu don't. But I generally wouldn't count on the
key being present on a typical user's machine.

Ondrej
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include "unbound.h"
#include "ldns/ldns.h"
#include "ldns/packet.h"
#include "ldns/wire2host.h"

#define RR_TYPE_TLSA 52

int main(void)
{
	struct ub_ctx* ctx;
	struct ub_result* result;
	int retval, i;
        int exitcode = 0;

	/* create context */
	ctx = ub_ctx_create();
	if(!ctx) {
		printf("error: could not create unbound context\n");
		return 1;
	}
	/* read public keys for DNSSEC verification */
	if( (retval=ub_ctx_add_ta(ctx, ".   IN DS   19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5")) != 0) {
		printf("error adding keys: %s\n", ub_strerror(retval));
		return 1;
	}
        if( (retval=ub_ctx_set_option(ctx, "dlv-anchor:", "dlv.isc.org. IN DNSKEY 257 3 5 BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+ cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh"))) {
		printf("error adding DLV keys: %s\n", ub_strerror(retval));
		return 1;
	}

	/* query for TLSA */
	retval = ub_resolve(ctx, "_443._tcp.www.torproject.org", //"_443._tcp.nohats.ca", 
		RR_TYPE_TLSA, 
		1 /* CLASS IN (internet) */, &result);
	if(retval != 0) {
		printf("resolve error: %s\n", ub_strerror(retval));
		return 1;
	}

	/* show first result */
	if(result->havedata) {
                ldns_pkt *packet;
                ldns_status parse_status = ldns_wire2pkt(&packet, (uint8_t*)(result->answer_packet), result->answer_len);
                
                if (parse_status != LDNS_STATUS_OK) {
                        printf("Failed to parse response packet\n");
                        return 1;
                }
                
                ldns_rr_list *rrs = ldns_pkt_rr_list_by_type(packet, RR_TYPE_TLSA, LDNS_SECTION_ANSWER);
                for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
                        /* extract first rdf, which is the whole TLSA record */
                        ldns_rr *rr = ldns_rr_list_rr(rrs, i);
                        if (ldns_rr_rd_count(rr) < 1) {
                                printf("RR %d does have no RDFs\n", i);
                                return 1;
                        }

                        ldns_rdf *rdf = ldns_rr_rdf(rr, 0);
                        
                        size_t rdf_size = ldns_rdf_size(rdf);
                        if (rdf_size < 4) {
                                printf("TLSA record in RR %d too short\n", i);
                                return 1;
                        }

                        uint8_t cert_usage, selector, matching_type;
                        uint8_t *rdf_data = ldns_rdf_data(rdf);

                        cert_usage = rdf_data[0];
                        selector = rdf_data[1];
                        matching_type = rdf_data[2];
                        
                        printf("RR %d: cert usage %d, selector %d, matching type %d, data ",
                                i, cert_usage, selector, matching_type);
                        int n;
                        for(n=3; n<rdf_size; n++) {
                                printf("%02x", rdf_data[n]);
                        }
                        printf("\n");

                        ldns_rr_free(rr);
                }
                
                ldns_pkt_free(packet);
                ldns_rr_list_free(rrs);
        } else {
                printf("We haven't received any data\n");
                return 1;
        }

	/* show security status */
	if(result->secure) {
		printf("Result is secure\n");
	} else if(result->bogus) {
		printf("Result is bogus: %s\n", result->why_bogus);
                exitcode = 1;
	} else 	{
                printf("Result is insecure\n");
                exitcode = 1;
        }

	ub_resolve_free(result);
	ub_ctx_delete(ctx);
	return exitcode;
}

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Unbound-users mailing list
[email protected]
http://unbound.nlnetlabs.nl/mailman/listinfo/unbound-users

Reply via email to