}
/* the TTL is already a TTD by now */
- if (!nsec3 && isWildcardExpanded(owner.countLabels(), signatures.at(0))) {
+ if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) {
DNSName realOwner = getNSECOwnerName(owner, signatures);
auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, std::move(realOwner), std::move(next), record.d_ttl});
if (pair.second) {
return false;
}
- if (!isTypeDenied(nsec3, type)) {
+ if (!isTypeDenied(*nsec3, type)) {
VLOG_NO_PREFIX(log, " but the requested type (" << type.toString() << ") does exist" << endl);
return false;
}
const DNSName signer = getSigner(exactNSEC3.d_signatures);
/* here we need to allow an ancestor NSEC3 proving that a DS does not exist as it is an
exact match for the name */
- if (type != QType::DS && isNSEC3AncestorDelegation(signer, exactNSEC3.d_owner, nsec3)) {
+ if (type != QType::DS && isNSEC3AncestorDelegation(signer, exactNSEC3.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
const DNSName signer = getSigner(closestNSEC3.d_signatures);
/* This time we do not allow any ancestor NSEC3, as if the closest encloser is a delegation
NS we know nothing about the names in the child zone. */
- if (isNSEC3AncestorDelegation(signer, closestNSEC3.d_owner, nsec3)) {
+ if (isNSEC3AncestorDelegation(signer, closestNSEC3.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
const DNSName wcSigner = getSigner(wcEntry.d_signatures);
/* It's an exact match for the wildcard, so it does exist. If we are looking for a DS
an ancestor NSEC3 is fine, otherwise it does not prove anything. */
- if (type != QType::DS && isNSEC3AncestorDelegation(wcSigner, wcEntry.d_owner, nsec3)) {
+ if (type != QType::DS && isNSEC3AncestorDelegation(wcSigner, wcEntry.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
return false;
}
- if (!isTypeDenied(nsec3, type)) {
+ if (!isTypeDenied(*nsec3, type)) {
VLOG_NO_PREFIX(log, " but the requested type (" << type.toString() << ") does exist" << endl);
return synthesizeFromNSEC3Wildcard(now, name, type, ret, res, doDNSSEC, nextCloserEntry, wildcard, log);
}
VLOG_NO_PREFIX(log, ": found a possible NSEC at " << entry.d_owner << " ");
// note that matchesNSEC() takes care of ruling out ancestor NSECs for us
- auto denial = matchesNSEC(name, type.getCode(), entry.d_owner, content, entry.d_signatures, log);
+ auto denial = matchesNSEC(name, type.getCode(), entry.d_owner, *content, entry.d_signatures, log);
if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) {
VLOG_NO_PREFIX(log, " but it does not cover us" << endl);
return false;
auto nsecContent = std::dynamic_pointer_cast<const NSECRecordContent>(wcEntry.d_record);
- denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, nsecContent, wcEntry.d_signatures, log);
+ denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, *nsecContent, wcEntry.d_signatures, log);
if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) {
if (wcEntry.d_owner == wc) {
if (rrsig) {
if (rrsig->d_type == QType::SOA) {
ne.authoritySOA.signatures.push_back(rec);
- if (lowestTTL && isRRSIGNotExpired(now, rrsig)) {
+ if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) {
*lowestTTL = min(*lowestTTL, rec.d_ttl);
*lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig));
}
}
if (nsecTypes.count(rrsig->d_type)) {
ne.DNSSECRecords.signatures.push_back(rec);
- if (lowestTTL && isRRSIGNotExpired(now, rrsig)) {
+ if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) {
*lowestTTL = min(*lowestTTL, rec.d_ttl);
*lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig));
}
lowestTTD = min(lowestTTD, static_cast<uint32_t>(signaturesTTL + d_now.tv_sec));
for (const auto& sig : signatures) {
- if (isRRSIGNotExpired(d_now.tv_sec, sig)) {
+ if (isRRSIGNotExpired(d_now.tv_sec, *sig)) {
// we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */
lowestTTD = min(lowestTTD, static_cast<uint32_t>(sig->d_sigexpire));
}
if (entry->d_type == QType::RRSIG && validationEnabled()) {
auto rrsig = getRR<RRSIGRecordContent>(*entry);
if (rrsig) {
- if (isRRSIGNotExpired(d_now.tv_sec, rrsig)) {
+ if (isRRSIGNotExpired(d_now.tv_sec, *rrsig)) {
// we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */
lowestTTD = min(lowestTTD, static_cast<uint32_t>(rrsig->d_sigexpire));
}
count can be lower than the name's label count if it was
synthesized from the wildcard. Note that the difference might
be > 1. */
- if (rec.d_name == qname && isWildcardExpanded(labelCount, rrsig)) {
+ if (rec.d_name == qname && isWildcardExpanded(labelCount, *rrsig)) {
gatherWildcardProof = true;
- if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, rrsig)) {
+ if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, *rrsig)) {
/* if we have a wildcard expanded onto itself, we don't need to prove
that the exact name doesn't exist because it actually does.
We still want to gather the corresponding NSEC/NSEC3 records
wildcard in its non-expanded form in the cache to be able to synthesize wildcard answers later */
const auto& rrsig = i->second.signatures.at(0);
- if (isWildcardExpanded(labelCount, rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, rrsig)) {
+ if (isWildcardExpanded(labelCount, *rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, *rrsig)) {
DNSName realOwner = getNSECOwnerName(i->first.name, i->second.signatures);
std::vector<DNSRecord> content;
using nsec3HashesCache = std::map<std::tuple<DNSName, std::string, uint16_t>, std::string>;
-static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr<const NSEC3RecordContent>& nsec3, nsec3HashesCache& cache)
+static std::string getHashFromNSEC3(const DNSName& qname, const NSEC3RecordContent& nsec3, nsec3HashesCache& cache)
{
std::string result;
- if (g_maxNSEC3Iterations && nsec3->d_iterations > g_maxNSEC3Iterations) {
+ if (g_maxNSEC3Iterations && nsec3.d_iterations > g_maxNSEC3Iterations) {
return result;
}
- auto key = std::make_tuple(qname, nsec3->d_salt, nsec3->d_iterations);
+ auto key = std::make_tuple(qname, nsec3.d_salt, nsec3.d_iterations);
auto it = cache.find(key);
if (it != cache.end())
{
return it->second;
}
- result = hashQNameWithSalt(nsec3->d_salt, nsec3->d_iterations, qname);
+ result = hashQNameWithSalt(nsec3.d_salt, nsec3.d_iterations, qname);
cache[key] = result;
return result;
}
continue;
}
- const string h = getHashFromNSEC3(zone, nsec3, cache);
+ const string h = getHashFromNSEC3(zone, *nsec3, cache);
if (h.empty()) {
return false;
}
Labels field of the covering RRSIG RR, then the RRset and its
covering RRSIG RR were created as a result of wildcard expansion."
*/
-bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign)
+bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign)
{
- if (sign && sign->d_labels < labelCount) {
+ if (sign.d_labels < labelCount) {
return true;
}
const auto& sign = signatures.at(0);
unsigned int labelsCount = owner.countLabels();
- return isWildcardExpanded(labelsCount, sign);
+ return isWildcardExpanded(labelsCount, *sign);
}
-bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign)
+bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign)
{
- if (owner.isWildcard() && (labelCount - 1) == sign->d_labels) {
+ if (owner.isWildcard() && (labelCount - 1) == sign.d_labels) {
/* this is a wildcard alright, but it has not been expanded */
return true;
}
const auto& sign = signatures.at(0);
unsigned int labelsCount = owner.countLabels();
- return isWildcardExpandedOntoItself(owner, labelsCount, sign);
+ return isWildcardExpandedOntoItself(owner, labelsCount, *sign);
}
/* if this is a wildcard NSEC, the owner name has been modified
return result;
}
-static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<const NSECRecordContent>& nsec)
+static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const NSECRecordContent& nsec)
{
- return nsec->isSet(QType::NS) &&
- !nsec->isSet(QType::SOA) &&
+ return nsec.isSet(QType::NS) &&
+ !nsec.isSet(QType::SOA) &&
signer.countLabels() < owner.countLabels();
}
-bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<const NSEC3RecordContent>& nsec3)
+bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3)
{
- return nsec3->isSet(QType::NS) &&
- !nsec3->isSet(QType::SOA) &&
+ return nsec3.isSet(QType::NS) &&
+ !nsec3.isSet(QType::SOA) &&
signer.countLabels() < owner.countLabels();
}
}
VLOG(log, qname << ":\tWildcard matches");
- if (qtype == 0 || isTypeDenied(nsec, QType(qtype))) {
+ if (qtype == 0 || isTypeDenied(*nsec, QType(qtype))) {
VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
return true;
}
continue;
}
- string h = getHashFromNSEC3(wildcard, nsec3, cache);
+ string h = getHashFromNSEC3(wildcard, *nsec3, cache);
if (h.empty()) {
return false;
}
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+ if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, v.first.first, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
VLOG_NO_PREFIX(log, " BUT an ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
return false;
}
- if (qtype == 0 || isTypeDenied(nsec3, QType(qtype))) {
+ if (qtype == 0 || isTypeDenied(*nsec3, QType(qtype))) {
VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
return true;
}
return false;
}
-dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const std::shared_ptr<const NSECRecordContent>& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog& log)
+dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog& log)
{
const DNSName signer = getSigner(signatures);
if (!name.isPartOf(signer) || !nsecOwner.isPartOf(signer)) {
return dState::NXQTYPE;
}
- if (name.isPartOf(owner) && nsec->isSet(QType::DNAME)) {
+ if (name.isPartOf(owner) && nsec.isSet(QType::DNAME)) {
/* rfc6672 section 5.3.2: DNAME Bit in NSEC Type Map
In any negative response, the NSEC or NSEC3 [RFC5155] record type
return dState::NODENIAL;
}
- if (isCoveredByNSEC(name, owner, nsec->d_next)) {
- VLOG_NO_PREFIX(log, name << ": is covered by ("<<owner<<" to "<<nsec->d_next<<")");
+ if (isCoveredByNSEC(name, owner, nsec.d_next)) {
+ VLOG_NO_PREFIX(log, name << ": is covered by ("<<owner<<" to "<<nsec.d_next<<")");
- if (nsecProvesENT(name, owner, nsec->d_next)) {
+ if (nsecProvesENT(name, owner, nsec.d_next)) {
VLOG_NO_PREFIX(log, " denies existence of type "<<name<<"/"<<QType(qtype)<<" by proving that "<<name<<" is an ENT"<<endl);
return dState::NXQTYPE;
}
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, nsec)) {
+ if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, *nsec)) {
/* this is an "ancestor delegation" NSEC RR */
if (!(qtype == QType::DS && qname == owner)) {
VLOG(log, qname << ": An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
/* check if the type is denied */
if (qname == owner) {
- if (!isTypeDenied(nsec, QType(qtype))) {
+ if (!isTypeDenied(*nsec, QType(qtype))) {
VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<endl);
return dState::NODENIAL;
}
continue;
}
- string h = getHashFromNSEC3(qname, nsec3, cache);
+ string h = getHashFromNSEC3(qname, *nsec3, cache);
if (h.empty()) {
VLOG(log, qname << ": Unsupported hash, ignoring"<<endl);
return dState::INSECURE;
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, qname, nsec3)) {
+ if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, qname, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
return dState::NODENIAL;
}
- if (!isTypeDenied(nsec3, QType(qtype))) {
+ if (!isTypeDenied(*nsec3, QType(qtype))) {
VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<" for name "<<qname<<" (not opt-out)."<<endl);
return dState::NODENIAL;
}
continue;
}
- string h = getHashFromNSEC3(closestEncloser, nsec3, cache);
+ string h = getHashFromNSEC3(closestEncloser, *nsec3, cache);
if (h.empty()) {
return dState::INSECURE;
}
VLOG(log, qname << ": Comparing "<<toBase32Hex(h)<<" ("<<closestEncloser<<") against "<<toBase32Hex(beginHash)<<endl);
if (beginHash == h) {
/* If the closest encloser is a delegation NS we know nothing about the names in the child zone. */
- if (isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+ if (isNSEC3AncestorDelegation(signer, v.first.first, *nsec3)) {
VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
continue;
}
if(!nsec3)
continue;
- string h = getHashFromNSEC3(nextCloser, nsec3, cache);
+ string h = getHashFromNSEC3(nextCloser, *nsec3, cache);
if (h.empty()) {
return dState::INSECURE;
}
return dState::NODENIAL;
}
-bool isRRSIGNotExpired(const time_t now, const shared_ptr<const RRSIGRecordContent>& sig)
+bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig)
{
// Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
- return sig->d_sigexpire >= now;
+ return sig.d_sigexpire >= now;
}
-bool isRRSIGIncepted(const time_t now, const shared_ptr<const RRSIGRecordContent>& sig)
+bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig)
{
// Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
- return sig->d_siginception - g_signatureInceptionSkew <= now;
+ return sig.d_siginception - g_signatureInceptionSkew <= now;
}
-static bool checkSignatureWithKey(const DNSName& qname, time_t now, const shared_ptr<const RRSIGRecordContent>& sig, const shared_ptr<const DNSKEYRecordContent>& key, const std::string& msg, vState& ede, const OptLog& log)
+static bool checkSignatureWithKey(const DNSName& qname, time_t now, const RRSIGRecordContent& sig, const DNSKEYRecordContent& key, const std::string& msg, vState& ede, const OptLog& log)
{
bool result = false;
try {
- The validator's notion of the current time MUST be greater than or equal to the time listed in the RRSIG RR's Inception field.
*/
if (isRRSIGIncepted(now, sig) && isRRSIGNotExpired(now, sig)) {
- auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key->d_algorithm, key->d_key);
- result = dke->verify(msg, sig->d_signature);
- VLOG(log, qname << ": Signature by key with tag "<<sig->d_tag<<" and algorithm "<<DNSSECKeeper::algorithm2name(sig->d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
+ auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key.d_algorithm, key.d_key);
+ result = dke->verify(msg, sig.d_signature);
+ VLOG(log, qname << ": Signature by key with tag "<<sig.d_tag<<" and algorithm "<<DNSSECKeeper::algorithm2name(sig.d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
if (!result) {
ede = vState::BogusNoValidRRSIG;
}
}
else {
- ede = ((sig->d_siginception - g_signatureInceptionSkew) > now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired;
- VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<<sig->d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig->d_sigexpire<<", now: "<<now<<")"<<endl);
+ ede = ((sig.d_siginception - g_signatureInceptionSkew) > now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired;
+ VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<<sig.d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig.d_sigexpire<<", now: "<<now<<")"<<endl);
}
}
catch (const std::exception& e) {
string msg = getMessageForRRSET(name, *signature, toSign, true);
for (const auto& key : keysMatchingTag) {
vState ede;
- bool signIsValid = checkSignatureWithKey(name, now, signature, key, msg, ede, log);
+ bool signIsValid = checkSignatureWithKey(name, now, *signature, *key, msg, ede, log);
foundKey = true;
if (signIsValid) {
}
else {
VLOG(log, name << ": signature invalid"<<endl);
- if (isRRSIGIncepted(now, signature)) {
+ if (isRRSIGIncepted(now, *signature)) {
noneIncepted = false;
}
- if (isRRSIGNotExpired(now, signature)) {
+ if (isRRSIGNotExpired(now, *signature)) {
allExpired = false;
}
}
string msg = getMessageForRRSET(zone, *sig, toSign);
for (const auto& key : bytag) {
// cerr<<"validating : ";
- bool signIsValid = checkSignatureWithKey(zone, now, sig, key, msg, ede, log);
+ bool signIsValid = checkSignatureWithKey(zone, now, *sig, *key, msg, ede, log);
- if (signIsValid)
- {
+ if (signIsValid) {
VLOG(log, zone << ": Validation succeeded - whole DNSKEY set is valid"<<endl);
validkeys = tkeys;
break;