]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Add more Bogus states to better match rfc8914 extended codes 9597/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 29 Oct 2020 15:00:14 +0000 (16:00 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 29 Oct 2020 15:00:14 +0000 (16:00 +0100)
pdns/lua-recursor4.cc
pdns/rec_channel_rec.cc
pdns/recursordist/test-syncres_cc4.cc
pdns/recursordist/test-syncres_cc6.cc
pdns/syncres.cc
pdns/validate.cc
pdns/validate.hh

index f240f0c550ae6df97a6543607ea06597f30680bf..f16e02025796486681a52a1feb329dc6273e2f44 100644 (file)
@@ -355,6 +355,13 @@ void RecursorLua4::postPrepareContext()
         {"BogusNoRRSIG", static_cast<unsigned int>(vState::BogusNoRRSIG) },
         {"BogusNoValidRRSIG", static_cast<unsigned int>(vState::BogusNoValidRRSIG) },
         {"BogusMissingNegativeIndication", static_cast<unsigned int>(vState::BogusMissingNegativeIndication) },
+        {"BogusSignatureNotYetValid", static_cast<unsigned int>(vState::BogusSignatureNotYetValid)},
+        {"BogusSignatureExpired", static_cast<unsigned int>(vState::BogusSignatureExpired)},
+        {"BogusUnsupportedDNSKEYAlgo", static_cast<unsigned int>(vState::BogusUnsupportedDNSKEYAlgo)},
+        {"BogusUnsupportedDSDigestType", static_cast<unsigned int>(vState::BogusUnsupportedDSDigestType)},
+        {"BogusNoZoneKeyBitSet", static_cast<unsigned int>(vState::BogusNoZoneKeyBitSet)},
+        {"BogusRevokedDNSKEY", static_cast<unsigned int>(vState::BogusRevokedDNSKEY)},
+        {"BogusInvalidDNSKEYProtocol", static_cast<unsigned int>(vState::BogusInvalidDNSKEYProtocol)},
         {"Insecure", static_cast<unsigned int>(vState::Insecure) },
         {"Secure", static_cast<unsigned int>(vState::Secure) },
   }});
index 468f130999628ba71694f845805d180f9694d457..ec48ffb02f2737ea939485b19b570eab58d5e785 100644 (file)
@@ -1177,6 +1177,13 @@ void registerAllStats()
   addGetStat("dnssec-result-bogus-no-rrsig", &g_stats.dnssecResults[vState::BogusNoRRSIG]);
   addGetStat("dnssec-result-bogus-no-valid-rrsig", &g_stats.dnssecResults[vState::BogusNoValidRRSIG]);
   addGetStat("dnssec-result-bogus-missing-negative-indication", &g_stats.dnssecResults[vState::BogusMissingNegativeIndication]);
+  addGetStat("dnssec-result-bogus-signature-not-yet-valid", &g_stats.dnssecResults[vState::BogusSignatureNotYetValid]);
+  addGetStat("dnssec-result-bogus-signature-expired", &g_stats.dnssecResults[vState::BogusSignatureExpired]);
+  addGetStat("dnssec-result-bogus-unsupported-dnskey-algo", &g_stats.dnssecResults[vState::BogusUnsupportedDNSKEYAlgo]);
+  addGetStat("dnssec-result-bogus-unsupported-ds-digest-type", &g_stats.dnssecResults[vState::BogusUnsupportedDSDigestType]);
+  addGetStat("dnssec-result-bogus-no-zone-key-bit-set", &g_stats.dnssecResults[vState::BogusNoZoneKeyBitSet]);
+  addGetStat("dnssec-result-bogus-revoked-dnskey", &g_stats.dnssecResults[vState::BogusRevokedDNSKEY]);
+  addGetStat("dnssec-result-bogus-invalid-dnskey-protocol", &g_stats.dnssecResults[vState::BogusInvalidDNSKEYProtocol]);
   addGetStat("dnssec-result-indeterminate", &g_stats.dnssecResults[vState::Indeterminate]);
   addGetStat("dnssec-result-nta", &g_stats.dnssecResults[vState::NTA]);
 
index 761d84cc31707965737573a03c396a591f3871b5..c7b9bf52f3efd850f525aa830df6bfb4bbba81c4 100644 (file)
@@ -460,7 +460,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig)
   std::vector<std::shared_ptr<RRSIGRecordContent>> sigs;
   sigs.push_back(std::make_shared<RRSIGRecordContent>(rrc));
 
-  BOOST_CHECK(validateWithKeySet(now, qname, recordcontents, sigs, keyset));
+  BOOST_CHECK(validateWithKeySet(now, qname, recordcontents, sigs, keyset) == vState::Secure);
 }
 
 BOOST_AUTO_TEST_CASE(test_dnssec_root_validation_csk)
@@ -747,7 +747,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_without_zone_flag)
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoZoneKeyBitSet);
   /* 13 NS + 1 RRSIG */
   BOOST_REQUIRE_EQUAL(ret.size(), 14U);
   BOOST_CHECK_EQUAL(queriesCount, 2U);
@@ -756,7 +756,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_without_zone_flag)
   ret.clear();
   res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoZoneKeyBitSet);
   BOOST_REQUIRE_EQUAL(ret.size(), 14U);
   BOOST_CHECK_EQUAL(queriesCount, 2U);
 }
@@ -824,7 +824,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_revoked)
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusRevokedDNSKEY);
   /* 13 NS + 1 RRSIG */
   BOOST_REQUIRE_EQUAL(ret.size(), 14U);
   BOOST_CHECK_EQUAL(queriesCount, 2U);
@@ -833,7 +833,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_revoked)
   ret.clear();
   res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusRevokedDNSKEY);
   BOOST_REQUIRE_EQUAL(ret.size(), 14U);
   BOOST_CHECK_EQUAL(queriesCount, 2U);
 }
index dc056974afbf2d29c6c970f22084ff0a3a1acd0c..152a144712fe3ba40e82f974176a09a5247c808a 100644 (file)
@@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_signed_child)
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidRRSIG);
   BOOST_REQUIRE_EQUAL(ret.size(), 2U);
   BOOST_CHECK_EQUAL(queriesCount, 10U);
 
@@ -393,7 +393,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_signed_child)
   ret.clear();
   res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NoError);
-  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidRRSIG);
   BOOST_REQUIRE_EQUAL(ret.size(), 2U);
   BOOST_CHECK_EQUAL(queriesCount, 10U);
 }
index 5b021d01480239a009a95db17c60c70f4ed0f3ff..522acd04d2275e9de93570acf87f4ddfa3f28ebb 100644 (file)
@@ -2594,6 +2594,14 @@ vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord
         return state;
       }
     }
+    else {
+      LOG(d_prefix<<": we have "<<std::to_string(dnskeys.size())<<" DNSKEYs but the zone ("<<zone<<") is not part of the signer ("<<signer<<"), going Bogus!"<<endl);
+      return vState::BogusNoValidRRSIG;
+    }
+  }
+  else {
+    LOG(d_prefix<<": we have "<<std::to_string(dnskeys.size())<<" DNSKEYs but no signature, going Bogus!"<<endl);
+    return vState::BogusNoRRSIG;
   }
 
   skeyset_t tentativeKeys;
@@ -2611,7 +2619,7 @@ vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord
 
   LOG(d_prefix<<": trying to validate "<<std::to_string(tentativeKeys.size())<<" DNSKEYs with "<<std::to_string(ds.size())<<" DS"<<endl);
   skeyset_t validatedKeys;
-  validateDNSKeysAgainstDS(d_now.tv_sec, zone, ds, tentativeKeys, toSign, signatures, validatedKeys);
+  auto state = validateDNSKeysAgainstDS(d_now.tv_sec, zone, ds, tentativeKeys, toSign, signatures, validatedKeys);
 
   LOG(d_prefix<<": we now have "<<std::to_string(validatedKeys.size())<<" DNSKEYs"<<endl);
 
@@ -2621,10 +2629,10 @@ vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord
      covering this set, this looks Bogus. */
   if (validatedKeys.size() != tentativeKeys.size()) {
     LOG(d_prefix<<": returning Bogus state from "<<__func__<<"("<<zone<<")"<<endl);
-    return vState::BogusNoValidDNSKEY;
+    return state;
   }
 
-  return vState::Secure;
+  return state;
 }
 
 vState SyncRes::getDNSKeys(const DNSName& signer, skeyset_t& keys, unsigned int depth)
@@ -2694,13 +2702,14 @@ vState SyncRes::validateRecordsWithSigs(unsigned int depth, const DNSName& qname
   }
 
   LOG(d_prefix<<"Going to validate "<<recordcontents.size()<< " record contents with "<<signatures.size()<<" sigs and "<<keys.size()<<" keys for "<<name<<"|"<<qtype.getName()<<endl);
-  if (validateWithKeySet(d_now.tv_sec, name, recordcontents, signatures, keys, false)) {
+  vState state = validateWithKeySet(d_now.tv_sec, name, recordcontents, signatures, keys, false);
+  if (state == vState::Secure) {
     LOG(d_prefix<<"Secure!"<<endl);
     return vState::Secure;
   }
 
-  LOG(d_prefix<<"Bogus!"<<endl);
-  return vState::BogusNoValidRRSIG;
+  LOG(d_prefix<<vStateToString(state)<<"!"<<endl);
+  return state;
 }
 
 static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec)
index 4b09dd2c4d8a80607b0505776b3edd02e598a08e..dc1e4c4dce9ed9240622852e145a89676c462272 100644 (file)
@@ -745,9 +745,14 @@ static const vector<DNSName> getZoneCuts(const DNSName& begin, const DNSName& en
   return ret;
 }
 
-bool isRRSIGNotExpired(const time_t now, const shared_ptr<RRSIGRecordContent> sig)
+bool isRRSIGNotExpired(const time_t now, const shared_ptr<RRSIGRecordContent>& sig)
 {
-  return sig->d_siginception - g_signatureInceptionSkew <= now && sig->d_sigexpire >= now;
+  return sig->d_sigexpire >= now;
+}
+
+bool isRRSIGIncepted(const time_t now, const shared_ptr<RRSIGRecordContent>& sig)
+{
+  return sig->d_siginception - g_signatureInceptionSkew <= now;
 }
 
 static bool checkSignatureWithKey(time_t now, const shared_ptr<RRSIGRecordContent> sig, const shared_ptr<DNSKEYRecordContent> key, const std::string& msg)
@@ -758,7 +763,7 @@ static bool checkSignatureWithKey(time_t now, const shared_ptr<RRSIGRecordConten
        - The validator's notion of the current time MUST be less than or equal to the time listed in the RRSIG RR's Expiration field.
        - 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(isRRSIGNotExpired(now, sig)) {
+    if (isRRSIGIncepted(now, sig) && isRRSIGNotExpired(now, sig)) {
       std::shared_ptr<DNSCryptoKeyEngine> dke = shared_ptr<DNSCryptoKeyEngine>(DNSCryptoKeyEngine::makeFromPublicKeyString(key->d_algorithm, key->d_key));
       result = dke->verify(msg, sig->d_signature);
       LOG("signature by key with tag "<<sig->d_tag<<" and algorithm "<<DNSSECKeeper::algorithm2name(sig->d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
@@ -767,15 +772,18 @@ static bool checkSignatureWithKey(time_t now, const shared_ptr<RRSIGRecordConten
       LOG("Signature is "<<((sig->d_siginception - g_signatureInceptionSkew > now) ? "not yet valid" : "expired")<<" (inception: "<<sig->d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig->d_sigexpire<<", now: "<<now<<")"<<endl);
     }
   }
-  catch(const std::exception& e) {
+  catch (const std::exception& e) {
     LOG("Could not make a validator for signature: "<<e.what()<<endl);
   }
   return result;
 }
 
-bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs)
+vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs)
 {
+  bool foundKey = false;
   bool isValid = false;
+  bool allExpired = true;
+  bool noneIncepted = true;
 
   for(const auto& signature : signatures) {
     unsigned int labelCount = name.countLabels();
@@ -791,8 +799,10 @@ bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t&
     }
 
     string msg = getMessageForRRSET(name, *signature, toSign, true);
-    for(const auto& key : keysMatchingTag) {
+    for (const auto& key : keysMatchingTag) {
       bool signIsValid = checkSignatureWithKey(now, signature, key, msg);
+      foundKey = true;
+
       if (signIsValid) {
         isValid = true;
         LOG("Validated "<<name<<"/"<<DNSRecordContent::NumberToType(signature->d_type)<<endl);
@@ -801,14 +811,34 @@ bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t&
       }
       else {
         LOG("signature invalid"<<endl);
+        if (isRRSIGIncepted(now, signature)) {
+          noneIncepted = false;
+        }
+        if (isRRSIGNotExpired(now, signature)) {
+          allExpired = false;
+        }
       }
+
       if (signIsValid && !validateAllSigs) {
-        return true;
+        return vState::Secure;
       }
     }
   }
 
-  return isValid;
+  if (isValid) {
+    return vState::Secure;
+  }
+  if (!foundKey) {
+    return vState::BogusNoValidRRSIG;
+  }
+  if (noneIncepted) {
+    return vState::BogusSignatureNotYetValid;
+  }
+  if (allExpired) {
+    return vState::BogusSignatureExpired;
+  }
+
+  return vState::BogusNoValidRRSIG;
 }
 
 void validateWithKeySet(const cspmap_t& rrsets, cspmap_t& validated, const skeyset_t& keys)
@@ -822,7 +852,7 @@ void validateWithKeySet(const cspmap_t& rrsets, cspmap_t& validated, const skeys
   time_t now = time(nullptr);
   for(auto i=rrsets.cbegin(); i!=rrsets.cend(); i++) {
     LOG("validating "<<(i->first.first)<<"/"<<DNSRecordContent::NumberToType(i->first.second)<<" with "<<i->second.signatures.size()<<" sigs"<<endl);
-    if (validateWithKeySet(now, i->first.first, i->second.records, i->second.signatures, keys, true)) {
+    if (validateWithKeySet(now, i->first.first, i->second.records, i->second.signatures, keys, true) == vState::Secure) {
       validated[i->first] = i->second;
     }
   }
@@ -878,18 +908,18 @@ bool haveNegativeTrustAnchor(const map<DNSName,std::string>& negAnchors, const D
   return true;
 }
 
-void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys)
+vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys)
 {
   /*
    * Check all DNSKEY records against all DS records and place all DNSKEY records
    * that have DS records (that we support the algo for) in the tentative key storage
    */
-  for(auto const& dsrc : dsmap)
+  for (const auto& dsrc : dsmap)
   {
     auto r = getByTag(tkeys, dsrc.d_tag, dsrc.d_algorithm);
     // cerr<<"looking at DS with tag "<<dsrc.d_tag<<", algo "<<DNSSECKeeper::algorithm2name(dsrc.d_algorithm)<<", digest "<<std::to_string(dsrc.d_digesttype)<<" for "<<zone<<", got "<<r.size()<<" DNSKEYs for tag"<<endl;
 
-    for(const auto& drc : r)
+    for (const auto& drc : r)
     {
       bool isValid = false;
       bool dsCreated = false;
@@ -899,11 +929,11 @@ void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& ds
         dsCreated = true;
         isValid = dsrc == dsrc2;
       }
-      catch(const std::exception &e) {
+      catch (const std::exception &e) {
         LOG("Unable to make DS from DNSKey: "<<e.what()<<endl);
       }
 
-      if(isValid) {
+      if (isValid) {
         LOG("got valid DNSKEY (it matches the DS) with tag "<<dsrc.d_tag<<" and algorithm "<<std::to_string(dsrc.d_algorithm)<<" for "<<zone<<endl);
 
         validkeys.insert(drc);
@@ -919,13 +949,13 @@ void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& ds
   //    cerr<<"got "<<validkeys.size()<<"/"<<tkeys.size()<<" valid/tentative keys"<<endl;
   // these counts could be off if we somehow ended up with
   // duplicate keys. Should switch to a type that prevents that.
-  if(validkeys.size() < tkeys.size())
+  if (validkeys.size() < tkeys.size())
   {
     // this should mean that we have one or more DS-validated DNSKEYs
     // but not a fully validated DNSKEY set, yet
     // one of these valid DNSKEYs should be able to validate the
     // whole set
-    for(const auto& sig : sigs)
+    for (const auto& sig : sigs)
     {
       //        cerr<<"got sig for keytag "<<i->d_tag<<" matching "<<getByTag(tkeys, i->d_tag).size()<<" keys of which "<<getByTag(validkeys, i->d_tag).size()<<" valid"<<endl;
       auto bytag = getByTag(validkeys, sig->d_tag, sig->d_algorithm);
@@ -935,11 +965,11 @@ void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& ds
       }
 
       string msg = getMessageForRRSET(zone, *sig, toSign);
-      for(const auto& key : bytag) {
+      for (const auto& key : bytag) {
         //          cerr<<"validating : ";
         bool signIsValid = checkSignatureWithKey(now, sig, key, msg);
 
-        if(signIsValid)
+        if (signIsValid)
         {
           LOG("validation succeeded - whole DNSKEY set is valid"<<endl);
           validkeys = tkeys;
@@ -952,6 +982,64 @@ void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& ds
       //        if(validkeys.empty()) cerr<<"did not manage to validate DNSKEY set based on DS-validated KSK, only passing KSK on"<<endl;
     }
   }
+
+  if (validkeys.size() < tkeys.size()) {
+    /* so we failed to validate the whole set, let's try to find out why exactly */
+    bool dnskeyAlgoSupported = false;
+    bool dsDigestSupported = false;
+
+    for (const auto& dsrc : dsmap)
+    {
+      if (DNSCryptoKeyEngine::isAlgorithmSupported(dsrc.d_algorithm)) {
+        dnskeyAlgoSupported = true;
+        if (DNSCryptoKeyEngine::isDigestSupported(dsrc.d_digesttype)) {
+          dsDigestSupported = true;
+        }
+      }
+    }
+
+    if (!dnskeyAlgoSupported) {
+      return vState::BogusUnsupportedDNSKEYAlgo;
+    }
+    if (!dsDigestSupported) {
+      return vState::BogusUnsupportedDSDigestType;
+    }
+
+    bool zoneKey = false;
+    bool notRevoked = false;
+    bool validProtocol = false;
+
+    for (const auto& key : tkeys) {
+      if (!isAZoneKey(*key)) {
+        continue;
+      }
+      zoneKey = true;
+
+      if (isRevokedKey(*key)) {
+        continue;
+      }
+      notRevoked = true;
+
+      if (key->d_protocol != 3) {
+        continue;
+      }
+      validProtocol = true;
+    }
+
+    if (!zoneKey) {
+      return vState::BogusNoZoneKeyBitSet;
+    }
+    if (!notRevoked) {
+      return vState::BogusRevokedDNSKEY;
+    }
+    if (!validProtocol) {
+      return vState::BogusInvalidDNSKEYProtocol;
+    }
+
+    return vState::BogusNoValidDNSKEY;
+  }
+
+  return vState::Secure;
 }
 
 vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset)
@@ -1050,19 +1138,19 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset)
      * Check all DNSKEY records against all DS records and place all DNSKEY records
      * that have DS records (that we support the algo for) in the tentative key storage
      */
-    validateDNSKeysAgainstDS(time(nullptr), *zoneCutIter, dsmap, tkeys, toSign, sigs, validkeys);
+    auto state = validateDNSKeysAgainstDS(time(nullptr), *zoneCutIter, dsmap, tkeys, toSign, sigs, validkeys);
 
-    if(validkeys.empty())
+    if (validkeys.empty())
     {
       LOG("ended up with zero valid DNSKEYs, going Bogus"<<endl);
-      return vState::BogusNoValidDNSKEY;
+      return state;
     }
     LOG("situation: we have one or more valid DNSKEYs for ["<<*zoneCutIter<<"] (want ["<<zone<<"])"<<endl);
 
-    if(zoneCutIter == zoneCuts.cend()-1) {
+    if (zoneCutIter == zoneCuts.cend()-1) {
       LOG("requested keyset found! returning Secure for the keyset"<<endl);
       keyset.insert(validkeys.cbegin(), validkeys.cend());
-      return vState::Secure;
+      return state;
     }
 
     // We now have the DNSKEYs, use them to validate the DS records at the next zonecut
@@ -1136,7 +1224,7 @@ DNSName getSigner(const std::vector<std::shared_ptr<RRSIGRecordContent> >& signa
 
 const std::string& vStateToString(vState state)
 {
-  static const std::vector<std::string> vStates = {"Indeterminate", "Insecure", "Secure", "NTA", "TA", "Bogus - No valid DNSKEY", "Bogus - Invalid denial", "Bogus - Unable to get DSs", "Bogus - Unable to get DNSKEYs", "Bogus - Self Signed DS", "Bogus - No RRSIG", "Bogus - No valid RRSIG", "Bogus - Missing negative indication" };
+  static const std::vector<std::string> vStates = {"Indeterminate", "Insecure", "Secure", "NTA", "TA", "Bogus - No valid DNSKEY", "Bogus - Invalid denial", "Bogus - Unable to get DSs", "Bogus - Unable to get DNSKEYs", "Bogus - Self Signed DS", "Bogus - No RRSIG", "Bogus - No valid RRSIG", "Bogus - Missing negative indication", "Bogus - Signature not yet valid", "Bogus - Signature expired", "Bogus - Unsupported DNSKEY algorithm", "Bogus - Unsuuported DS digest type", "Bogus - No zone key bit set", "Bogus - Revoked DNSKEY", "Bogus - Invalid DNSKEY Protocol" };
   return vStates.at(static_cast<size_t>(state));
 }
 
index 99229d0e915177ba1a8f3d498d0bb8469d6bdf29..4819eb026e66ec4205f18a39accd3b4d9fd2af16 100644 (file)
@@ -33,7 +33,7 @@ extern time_t g_signatureInceptionSkew;
 extern uint16_t g_maxNSEC3Iterations;
 
 // 4033 5
-enum class vState : uint8_t { Indeterminate, Insecure, Secure, NTA, TA, BogusNoValidDNSKEY, BogusInvalidDenial, BogusUnableToGetDSs, BogusUnableToGetDNSKEYs, BogusSelfSignedDS, BogusNoRRSIG, BogusNoValidRRSIG, BogusMissingNegativeIndication };
+enum class vState : uint8_t { Indeterminate, Insecure, Secure, NTA, TA, BogusNoValidDNSKEY, BogusInvalidDenial, BogusUnableToGetDSs, BogusUnableToGetDNSKEYs, BogusSelfSignedDS, BogusNoRRSIG, BogusNoValidRRSIG, BogusMissingNegativeIndication, BogusSignatureNotYetValid, BogusSignatureExpired, BogusUnsupportedDNSKEYAlgo, BogusUnsupportedDSDigestType, BogusNoZoneKeyBitSet, BogusRevokedDNSKEY, BogusInvalidDNSKEYProtocol };
 const std::string& vStateToString(vState state);
 inline bool vStateIsBogus(vState state)
 {
@@ -72,18 +72,19 @@ struct sharedDNSKeyRecordContentCompare
 
 typedef set<shared_ptr<DNSKEYRecordContent>, sharedDNSKeyRecordContentCompare > skeyset_t;
 
-bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& records, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs=true);
+vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& records, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs=true);
 void validateWithKeySet(const cspmap_t& rrsets, cspmap_t& validated, const skeyset_t& keys);
 cspmap_t harvestCSPFromRecs(const vector<DNSRecord>& recs);
 vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset);
 bool getTrustAnchor(const map<DNSName,dsmap_t>& anchors, const DNSName& zone, dsmap_t &res);
 bool haveNegativeTrustAnchor(const map<DNSName,std::string>& negAnchors, const DNSName& zone, std::string& reason);
-void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys);
+vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys);
 dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, bool needsWildcardProof=true, unsigned int wildcardLabelsCount=0);
 bool isSupportedDS(const DSRecordContent& ds);
 DNSName getSigner(const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures);
 bool denialProvesNoDelegation(const DNSName& zone, const std::vector<DNSRecord>& dsrecords);
-bool isRRSIGNotExpired(const time_t now, const shared_ptr<RRSIGRecordContent> sig);
+bool isRRSIGNotExpired(const time_t now, const std::shared_ptr<RRSIGRecordContent>& sig);
+bool isRRSIGIncepted(const time_t now, const shared_ptr<RRSIGRecordContent>& sig);
 bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr<RRSIGRecordContent>& sign);
 bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const std::shared_ptr<RRSIGRecordContent>& sign);
 void updateDNSSECValidationState(vState& state, const vState stateUpdate);