summaryrefslogtreecommitdiff
path: root/validator/validator.c
diff options
context:
space:
mode:
Diffstat (limited to 'validator/validator.c')
-rw-r--r--validator/validator.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/validator/validator.c b/validator/validator.c
index 5ed45e9bdefd4..5777b2932cb46 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -40,6 +40,7 @@
* According to RFC 4034.
*/
#include "config.h"
+#include <ctype.h>
#include "validator/validator.h"
#include "validator/val_anchor.h"
#include "validator/val_kcache.h"
@@ -478,6 +479,31 @@ generate_keytag_query(struct module_qstate* qstate, int id,
}
/**
+ * Get keytag as uint16_t from string
+ *
+ * @param start: start of string containing keytag
+ * @param keytag: pointer where to store the extracted keytag
+ * @return: 1 if keytag was extracted, else 0.
+ */
+static int
+sentinel_get_keytag(char* start, uint16_t* keytag) {
+ char* keytag_str;
+ char* e = NULL;
+ keytag_str = calloc(1, SENTINEL_KEYTAG_LEN + 1 /* null byte */);
+ if(!keytag_str)
+ return 0;
+ memmove(keytag_str, start, SENTINEL_KEYTAG_LEN);
+ keytag_str[SENTINEL_KEYTAG_LEN] = '\0';
+ *keytag = (uint16_t)strtol(keytag_str, &e, 10);
+ if(!e || *e != '\0') {
+ free(keytag_str);
+ return 0;
+ }
+ free(keytag_str);
+ return 1;
+}
+
+/**
* Prime trust anchor for use.
* Generate and dispatch a priming query for the given trust anchor.
* The trust anchor can be DNSKEY or DS and does not have to be signed.
@@ -2223,6 +2249,34 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
vq->orig_msg->rep->security = sec_status_indeterminate;
}
+ if(vq->orig_msg->rep->security == sec_status_secure &&
+ qstate->env->cfg->root_key_sentinel &&
+ (qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
+ qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)) {
+ char* keytag_start;
+ uint16_t keytag;
+ if(*qstate->qinfo.qname == strlen(SENTINEL_IS) +
+ SENTINEL_KEYTAG_LEN &&
+ dname_lab_startswith(qstate->qinfo.qname, SENTINEL_IS,
+ &keytag_start)) {
+ if(sentinel_get_keytag(keytag_start, &keytag) &&
+ !anchor_has_keytag(qstate->env->anchors,
+ (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
+ vq->orig_msg->rep->security =
+ sec_status_secure_sentinel_fail;
+ }
+ } else if(*qstate->qinfo.qname == strlen(SENTINEL_NOT) +
+ SENTINEL_KEYTAG_LEN &&
+ dname_lab_startswith(qstate->qinfo.qname, SENTINEL_NOT,
+ &keytag_start)) {
+ if(sentinel_get_keytag(keytag_start, &keytag) &&
+ anchor_has_keytag(qstate->env->anchors,
+ (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
+ vq->orig_msg->rep->security =
+ sec_status_secure_sentinel_fail;
+ }
+ }
+ }
/* store results in cache */
if(qstate->query_flags&BIT_RD) {
/* if secure, this will override cache anyway, no need