lci.dsAnchors.clear();
});
+ Lua.writeFunction("addNTA", [&lci](const std::string& who, const boost::optional<std::string> why) {
+ if(why)
+ lci.negAnchors[DNSName(who)] = static_cast<string>(*why);
+ else
+ lci.negAnchors[DNSName(who)] = "";
+ });
+
+ Lua.writeFunction("clearNTA", [&lci](boost::optional<string> who) {
+ if(who)
+ lci.negAnchors.erase(DNSName(*who));
+ else
+ lci.negAnchors.clear();
+ });
+
#if HAVE_PROTOBUF
Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional<uint16_t> timeout, const boost::optional<uint64_t> maxQueuedEntries, const boost::optional<uint8_t> reconnectWaitTime) {
try {
string dotEscape(string name);
const char *dStates[]={"nodata", "nxdomain", "empty non-terminal", "insecure (no-DS proof)"};
-const char *vStates[]={"Indeterminate", "Bogus", "Insecure", "Secure"};
+const char *vStates[]={"Indeterminate", "Bogus", "Insecure", "Secure", "NTA"};
typedef set<DNSKEYRecordContent> keyset_t;
vector<DNSKEYRecordContent> getByTag(const keyset_t& keys, uint16_t tag)
vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
{
+ auto luaLocal = g_luaconfs.getLocal();
+ auto anchors = luaLocal->dsAnchors;
+
+ // Before searching for the keys, see if we have a Negative Trust Anchor. If
+ // so, test if the NTA is valid and return an NTA state
+ auto negAnchors = luaLocal->negAnchors;
+
+ if (!negAnchors.empty()) {
+ DNSName lowestNTA, lowestTA;
+
+ for (auto const &negAnchor : negAnchors)
+ if (zone.isPartOf(negAnchor.first) && lowestNTA.countLabels() < negAnchor.first.countLabels())
+ lowestNTA = negAnchor.first;
+
+ for (auto const &anchor : anchors)
+ if (zone.isPartOf(anchor.first) && lowestTA.countLabels() < anchor.first.countLabels())
+ lowestTA = anchor.first;
+
+ if(!lowestNTA.empty()) {
+ LOG("Found a Negative Trust Anchor for "<<lowestNTA.toStringRootDot()<<", which was added with reason '"<<negAnchors[lowestNTA]<<"', ");
+
+ /* RFC 7646 section 2.1 tells us that we SHOULD still validate if there
+ * is a Trust Anchor below the Negative Trust Anchor for the name we
+ * attempt validation for. However, section 3 tells us this positive
+ * Trust Anchor MUST be *below* the name and not the name itself
+ */
+ if(lowestTA.countLabels() < lowestNTA.countLabels()) {
+ LOG("marking answer Insecure"<<endl);
+ return NTA; // Not Insecure, this way validateRecords() can shortcut
+ }
+ LOG("but a Trust Anchor for "<<lowestTA.toStringRootDot()<<" is configured, continuing validation."<<endl);
+ }
+ }
+
vector<string> labels = zone.getRawLabels();
vState state;
DNSName qname(".");
state = Secure; // the root is secure
- auto luaLocal = g_luaconfs.getLocal();
while(zone.isPartOf(qname))
{
if(auto ds = rplookup(luaLocal->dsAnchors, qname))