Native DS with DNSKEY compare + rm ldns dependency

This commit is contained in:
Willem Toorop 2015-09-25 14:28:47 +02:00
parent d8cc7b1ba3
commit 59f4feb5e6
2 changed files with 71 additions and 85 deletions

View File

@ -469,26 +469,6 @@ else
fi fi
fi fi
# find libldns
AC_ARG_WITH(libldns, AS_HELP_STRING([--with-libldns=pathname],
[path to libldns (default: search /usr/local ..)]),
[], [withval="yes"])
if test x_$withval = x_yes; then
for dir in /usr/local /opt/local /usr/pkg /usr/sfw; do
if test -f "$dir/include/ldns/ldns.h"; then
CFLAGS="$CFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
AC_MSG_NOTICE([Found libldns in $dir])
break
fi
done
else
if test x_$withval != x_no; then
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
fi
fi
if test $my_with_libunbound = 1 if test $my_with_libunbound = 1
then then
# find libunbound # find libunbound
@ -517,18 +497,12 @@ fi
# Checks for libraries. # Checks for libraries.
found_all_libs=1 found_all_libs=1
AC_MSG_NOTICE([Checking for dependency ldns])
AC_CHECK_LIB([ldns], [ldns_dname_new_frm_str], [], [found_all_libs=0])
if test $my_with_libidn = 1 if test $my_with_libidn = 1
then then
AC_MSG_NOTICE([Checking for dependency libidn]) AC_MSG_NOTICE([Checking for dependency libidn])
AC_CHECK_LIB([idn], [idna_to_ascii_8z], [], [found_all_libs=0]) AC_CHECK_LIB([idn], [idna_to_ascii_8z], [], [found_all_libs=0])
fi fi
AC_CHECK_MEMBER([struct ldns_struct_dnssec_zone.hashed_names],
[AC_DEFINE_UNQUOTED([LDNS_DNSSEC_ZONE_HASHED_NAMES], [1], [When defined ldns_dnssec_zone contained the hashed_names member.])], [], [[#include <ldns/ldns.h>]])
if test $my_with_libunbound = 1 if test $my_with_libunbound = 1
then then
AC_MSG_NOTICE([Checking for dependency libunbound]) AC_MSG_NOTICE([Checking for dependency libunbound])

View File

@ -191,7 +191,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <ldns/ldns.h> #include <ctype.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include "getdns/getdns.h" #include "getdns/getdns.h"
#include "config.h" #include "config.h"
@ -1384,18 +1384,6 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset)
return 0; return 0;
} }
static ldns_rr *rr2ldns_rr(_getdns_rr_iter *rr)
{
ldns_rr *rr_l;
size_t pos = rr->pos - rr->pkt;
if (ldns_wire2rr(&rr_l, rr->pkt, rr->pkt_end - rr->pkt, &pos,
(ldns_pkt_section)_getdns_rr_iter_section(rr)))
return NULL;
else
return rr_l;
}
static size_t _rr_uncompressed_rdata_size(rrtype_iter *rr) static size_t _rr_uncompressed_rdata_size(rrtype_iter *rr)
{ {
_getdns_rdf_iter *rdf, rdf_spc; _getdns_rdf_iter *rdf, rdf_spc;
@ -1485,17 +1473,17 @@ inline static void canon_rdata_iter_next(canon_rdata_iter *i)
inline static int _dnssec_rdata_to_canonicalize(uint16_t rr_type) inline static int _dnssec_rdata_to_canonicalize(uint16_t rr_type)
{ {
return rr_type == LDNS_RR_TYPE_NS || rr_type == LDNS_RR_TYPE_MD return rr_type == GLDNS_RR_TYPE_NS || rr_type == GLDNS_RR_TYPE_MD
|| rr_type == LDNS_RR_TYPE_MF || rr_type == LDNS_RR_TYPE_CNAME || rr_type == GLDNS_RR_TYPE_MF || rr_type == GLDNS_RR_TYPE_CNAME
|| rr_type == LDNS_RR_TYPE_SOA || rr_type == LDNS_RR_TYPE_MB || rr_type == GLDNS_RR_TYPE_SOA || rr_type == GLDNS_RR_TYPE_MB
|| rr_type == LDNS_RR_TYPE_MG || rr_type == LDNS_RR_TYPE_MR || rr_type == GLDNS_RR_TYPE_MG || rr_type == GLDNS_RR_TYPE_MR
|| rr_type == LDNS_RR_TYPE_PTR || rr_type == LDNS_RR_TYPE_MINFO || rr_type == GLDNS_RR_TYPE_PTR || rr_type == GLDNS_RR_TYPE_MINFO
|| rr_type == LDNS_RR_TYPE_MX || rr_type == LDNS_RR_TYPE_RP || rr_type == GLDNS_RR_TYPE_MX || rr_type == GLDNS_RR_TYPE_RP
|| rr_type == LDNS_RR_TYPE_AFSDB || rr_type == LDNS_RR_TYPE_RT || rr_type == GLDNS_RR_TYPE_AFSDB || rr_type == GLDNS_RR_TYPE_RT
|| rr_type == LDNS_RR_TYPE_SIG || rr_type == LDNS_RR_TYPE_PX || rr_type == GLDNS_RR_TYPE_SIG || rr_type == GLDNS_RR_TYPE_PX
|| rr_type == LDNS_RR_TYPE_NXT || rr_type == LDNS_RR_TYPE_NAPTR || rr_type == GLDNS_RR_TYPE_NXT || rr_type == GLDNS_RR_TYPE_NAPTR
|| rr_type == LDNS_RR_TYPE_KX || rr_type == LDNS_RR_TYPE_SRV || rr_type == GLDNS_RR_TYPE_KX || rr_type == GLDNS_RR_TYPE_SRV
|| rr_type == LDNS_RR_TYPE_DNAME || rr_type == LDNS_RR_TYPE_RRSIG; || rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
} }
static int _rr_iter_rdata_cmp(const void *a, const void *b) static int _rr_iter_rdata_cmp(const void *a, const void *b)
@ -1918,10 +1906,12 @@ static int ds_authenticates_keys(
rrtype_iter ds_spc, *ds; rrtype_iter ds_spc, *ds;
uint16_t keytag; uint16_t keytag;
uint8_t *nc_name; uint8_t *nc_name;
ldns_rr *dnskey_l, *ds_gen_l, *ds_l;
size_t valid_dsses = 0, supported_dsses = 0; size_t valid_dsses = 0, supported_dsses = 0;
uint8_t max_supported_digest = 0; uint8_t max_supported_digest = 0;
int max_supported_result = 0; int max_supported_result = 0;
unsigned char digest_spc[256], *digest;
unsigned char digest_buf_spc[2048], *digest_buf;
size_t digest_len, digest_buf_len, dnskey_owner_len;
assert(ds_set->rr_type == GETDNS_RRTYPE_DS); assert(ds_set->rr_type == GETDNS_RRTYPE_DS);
assert(dnskey_set->rr_type == GETDNS_RRTYPE_DNSKEY); assert(dnskey_set->rr_type == GETDNS_RRTYPE_DNSKEY);
@ -1934,6 +1924,12 @@ static int ds_authenticates_keys(
debug_sec_print_rrset("ds_authenticates_keys DS: ", ds_set); debug_sec_print_rrset("ds_authenticates_keys DS: ", ds_set);
debug_sec_print_rrset("ds_authenticates_keys DNSKEY: ", dnskey_set); debug_sec_print_rrset("ds_authenticates_keys DNSKEY: ", dnskey_set);
if ((dnskey_owner_len = _dname_len(dnskey_set->name)) >= 255)
return 0;
(void) memcpy(digest_buf_spc, dnskey_set->name, dnskey_owner_len);
_dname_canonicalize(digest_buf_spc);
for ( dnskey = rrtype_iter_init(&dnskey_spc, dnskey_set) for ( dnskey = rrtype_iter_init(&dnskey_spc, dnskey_set)
; dnskey ; dnskey = rrtype_iter_next(dnskey)) { ; dnskey ; dnskey = rrtype_iter_next(dnskey)) {
@ -1944,8 +1940,6 @@ static int ds_authenticates_keys(
keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10, keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10); dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
dnskey_l = NULL;
for ( ds = rrtype_iter_init(&ds_spc, ds_set) for ( ds = rrtype_iter_init(&ds_spc, ds_set)
; ds ; ds = rrtype_iter_next(ds)) { ; ds ; ds = rrtype_iter_next(ds)) {
@ -1966,28 +1960,40 @@ static int ds_authenticates_keys(
ds->rr_i.rr_type[12] == GLDNS_RSAMD5 ds->rr_i.rr_type[12] == GLDNS_RSAMD5
/* Algorithm is supported */ /* Algorithm is supported */
|| !ldns_key_algo_supported(ds->rr_i.rr_type[12])) || !_getdns_dnskey_algo_id_is_supported(
ds->rr_i.rr_type[12])
/* Digest is supported */
|| !(digest_len = _getdns_ds_digest_size_supported(
ds->rr_i.rr_type[13])))
continue; continue;
if (!dnskey_l) digest = digest_len <= sizeof(digest_spc) ? digest_spc
if (!(dnskey_l = rr2ldns_rr(&dnskey->rr_i))) : GETDNS_XMALLOC(*mf, unsigned char, digest_len);
continue;
/* Unfortunately there is no ldns_ds_digest_supported() digest_buf_len = dnskey->rr_i.nxt
* function. The only way to check if a digest type is - dnskey->rr_i.rr_type - 10
* supported, is by trying to hashing the key with the + dnskey_owner_len;
* given digest type. digest_buf = digest_buf_len <= sizeof(digest_buf_spc)
*/ ? digest_buf_spc
if (!(ds_gen_l = ldns_key_rr2ds(dnskey_l, : GETDNS_XMALLOC(*mf, unsigned char, digest_buf_len);
ds->rr_i.rr_type[13])))
/* Hash algorithm not supported */ if (digest_buf != digest_buf_spc)
continue; (void) memcpy(digest_buf,
digest_buf_spc, dnskey_owner_len);
if (ldns_rr_rd_count(ds_gen_l) < 4) { (void) memcpy(digest_buf + dnskey_owner_len,
ldns_rr_free(ds_gen_l); dnskey->rr_i.rr_type + 10,
/* Hash algorithm not supported */ dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
if (!_getdns_secalgo_ds_digest(ds->rr_i.rr_type[13],
digest_buf, digest_buf_len, digest)) {
if (digest != digest_spc)
GETDNS_FREE(*mf, digest);
if (digest_buf != digest_buf_spc)
GETDNS_FREE(*mf, digest_buf);
continue; continue;
} }
supported_dsses++; supported_dsses++;
@ -2005,26 +2011,33 @@ static int ds_authenticates_keys(
*/ */
|| ( ds->rr_i.rr_type[13] == max_supported_digest || ( ds->rr_i.rr_type[13] == max_supported_digest
&& max_supported_result)) { && max_supported_result)) {
ldns_rr_free(ds_gen_l); if (digest != digest_spc)
GETDNS_FREE(*mf, digest);
if (digest_buf != digest_buf_spc)
GETDNS_FREE(*mf, digest_buf);
DEBUG_SEC("Better DS available\n");
continue; continue;
} }
max_supported_digest = ds->rr_i.rr_type[13]; max_supported_digest = ds->rr_i.rr_type[13];
max_supported_result = 0; max_supported_result = 0;
if (!(ds_l = rr2ldns_rr(&ds->rr_i))) { if (digest_len != ds->rr_i.nxt - ds->rr_i.rr_type-14
ldns_rr_free(ds_gen_l); || memcmp(digest, ds->rr_i.rr_type+14, digest_len) != 0) {
continue; if (digest != digest_spc)
} GETDNS_FREE(*mf, digest);
if (digest_buf != digest_buf_spc)
GETDNS_FREE(*mf, digest_buf);
if (ldns_rr_compare(ds_l, ds_gen_l) != 0) { DEBUG_SEC("HASH length mismatch %zu != %zu\n",
/* No match */ digest_len, ds->rr_i.nxt - ds->rr_i.rr_type-14);
ldns_rr_free(ds_l);
ldns_rr_free(ds_gen_l);
continue; continue;
} }
/* Match! */ /* Match! */
ldns_rr_free(ds_l); if (digest != digest_spc)
ldns_rr_free(ds_gen_l); GETDNS_FREE(*mf, digest);
if (digest_buf != digest_buf_spc)
GETDNS_FREE(*mf, digest_buf);
if (!dnskey_signed_rrset(mf,dnskey,dnskey_set,&nc_name) if (!dnskey_signed_rrset(mf,dnskey,dnskey_set,&nc_name)
|| nc_name /* No DNSKEY's on wildcards! */) { || nc_name /* No DNSKEY's on wildcards! */) {
@ -2037,7 +2050,6 @@ static int ds_authenticates_keys(
"keyset authenticated: ", dnskey_set); "keyset authenticated: ", dnskey_set);
max_supported_result = SIGNATURE_VERIFIED | keytag; max_supported_result = SIGNATURE_VERIFIED | keytag;
} }
ldns_rr_free(dnskey_l);
} }
DEBUG_SEC("valid_dsses: %zu, supported_dsses: %zu\n", DEBUG_SEC("valid_dsses: %zu, supported_dsses: %zu\n",
valid_dsses, supported_dsses); valid_dsses, supported_dsses);
@ -2769,8 +2781,8 @@ static int chain_head_validate(
; rr; rr = rrtype_iter_next(rr)) { ; rr; rr = rrtype_iter_next(rr)) {
if ( rr->rr_i.rr_type + 14 <= rr->rr_i.nxt if ( rr->rr_i.rr_type + 14 <= rr->rr_i.nxt
&& rr->rr_i.rr_type[13] != GLDNS_RSAMD5 /* Deprecated */ && _getdns_dnskey_algo_id_is_supported(
&& ldns_key_algo_supported(rr->rr_i.rr_type[13])) rr->rr_i.rr_type[13]))
supported_algorithms++; supported_algorithms++;
} }
@ -3334,9 +3346,9 @@ _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf)
if (len == 0) /* empty, $TTL, $ORIGIN */ if (len == 0) /* empty, $TTL, $ORIGIN */
continue; continue;
if (gldns_wirerr_get_type(rr, len, dname_len) if (gldns_wirerr_get_type(rr, len, dname_len)
!= LDNS_RR_TYPE_DS && != GLDNS_RR_TYPE_DS &&
gldns_wirerr_get_type(rr, len, dname_len) gldns_wirerr_get_type(rr, len, dname_len)
!= LDNS_RR_TYPE_DNSKEY) != GLDNS_RR_TYPE_DNSKEY)
continue; continue;
gldns_buffer_write(gbuf, rr, len); gldns_buffer_write(gbuf, rr, len);