void val_log_assertion_pfx(const val_context_t * ctx, int level, const char *prefix, const char * name_pr, struct val_authentication_chain *next_as) { char name_buf[INET6_ADDRSTRLEN + 1]; const char *serv_pr; int tag = 0; int class_h; int type_h; struct val_rr_rec *data; struct sockaddr *serv; val_astatus_t status; struct val_rr_rec *curkey; #undef VAL_LOG_SIG #ifdef VAL_LOG_SIG struct val_rr_rec *sig; struct val_rr_rec *cursig; #endif if (next_as == NULL) return; class_h = next_as->val_ac_rrset->val_rrset_class; type_h = next_as->val_ac_rrset->val_rrset_type; data = next_as->val_ac_rrset->val_rrset_data; #ifdef VAL_LOG_SIG sig = next_as->val_ac_rrset->val_rrset_sig; #endif serv = next_as->val_ac_rrset->val_rrset_server; status = next_as->val_ac_status; if (NULL == prefix) prefix = ""; if (serv) serv_pr = ((serv_pr = val_get_ns_string(serv, name_buf, sizeof(name_buf))) == NULL) ? "VAL_CACHE" : serv_pr; else serv_pr = "NULL"; if (type_h == ns_t_dnskey) { for (curkey = data; curkey; curkey = curkey->rr_next) { if ((curkey->rr_status == VAL_AC_VERIFIED_LINK) || (curkey->rr_status == VAL_AC_TRUST_POINT) || (curkey->rr_status == VAL_AC_UNKNOWN_ALGORITHM_LINK)) { /* * Extract the key tag */ val_dnskey_rdata_t dnskey; if (VAL_NO_ERROR != val_parse_dnskey_rdata(curkey->rr_rdata, curkey->rr_rdata_length, &dnskey)) { val_log(ctx, LOG_INFO, "val_log_assertion_pfx(): Cannot parse DNSKEY data"); } else { tag = dnskey.key_tag; if (dnskey.public_key) FREE(dnskey.public_key); } break; } } } if (tag != 0) { val_log(ctx, level, "%sname=%s class=%s type=%s[tag=%d] from-server=%s " "status=%s:%d", prefix, name_pr, p_class(class_h), p_type(type_h), tag, serv_pr, p_ac_status(status), status); } else { val_log(ctx, level, "%sname=%s class=%s type=%s from-server=%s status=%s:%d", prefix, name_pr, p_class(class_h), p_type(type_h), serv_pr, p_ac_status(status), status); } #ifdef VAL_LOG_SIG for (cursig = sig; cursig; cursig = cursig->rr_next) { char incpTime[1028]; char exprTime[1028]; struct timeval tv_sig; val_rrsig_rdata_t rrsig; val_parse_rrsig_rdata(cursig->rr_rdata, cursig->rr_rdata_length, &rrsig); memset(&tv_sig, 0, sizeof(tv_sig)); tv_sig.tv_sec = rrsig.sig_incp; GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), incpTime); memset(&tv_sig, 0, sizeof(tv_sig)); tv_sig.tv_sec = rrsig.sig_expr; GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), exprTime); val_log(ctx, level, "%s ->tag=%d status=%s sig-incep=%s sig-expr=%s", prefix, rrsig.key_tag, p_ac_status(cursig->rr_status), incpTime, exprTime); } #endif #ifdef VAL_LOG_SIG struct val_rr_rec *rr; struct val_rr_rec *sig = next_as->val_ac_rrset->val_rrset_sig; for (rr = data; rr; rr = rr->rr_next) { val_log(ctx, level, " data_status=%s:%d", p_ac_status(rr->rr_status), rr->rr_status); } for (rr = sig; rr; rr = rr->rr_next) { val_log(ctx, level, " sig_status=%s:%d", p_ac_status(rr->rr_status), rr->rr_status); } #endif }
/* * helper function for a set of verify-related operations */ static int do_verify(val_context_t * ctx, u_char *zone_n, val_astatus_t * dnskey_status, val_astatus_t * sig_status, struct rrset_rec *the_set, struct rrset_rr *the_sig, val_dnskey_rdata_t * the_key, int is_a_wildcard, u_int32_t flags) { /* * Use the crypto routines to verify the signature */ u_char *ver_field; size_t ver_length; int ret_val; val_rrsig_rdata_t rrsig_rdata; int clock_skew = 0; u_int32_t ttl_x = 0; int retval = 0; /* * Wildcard expansions for DNSKEYs and DSs are not permitted */ if (is_a_wildcard && ((the_set->rrs_type_h == ns_t_ds) || (the_set->rrs_type_h == ns_t_dnskey))) { val_log(ctx, LOG_INFO, "do_verify(): Invalid DNSKEY or DS record - cannot be wildcard expanded"); *dnskey_status = VAL_AC_INVALID_KEY; return 0; } if ((ret_val = make_sigfield(&ver_field, &ver_length, the_set, the_sig, is_a_wildcard)) != VAL_NO_ERROR || ver_field == NULL || ver_length == 0) { val_log(ctx, LOG_INFO, "do_verify(): Could not construct signature field for verification: %s", p_val_err(ret_val)); *sig_status = VAL_AC_INVALID_RRSIG; return 0; } /* * Find the signature - no memory is malloc'ed for this operation */ if (VAL_NO_ERROR != val_parse_rrsig_rdata(the_sig->rr_rdata, the_sig->rr_rdata_length, &rrsig_rdata)) { if (ver_field) FREE(ver_field); val_log(ctx, LOG_INFO, "do_verify(): Could not parse signature field"); *sig_status = VAL_AC_INVALID_RRSIG; return 0; } rrsig_rdata.next = NULL; if (flags & VAL_QUERY_IGNORE_SKEW) { clock_skew = -1; val_log(ctx, LOG_DEBUG, "do_verify(): Ignoring clock skew"); } else { get_clock_skew(ctx, zone_n, &clock_skew, &ttl_x); /* the state is valid for only as long as the policy validity period */ SET_MIN_TTL(the_set->rrs_ttl_x, ttl_x); } /* * Perform the verification */ retval = val_sigverify(ctx, is_a_wildcard, ver_field, ver_length, the_key, &rrsig_rdata, dnskey_status, sig_status, clock_skew); if (rrsig_rdata.signature != NULL) { FREE(rrsig_rdata.signature); rrsig_rdata.signature = NULL; } FREE(ver_field); return retval; }