diff --git a/CMakeLists.txt b/CMakeLists.txt index 15a56bca7..a8e731d06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,6 @@ cmake_minimum_required(VERSION 2.8.12) project(PIHOLE_FTL C) -set(DNSMASQ_VERSION pi-hole-v2.88test3) +set(DNSMASQ_VERSION pi-hole-v2.88rc1) add_subdirectory(src) diff --git a/src/dnsmasq/crypto.c b/src/dnsmasq/crypto.c index 060e27ffe..2678683ec 100644 --- a/src/dnsmasq/crypto.c +++ b/src/dnsmasq/crypto.c @@ -309,14 +309,14 @@ static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_l mpz_init(y); } - mpz_import(x, 32 , 1, 1, 0, 0, p); - mpz_import(y, 32 , 1, 1, 0, 0, p + 32); + mpz_import(x, 32, -1, 1, 0, 0, p); + mpz_import(y, 32, -1, 1, 0, 0, p + 32); if (!ecc_point_set(gost_key, x, y)) - return 0; + return 0; - mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig); - mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32); + mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig); + mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig + 32); return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct); } @@ -390,7 +390,12 @@ static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key return dnsmasq_ecdsa_verify; #if MIN_VERSION(3, 1) - case 15: case 16: + case 15: + return dnsmasq_eddsa_verify; +#endif + +#if MIN_VERSION(3, 6) + case 16: return dnsmasq_eddsa_verify; #endif } @@ -425,7 +430,9 @@ char *ds_digest_name(int digest) { case 1: return "sha1"; case 2: return "sha256"; - case 3: return "gosthash94"; +#if MIN_VERSION(3, 6) + case 3: return "gosthash94cp"; +#endif case 4: return "sha384"; default: return NULL; } @@ -444,11 +451,17 @@ char *algo_digest_name(int algo) case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */ case 8: return "sha256"; /* RSA/SHA-256 */ case 10: return "sha512"; /* RSA/SHA-512 */ - case 12: return "gosthash94"; /* ECC-GOST */ +#if MIN_VERSION(3, 6) + case 12: return "gosthash94cp"; /* ECC-GOST */ +#endif case 13: return "sha256"; /* ECDSAP256SHA256 */ case 14: return "sha384"; /* ECDSAP384SHA384 */ +#if MIN_VERSION(3, 1) case 15: return "null_hash"; /* ED25519 */ +# if MIN_VERSION(3, 6) case 16: return "null_hash"; /* ED448 */ +# endif +#endif default: return NULL; } } diff --git a/src/dnsmasq/dnssec.c b/src/dnsmasq/dnssec.c index daf679e07..ce01b2e6b 100644 --- a/src/dnsmasq/dnssec.c +++ b/src/dnsmasq/dnssec.c @@ -979,10 +979,13 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch } /* The DNS packet is expected to contain the answer to a DS query - Put all DSs in the answer which are valid into the cache. + Put all DSs in the answer which are valid and have hash and signature algos + we support into the cache. Also handles replies which prove that there's no DS at this location, either because the zone is unsigned or this isn't a zone cut. These are cached too. + If none of the DS's are for supported algos, treat the answer as if + it's a proof of no DS at this location. RFC4035 para 5.2. return codes: STAT_OK At least one valid DS found and in cache. STAT_BOGUS no DS in reply or not signed, fails validation, bad packet. @@ -993,8 +996,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class) { unsigned char *p = (unsigned char *)(header+1); - int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0; - int aclass, atype, rdlen; + int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0, found_supported = 0; + int aclass, atype, rdlen, flags; unsigned long ttl; union all_addr a; @@ -1065,14 +1068,22 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char algo = *p++; digest = *p++; - if ((key = blockdata_alloc((char*)p, rdlen - 4))) + if (!ds_digest_name(digest) || !ds_digest_name(digest)) + { + a.log.keytag = keytag; + a.log.algo = algo; + a.log.digest = digest; + log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0); + neg_ttl = ttl; + } + else if ((key = blockdata_alloc((char*)p, rdlen - 4))) { a.ds.digest = digest; a.ds.keydata = key; a.ds.algo = algo; a.ds.keytag = keytag; a.ds.keylen = rdlen - 4; - + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)) { blockdata_free(key); @@ -1083,26 +1094,29 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char a.log.keytag = keytag; a.log.algo = algo; a.log.digest = digest; - if (ds_digest_name(digest) && algo_digest_name(algo)) - log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0); - else - log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0); + log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0); + found_supported = 1; } } p = psave; } + if (!ADD_RDLEN(header, p, plen, rdlen)) return STAT_BOGUS; /* bad packet */ } cache_end_insert(); + /* Fall through if no supported algo DS found. */ + if (found_supported) + return STAT_OK; } - else + + flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK; + + if (neganswer) { - int flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK; - if (RCODE(header) == NXDOMAIN) flags |= F_NXDOMAIN; @@ -1110,17 +1124,18 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char to store presence/absence of NS. */ if (nons) flags &= ~F_DNSSECOK; - - cache_start_insert(); - - /* Use TTL from NSEC for negative cache entries */ - if (!cache_insert(name, NULL, class, now, neg_ttl, flags)) - return STAT_BOGUS; - - cache_end_insert(); - - log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0); } + + cache_start_insert(); + + /* Use TTL from NSEC for negative cache entries */ + if (!cache_insert(name, NULL, class, now, neg_ttl, flags)) + return STAT_BOGUS; + + cache_end_insert(); + + if (neganswer) + log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0); return STAT_OK; }