1*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 2*7b5038d7SDag-Erling Smørgrav 3*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 4*7b5038d7SDag-Erling Smørgrav 5*7b5038d7SDag-Erling Smørgrav #include <strings.h> 6*7b5038d7SDag-Erling Smørgrav #include <time.h> 7*7b5038d7SDag-Erling Smørgrav 8*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 9*7b5038d7SDag-Erling Smørgrav /* this entire file is rather useless when you don't have 10*7b5038d7SDag-Erling Smørgrav * crypto... 11*7b5038d7SDag-Erling Smørgrav */ 12*7b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h> 13*7b5038d7SDag-Erling Smørgrav #include <openssl/evp.h> 14*7b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 15*7b5038d7SDag-Erling Smørgrav #include <openssl/err.h> 16*7b5038d7SDag-Erling Smørgrav #include <openssl/md5.h> 17*7b5038d7SDag-Erling Smørgrav 18*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain * 19*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_new(void) 20*7b5038d7SDag-Erling Smørgrav { 21*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1); 22*7b5038d7SDag-Erling Smørgrav if(!nc) return NULL; 23*7b5038d7SDag-Erling Smørgrav /* 24*7b5038d7SDag-Erling Smørgrav * not needed anymore because CALLOC initalizes everything to zero. 25*7b5038d7SDag-Erling Smørgrav 26*7b5038d7SDag-Erling Smørgrav nc->rrset = NULL; 27*7b5038d7SDag-Erling Smørgrav nc->parent_type = 0; 28*7b5038d7SDag-Erling Smørgrav nc->parent = NULL; 29*7b5038d7SDag-Erling Smørgrav nc->signatures = NULL; 30*7b5038d7SDag-Erling Smørgrav nc->packet_rcode = 0; 31*7b5038d7SDag-Erling Smørgrav nc->packet_qtype = 0; 32*7b5038d7SDag-Erling Smørgrav nc->packet_nodata = false; 33*7b5038d7SDag-Erling Smørgrav 34*7b5038d7SDag-Erling Smørgrav */ 35*7b5038d7SDag-Erling Smørgrav return nc; 36*7b5038d7SDag-Erling Smørgrav } 37*7b5038d7SDag-Erling Smørgrav 38*7b5038d7SDag-Erling Smørgrav void 39*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain) 40*7b5038d7SDag-Erling Smørgrav { 41*7b5038d7SDag-Erling Smørgrav LDNS_FREE(chain); 42*7b5038d7SDag-Erling Smørgrav } 43*7b5038d7SDag-Erling Smørgrav 44*7b5038d7SDag-Erling Smørgrav void 45*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain) 46*7b5038d7SDag-Erling Smørgrav { 47*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(chain->rrset); 48*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(chain->signatures); 49*7b5038d7SDag-Erling Smørgrav if (chain->parent) { 50*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_deep_free(chain->parent); 51*7b5038d7SDag-Erling Smørgrav } 52*7b5038d7SDag-Erling Smørgrav LDNS_FREE(chain); 53*7b5038d7SDag-Erling Smørgrav } 54*7b5038d7SDag-Erling Smørgrav 55*7b5038d7SDag-Erling Smørgrav void 56*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt, 57*7b5038d7SDag-Erling Smørgrav const ldns_dnssec_data_chain *chain) 58*7b5038d7SDag-Erling Smørgrav { 59*7b5038d7SDag-Erling Smørgrav ldns_lookup_table *rcode; 60*7b5038d7SDag-Erling Smørgrav const ldns_rr_descriptor *rr_descriptor; 61*7b5038d7SDag-Erling Smørgrav if (chain) { 62*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent); 63*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(chain->rrset) > 0) { 64*7b5038d7SDag-Erling Smørgrav rcode = ldns_lookup_by_id(ldns_rcodes, 65*7b5038d7SDag-Erling Smørgrav (int) chain->packet_rcode); 66*7b5038d7SDag-Erling Smørgrav if (rcode) { 67*7b5038d7SDag-Erling Smørgrav fprintf(out, ";; rcode: %s\n", rcode->name); 68*7b5038d7SDag-Erling Smørgrav } 69*7b5038d7SDag-Erling Smørgrav 70*7b5038d7SDag-Erling Smørgrav rr_descriptor = ldns_rr_descript(chain->packet_qtype); 71*7b5038d7SDag-Erling Smørgrav if (rr_descriptor && rr_descriptor->_name) { 72*7b5038d7SDag-Erling Smørgrav fprintf(out, ";; qtype: %s\n", rr_descriptor->_name); 73*7b5038d7SDag-Erling Smørgrav } else if (chain->packet_qtype != 0) { 74*7b5038d7SDag-Erling Smørgrav fprintf(out, "TYPE%u", 75*7b5038d7SDag-Erling Smørgrav chain->packet_qtype); 76*7b5038d7SDag-Erling Smørgrav } 77*7b5038d7SDag-Erling Smørgrav if (chain->packet_nodata) { 78*7b5038d7SDag-Erling Smørgrav fprintf(out, ";; NODATA response\n"); 79*7b5038d7SDag-Erling Smørgrav } 80*7b5038d7SDag-Erling Smørgrav fprintf(out, "rrset:\n"); 81*7b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt, chain->rrset); 82*7b5038d7SDag-Erling Smørgrav fprintf(out, "sigs:\n"); 83*7b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt, chain->signatures); 84*7b5038d7SDag-Erling Smørgrav fprintf(out, "---\n"); 85*7b5038d7SDag-Erling Smørgrav } else { 86*7b5038d7SDag-Erling Smørgrav fprintf(out, "<no data>\n"); 87*7b5038d7SDag-Erling Smørgrav } 88*7b5038d7SDag-Erling Smørgrav } 89*7b5038d7SDag-Erling Smørgrav } 90*7b5038d7SDag-Erling Smørgrav void 91*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain) 92*7b5038d7SDag-Erling Smørgrav { 93*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt( 94*7b5038d7SDag-Erling Smørgrav out, ldns_output_format_default, chain); 95*7b5038d7SDag-Erling Smørgrav } 96*7b5038d7SDag-Erling Smørgrav 97*7b5038d7SDag-Erling Smørgrav 98*7b5038d7SDag-Erling Smørgrav static void 99*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res, 100*7b5038d7SDag-Erling Smørgrav uint16_t qflags, 101*7b5038d7SDag-Erling Smørgrav const ldns_pkt *pkt, 102*7b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures, 103*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain, 104*7b5038d7SDag-Erling Smørgrav ldns_rdf *key_name, 105*7b5038d7SDag-Erling Smørgrav ldns_rr_class c) { 106*7b5038d7SDag-Erling Smørgrav ldns_rr_list *keys; 107*7b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt; 108*7b5038d7SDag-Erling Smørgrav if (signatures && ldns_rr_list_rr_count(signatures) > 0) { 109*7b5038d7SDag-Erling Smørgrav new_chain->signatures = ldns_rr_list_clone(signatures); 110*7b5038d7SDag-Erling Smørgrav new_chain->parent_type = 0; 111*7b5038d7SDag-Erling Smørgrav 112*7b5038d7SDag-Erling Smørgrav keys = ldns_pkt_rr_list_by_name_and_type( 113*7b5038d7SDag-Erling Smørgrav pkt, 114*7b5038d7SDag-Erling Smørgrav key_name, 115*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, 116*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 117*7b5038d7SDag-Erling Smørgrav ); 118*7b5038d7SDag-Erling Smørgrav if (!keys) { 119*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, 120*7b5038d7SDag-Erling Smørgrav key_name, 121*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, 122*7b5038d7SDag-Erling Smørgrav c, 123*7b5038d7SDag-Erling Smørgrav qflags); 124*7b5038d7SDag-Erling Smørgrav if (my_pkt) { 125*7b5038d7SDag-Erling Smørgrav keys = ldns_pkt_rr_list_by_name_and_type( 126*7b5038d7SDag-Erling Smørgrav my_pkt, 127*7b5038d7SDag-Erling Smørgrav key_name, 128*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, 129*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 130*7b5038d7SDag-Erling Smørgrav ); 131*7b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res, 132*7b5038d7SDag-Erling Smørgrav qflags, 133*7b5038d7SDag-Erling Smørgrav keys, 134*7b5038d7SDag-Erling Smørgrav my_pkt, 135*7b5038d7SDag-Erling Smørgrav NULL); 136*7b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY; 137*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 138*7b5038d7SDag-Erling Smørgrav } 139*7b5038d7SDag-Erling Smørgrav } else { 140*7b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res, 141*7b5038d7SDag-Erling Smørgrav qflags, 142*7b5038d7SDag-Erling Smørgrav keys, 143*7b5038d7SDag-Erling Smørgrav pkt, 144*7b5038d7SDag-Erling Smørgrav NULL); 145*7b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY; 146*7b5038d7SDag-Erling Smørgrav } 147*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(keys); 148*7b5038d7SDag-Erling Smørgrav } 149*7b5038d7SDag-Erling Smørgrav } 150*7b5038d7SDag-Erling Smørgrav 151*7b5038d7SDag-Erling Smørgrav static void 152*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_other(ldns_resolver *res, 153*7b5038d7SDag-Erling Smørgrav uint16_t qflags, 154*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain, 155*7b5038d7SDag-Erling Smørgrav ldns_rdf *key_name, 156*7b5038d7SDag-Erling Smørgrav ldns_rr_class c, 157*7b5038d7SDag-Erling Smørgrav ldns_rr_list *dss) 158*7b5038d7SDag-Erling Smørgrav { 159*7b5038d7SDag-Erling Smørgrav /* 'self-signed', parent is a DS */ 160*7b5038d7SDag-Erling Smørgrav 161*7b5038d7SDag-Erling Smørgrav /* okay, either we have other keys signing the current one, 162*7b5038d7SDag-Erling Smørgrav * or the current 163*7b5038d7SDag-Erling Smørgrav * one should have a DS record in the parent zone. 164*7b5038d7SDag-Erling Smørgrav * How do we find this out? Try both? 165*7b5038d7SDag-Erling Smørgrav * 166*7b5038d7SDag-Erling Smørgrav * request DNSKEYS for current zone, 167*7b5038d7SDag-Erling Smørgrav * add all signatures to current level 168*7b5038d7SDag-Erling Smørgrav */ 169*7b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt; 170*7b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures2; 171*7b5038d7SDag-Erling Smørgrav 172*7b5038d7SDag-Erling Smørgrav new_chain->parent_type = 1; 173*7b5038d7SDag-Erling Smørgrav 174*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, 175*7b5038d7SDag-Erling Smørgrav key_name, 176*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, 177*7b5038d7SDag-Erling Smørgrav c, 178*7b5038d7SDag-Erling Smørgrav qflags); 179*7b5038d7SDag-Erling Smørgrav if (my_pkt) { 180*7b5038d7SDag-Erling Smørgrav dss = ldns_pkt_rr_list_by_name_and_type(my_pkt, 181*7b5038d7SDag-Erling Smørgrav key_name, 182*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, 183*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 184*7b5038d7SDag-Erling Smørgrav ); 185*7b5038d7SDag-Erling Smørgrav if (dss) { 186*7b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res, 187*7b5038d7SDag-Erling Smørgrav qflags, 188*7b5038d7SDag-Erling Smørgrav dss, 189*7b5038d7SDag-Erling Smørgrav my_pkt, 190*7b5038d7SDag-Erling Smørgrav NULL); 191*7b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS; 192*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(dss); 193*7b5038d7SDag-Erling Smørgrav } 194*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 195*7b5038d7SDag-Erling Smørgrav } 196*7b5038d7SDag-Erling Smørgrav 197*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, 198*7b5038d7SDag-Erling Smørgrav key_name, 199*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, 200*7b5038d7SDag-Erling Smørgrav c, 201*7b5038d7SDag-Erling Smørgrav qflags); 202*7b5038d7SDag-Erling Smørgrav if (my_pkt) { 203*7b5038d7SDag-Erling Smørgrav signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt, 204*7b5038d7SDag-Erling Smørgrav key_name, 205*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG, 206*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER); 207*7b5038d7SDag-Erling Smørgrav if (signatures2) { 208*7b5038d7SDag-Erling Smørgrav if (new_chain->signatures) { 209*7b5038d7SDag-Erling Smørgrav printf("There were already sigs!\n"); 210*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_chain->signatures); 211*7b5038d7SDag-Erling Smørgrav printf("replacing the old sigs\n"); 212*7b5038d7SDag-Erling Smørgrav } 213*7b5038d7SDag-Erling Smørgrav new_chain->signatures = signatures2; 214*7b5038d7SDag-Erling Smørgrav } 215*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 216*7b5038d7SDag-Erling Smørgrav } 217*7b5038d7SDag-Erling Smørgrav } 218*7b5038d7SDag-Erling Smørgrav 219*7b5038d7SDag-Erling Smørgrav static ldns_dnssec_data_chain * 220*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res, 221*7b5038d7SDag-Erling Smørgrav uint16_t qflags, 222*7b5038d7SDag-Erling Smørgrav ldns_rr *orig_rr, 223*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrset, 224*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain) 225*7b5038d7SDag-Erling Smørgrav { 226*7b5038d7SDag-Erling Smørgrav ldns_rdf *possible_parent_name; 227*7b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt; 228*7b5038d7SDag-Erling Smørgrav /* apparently we were not able to find a signing key, so 229*7b5038d7SDag-Erling Smørgrav we assume the chain ends here 230*7b5038d7SDag-Erling Smørgrav */ 231*7b5038d7SDag-Erling Smørgrav /* try parents for auth denial of DS */ 232*7b5038d7SDag-Erling Smørgrav if (orig_rr) { 233*7b5038d7SDag-Erling Smørgrav possible_parent_name = ldns_rr_owner(orig_rr); 234*7b5038d7SDag-Erling Smørgrav } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) { 235*7b5038d7SDag-Erling Smørgrav possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0)); 236*7b5038d7SDag-Erling Smørgrav } else { 237*7b5038d7SDag-Erling Smørgrav /* no information to go on, give up */ 238*7b5038d7SDag-Erling Smørgrav return new_chain; 239*7b5038d7SDag-Erling Smørgrav } 240*7b5038d7SDag-Erling Smørgrav 241*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, 242*7b5038d7SDag-Erling Smørgrav possible_parent_name, 243*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, 244*7b5038d7SDag-Erling Smørgrav LDNS_RR_CLASS_IN, 245*7b5038d7SDag-Erling Smørgrav qflags); 246*7b5038d7SDag-Erling Smørgrav if (!my_pkt) { 247*7b5038d7SDag-Erling Smørgrav return new_chain; 248*7b5038d7SDag-Erling Smørgrav } 249*7b5038d7SDag-Erling Smørgrav 250*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(my_pkt) > 0) { 251*7b5038d7SDag-Erling Smørgrav /* add error, no sigs but DS in parent */ 252*7b5038d7SDag-Erling Smørgrav /*ldns_pkt_print(stdout, my_pkt);*/ 253*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 254*7b5038d7SDag-Erling Smørgrav } else { 255*7b5038d7SDag-Erling Smørgrav /* are there signatures? */ 256*7b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res, 257*7b5038d7SDag-Erling Smørgrav qflags, 258*7b5038d7SDag-Erling Smørgrav NULL, 259*7b5038d7SDag-Erling Smørgrav my_pkt, 260*7b5038d7SDag-Erling Smørgrav NULL); 261*7b5038d7SDag-Erling Smørgrav 262*7b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS; 263*7b5038d7SDag-Erling Smørgrav 264*7b5038d7SDag-Erling Smørgrav } 265*7b5038d7SDag-Erling Smørgrav return new_chain; 266*7b5038d7SDag-Erling Smørgrav } 267*7b5038d7SDag-Erling Smørgrav 268*7b5038d7SDag-Erling Smørgrav 269*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain * 270*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain(ldns_resolver *res, 271*7b5038d7SDag-Erling Smørgrav uint16_t qflags, 272*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrset, 273*7b5038d7SDag-Erling Smørgrav const ldns_pkt *pkt, 274*7b5038d7SDag-Erling Smørgrav ldns_rr *orig_rr) 275*7b5038d7SDag-Erling Smørgrav { 276*7b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures = NULL; 277*7b5038d7SDag-Erling Smørgrav ldns_rr_list *dss = NULL; 278*7b5038d7SDag-Erling Smørgrav 279*7b5038d7SDag-Erling Smørgrav ldns_rr_list *my_rrset; 280*7b5038d7SDag-Erling Smørgrav 281*7b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt; 282*7b5038d7SDag-Erling Smørgrav 283*7b5038d7SDag-Erling Smørgrav ldns_rdf *name = NULL, *key_name = NULL; 284*7b5038d7SDag-Erling Smørgrav ldns_rr_type type = 0; 285*7b5038d7SDag-Erling Smørgrav ldns_rr_class c = 0; 286*7b5038d7SDag-Erling Smørgrav 287*7b5038d7SDag-Erling Smørgrav bool other_rrset = false; 288*7b5038d7SDag-Erling Smørgrav 289*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new(); 290*7b5038d7SDag-Erling Smørgrav 291*7b5038d7SDag-Erling Smørgrav if (!ldns_dnssec_pkt_has_rrsigs(pkt)) { 292*7b5038d7SDag-Erling Smørgrav /* hmm. no dnssec data in the packet. go up to try and deny 293*7b5038d7SDag-Erling Smørgrav * DS? */ 294*7b5038d7SDag-Erling Smørgrav return new_chain; 295*7b5038d7SDag-Erling Smørgrav } 296*7b5038d7SDag-Erling Smørgrav 297*7b5038d7SDag-Erling Smørgrav if (orig_rr) { 298*7b5038d7SDag-Erling Smørgrav new_chain->rrset = ldns_rr_list_new(); 299*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_chain->rrset, orig_rr); 300*7b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res, 301*7b5038d7SDag-Erling Smørgrav qflags, 302*7b5038d7SDag-Erling Smørgrav rrset, 303*7b5038d7SDag-Erling Smørgrav pkt, 304*7b5038d7SDag-Erling Smørgrav NULL); 305*7b5038d7SDag-Erling Smørgrav new_chain->packet_rcode = ldns_pkt_get_rcode(pkt); 306*7b5038d7SDag-Erling Smørgrav new_chain->packet_qtype = ldns_rr_get_type(orig_rr); 307*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(pkt) == 0) { 308*7b5038d7SDag-Erling Smørgrav new_chain->packet_nodata = true; 309*7b5038d7SDag-Erling Smørgrav } 310*7b5038d7SDag-Erling Smørgrav return new_chain; 311*7b5038d7SDag-Erling Smørgrav } 312*7b5038d7SDag-Erling Smørgrav 313*7b5038d7SDag-Erling Smørgrav if (!rrset || ldns_rr_list_rr_count(rrset) < 1) { 314*7b5038d7SDag-Erling Smørgrav /* hmm, no data, do we have denial? only works if pkt was given, 315*7b5038d7SDag-Erling Smørgrav otherwise caller has to do the check himself */ 316*7b5038d7SDag-Erling Smørgrav new_chain->packet_nodata = true; 317*7b5038d7SDag-Erling Smørgrav if (pkt) { 318*7b5038d7SDag-Erling Smørgrav my_rrset = ldns_pkt_rr_list_by_type(pkt, 319*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC, 320*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 321*7b5038d7SDag-Erling Smørgrav ); 322*7b5038d7SDag-Erling Smørgrav if (my_rrset) { 323*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(my_rrset) > 0) { 324*7b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_NSEC; 325*7b5038d7SDag-Erling Smørgrav other_rrset = true; 326*7b5038d7SDag-Erling Smørgrav } else { 327*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset); 328*7b5038d7SDag-Erling Smørgrav my_rrset = NULL; 329*7b5038d7SDag-Erling Smørgrav } 330*7b5038d7SDag-Erling Smørgrav } else { 331*7b5038d7SDag-Erling Smørgrav /* nothing, try nsec3 */ 332*7b5038d7SDag-Erling Smørgrav my_rrset = ldns_pkt_rr_list_by_type(pkt, 333*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3, 334*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION); 335*7b5038d7SDag-Erling Smørgrav if (my_rrset) { 336*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(my_rrset) > 0) { 337*7b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_NSEC3; 338*7b5038d7SDag-Erling Smørgrav other_rrset = true; 339*7b5038d7SDag-Erling Smørgrav } else { 340*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset); 341*7b5038d7SDag-Erling Smørgrav my_rrset = NULL; 342*7b5038d7SDag-Erling Smørgrav } 343*7b5038d7SDag-Erling Smørgrav } else { 344*7b5038d7SDag-Erling Smørgrav /* nothing, stop */ 345*7b5038d7SDag-Erling Smørgrav /* try parent zone? for denied insecure? */ 346*7b5038d7SDag-Erling Smørgrav return new_chain; 347*7b5038d7SDag-Erling Smørgrav } 348*7b5038d7SDag-Erling Smørgrav } 349*7b5038d7SDag-Erling Smørgrav } else { 350*7b5038d7SDag-Erling Smørgrav return new_chain; 351*7b5038d7SDag-Erling Smørgrav } 352*7b5038d7SDag-Erling Smørgrav } else { 353*7b5038d7SDag-Erling Smørgrav my_rrset = (ldns_rr_list *) rrset; 354*7b5038d7SDag-Erling Smørgrav } 355*7b5038d7SDag-Erling Smørgrav 356*7b5038d7SDag-Erling Smørgrav if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) { 357*7b5038d7SDag-Erling Smørgrav new_chain->rrset = ldns_rr_list_clone(my_rrset); 358*7b5038d7SDag-Erling Smørgrav name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0)); 359*7b5038d7SDag-Erling Smørgrav type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0)); 360*7b5038d7SDag-Erling Smørgrav c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0)); 361*7b5038d7SDag-Erling Smørgrav } 362*7b5038d7SDag-Erling Smørgrav 363*7b5038d7SDag-Erling Smørgrav if (other_rrset) { 364*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset); 365*7b5038d7SDag-Erling Smørgrav } 366*7b5038d7SDag-Erling Smørgrav 367*7b5038d7SDag-Erling Smørgrav /* normally there will only be 1 signature 'set' 368*7b5038d7SDag-Erling Smørgrav but there can be more than 1 denial (wildcards) 369*7b5038d7SDag-Erling Smørgrav so check for NSEC 370*7b5038d7SDag-Erling Smørgrav */ 371*7b5038d7SDag-Erling Smørgrav if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) { 372*7b5038d7SDag-Erling Smørgrav /* just throw in all signatures, the tree builder must sort 373*7b5038d7SDag-Erling Smørgrav this out */ 374*7b5038d7SDag-Erling Smørgrav if (pkt) { 375*7b5038d7SDag-Erling Smørgrav signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type); 376*7b5038d7SDag-Erling Smørgrav } else { 377*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, name, type, c, qflags); 378*7b5038d7SDag-Erling Smørgrav if (my_pkt) { 379*7b5038d7SDag-Erling Smørgrav signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type); 380*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 381*7b5038d7SDag-Erling Smørgrav } 382*7b5038d7SDag-Erling Smørgrav } 383*7b5038d7SDag-Erling Smørgrav } else { 384*7b5038d7SDag-Erling Smørgrav if (pkt) { 385*7b5038d7SDag-Erling Smørgrav signatures = 386*7b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt, 387*7b5038d7SDag-Erling Smørgrav name, 388*7b5038d7SDag-Erling Smørgrav type); 389*7b5038d7SDag-Erling Smørgrav } 390*7b5038d7SDag-Erling Smørgrav if (!signatures) { 391*7b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, name, type, c, qflags); 392*7b5038d7SDag-Erling Smørgrav if (my_pkt) { 393*7b5038d7SDag-Erling Smørgrav signatures = 394*7b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt, 395*7b5038d7SDag-Erling Smørgrav name, 396*7b5038d7SDag-Erling Smørgrav type); 397*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt); 398*7b5038d7SDag-Erling Smørgrav } 399*7b5038d7SDag-Erling Smørgrav } 400*7b5038d7SDag-Erling Smørgrav } 401*7b5038d7SDag-Erling Smørgrav 402*7b5038d7SDag-Erling Smørgrav if (signatures && ldns_rr_list_rr_count(signatures) > 0) { 403*7b5038d7SDag-Erling Smørgrav key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7); 404*7b5038d7SDag-Erling Smørgrav } 405*7b5038d7SDag-Erling Smørgrav 406*7b5038d7SDag-Erling Smørgrav if (!key_name) { 407*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_build_data_chain_nokeyname(res, 408*7b5038d7SDag-Erling Smørgrav qflags, 409*7b5038d7SDag-Erling Smørgrav orig_rr, 410*7b5038d7SDag-Erling Smørgrav rrset, 411*7b5038d7SDag-Erling Smørgrav new_chain); 412*7b5038d7SDag-Erling Smørgrav } 413*7b5038d7SDag-Erling Smørgrav 414*7b5038d7SDag-Erling Smørgrav if (type != LDNS_RR_TYPE_DNSKEY) { 415*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_dnskey(res, 416*7b5038d7SDag-Erling Smørgrav qflags, 417*7b5038d7SDag-Erling Smørgrav pkt, 418*7b5038d7SDag-Erling Smørgrav signatures, 419*7b5038d7SDag-Erling Smørgrav new_chain, 420*7b5038d7SDag-Erling Smørgrav key_name, 421*7b5038d7SDag-Erling Smørgrav c 422*7b5038d7SDag-Erling Smørgrav ); 423*7b5038d7SDag-Erling Smørgrav } else { 424*7b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_other(res, 425*7b5038d7SDag-Erling Smørgrav qflags, 426*7b5038d7SDag-Erling Smørgrav new_chain, 427*7b5038d7SDag-Erling Smørgrav key_name, 428*7b5038d7SDag-Erling Smørgrav c, 429*7b5038d7SDag-Erling Smørgrav dss 430*7b5038d7SDag-Erling Smørgrav 431*7b5038d7SDag-Erling Smørgrav ); 432*7b5038d7SDag-Erling Smørgrav } 433*7b5038d7SDag-Erling Smørgrav if (signatures) { 434*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(signatures); 435*7b5038d7SDag-Erling Smørgrav } 436*7b5038d7SDag-Erling Smørgrav 437*7b5038d7SDag-Erling Smørgrav return new_chain; 438*7b5038d7SDag-Erling Smørgrav } 439*7b5038d7SDag-Erling Smørgrav 440*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree * 441*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_new(void) 442*7b5038d7SDag-Erling Smørgrav { 443*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree, 444*7b5038d7SDag-Erling Smørgrav 1); 445*7b5038d7SDag-Erling Smørgrav if(!new_tree) return NULL; 446*7b5038d7SDag-Erling Smørgrav new_tree->rr = NULL; 447*7b5038d7SDag-Erling Smørgrav new_tree->rrset = NULL; 448*7b5038d7SDag-Erling Smørgrav new_tree->parent_count = 0; 449*7b5038d7SDag-Erling Smørgrav 450*7b5038d7SDag-Erling Smørgrav return new_tree; 451*7b5038d7SDag-Erling Smørgrav } 452*7b5038d7SDag-Erling Smørgrav 453*7b5038d7SDag-Erling Smørgrav void 454*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree) 455*7b5038d7SDag-Erling Smørgrav { 456*7b5038d7SDag-Erling Smørgrav size_t i; 457*7b5038d7SDag-Erling Smørgrav if (tree) { 458*7b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) { 459*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(tree->parents[i]); 460*7b5038d7SDag-Erling Smørgrav } 461*7b5038d7SDag-Erling Smørgrav } 462*7b5038d7SDag-Erling Smørgrav LDNS_FREE(tree); 463*7b5038d7SDag-Erling Smørgrav } 464*7b5038d7SDag-Erling Smørgrav 465*7b5038d7SDag-Erling Smørgrav size_t 466*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree) 467*7b5038d7SDag-Erling Smørgrav { 468*7b5038d7SDag-Erling Smørgrav size_t result = 0; 469*7b5038d7SDag-Erling Smørgrav size_t parent = 0; 470*7b5038d7SDag-Erling Smørgrav size_t i; 471*7b5038d7SDag-Erling Smørgrav 472*7b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) { 473*7b5038d7SDag-Erling Smørgrav parent = ldns_dnssec_trust_tree_depth(tree->parents[i]); 474*7b5038d7SDag-Erling Smørgrav if (parent > result) { 475*7b5038d7SDag-Erling Smørgrav result = parent; 476*7b5038d7SDag-Erling Smørgrav } 477*7b5038d7SDag-Erling Smørgrav } 478*7b5038d7SDag-Erling Smørgrav return 1 + result; 479*7b5038d7SDag-Erling Smørgrav } 480*7b5038d7SDag-Erling Smørgrav 481*7b5038d7SDag-Erling Smørgrav /* TODO ldns_ */ 482*7b5038d7SDag-Erling Smørgrav static void 483*7b5038d7SDag-Erling Smørgrav print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth) 484*7b5038d7SDag-Erling Smørgrav { 485*7b5038d7SDag-Erling Smørgrav size_t i; 486*7b5038d7SDag-Erling Smørgrav for (i = 0; i < nr; i++) { 487*7b5038d7SDag-Erling Smørgrav if (i == nr - 1) { 488*7b5038d7SDag-Erling Smørgrav fprintf(out, "|---"); 489*7b5038d7SDag-Erling Smørgrav } else if (map && i < treedepth && map[i] == 1) { 490*7b5038d7SDag-Erling Smørgrav fprintf(out, "| "); 491*7b5038d7SDag-Erling Smørgrav } else { 492*7b5038d7SDag-Erling Smørgrav fprintf(out, " "); 493*7b5038d7SDag-Erling Smørgrav } 494*7b5038d7SDag-Erling Smørgrav } 495*7b5038d7SDag-Erling Smørgrav } 496*7b5038d7SDag-Erling Smørgrav 497*7b5038d7SDag-Erling Smørgrav static void 498*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 499*7b5038d7SDag-Erling Smørgrav const ldns_output_format *fmt, 500*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree, 501*7b5038d7SDag-Erling Smørgrav size_t tabs, 502*7b5038d7SDag-Erling Smørgrav bool extended, 503*7b5038d7SDag-Erling Smørgrav uint8_t *sibmap, 504*7b5038d7SDag-Erling Smørgrav size_t treedepth) 505*7b5038d7SDag-Erling Smørgrav { 506*7b5038d7SDag-Erling Smørgrav size_t i; 507*7b5038d7SDag-Erling Smørgrav const ldns_rr_descriptor *descriptor; 508*7b5038d7SDag-Erling Smørgrav bool mapset = false; 509*7b5038d7SDag-Erling Smørgrav 510*7b5038d7SDag-Erling Smørgrav if (!sibmap) { 511*7b5038d7SDag-Erling Smørgrav treedepth = ldns_dnssec_trust_tree_depth(tree); 512*7b5038d7SDag-Erling Smørgrav sibmap = LDNS_XMALLOC(uint8_t, treedepth); 513*7b5038d7SDag-Erling Smørgrav if(!sibmap) 514*7b5038d7SDag-Erling Smørgrav return; /* mem err */ 515*7b5038d7SDag-Erling Smørgrav memset(sibmap, 0, treedepth); 516*7b5038d7SDag-Erling Smørgrav mapset = true; 517*7b5038d7SDag-Erling Smørgrav } 518*7b5038d7SDag-Erling Smørgrav 519*7b5038d7SDag-Erling Smørgrav if (tree) { 520*7b5038d7SDag-Erling Smørgrav if (tree->rr) { 521*7b5038d7SDag-Erling Smørgrav print_tabs(out, tabs, sibmap, treedepth); 522*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_owner(tree->rr)); 523*7b5038d7SDag-Erling Smørgrav descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr)); 524*7b5038d7SDag-Erling Smørgrav 525*7b5038d7SDag-Erling Smørgrav if (descriptor->_name) { 526*7b5038d7SDag-Erling Smørgrav fprintf(out, " (%s", descriptor->_name); 527*7b5038d7SDag-Erling Smørgrav } else { 528*7b5038d7SDag-Erling Smørgrav fprintf(out, " (TYPE%d", 529*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->rr)); 530*7b5038d7SDag-Erling Smørgrav } 531*7b5038d7SDag-Erling Smørgrav if (tabs > 0) { 532*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) { 533*7b5038d7SDag-Erling Smørgrav fprintf(out, " keytag: %u", 534*7b5038d7SDag-Erling Smørgrav (unsigned int) ldns_calc_keytag(tree->rr)); 535*7b5038d7SDag-Erling Smørgrav fprintf(out, " alg: "); 536*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2)); 537*7b5038d7SDag-Erling Smørgrav fprintf(out, " flags: "); 538*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0)); 539*7b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) { 540*7b5038d7SDag-Erling Smørgrav fprintf(out, " keytag: "); 541*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0)); 542*7b5038d7SDag-Erling Smørgrav fprintf(out, " digest type: "); 543*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2)); 544*7b5038d7SDag-Erling Smørgrav } 545*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) { 546*7b5038d7SDag-Erling Smørgrav fprintf(out, " "); 547*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0)); 548*7b5038d7SDag-Erling Smørgrav fprintf(out, " "); 549*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1)); 550*7b5038d7SDag-Erling Smørgrav } 551*7b5038d7SDag-Erling Smørgrav } 552*7b5038d7SDag-Erling Smørgrav 553*7b5038d7SDag-Erling Smørgrav fprintf(out, ")\n"); 554*7b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) { 555*7b5038d7SDag-Erling Smørgrav if (tree->parent_count > 1 && i < tree->parent_count - 1) { 556*7b5038d7SDag-Erling Smørgrav sibmap[tabs] = 1; 557*7b5038d7SDag-Erling Smørgrav } else { 558*7b5038d7SDag-Erling Smørgrav sibmap[tabs] = 0; 559*7b5038d7SDag-Erling Smørgrav } 560*7b5038d7SDag-Erling Smørgrav /* only print errors */ 561*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->parents[i]->rr) == 562*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC || 563*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->parents[i]->rr) == 564*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3) { 565*7b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] == LDNS_STATUS_OK) { 566*7b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth); 567*7b5038d7SDag-Erling Smørgrav if (tabs == 0 && 568*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS && 569*7b5038d7SDag-Erling Smørgrav ldns_rr_rd_count(tree->rr) > 0) { 570*7b5038d7SDag-Erling Smørgrav fprintf(out, "Existence of DS is denied by:\n"); 571*7b5038d7SDag-Erling Smørgrav } else { 572*7b5038d7SDag-Erling Smørgrav fprintf(out, "Existence is denied by:\n"); 573*7b5038d7SDag-Erling Smørgrav } 574*7b5038d7SDag-Erling Smørgrav } else { 575*7b5038d7SDag-Erling Smørgrav /* NS records aren't signed */ 576*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) { 577*7b5038d7SDag-Erling Smørgrav fprintf(out, "Existence of DS is denied by:\n"); 578*7b5038d7SDag-Erling Smørgrav } else { 579*7b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth); 580*7b5038d7SDag-Erling Smørgrav fprintf(out, 581*7b5038d7SDag-Erling Smørgrav "Error in denial of existence: %s\n", 582*7b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id( 583*7b5038d7SDag-Erling Smørgrav tree->parent_status[i])); 584*7b5038d7SDag-Erling Smørgrav } 585*7b5038d7SDag-Erling Smørgrav } 586*7b5038d7SDag-Erling Smørgrav } else 587*7b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] != LDNS_STATUS_OK) { 588*7b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth); 589*7b5038d7SDag-Erling Smørgrav fprintf(out, 590*7b5038d7SDag-Erling Smørgrav "%s:\n", 591*7b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id( 592*7b5038d7SDag-Erling Smørgrav tree->parent_status[i])); 593*7b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] 594*7b5038d7SDag-Erling Smørgrav == LDNS_STATUS_SSL_ERR) { 595*7b5038d7SDag-Erling Smørgrav printf("; SSL Error: "); 596*7b5038d7SDag-Erling Smørgrav ERR_load_crypto_strings(); 597*7b5038d7SDag-Erling Smørgrav ERR_print_errors_fp(stdout); 598*7b5038d7SDag-Erling Smørgrav printf("\n"); 599*7b5038d7SDag-Erling Smørgrav } 600*7b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, 601*7b5038d7SDag-Erling Smørgrav tree-> 602*7b5038d7SDag-Erling Smørgrav parent_signature[i]); 603*7b5038d7SDag-Erling Smørgrav printf("For RRset:\n"); 604*7b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt, 605*7b5038d7SDag-Erling Smørgrav tree->rrset); 606*7b5038d7SDag-Erling Smørgrav printf("With key:\n"); 607*7b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, 608*7b5038d7SDag-Erling Smørgrav tree->parents[i]->rr); 609*7b5038d7SDag-Erling Smørgrav } 610*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 611*7b5038d7SDag-Erling Smørgrav tree->parents[i], 612*7b5038d7SDag-Erling Smørgrav tabs+1, 613*7b5038d7SDag-Erling Smørgrav extended, 614*7b5038d7SDag-Erling Smørgrav sibmap, 615*7b5038d7SDag-Erling Smørgrav treedepth); 616*7b5038d7SDag-Erling Smørgrav } 617*7b5038d7SDag-Erling Smørgrav } else { 618*7b5038d7SDag-Erling Smørgrav print_tabs(out, tabs, sibmap, treedepth); 619*7b5038d7SDag-Erling Smørgrav fprintf(out, "<no data>\n"); 620*7b5038d7SDag-Erling Smørgrav } 621*7b5038d7SDag-Erling Smørgrav } else { 622*7b5038d7SDag-Erling Smørgrav fprintf(out, "<null pointer>\n"); 623*7b5038d7SDag-Erling Smørgrav } 624*7b5038d7SDag-Erling Smørgrav 625*7b5038d7SDag-Erling Smørgrav if (mapset) { 626*7b5038d7SDag-Erling Smørgrav LDNS_FREE(sibmap); 627*7b5038d7SDag-Erling Smørgrav } 628*7b5038d7SDag-Erling Smørgrav } 629*7b5038d7SDag-Erling Smørgrav 630*7b5038d7SDag-Erling Smørgrav static void 631*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm(FILE *out, 632*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree, 633*7b5038d7SDag-Erling Smørgrav size_t tabs, 634*7b5038d7SDag-Erling Smørgrav bool extended, 635*7b5038d7SDag-Erling Smørgrav uint8_t *sibmap, 636*7b5038d7SDag-Erling Smørgrav size_t treedepth) 637*7b5038d7SDag-Erling Smørgrav { 638*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default, 639*7b5038d7SDag-Erling Smørgrav tree, tabs, extended, sibmap, treedepth); 640*7b5038d7SDag-Erling Smørgrav } 641*7b5038d7SDag-Erling Smørgrav 642*7b5038d7SDag-Erling Smørgrav void 643*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt, 644*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree, 645*7b5038d7SDag-Erling Smørgrav size_t tabs, 646*7b5038d7SDag-Erling Smørgrav bool extended) 647*7b5038d7SDag-Erling Smørgrav { 648*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 649*7b5038d7SDag-Erling Smørgrav tree, tabs, extended, NULL, 0); 650*7b5038d7SDag-Erling Smørgrav } 651*7b5038d7SDag-Erling Smørgrav 652*7b5038d7SDag-Erling Smørgrav void 653*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print(FILE *out, 654*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree, 655*7b5038d7SDag-Erling Smørgrav size_t tabs, 656*7b5038d7SDag-Erling Smørgrav bool extended) 657*7b5038d7SDag-Erling Smørgrav { 658*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default, 659*7b5038d7SDag-Erling Smørgrav tree, tabs, extended); 660*7b5038d7SDag-Erling Smørgrav } 661*7b5038d7SDag-Erling Smørgrav 662*7b5038d7SDag-Erling Smørgrav 663*7b5038d7SDag-Erling Smørgrav ldns_status 664*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree, 665*7b5038d7SDag-Erling Smørgrav const ldns_dnssec_trust_tree *parent, 666*7b5038d7SDag-Erling Smørgrav const ldns_rr *signature, 667*7b5038d7SDag-Erling Smørgrav const ldns_status parent_status) 668*7b5038d7SDag-Erling Smørgrav { 669*7b5038d7SDag-Erling Smørgrav if (tree 670*7b5038d7SDag-Erling Smørgrav && parent 671*7b5038d7SDag-Erling Smørgrav && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) { 672*7b5038d7SDag-Erling Smørgrav /* 673*7b5038d7SDag-Erling Smørgrav printf("Add parent for: "); 674*7b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, tree->rr); 675*7b5038d7SDag-Erling Smørgrav printf("parent: "); 676*7b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, parent->rr); 677*7b5038d7SDag-Erling Smørgrav */ 678*7b5038d7SDag-Erling Smørgrav tree->parents[tree->parent_count] = 679*7b5038d7SDag-Erling Smørgrav (ldns_dnssec_trust_tree *) parent; 680*7b5038d7SDag-Erling Smørgrav tree->parent_status[tree->parent_count] = parent_status; 681*7b5038d7SDag-Erling Smørgrav tree->parent_signature[tree->parent_count] = (ldns_rr *) signature; 682*7b5038d7SDag-Erling Smørgrav tree->parent_count++; 683*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 684*7b5038d7SDag-Erling Smørgrav } else { 685*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 686*7b5038d7SDag-Erling Smørgrav } 687*7b5038d7SDag-Erling Smørgrav } 688*7b5038d7SDag-Erling Smørgrav 689*7b5038d7SDag-Erling Smørgrav /* if rr is null, take the first from the rrset */ 690*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree * 691*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time( 692*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 693*7b5038d7SDag-Erling Smørgrav ldns_rr *rr, 694*7b5038d7SDag-Erling Smørgrav time_t check_time 695*7b5038d7SDag-Erling Smørgrav ) 696*7b5038d7SDag-Erling Smørgrav { 697*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset; 698*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_sigs; 699*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr = NULL; 700*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr; 701*7b5038d7SDag-Erling Smørgrav size_t i, j; 702*7b5038d7SDag-Erling Smørgrav 703*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new(); 704*7b5038d7SDag-Erling Smørgrav if(!new_tree) 705*7b5038d7SDag-Erling Smørgrav return NULL; 706*7b5038d7SDag-Erling Smørgrav 707*7b5038d7SDag-Erling Smørgrav if (data_chain && data_chain->rrset) { 708*7b5038d7SDag-Erling Smørgrav cur_rrset = data_chain->rrset; 709*7b5038d7SDag-Erling Smørgrav 710*7b5038d7SDag-Erling Smørgrav cur_sigs = data_chain->signatures; 711*7b5038d7SDag-Erling Smørgrav 712*7b5038d7SDag-Erling Smørgrav if (rr) { 713*7b5038d7SDag-Erling Smørgrav cur_rr = rr; 714*7b5038d7SDag-Erling Smørgrav } 715*7b5038d7SDag-Erling Smørgrav 716*7b5038d7SDag-Erling Smørgrav if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) { 717*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, 0); 718*7b5038d7SDag-Erling Smørgrav } 719*7b5038d7SDag-Erling Smørgrav 720*7b5038d7SDag-Erling Smørgrav if (cur_rr) { 721*7b5038d7SDag-Erling Smørgrav new_tree->rr = cur_rr; 722*7b5038d7SDag-Erling Smørgrav new_tree->rrset = cur_rrset; 723*7b5038d7SDag-Erling Smørgrav /* there are three possibilities: 724*7b5038d7SDag-Erling Smørgrav 1 - 'normal' rrset, signed by a key 725*7b5038d7SDag-Erling Smørgrav 2 - dnskey signed by other dnskey 726*7b5038d7SDag-Erling Smørgrav 3 - dnskey proven by higher level DS 727*7b5038d7SDag-Erling Smørgrav (data denied by nsec is a special case that can 728*7b5038d7SDag-Erling Smørgrav occur in multiple places) 729*7b5038d7SDag-Erling Smørgrav 730*7b5038d7SDag-Erling Smørgrav */ 731*7b5038d7SDag-Erling Smørgrav if (cur_sigs) { 732*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) { 733*7b5038d7SDag-Erling Smørgrav /* find the appropriate key in the parent list */ 734*7b5038d7SDag-Erling Smørgrav cur_sig_rr = ldns_rr_list_rr(cur_sigs, i); 735*7b5038d7SDag-Erling Smørgrav 736*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) { 737*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 738*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_rr))) 739*7b5038d7SDag-Erling Smørgrav { 740*7b5038d7SDag-Erling Smørgrav /* find first that does match */ 741*7b5038d7SDag-Erling Smørgrav 742*7b5038d7SDag-Erling Smørgrav for (j = 0; 743*7b5038d7SDag-Erling Smørgrav j < ldns_rr_list_rr_count(cur_rrset) && 744*7b5038d7SDag-Erling Smørgrav ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0; 745*7b5038d7SDag-Erling Smørgrav j++) { 746*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, j); 747*7b5038d7SDag-Erling Smørgrav 748*7b5038d7SDag-Erling Smørgrav } 749*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 750*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_rr))) 751*7b5038d7SDag-Erling Smørgrav { 752*7b5038d7SDag-Erling Smørgrav break; 753*7b5038d7SDag-Erling Smørgrav } 754*7b5038d7SDag-Erling Smørgrav } 755*7b5038d7SDag-Erling Smørgrav 756*7b5038d7SDag-Erling Smørgrav } 757*7b5038d7SDag-Erling Smørgrav /* option 1 */ 758*7b5038d7SDag-Erling Smørgrav if (data_chain->parent) { 759*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time( 760*7b5038d7SDag-Erling Smørgrav new_tree, 761*7b5038d7SDag-Erling Smørgrav data_chain, 762*7b5038d7SDag-Erling Smørgrav cur_sig_rr, 763*7b5038d7SDag-Erling Smørgrav check_time); 764*7b5038d7SDag-Erling Smørgrav } 765*7b5038d7SDag-Erling Smørgrav 766*7b5038d7SDag-Erling Smørgrav /* option 2 */ 767*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time( 768*7b5038d7SDag-Erling Smørgrav new_tree, 769*7b5038d7SDag-Erling Smørgrav data_chain, 770*7b5038d7SDag-Erling Smørgrav cur_rr, 771*7b5038d7SDag-Erling Smørgrav cur_sig_rr, 772*7b5038d7SDag-Erling Smørgrav check_time); 773*7b5038d7SDag-Erling Smørgrav } 774*7b5038d7SDag-Erling Smørgrav 775*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time( 776*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, 777*7b5038d7SDag-Erling Smørgrav cur_rr, check_time); 778*7b5038d7SDag-Erling Smørgrav } else { 779*7b5038d7SDag-Erling Smørgrav /* no signatures? maybe it's nsec data */ 780*7b5038d7SDag-Erling Smørgrav 781*7b5038d7SDag-Erling Smørgrav /* just add every rr from parent as new parent */ 782*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time( 783*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, check_time); 784*7b5038d7SDag-Erling Smørgrav } 785*7b5038d7SDag-Erling Smørgrav } 786*7b5038d7SDag-Erling Smørgrav } 787*7b5038d7SDag-Erling Smørgrav 788*7b5038d7SDag-Erling Smørgrav return new_tree; 789*7b5038d7SDag-Erling Smørgrav } 790*7b5038d7SDag-Erling Smørgrav 791*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree * 792*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr) 793*7b5038d7SDag-Erling Smørgrav { 794*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL)); 795*7b5038d7SDag-Erling Smørgrav } 796*7b5038d7SDag-Erling Smørgrav 797*7b5038d7SDag-Erling Smørgrav void 798*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time( 799*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree, 800*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 801*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr, 802*7b5038d7SDag-Erling Smørgrav time_t check_time) 803*7b5038d7SDag-Erling Smørgrav { 804*7b5038d7SDag-Erling Smørgrav size_t i, j; 805*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset); 806*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree; 807*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr; 808*7b5038d7SDag-Erling Smørgrav uint16_t cur_keytag; 809*7b5038d7SDag-Erling Smørgrav ldns_rr_list *tmp_rrset = NULL; 810*7b5038d7SDag-Erling Smørgrav ldns_status cur_status; 811*7b5038d7SDag-Erling Smørgrav 812*7b5038d7SDag-Erling Smørgrav cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr)); 813*7b5038d7SDag-Erling Smørgrav 814*7b5038d7SDag-Erling Smørgrav for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) { 815*7b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j); 816*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) { 817*7b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) { 818*7b5038d7SDag-Erling Smørgrav 819*7b5038d7SDag-Erling Smørgrav /* TODO: check wildcard nsec too */ 820*7b5038d7SDag-Erling Smørgrav if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) { 821*7b5038d7SDag-Erling Smørgrav tmp_rrset = cur_rrset; 822*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) 823*7b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC || 824*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) 825*7b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3) { 826*7b5038d7SDag-Erling Smørgrav /* might contain different names! 827*7b5038d7SDag-Erling Smørgrav sort and split */ 828*7b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(cur_rrset); 829*7b5038d7SDag-Erling Smørgrav if (tmp_rrset && tmp_rrset != cur_rrset) { 830*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp_rrset); 831*7b5038d7SDag-Erling Smørgrav tmp_rrset = NULL; 832*7b5038d7SDag-Erling Smørgrav } 833*7b5038d7SDag-Erling Smørgrav tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset); 834*7b5038d7SDag-Erling Smørgrav 835*7b5038d7SDag-Erling Smørgrav /* with nsecs, this might be the wrong one */ 836*7b5038d7SDag-Erling Smørgrav while (tmp_rrset && 837*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr_count(cur_rrset) > 0 && 838*7b5038d7SDag-Erling Smørgrav ldns_dname_compare( 839*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr( 840*7b5038d7SDag-Erling Smørgrav tmp_rrset, 0)), 841*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_sig_rr)) != 0) { 842*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp_rrset); 843*7b5038d7SDag-Erling Smørgrav tmp_rrset = 844*7b5038d7SDag-Erling Smørgrav ldns_rr_list_pop_rrset(cur_rrset); 845*7b5038d7SDag-Erling Smørgrav } 846*7b5038d7SDag-Erling Smørgrav } 847*7b5038d7SDag-Erling Smørgrav cur_status = ldns_verify_rrsig_time( 848*7b5038d7SDag-Erling Smørgrav tmp_rrset, 849*7b5038d7SDag-Erling Smørgrav cur_sig_rr, 850*7b5038d7SDag-Erling Smørgrav cur_parent_rr, 851*7b5038d7SDag-Erling Smørgrav check_time); 852*7b5038d7SDag-Erling Smørgrav /* avoid dupes */ 853*7b5038d7SDag-Erling Smørgrav for (i = 0; i < new_tree->parent_count; i++) { 854*7b5038d7SDag-Erling Smørgrav if (cur_parent_rr == new_tree->parents[i]->rr) { 855*7b5038d7SDag-Erling Smørgrav goto done; 856*7b5038d7SDag-Erling Smørgrav } 857*7b5038d7SDag-Erling Smørgrav } 858*7b5038d7SDag-Erling Smørgrav 859*7b5038d7SDag-Erling Smørgrav cur_parent_tree = 860*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time( 861*7b5038d7SDag-Erling Smørgrav data_chain->parent, 862*7b5038d7SDag-Erling Smørgrav cur_parent_rr, 863*7b5038d7SDag-Erling Smørgrav check_time); 864*7b5038d7SDag-Erling Smørgrav (void)ldns_dnssec_trust_tree_add_parent(new_tree, 865*7b5038d7SDag-Erling Smørgrav cur_parent_tree, 866*7b5038d7SDag-Erling Smørgrav cur_sig_rr, 867*7b5038d7SDag-Erling Smørgrav cur_status); 868*7b5038d7SDag-Erling Smørgrav } 869*7b5038d7SDag-Erling Smørgrav } 870*7b5038d7SDag-Erling Smørgrav } 871*7b5038d7SDag-Erling Smørgrav } 872*7b5038d7SDag-Erling Smørgrav done: 873*7b5038d7SDag-Erling Smørgrav if (tmp_rrset && tmp_rrset != cur_rrset) { 874*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp_rrset); 875*7b5038d7SDag-Erling Smørgrav } 876*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(cur_rrset); 877*7b5038d7SDag-Erling Smørgrav } 878*7b5038d7SDag-Erling Smørgrav 879*7b5038d7SDag-Erling Smørgrav void 880*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree, 881*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 882*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr) 883*7b5038d7SDag-Erling Smørgrav { 884*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time( 885*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_sig_rr, ldns_time(NULL)); 886*7b5038d7SDag-Erling Smørgrav } 887*7b5038d7SDag-Erling Smørgrav 888*7b5038d7SDag-Erling Smørgrav void 889*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time( 890*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree, 891*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 892*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr, 893*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr, 894*7b5038d7SDag-Erling Smørgrav time_t check_time) 895*7b5038d7SDag-Erling Smørgrav { 896*7b5038d7SDag-Erling Smørgrav size_t j; 897*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = data_chain->rrset; 898*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree; 899*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr; 900*7b5038d7SDag-Erling Smørgrav uint16_t cur_keytag; 901*7b5038d7SDag-Erling Smørgrav ldns_status cur_status; 902*7b5038d7SDag-Erling Smørgrav 903*7b5038d7SDag-Erling Smørgrav cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr)); 904*7b5038d7SDag-Erling Smørgrav 905*7b5038d7SDag-Erling Smørgrav for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) { 906*7b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(cur_rrset, j); 907*7b5038d7SDag-Erling Smørgrav if (cur_parent_rr != cur_rr && 908*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) { 909*7b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(cur_parent_rr) == cur_keytag 910*7b5038d7SDag-Erling Smørgrav ) { 911*7b5038d7SDag-Erling Smørgrav cur_parent_tree = ldns_dnssec_trust_tree_new(); 912*7b5038d7SDag-Erling Smørgrav cur_parent_tree->rr = cur_parent_rr; 913*7b5038d7SDag-Erling Smørgrav cur_parent_tree->rrset = cur_rrset; 914*7b5038d7SDag-Erling Smørgrav cur_status = ldns_verify_rrsig_time( 915*7b5038d7SDag-Erling Smørgrav cur_rrset, cur_sig_rr, 916*7b5038d7SDag-Erling Smørgrav cur_parent_rr, check_time); 917*7b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_trust_tree_add_parent(new_tree, 918*7b5038d7SDag-Erling Smørgrav cur_parent_tree, cur_sig_rr, cur_status); 919*7b5038d7SDag-Erling Smørgrav } 920*7b5038d7SDag-Erling Smørgrav } 921*7b5038d7SDag-Erling Smørgrav } 922*7b5038d7SDag-Erling Smørgrav } 923*7b5038d7SDag-Erling Smørgrav 924*7b5038d7SDag-Erling Smørgrav void 925*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree, 926*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 927*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr, 928*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr) 929*7b5038d7SDag-Erling Smørgrav { 930*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time( 931*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL)); 932*7b5038d7SDag-Erling Smørgrav } 933*7b5038d7SDag-Erling Smørgrav 934*7b5038d7SDag-Erling Smørgrav void 935*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time( 936*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree, 937*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 938*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr, 939*7b5038d7SDag-Erling Smørgrav time_t check_time) 940*7b5038d7SDag-Erling Smørgrav { 941*7b5038d7SDag-Erling Smørgrav size_t j, h; 942*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = data_chain->rrset; 943*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree; 944*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr; 945*7b5038d7SDag-Erling Smørgrav 946*7b5038d7SDag-Erling Smørgrav /* try the parent to see whether there are DSs there */ 947*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY && 948*7b5038d7SDag-Erling Smørgrav data_chain->parent && 949*7b5038d7SDag-Erling Smørgrav data_chain->parent->rrset 950*7b5038d7SDag-Erling Smørgrav ) { 951*7b5038d7SDag-Erling Smørgrav for (j = 0; 952*7b5038d7SDag-Erling Smørgrav j < ldns_rr_list_rr_count(data_chain->parent->rrset); 953*7b5038d7SDag-Erling Smørgrav j++) { 954*7b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j); 955*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) { 956*7b5038d7SDag-Erling Smørgrav for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) { 957*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, h); 958*7b5038d7SDag-Erling Smørgrav if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) { 959*7b5038d7SDag-Erling Smørgrav cur_parent_tree = 960*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time( 961*7b5038d7SDag-Erling Smørgrav data_chain->parent, 962*7b5038d7SDag-Erling Smørgrav cur_parent_rr, 963*7b5038d7SDag-Erling Smørgrav check_time); 964*7b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_trust_tree_add_parent( 965*7b5038d7SDag-Erling Smørgrav new_tree, 966*7b5038d7SDag-Erling Smørgrav cur_parent_tree, 967*7b5038d7SDag-Erling Smørgrav NULL, 968*7b5038d7SDag-Erling Smørgrav LDNS_STATUS_OK); 969*7b5038d7SDag-Erling Smørgrav } else { 970*7b5038d7SDag-Erling Smørgrav /*ldns_rr_print(stdout, cur_parent_rr);*/ 971*7b5038d7SDag-Erling Smørgrav } 972*7b5038d7SDag-Erling Smørgrav } 973*7b5038d7SDag-Erling Smørgrav } 974*7b5038d7SDag-Erling Smørgrav } 975*7b5038d7SDag-Erling Smørgrav } 976*7b5038d7SDag-Erling Smørgrav } 977*7b5038d7SDag-Erling Smørgrav 978*7b5038d7SDag-Erling Smørgrav void 979*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree, 980*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 981*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr) 982*7b5038d7SDag-Erling Smørgrav { 983*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time( 984*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_rr, ldns_time(NULL)); 985*7b5038d7SDag-Erling Smørgrav } 986*7b5038d7SDag-Erling Smørgrav 987*7b5038d7SDag-Erling Smørgrav void 988*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time( 989*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree, 990*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain, 991*7b5038d7SDag-Erling Smørgrav time_t check_time) 992*7b5038d7SDag-Erling Smørgrav { 993*7b5038d7SDag-Erling Smørgrav size_t i; 994*7b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset; 995*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr; 996*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree; 997*7b5038d7SDag-Erling Smørgrav ldns_status result; 998*7b5038d7SDag-Erling Smørgrav 999*7b5038d7SDag-Erling Smørgrav if (data_chain->parent && data_chain->parent->rrset) { 1000*7b5038d7SDag-Erling Smørgrav cur_rrset = data_chain->parent->rrset; 1001*7b5038d7SDag-Erling Smørgrav /* nsec? */ 1002*7b5038d7SDag-Erling Smørgrav if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) { 1003*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) == 1004*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3) { 1005*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_verify_denial_nsec3( 1006*7b5038d7SDag-Erling Smørgrav new_tree->rr, 1007*7b5038d7SDag-Erling Smørgrav cur_rrset, 1008*7b5038d7SDag-Erling Smørgrav data_chain->parent->signatures, 1009*7b5038d7SDag-Erling Smørgrav data_chain->packet_rcode, 1010*7b5038d7SDag-Erling Smørgrav data_chain->packet_qtype, 1011*7b5038d7SDag-Erling Smørgrav data_chain->packet_nodata); 1012*7b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) == 1013*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC) { 1014*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_verify_denial( 1015*7b5038d7SDag-Erling Smørgrav new_tree->rr, 1016*7b5038d7SDag-Erling Smørgrav cur_rrset, 1017*7b5038d7SDag-Erling Smørgrav data_chain->parent->signatures); 1018*7b5038d7SDag-Erling Smørgrav } else { 1019*7b5038d7SDag-Erling Smørgrav /* unsigned zone, unsigned parent */ 1020*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1021*7b5038d7SDag-Erling Smørgrav } 1022*7b5038d7SDag-Erling Smørgrav } else { 1023*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1024*7b5038d7SDag-Erling Smørgrav } 1025*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) { 1026*7b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(cur_rrset, i); 1027*7b5038d7SDag-Erling Smørgrav cur_parent_tree = 1028*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time( 1029*7b5038d7SDag-Erling Smørgrav data_chain->parent, 1030*7b5038d7SDag-Erling Smørgrav cur_parent_rr, 1031*7b5038d7SDag-Erling Smørgrav check_time); 1032*7b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_trust_tree_add_parent(new_tree, 1033*7b5038d7SDag-Erling Smørgrav cur_parent_tree, NULL, result); 1034*7b5038d7SDag-Erling Smørgrav } 1035*7b5038d7SDag-Erling Smørgrav } 1036*7b5038d7SDag-Erling Smørgrav } 1037*7b5038d7SDag-Erling Smørgrav 1038*7b5038d7SDag-Erling Smørgrav void 1039*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree, 1040*7b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain) 1041*7b5038d7SDag-Erling Smørgrav { 1042*7b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time( 1043*7b5038d7SDag-Erling Smørgrav new_tree, data_chain, ldns_time(NULL)); 1044*7b5038d7SDag-Erling Smørgrav } 1045*7b5038d7SDag-Erling Smørgrav 1046*7b5038d7SDag-Erling Smørgrav /* 1047*7b5038d7SDag-Erling Smørgrav * returns OK if there is a path from tree to key with only OK 1048*7b5038d7SDag-Erling Smørgrav * the (first) error in between otherwise 1049*7b5038d7SDag-Erling Smørgrav * or NOT_FOUND if the key wasn't present at all 1050*7b5038d7SDag-Erling Smørgrav */ 1051*7b5038d7SDag-Erling Smørgrav ldns_status 1052*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree, 1053*7b5038d7SDag-Erling Smørgrav ldns_rr_list *trusted_keys) 1054*7b5038d7SDag-Erling Smørgrav { 1055*7b5038d7SDag-Erling Smørgrav size_t i; 1056*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY; 1057*7b5038d7SDag-Erling Smørgrav bool equal; 1058*7b5038d7SDag-Erling Smørgrav ldns_status parent_result; 1059*7b5038d7SDag-Erling Smørgrav 1060*7b5038d7SDag-Erling Smørgrav if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0) 1061*7b5038d7SDag-Erling Smørgrav { if (tree->rr) { 1062*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) { 1063*7b5038d7SDag-Erling Smørgrav equal = ldns_rr_compare_ds( 1064*7b5038d7SDag-Erling Smørgrav tree->rr, 1065*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(trusted_keys, i)); 1066*7b5038d7SDag-Erling Smørgrav if (equal) { 1067*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1068*7b5038d7SDag-Erling Smørgrav return result; 1069*7b5038d7SDag-Erling Smørgrav } 1070*7b5038d7SDag-Erling Smørgrav } 1071*7b5038d7SDag-Erling Smørgrav } 1072*7b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) { 1073*7b5038d7SDag-Erling Smørgrav parent_result = 1074*7b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_contains_keys(tree->parents[i], 1075*7b5038d7SDag-Erling Smørgrav trusted_keys); 1076*7b5038d7SDag-Erling Smørgrav if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) { 1077*7b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] != LDNS_STATUS_OK) { 1078*7b5038d7SDag-Erling Smørgrav result = tree->parent_status[i]; 1079*7b5038d7SDag-Erling Smørgrav } else { 1080*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) 1081*7b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC && 1082*7b5038d7SDag-Erling Smørgrav parent_result == LDNS_STATUS_OK 1083*7b5038d7SDag-Erling Smørgrav ) { 1084*7b5038d7SDag-Erling Smørgrav result = 1085*7b5038d7SDag-Erling Smørgrav LDNS_STATUS_DNSSEC_EXISTENCE_DENIED; 1086*7b5038d7SDag-Erling Smørgrav } else { 1087*7b5038d7SDag-Erling Smørgrav result = parent_result; 1088*7b5038d7SDag-Erling Smørgrav } 1089*7b5038d7SDag-Erling Smørgrav } 1090*7b5038d7SDag-Erling Smørgrav } 1091*7b5038d7SDag-Erling Smørgrav } 1092*7b5038d7SDag-Erling Smørgrav } else { 1093*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_ERR; 1094*7b5038d7SDag-Erling Smørgrav } 1095*7b5038d7SDag-Erling Smørgrav 1096*7b5038d7SDag-Erling Smørgrav return result; 1097*7b5038d7SDag-Erling Smørgrav } 1098*7b5038d7SDag-Erling Smørgrav 1099*7b5038d7SDag-Erling Smørgrav ldns_status 1100*7b5038d7SDag-Erling Smørgrav ldns_verify_time( 1101*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset, 1102*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrsig, 1103*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 1104*7b5038d7SDag-Erling Smørgrav time_t check_time, 1105*7b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys 1106*7b5038d7SDag-Erling Smørgrav ) 1107*7b5038d7SDag-Erling Smørgrav { 1108*7b5038d7SDag-Erling Smørgrav uint16_t i; 1109*7b5038d7SDag-Erling Smørgrav ldns_status verify_result = LDNS_STATUS_ERR; 1110*7b5038d7SDag-Erling Smørgrav 1111*7b5038d7SDag-Erling Smørgrav if (!rrset || !rrsig || !keys) { 1112*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1113*7b5038d7SDag-Erling Smørgrav } 1114*7b5038d7SDag-Erling Smørgrav 1115*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) { 1116*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1117*7b5038d7SDag-Erling Smørgrav } 1118*7b5038d7SDag-Erling Smørgrav 1119*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsig) < 1) { 1120*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG; 1121*7b5038d7SDag-Erling Smørgrav } 1122*7b5038d7SDag-Erling Smørgrav 1123*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(keys) < 1) { 1124*7b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY; 1125*7b5038d7SDag-Erling Smørgrav } else { 1126*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) { 1127*7b5038d7SDag-Erling Smørgrav ldns_status s = ldns_verify_rrsig_keylist_time( 1128*7b5038d7SDag-Erling Smørgrav rrset, ldns_rr_list_rr(rrsig, i), 1129*7b5038d7SDag-Erling Smørgrav keys, check_time, good_keys); 1130*7b5038d7SDag-Erling Smørgrav /* try a little to get more descriptive error */ 1131*7b5038d7SDag-Erling Smørgrav if(s == LDNS_STATUS_OK) { 1132*7b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_OK; 1133*7b5038d7SDag-Erling Smørgrav } else if(verify_result == LDNS_STATUS_ERR) 1134*7b5038d7SDag-Erling Smørgrav verify_result = s; 1135*7b5038d7SDag-Erling Smørgrav else if(s != LDNS_STATUS_ERR && verify_result == 1136*7b5038d7SDag-Erling Smørgrav LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) 1137*7b5038d7SDag-Erling Smørgrav verify_result = s; 1138*7b5038d7SDag-Erling Smørgrav } 1139*7b5038d7SDag-Erling Smørgrav } 1140*7b5038d7SDag-Erling Smørgrav return verify_result; 1141*7b5038d7SDag-Erling Smørgrav } 1142*7b5038d7SDag-Erling Smørgrav 1143*7b5038d7SDag-Erling Smørgrav ldns_status 1144*7b5038d7SDag-Erling Smørgrav ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, 1145*7b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys) 1146*7b5038d7SDag-Erling Smørgrav { 1147*7b5038d7SDag-Erling Smørgrav return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys); 1148*7b5038d7SDag-Erling Smørgrav } 1149*7b5038d7SDag-Erling Smørgrav 1150*7b5038d7SDag-Erling Smørgrav ldns_status 1151*7b5038d7SDag-Erling Smørgrav ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig, 1152*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, ldns_rr_list *good_keys) 1153*7b5038d7SDag-Erling Smørgrav { 1154*7b5038d7SDag-Erling Smørgrav uint16_t i; 1155*7b5038d7SDag-Erling Smørgrav ldns_status verify_result = LDNS_STATUS_ERR; 1156*7b5038d7SDag-Erling Smørgrav 1157*7b5038d7SDag-Erling Smørgrav if (!rrset || !rrsig || !keys) { 1158*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1159*7b5038d7SDag-Erling Smørgrav } 1160*7b5038d7SDag-Erling Smørgrav 1161*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) { 1162*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1163*7b5038d7SDag-Erling Smørgrav } 1164*7b5038d7SDag-Erling Smørgrav 1165*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsig) < 1) { 1166*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG; 1167*7b5038d7SDag-Erling Smørgrav } 1168*7b5038d7SDag-Erling Smørgrav 1169*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(keys) < 1) { 1170*7b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY; 1171*7b5038d7SDag-Erling Smørgrav } else { 1172*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) { 1173*7b5038d7SDag-Erling Smørgrav ldns_status s = ldns_verify_rrsig_keylist_notime(rrset, 1174*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrsig, i), keys, good_keys); 1175*7b5038d7SDag-Erling Smørgrav 1176*7b5038d7SDag-Erling Smørgrav /* try a little to get more descriptive error */ 1177*7b5038d7SDag-Erling Smørgrav if (s == LDNS_STATUS_OK) { 1178*7b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_OK; 1179*7b5038d7SDag-Erling Smørgrav } else if (verify_result == LDNS_STATUS_ERR) { 1180*7b5038d7SDag-Erling Smørgrav verify_result = s; 1181*7b5038d7SDag-Erling Smørgrav } else if (s != LDNS_STATUS_ERR && verify_result == 1182*7b5038d7SDag-Erling Smørgrav LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) { 1183*7b5038d7SDag-Erling Smørgrav verify_result = s; 1184*7b5038d7SDag-Erling Smørgrav } 1185*7b5038d7SDag-Erling Smørgrav } 1186*7b5038d7SDag-Erling Smørgrav } 1187*7b5038d7SDag-Erling Smørgrav return verify_result; 1188*7b5038d7SDag-Erling Smørgrav } 1189*7b5038d7SDag-Erling Smørgrav 1190*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1191*7b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time(const ldns_resolver *res, 1192*7b5038d7SDag-Erling Smørgrav const ldns_rdf *domain, 1193*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 1194*7b5038d7SDag-Erling Smørgrav time_t check_time, 1195*7b5038d7SDag-Erling Smørgrav ldns_status *status) 1196*7b5038d7SDag-Erling Smørgrav { 1197*7b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL; 1198*7b5038d7SDag-Erling Smørgrav ldns_rr_list * ds_keys = NULL; 1199*7b5038d7SDag-Erling Smørgrav ldns_rdf * prev_parent_domain; 1200*7b5038d7SDag-Erling Smørgrav ldns_rdf * parent_domain; 1201*7b5038d7SDag-Erling Smørgrav ldns_rr_list * parent_keys = NULL; 1202*7b5038d7SDag-Erling Smørgrav 1203*7b5038d7SDag-Erling Smørgrav if (res && domain && keys) { 1204*7b5038d7SDag-Erling Smørgrav 1205*7b5038d7SDag-Erling Smørgrav if ((trusted_keys = ldns_validate_domain_dnskey_time(res, 1206*7b5038d7SDag-Erling Smørgrav domain, keys, check_time))) { 1207*7b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_OK; 1208*7b5038d7SDag-Erling Smørgrav } else { 1209*7b5038d7SDag-Erling Smørgrav /* No trusted keys in this domain, we'll have to find some in the parent domain */ 1210*7b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY; 1211*7b5038d7SDag-Erling Smørgrav 1212*7b5038d7SDag-Erling Smørgrav parent_domain = ldns_dname_left_chop(domain); 1213*7b5038d7SDag-Erling Smørgrav while (ldns_rdf_size(parent_domain) > 0) { 1214*7b5038d7SDag-Erling Smørgrav /* Fail if we are at the root */ 1215*7b5038d7SDag-Erling Smørgrav 1216*7b5038d7SDag-Erling Smørgrav if ((parent_keys = 1217*7b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time(res, 1218*7b5038d7SDag-Erling Smørgrav parent_domain, 1219*7b5038d7SDag-Erling Smørgrav keys, 1220*7b5038d7SDag-Erling Smørgrav check_time, 1221*7b5038d7SDag-Erling Smørgrav status))) { 1222*7b5038d7SDag-Erling Smørgrav /* Check DS records */ 1223*7b5038d7SDag-Erling Smørgrav if ((ds_keys = 1224*7b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds_time(res, 1225*7b5038d7SDag-Erling Smørgrav domain, 1226*7b5038d7SDag-Erling Smørgrav parent_keys, 1227*7b5038d7SDag-Erling Smørgrav check_time))) { 1228*7b5038d7SDag-Erling Smørgrav trusted_keys = 1229*7b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time( 1230*7b5038d7SDag-Erling Smørgrav res, 1231*7b5038d7SDag-Erling Smørgrav domain, 1232*7b5038d7SDag-Erling Smørgrav ds_keys, 1233*7b5038d7SDag-Erling Smørgrav check_time, 1234*7b5038d7SDag-Erling Smørgrav status); 1235*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(ds_keys); 1236*7b5038d7SDag-Erling Smørgrav } else { 1237*7b5038d7SDag-Erling Smørgrav /* No valid DS at the parent -- fail */ 1238*7b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ; 1239*7b5038d7SDag-Erling Smørgrav } 1240*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(parent_keys); 1241*7b5038d7SDag-Erling Smørgrav break; 1242*7b5038d7SDag-Erling Smørgrav } else { 1243*7b5038d7SDag-Erling Smørgrav parent_domain = ldns_dname_left_chop(( 1244*7b5038d7SDag-Erling Smørgrav prev_parent_domain 1245*7b5038d7SDag-Erling Smørgrav = parent_domain 1246*7b5038d7SDag-Erling Smørgrav )); 1247*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(prev_parent_domain); 1248*7b5038d7SDag-Erling Smørgrav } 1249*7b5038d7SDag-Erling Smørgrav } 1250*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(parent_domain); 1251*7b5038d7SDag-Erling Smørgrav } 1252*7b5038d7SDag-Erling Smørgrav } 1253*7b5038d7SDag-Erling Smørgrav return trusted_keys; 1254*7b5038d7SDag-Erling Smørgrav } 1255*7b5038d7SDag-Erling Smørgrav 1256*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1257*7b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys(const ldns_resolver *res, 1258*7b5038d7SDag-Erling Smørgrav const ldns_rdf *domain, 1259*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 1260*7b5038d7SDag-Erling Smørgrav ldns_status *status) 1261*7b5038d7SDag-Erling Smørgrav { 1262*7b5038d7SDag-Erling Smørgrav return ldns_fetch_valid_domain_keys_time( 1263*7b5038d7SDag-Erling Smørgrav res, domain, keys, ldns_time(NULL), status); 1264*7b5038d7SDag-Erling Smørgrav } 1265*7b5038d7SDag-Erling Smørgrav 1266*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1267*7b5038d7SDag-Erling Smørgrav ldns_validate_domain_dnskey_time( 1268*7b5038d7SDag-Erling Smørgrav const ldns_resolver * res, 1269*7b5038d7SDag-Erling Smørgrav const ldns_rdf * domain, 1270*7b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys, 1271*7b5038d7SDag-Erling Smørgrav time_t check_time 1272*7b5038d7SDag-Erling Smørgrav ) 1273*7b5038d7SDag-Erling Smørgrav { 1274*7b5038d7SDag-Erling Smørgrav ldns_pkt * keypkt; 1275*7b5038d7SDag-Erling Smørgrav ldns_rr * cur_key; 1276*7b5038d7SDag-Erling Smørgrav uint16_t key_i; uint16_t key_j; uint16_t key_k; 1277*7b5038d7SDag-Erling Smørgrav uint16_t sig_i; ldns_rr * cur_sig; 1278*7b5038d7SDag-Erling Smørgrav 1279*7b5038d7SDag-Erling Smørgrav ldns_rr_list * domain_keys = NULL; 1280*7b5038d7SDag-Erling Smørgrav ldns_rr_list * domain_sigs = NULL; 1281*7b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL; 1282*7b5038d7SDag-Erling Smørgrav 1283*7b5038d7SDag-Erling Smørgrav /* Fetch keys for the domain */ 1284*7b5038d7SDag-Erling Smørgrav keypkt = ldns_resolver_query(res, domain, 1285*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD); 1286*7b5038d7SDag-Erling Smørgrav if (keypkt) { 1287*7b5038d7SDag-Erling Smørgrav domain_keys = ldns_pkt_rr_list_by_type(keypkt, 1288*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, 1289*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER); 1290*7b5038d7SDag-Erling Smørgrav domain_sigs = ldns_pkt_rr_list_by_type(keypkt, 1291*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG, 1292*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER); 1293*7b5038d7SDag-Erling Smørgrav 1294*7b5038d7SDag-Erling Smørgrav /* Try to validate the record using our keys */ 1295*7b5038d7SDag-Erling Smørgrav for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) { 1296*7b5038d7SDag-Erling Smørgrav 1297*7b5038d7SDag-Erling Smørgrav cur_key = ldns_rr_list_rr(domain_keys, key_i); 1298*7b5038d7SDag-Erling Smørgrav for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) { 1299*7b5038d7SDag-Erling Smørgrav if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j), 1300*7b5038d7SDag-Erling Smørgrav cur_key)) { 1301*7b5038d7SDag-Erling Smørgrav 1302*7b5038d7SDag-Erling Smørgrav /* Current key is trusted -- validate */ 1303*7b5038d7SDag-Erling Smørgrav trusted_keys = ldns_rr_list_new(); 1304*7b5038d7SDag-Erling Smørgrav 1305*7b5038d7SDag-Erling Smørgrav for (sig_i=0; 1306*7b5038d7SDag-Erling Smørgrav sig_i<ldns_rr_list_rr_count(domain_sigs); 1307*7b5038d7SDag-Erling Smørgrav sig_i++) { 1308*7b5038d7SDag-Erling Smørgrav cur_sig = ldns_rr_list_rr(domain_sigs, sig_i); 1309*7b5038d7SDag-Erling Smørgrav /* Avoid non-matching sigs */ 1310*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2native_int16( 1311*7b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_sig)) 1312*7b5038d7SDag-Erling Smørgrav == ldns_calc_keytag(cur_key)) { 1313*7b5038d7SDag-Erling Smørgrav if (ldns_verify_rrsig_time( 1314*7b5038d7SDag-Erling Smørgrav domain_keys, 1315*7b5038d7SDag-Erling Smørgrav cur_sig, 1316*7b5038d7SDag-Erling Smørgrav cur_key, 1317*7b5038d7SDag-Erling Smørgrav check_time) 1318*7b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) { 1319*7b5038d7SDag-Erling Smørgrav 1320*7b5038d7SDag-Erling Smørgrav /* Push the whole rrset 1321*7b5038d7SDag-Erling Smørgrav -- we can't do much more */ 1322*7b5038d7SDag-Erling Smørgrav for (key_k=0; 1323*7b5038d7SDag-Erling Smørgrav key_k<ldns_rr_list_rr_count( 1324*7b5038d7SDag-Erling Smørgrav domain_keys); 1325*7b5038d7SDag-Erling Smørgrav key_k++) { 1326*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr( 1327*7b5038d7SDag-Erling Smørgrav trusted_keys, 1328*7b5038d7SDag-Erling Smørgrav ldns_rr_clone( 1329*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr( 1330*7b5038d7SDag-Erling Smørgrav domain_keys, 1331*7b5038d7SDag-Erling Smørgrav key_k))); 1332*7b5038d7SDag-Erling Smørgrav } 1333*7b5038d7SDag-Erling Smørgrav 1334*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_keys); 1335*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_sigs); 1336*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(keypkt); 1337*7b5038d7SDag-Erling Smørgrav return trusted_keys; 1338*7b5038d7SDag-Erling Smørgrav } 1339*7b5038d7SDag-Erling Smørgrav } 1340*7b5038d7SDag-Erling Smørgrav } 1341*7b5038d7SDag-Erling Smørgrav 1342*7b5038d7SDag-Erling Smørgrav /* Only push our trusted key */ 1343*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(trusted_keys, 1344*7b5038d7SDag-Erling Smørgrav ldns_rr_clone(cur_key)); 1345*7b5038d7SDag-Erling Smørgrav } 1346*7b5038d7SDag-Erling Smørgrav } 1347*7b5038d7SDag-Erling Smørgrav } 1348*7b5038d7SDag-Erling Smørgrav 1349*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_keys); 1350*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_sigs); 1351*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(keypkt); 1352*7b5038d7SDag-Erling Smørgrav 1353*7b5038d7SDag-Erling Smørgrav } else { 1354*7b5038d7SDag-Erling Smørgrav /* LDNS_STATUS_CRYPTO_NO_DNSKEY */ 1355*7b5038d7SDag-Erling Smørgrav } 1356*7b5038d7SDag-Erling Smørgrav 1357*7b5038d7SDag-Erling Smørgrav return trusted_keys; 1358*7b5038d7SDag-Erling Smørgrav } 1359*7b5038d7SDag-Erling Smørgrav 1360*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1361*7b5038d7SDag-Erling Smørgrav ldns_validate_domain_dnskey(const ldns_resolver * res, 1362*7b5038d7SDag-Erling Smørgrav const ldns_rdf * domain, 1363*7b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys) 1364*7b5038d7SDag-Erling Smørgrav { 1365*7b5038d7SDag-Erling Smørgrav return ldns_validate_domain_dnskey_time( 1366*7b5038d7SDag-Erling Smørgrav res, domain, keys, ldns_time(NULL)); 1367*7b5038d7SDag-Erling Smørgrav } 1368*7b5038d7SDag-Erling Smørgrav 1369*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1370*7b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds_time( 1371*7b5038d7SDag-Erling Smørgrav const ldns_resolver *res, 1372*7b5038d7SDag-Erling Smørgrav const ldns_rdf * domain, 1373*7b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys, 1374*7b5038d7SDag-Erling Smørgrav time_t check_time) 1375*7b5038d7SDag-Erling Smørgrav { 1376*7b5038d7SDag-Erling Smørgrav ldns_pkt * dspkt; 1377*7b5038d7SDag-Erling Smørgrav uint16_t key_i; 1378*7b5038d7SDag-Erling Smørgrav ldns_rr_list * rrset = NULL; 1379*7b5038d7SDag-Erling Smørgrav ldns_rr_list * sigs = NULL; 1380*7b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL; 1381*7b5038d7SDag-Erling Smørgrav 1382*7b5038d7SDag-Erling Smørgrav /* Fetch DS for the domain */ 1383*7b5038d7SDag-Erling Smørgrav dspkt = ldns_resolver_query(res, domain, 1384*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD); 1385*7b5038d7SDag-Erling Smørgrav if (dspkt) { 1386*7b5038d7SDag-Erling Smørgrav rrset = ldns_pkt_rr_list_by_type(dspkt, 1387*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, 1388*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER); 1389*7b5038d7SDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_type(dspkt, 1390*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG, 1391*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER); 1392*7b5038d7SDag-Erling Smørgrav 1393*7b5038d7SDag-Erling Smørgrav /* Validate sigs */ 1394*7b5038d7SDag-Erling Smørgrav if (ldns_verify_time(rrset, sigs, keys, check_time, NULL) 1395*7b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) { 1396*7b5038d7SDag-Erling Smørgrav trusted_keys = ldns_rr_list_new(); 1397*7b5038d7SDag-Erling Smørgrav for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) { 1398*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(trusted_keys, 1399*7b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(rrset, 1400*7b5038d7SDag-Erling Smørgrav key_i) 1401*7b5038d7SDag-Erling Smørgrav ) 1402*7b5038d7SDag-Erling Smørgrav ); 1403*7b5038d7SDag-Erling Smørgrav } 1404*7b5038d7SDag-Erling Smørgrav } 1405*7b5038d7SDag-Erling Smørgrav 1406*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset); 1407*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs); 1408*7b5038d7SDag-Erling Smørgrav ldns_pkt_free(dspkt); 1409*7b5038d7SDag-Erling Smørgrav 1410*7b5038d7SDag-Erling Smørgrav } else { 1411*7b5038d7SDag-Erling Smørgrav /* LDNS_STATUS_CRYPTO_NO_DS */ 1412*7b5038d7SDag-Erling Smørgrav } 1413*7b5038d7SDag-Erling Smørgrav 1414*7b5038d7SDag-Erling Smørgrav return trusted_keys; 1415*7b5038d7SDag-Erling Smørgrav } 1416*7b5038d7SDag-Erling Smørgrav 1417*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 1418*7b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds(const ldns_resolver *res, 1419*7b5038d7SDag-Erling Smørgrav const ldns_rdf * domain, 1420*7b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys) 1421*7b5038d7SDag-Erling Smørgrav { 1422*7b5038d7SDag-Erling Smørgrav return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL)); 1423*7b5038d7SDag-Erling Smørgrav } 1424*7b5038d7SDag-Erling Smørgrav 1425*7b5038d7SDag-Erling Smørgrav ldns_status 1426*7b5038d7SDag-Erling Smørgrav ldns_verify_trusted_time( 1427*7b5038d7SDag-Erling Smørgrav ldns_resolver *res, 1428*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset, 1429*7b5038d7SDag-Erling Smørgrav ldns_rr_list * rrsigs, 1430*7b5038d7SDag-Erling Smørgrav time_t check_time, 1431*7b5038d7SDag-Erling Smørgrav ldns_rr_list * validating_keys 1432*7b5038d7SDag-Erling Smørgrav ) 1433*7b5038d7SDag-Erling Smørgrav { 1434*7b5038d7SDag-Erling Smørgrav uint16_t sig_i; uint16_t key_i; 1435*7b5038d7SDag-Erling Smørgrav ldns_rr * cur_sig; ldns_rr * cur_key; 1436*7b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL; 1437*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_ERR; 1438*7b5038d7SDag-Erling Smørgrav 1439*7b5038d7SDag-Erling Smørgrav if (!res || !rrset || !rrsigs) { 1440*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1441*7b5038d7SDag-Erling Smørgrav } 1442*7b5038d7SDag-Erling Smørgrav 1443*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) { 1444*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1445*7b5038d7SDag-Erling Smørgrav } 1446*7b5038d7SDag-Erling Smørgrav 1447*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsigs) < 1) { 1448*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG; 1449*7b5038d7SDag-Erling Smørgrav } 1450*7b5038d7SDag-Erling Smørgrav 1451*7b5038d7SDag-Erling Smørgrav /* Look at each sig */ 1452*7b5038d7SDag-Erling Smørgrav for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) { 1453*7b5038d7SDag-Erling Smørgrav 1454*7b5038d7SDag-Erling Smørgrav cur_sig = ldns_rr_list_rr(rrsigs, sig_i); 1455*7b5038d7SDag-Erling Smørgrav /* Get a valid signer key and validate the sig */ 1456*7b5038d7SDag-Erling Smørgrav if ((trusted_keys = ldns_fetch_valid_domain_keys_time( 1457*7b5038d7SDag-Erling Smørgrav res, 1458*7b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_signame(cur_sig), 1459*7b5038d7SDag-Erling Smørgrav ldns_resolver_dnssec_anchors(res), 1460*7b5038d7SDag-Erling Smørgrav check_time, 1461*7b5038d7SDag-Erling Smørgrav &result))) { 1462*7b5038d7SDag-Erling Smørgrav 1463*7b5038d7SDag-Erling Smørgrav for (key_i = 0; 1464*7b5038d7SDag-Erling Smørgrav key_i < ldns_rr_list_rr_count(trusted_keys); 1465*7b5038d7SDag-Erling Smørgrav key_i++) { 1466*7b5038d7SDag-Erling Smørgrav cur_key = ldns_rr_list_rr(trusted_keys, key_i); 1467*7b5038d7SDag-Erling Smørgrav 1468*7b5038d7SDag-Erling Smørgrav if ((result = ldns_verify_rrsig_time(rrset, 1469*7b5038d7SDag-Erling Smørgrav cur_sig, 1470*7b5038d7SDag-Erling Smørgrav cur_key, 1471*7b5038d7SDag-Erling Smørgrav check_time)) 1472*7b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) { 1473*7b5038d7SDag-Erling Smørgrav if (validating_keys) { 1474*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(validating_keys, 1475*7b5038d7SDag-Erling Smørgrav ldns_rr_clone(cur_key)); 1476*7b5038d7SDag-Erling Smørgrav } 1477*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(trusted_keys); 1478*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 1479*7b5038d7SDag-Erling Smørgrav } 1480*7b5038d7SDag-Erling Smørgrav } 1481*7b5038d7SDag-Erling Smørgrav } 1482*7b5038d7SDag-Erling Smørgrav } 1483*7b5038d7SDag-Erling Smørgrav 1484*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(trusted_keys); 1485*7b5038d7SDag-Erling Smørgrav return result; 1486*7b5038d7SDag-Erling Smørgrav } 1487*7b5038d7SDag-Erling Smørgrav 1488*7b5038d7SDag-Erling Smørgrav ldns_status 1489*7b5038d7SDag-Erling Smørgrav ldns_verify_trusted( 1490*7b5038d7SDag-Erling Smørgrav ldns_resolver *res, 1491*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset, 1492*7b5038d7SDag-Erling Smørgrav ldns_rr_list * rrsigs, 1493*7b5038d7SDag-Erling Smørgrav ldns_rr_list * validating_keys) 1494*7b5038d7SDag-Erling Smørgrav { 1495*7b5038d7SDag-Erling Smørgrav return ldns_verify_trusted_time( 1496*7b5038d7SDag-Erling Smørgrav res, rrset, rrsigs, ldns_time(NULL), validating_keys); 1497*7b5038d7SDag-Erling Smørgrav } 1498*7b5038d7SDag-Erling Smørgrav 1499*7b5038d7SDag-Erling Smørgrav 1500*7b5038d7SDag-Erling Smørgrav ldns_status 1501*7b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial(ldns_rr *rr, 1502*7b5038d7SDag-Erling Smørgrav ldns_rr_list *nsecs, 1503*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrsigs) 1504*7b5038d7SDag-Erling Smørgrav { 1505*7b5038d7SDag-Erling Smørgrav ldns_rdf *rr_name; 1506*7b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_name; 1507*7b5038d7SDag-Erling Smørgrav ldns_rdf *chopped_dname; 1508*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_nsec; 1509*7b5038d7SDag-Erling Smørgrav size_t i; 1510*7b5038d7SDag-Erling Smørgrav ldns_status result; 1511*7b5038d7SDag-Erling Smørgrav /* needed for wildcard check on exact match */ 1512*7b5038d7SDag-Erling Smørgrav ldns_rr *rrsig; 1513*7b5038d7SDag-Erling Smørgrav bool name_covered = false; 1514*7b5038d7SDag-Erling Smørgrav bool type_covered = false; 1515*7b5038d7SDag-Erling Smørgrav bool wildcard_covered = false; 1516*7b5038d7SDag-Erling Smørgrav bool wildcard_type_covered = false; 1517*7b5038d7SDag-Erling Smørgrav 1518*7b5038d7SDag-Erling Smørgrav wildcard_name = ldns_dname_new_frm_str("*"); 1519*7b5038d7SDag-Erling Smørgrav rr_name = ldns_rr_owner(rr); 1520*7b5038d7SDag-Erling Smørgrav chopped_dname = ldns_dname_left_chop(rr_name); 1521*7b5038d7SDag-Erling Smørgrav result = ldns_dname_cat(wildcard_name, chopped_dname); 1522*7b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 1523*7b5038d7SDag-Erling Smørgrav return result; 1524*7b5038d7SDag-Erling Smørgrav } 1525*7b5038d7SDag-Erling Smørgrav 1526*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(chopped_dname); 1527*7b5038d7SDag-Erling Smørgrav 1528*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1529*7b5038d7SDag-Erling Smørgrav cur_nsec = ldns_rr_list_rr(nsecs, i); 1530*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) { 1531*7b5038d7SDag-Erling Smørgrav /* see section 5.4 of RFC4035, if the label count of the NSEC's 1532*7b5038d7SDag-Erling Smørgrav RRSIG is equal, then it is proven that wildcard expansion 1533*7b5038d7SDag-Erling Smørgrav could not have been used to match the request */ 1534*7b5038d7SDag-Erling Smørgrav rrsig = ldns_dnssec_get_rrsig_for_name_and_type( 1535*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_nsec), 1536*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(cur_nsec), 1537*7b5038d7SDag-Erling Smørgrav rrsigs); 1538*7b5038d7SDag-Erling Smørgrav if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig)) 1539*7b5038d7SDag-Erling Smørgrav == ldns_dname_label_count(rr_name)) { 1540*7b5038d7SDag-Erling Smørgrav wildcard_covered = true; 1541*7b5038d7SDag-Erling Smørgrav } 1542*7b5038d7SDag-Erling Smørgrav 1543*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), 1544*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr))) { 1545*7b5038d7SDag-Erling Smørgrav type_covered = true; 1546*7b5038d7SDag-Erling Smørgrav } 1547*7b5038d7SDag-Erling Smørgrav } 1548*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(cur_nsec, rr_name)) { 1549*7b5038d7SDag-Erling Smørgrav name_covered = true; 1550*7b5038d7SDag-Erling Smørgrav } 1551*7b5038d7SDag-Erling Smørgrav 1552*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(wildcard_name, 1553*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_nsec)) == 0) { 1554*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), 1555*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr))) { 1556*7b5038d7SDag-Erling Smørgrav wildcard_type_covered = true; 1557*7b5038d7SDag-Erling Smørgrav } 1558*7b5038d7SDag-Erling Smørgrav } 1559*7b5038d7SDag-Erling Smørgrav 1560*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) { 1561*7b5038d7SDag-Erling Smørgrav wildcard_covered = true; 1562*7b5038d7SDag-Erling Smørgrav } 1563*7b5038d7SDag-Erling Smørgrav 1564*7b5038d7SDag-Erling Smørgrav } 1565*7b5038d7SDag-Erling Smørgrav 1566*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_name); 1567*7b5038d7SDag-Erling Smørgrav 1568*7b5038d7SDag-Erling Smørgrav if (type_covered || !name_covered) { 1569*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1570*7b5038d7SDag-Erling Smørgrav } 1571*7b5038d7SDag-Erling Smørgrav 1572*7b5038d7SDag-Erling Smørgrav if (wildcard_type_covered || !wildcard_covered) { 1573*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED; 1574*7b5038d7SDag-Erling Smørgrav } 1575*7b5038d7SDag-Erling Smørgrav 1576*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 1577*7b5038d7SDag-Erling Smørgrav } 1578*7b5038d7SDag-Erling Smørgrav 1579*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1580*7b5038d7SDag-Erling Smørgrav ldns_status 1581*7b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr 1582*7b5038d7SDag-Erling Smørgrav , ldns_rr_list *nsecs 1583*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(ldns_rr_list *rrsigs) 1584*7b5038d7SDag-Erling Smørgrav , ldns_pkt_rcode packet_rcode 1585*7b5038d7SDag-Erling Smørgrav , ldns_rr_type packet_qtype 1586*7b5038d7SDag-Erling Smørgrav , bool packet_nodata 1587*7b5038d7SDag-Erling Smørgrav , ldns_rr **match 1588*7b5038d7SDag-Erling Smørgrav ) 1589*7b5038d7SDag-Erling Smørgrav { 1590*7b5038d7SDag-Erling Smørgrav ldns_rdf *closest_encloser; 1591*7b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard; 1592*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_wildcard_name; 1593*7b5038d7SDag-Erling Smørgrav bool wildcard_covered = false; 1594*7b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name; 1595*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_name; 1596*7b5038d7SDag-Erling Smørgrav /* self assignment to suppress uninitialized warning */ 1597*7b5038d7SDag-Erling Smørgrav ldns_rdf *next_closer = next_closer; 1598*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_next_closer; 1599*7b5038d7SDag-Erling Smørgrav size_t i; 1600*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1601*7b5038d7SDag-Erling Smørgrav 1602*7b5038d7SDag-Erling Smørgrav if (match) { 1603*7b5038d7SDag-Erling Smørgrav *match = NULL; 1604*7b5038d7SDag-Erling Smørgrav } 1605*7b5038d7SDag-Erling Smørgrav 1606*7b5038d7SDag-Erling Smørgrav zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0))); 1607*7b5038d7SDag-Erling Smørgrav 1608*7b5038d7SDag-Erling Smørgrav /* section 8.4 */ 1609*7b5038d7SDag-Erling Smørgrav if (packet_rcode == LDNS_RCODE_NXDOMAIN) { 1610*7b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser( 1611*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr), 1612*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr), 1613*7b5038d7SDag-Erling Smørgrav nsecs); 1614*7b5038d7SDag-Erling Smørgrav if(!closest_encloser) { 1615*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_NSEC3_ERR; 1616*7b5038d7SDag-Erling Smørgrav goto done; 1617*7b5038d7SDag-Erling Smørgrav } 1618*7b5038d7SDag-Erling Smørgrav 1619*7b5038d7SDag-Erling Smørgrav wildcard = ldns_dname_new_frm_str("*"); 1620*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard, closest_encloser); 1621*7b5038d7SDag-Erling Smørgrav 1622*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1623*7b5038d7SDag-Erling Smørgrav hashed_wildcard_name = 1624*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0), 1625*7b5038d7SDag-Erling Smørgrav wildcard 1626*7b5038d7SDag-Erling Smørgrav ); 1627*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_wildcard_name, zone_name); 1628*7b5038d7SDag-Erling Smørgrav 1629*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i), 1630*7b5038d7SDag-Erling Smørgrav hashed_wildcard_name)) { 1631*7b5038d7SDag-Erling Smørgrav wildcard_covered = true; 1632*7b5038d7SDag-Erling Smørgrav if (match) { 1633*7b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i); 1634*7b5038d7SDag-Erling Smørgrav } 1635*7b5038d7SDag-Erling Smørgrav } 1636*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_wildcard_name); 1637*7b5038d7SDag-Erling Smørgrav } 1638*7b5038d7SDag-Erling Smørgrav 1639*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser); 1640*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard); 1641*7b5038d7SDag-Erling Smørgrav 1642*7b5038d7SDag-Erling Smørgrav if (!wildcard_covered) { 1643*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED; 1644*7b5038d7SDag-Erling Smørgrav } else if (closest_encloser && wildcard_covered) { 1645*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1646*7b5038d7SDag-Erling Smørgrav } else { 1647*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1648*7b5038d7SDag-Erling Smørgrav } 1649*7b5038d7SDag-Erling Smørgrav } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) { 1650*7b5038d7SDag-Erling Smørgrav /* section 8.5 */ 1651*7b5038d7SDag-Erling Smørgrav hashed_name = ldns_nsec3_hash_name_frm_nsec3( 1652*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(nsecs, 0), 1653*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr)); 1654*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_name, zone_name); 1655*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1656*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_name, 1657*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) 1658*7b5038d7SDag-Erling Smørgrav == 0) { 1659*7b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type( 1660*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1661*7b5038d7SDag-Erling Smørgrav packet_qtype) 1662*7b5038d7SDag-Erling Smørgrav && 1663*7b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type( 1664*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1665*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) { 1666*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1667*7b5038d7SDag-Erling Smørgrav if (match) { 1668*7b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i); 1669*7b5038d7SDag-Erling Smørgrav } 1670*7b5038d7SDag-Erling Smørgrav goto done; 1671*7b5038d7SDag-Erling Smørgrav } 1672*7b5038d7SDag-Erling Smørgrav } 1673*7b5038d7SDag-Erling Smørgrav } 1674*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1675*7b5038d7SDag-Erling Smørgrav /* wildcard no data? section 8.7 */ 1676*7b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser( 1677*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr), 1678*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr), 1679*7b5038d7SDag-Erling Smørgrav nsecs); 1680*7b5038d7SDag-Erling Smørgrav if(!closest_encloser) { 1681*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_NSEC3_ERR; 1682*7b5038d7SDag-Erling Smørgrav goto done; 1683*7b5038d7SDag-Erling Smørgrav } 1684*7b5038d7SDag-Erling Smørgrav wildcard = ldns_dname_new_frm_str("*"); 1685*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard, closest_encloser); 1686*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1687*7b5038d7SDag-Erling Smørgrav hashed_wildcard_name = 1688*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0), 1689*7b5038d7SDag-Erling Smørgrav wildcard); 1690*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_wildcard_name, zone_name); 1691*7b5038d7SDag-Erling Smørgrav 1692*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_wildcard_name, 1693*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) 1694*7b5038d7SDag-Erling Smørgrav == 0) { 1695*7b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type( 1696*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1697*7b5038d7SDag-Erling Smørgrav packet_qtype) 1698*7b5038d7SDag-Erling Smørgrav && 1699*7b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type( 1700*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1701*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) { 1702*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1703*7b5038d7SDag-Erling Smørgrav if (match) { 1704*7b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i); 1705*7b5038d7SDag-Erling Smørgrav } 1706*7b5038d7SDag-Erling Smørgrav } 1707*7b5038d7SDag-Erling Smørgrav } 1708*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_wildcard_name); 1709*7b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_OK) { 1710*7b5038d7SDag-Erling Smørgrav break; 1711*7b5038d7SDag-Erling Smørgrav } 1712*7b5038d7SDag-Erling Smørgrav } 1713*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser); 1714*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard); 1715*7b5038d7SDag-Erling Smørgrav } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) { 1716*7b5038d7SDag-Erling Smørgrav /* section 8.6 */ 1717*7b5038d7SDag-Erling Smørgrav /* note: up to XXX this is the same as for 8.5 */ 1718*7b5038d7SDag-Erling Smørgrav hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 1719*7b5038d7SDag-Erling Smørgrav 0), 1720*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr) 1721*7b5038d7SDag-Erling Smørgrav ); 1722*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_name, zone_name); 1723*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1724*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_name, 1725*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs, 1726*7b5038d7SDag-Erling Smørgrav i))) 1727*7b5038d7SDag-Erling Smørgrav == 0) { 1728*7b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type( 1729*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1730*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS) 1731*7b5038d7SDag-Erling Smørgrav && 1732*7b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type( 1733*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), 1734*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) { 1735*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1736*7b5038d7SDag-Erling Smørgrav if (match) { 1737*7b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i); 1738*7b5038d7SDag-Erling Smørgrav } 1739*7b5038d7SDag-Erling Smørgrav goto done; 1740*7b5038d7SDag-Erling Smørgrav } 1741*7b5038d7SDag-Erling Smørgrav } 1742*7b5038d7SDag-Erling Smørgrav } 1743*7b5038d7SDag-Erling Smørgrav 1744*7b5038d7SDag-Erling Smørgrav /* XXX see note above */ 1745*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED; 1746*7b5038d7SDag-Erling Smørgrav 1747*7b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser( 1748*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr), 1749*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr), 1750*7b5038d7SDag-Erling Smørgrav nsecs); 1751*7b5038d7SDag-Erling Smørgrav if(!closest_encloser) { 1752*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_NSEC3_ERR; 1753*7b5038d7SDag-Erling Smørgrav goto done; 1754*7b5038d7SDag-Erling Smørgrav } 1755*7b5038d7SDag-Erling Smørgrav /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/ 1756*7b5038d7SDag-Erling Smørgrav 1757*7b5038d7SDag-Erling Smørgrav if (ldns_dname_label_count(closest_encloser) + 1 1758*7b5038d7SDag-Erling Smørgrav >= ldns_dname_label_count(ldns_rr_owner(rr))) { 1759*7b5038d7SDag-Erling Smørgrav 1760*7b5038d7SDag-Erling Smørgrav /* Query name *is* the "next closer". */ 1761*7b5038d7SDag-Erling Smørgrav hashed_next_closer = hashed_name; 1762*7b5038d7SDag-Erling Smørgrav } else { 1763*7b5038d7SDag-Erling Smørgrav 1764*7b5038d7SDag-Erling Smørgrav /* "next closer" has less labels than the query name. 1765*7b5038d7SDag-Erling Smørgrav * Create the name and hash it. 1766*7b5038d7SDag-Erling Smørgrav */ 1767*7b5038d7SDag-Erling Smørgrav next_closer = ldns_dname_clone_from( 1768*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr), 1769*7b5038d7SDag-Erling Smørgrav ldns_dname_label_count(ldns_rr_owner(rr)) 1770*7b5038d7SDag-Erling Smørgrav - (ldns_dname_label_count(closest_encloser) + 1) 1771*7b5038d7SDag-Erling Smørgrav ); 1772*7b5038d7SDag-Erling Smørgrav hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3( 1773*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(nsecs, 0), 1774*7b5038d7SDag-Erling Smørgrav next_closer 1775*7b5038d7SDag-Erling Smørgrav ); 1776*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_next_closer, zone_name); 1777*7b5038d7SDag-Erling Smørgrav } 1778*7b5038d7SDag-Erling Smørgrav /* Find the NSEC3 that covers the "next closer" */ 1779*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) { 1780*7b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i), 1781*7b5038d7SDag-Erling Smørgrav hashed_next_closer) && 1782*7b5038d7SDag-Erling Smørgrav ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) { 1783*7b5038d7SDag-Erling Smørgrav 1784*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK; 1785*7b5038d7SDag-Erling Smørgrav if (match) { 1786*7b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i); 1787*7b5038d7SDag-Erling Smørgrav } 1788*7b5038d7SDag-Erling Smørgrav break; 1789*7b5038d7SDag-Erling Smørgrav } 1790*7b5038d7SDag-Erling Smørgrav } 1791*7b5038d7SDag-Erling Smørgrav if (ldns_dname_label_count(closest_encloser) + 1 1792*7b5038d7SDag-Erling Smørgrav < ldns_dname_label_count(ldns_rr_owner(rr))) { 1793*7b5038d7SDag-Erling Smørgrav 1794*7b5038d7SDag-Erling Smørgrav /* "next closer" has less labels than the query name. 1795*7b5038d7SDag-Erling Smørgrav * Dispose of the temporary variables that held that name. 1796*7b5038d7SDag-Erling Smørgrav */ 1797*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_next_closer); 1798*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(next_closer); 1799*7b5038d7SDag-Erling Smørgrav } 1800*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser); 1801*7b5038d7SDag-Erling Smørgrav } 1802*7b5038d7SDag-Erling Smørgrav 1803*7b5038d7SDag-Erling Smørgrav done: 1804*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name); 1805*7b5038d7SDag-Erling Smørgrav return result; 1806*7b5038d7SDag-Erling Smørgrav } 1807*7b5038d7SDag-Erling Smørgrav 1808*7b5038d7SDag-Erling Smørgrav ldns_status 1809*7b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial_nsec3(ldns_rr *rr, 1810*7b5038d7SDag-Erling Smørgrav ldns_rr_list *nsecs, 1811*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrsigs, 1812*7b5038d7SDag-Erling Smørgrav ldns_pkt_rcode packet_rcode, 1813*7b5038d7SDag-Erling Smørgrav ldns_rr_type packet_qtype, 1814*7b5038d7SDag-Erling Smørgrav bool packet_nodata) 1815*7b5038d7SDag-Erling Smørgrav { 1816*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_verify_denial_nsec3_match( 1817*7b5038d7SDag-Erling Smørgrav rr, nsecs, rrsigs, packet_rcode, 1818*7b5038d7SDag-Erling Smørgrav packet_qtype, packet_nodata, NULL 1819*7b5038d7SDag-Erling Smørgrav ); 1820*7b5038d7SDag-Erling Smørgrav } 1821*7b5038d7SDag-Erling Smørgrav 1822*7b5038d7SDag-Erling Smørgrav 1823*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1824*7b5038d7SDag-Erling Smørgrav 1825*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1826*7b5038d7SDag-Erling Smørgrav EVP_PKEY* 1827*7b5038d7SDag-Erling Smørgrav ldns_gost2pkey_raw(unsigned char* key, size_t keylen) 1828*7b5038d7SDag-Erling Smørgrav { 1829*7b5038d7SDag-Erling Smørgrav /* prefix header for X509 encoding */ 1830*7b5038d7SDag-Erling Smørgrav uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 1831*7b5038d7SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 1832*7b5038d7SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 1833*7b5038d7SDag-Erling Smørgrav 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40}; 1834*7b5038d7SDag-Erling Smørgrav unsigned char encoded[37+64]; 1835*7b5038d7SDag-Erling Smørgrav const unsigned char* pp; 1836*7b5038d7SDag-Erling Smørgrav if(keylen != 64) { 1837*7b5038d7SDag-Erling Smørgrav /* key wrong size */ 1838*7b5038d7SDag-Erling Smørgrav return NULL; 1839*7b5038d7SDag-Erling Smørgrav } 1840*7b5038d7SDag-Erling Smørgrav 1841*7b5038d7SDag-Erling Smørgrav /* create evp_key */ 1842*7b5038d7SDag-Erling Smørgrav memmove(encoded, asn, 37); 1843*7b5038d7SDag-Erling Smørgrav memmove(encoded+37, key, 64); 1844*7b5038d7SDag-Erling Smørgrav pp = (unsigned char*)&encoded[0]; 1845*7b5038d7SDag-Erling Smørgrav 1846*7b5038d7SDag-Erling Smørgrav return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded)); 1847*7b5038d7SDag-Erling Smørgrav } 1848*7b5038d7SDag-Erling Smørgrav 1849*7b5038d7SDag-Erling Smørgrav static ldns_status 1850*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 1851*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen) 1852*7b5038d7SDag-Erling Smørgrav { 1853*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 1854*7b5038d7SDag-Erling Smørgrav ldns_status result; 1855*7b5038d7SDag-Erling Smørgrav 1856*7b5038d7SDag-Erling Smørgrav (void) ldns_key_EVP_load_gost_id(); 1857*7b5038d7SDag-Erling Smørgrav evp_key = ldns_gost2pkey_raw(key, keylen); 1858*7b5038d7SDag-Erling Smørgrav if(!evp_key) { 1859*7b5038d7SDag-Erling Smørgrav /* could not convert key */ 1860*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS; 1861*7b5038d7SDag-Erling Smørgrav } 1862*7b5038d7SDag-Erling Smørgrav 1863*7b5038d7SDag-Erling Smørgrav /* verify signature */ 1864*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, 1865*7b5038d7SDag-Erling Smørgrav evp_key, EVP_get_digestbyname("md_gost94")); 1866*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 1867*7b5038d7SDag-Erling Smørgrav 1868*7b5038d7SDag-Erling Smørgrav return result; 1869*7b5038d7SDag-Erling Smørgrav } 1870*7b5038d7SDag-Erling Smørgrav #endif 1871*7b5038d7SDag-Erling Smørgrav 1872*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1873*7b5038d7SDag-Erling Smørgrav EVP_PKEY* 1874*7b5038d7SDag-Erling Smørgrav ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) 1875*7b5038d7SDag-Erling Smørgrav { 1876*7b5038d7SDag-Erling Smørgrav unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 1877*7b5038d7SDag-Erling Smørgrav const unsigned char* pp = buf; 1878*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 1879*7b5038d7SDag-Erling Smørgrav EC_KEY *ec; 1880*7b5038d7SDag-Erling Smørgrav /* check length, which uncompressed must be 2 bignums */ 1881*7b5038d7SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 1882*7b5038d7SDag-Erling Smørgrav if(keylen != 2*256/8) return NULL; 1883*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 1884*7b5038d7SDag-Erling Smørgrav } else if(algo == LDNS_ECDSAP384SHA384) { 1885*7b5038d7SDag-Erling Smørgrav if(keylen != 2*384/8) return NULL; 1886*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 1887*7b5038d7SDag-Erling Smørgrav } else ec = NULL; 1888*7b5038d7SDag-Erling Smørgrav if(!ec) return NULL; 1889*7b5038d7SDag-Erling Smørgrav if(keylen+1 > sizeof(buf)) 1890*7b5038d7SDag-Erling Smørgrav return NULL; /* sanity check */ 1891*7b5038d7SDag-Erling Smørgrav /* prepend the 0x02 (from docs) (or actually 0x04 from implementation 1892*7b5038d7SDag-Erling Smørgrav * of openssl) for uncompressed data */ 1893*7b5038d7SDag-Erling Smørgrav buf[0] = POINT_CONVERSION_UNCOMPRESSED; 1894*7b5038d7SDag-Erling Smørgrav memmove(buf+1, key, keylen); 1895*7b5038d7SDag-Erling Smørgrav if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) { 1896*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 1897*7b5038d7SDag-Erling Smørgrav return NULL; 1898*7b5038d7SDag-Erling Smørgrav } 1899*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 1900*7b5038d7SDag-Erling Smørgrav if(!evp_key) { 1901*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 1902*7b5038d7SDag-Erling Smørgrav return NULL; 1903*7b5038d7SDag-Erling Smørgrav } 1904*7b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { 1905*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 1906*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 1907*7b5038d7SDag-Erling Smørgrav return NULL; 1908*7b5038d7SDag-Erling Smørgrav } 1909*7b5038d7SDag-Erling Smørgrav return evp_key; 1910*7b5038d7SDag-Erling Smørgrav } 1911*7b5038d7SDag-Erling Smørgrav 1912*7b5038d7SDag-Erling Smørgrav static ldns_status 1913*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen, 1914*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo) 1915*7b5038d7SDag-Erling Smørgrav { 1916*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 1917*7b5038d7SDag-Erling Smørgrav ldns_status result; 1918*7b5038d7SDag-Erling Smørgrav const EVP_MD *d; 1919*7b5038d7SDag-Erling Smørgrav 1920*7b5038d7SDag-Erling Smørgrav evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo); 1921*7b5038d7SDag-Erling Smørgrav if(!evp_key) { 1922*7b5038d7SDag-Erling Smørgrav /* could not convert key */ 1923*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS; 1924*7b5038d7SDag-Erling Smørgrav } 1925*7b5038d7SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) 1926*7b5038d7SDag-Erling Smørgrav d = EVP_sha256(); 1927*7b5038d7SDag-Erling Smørgrav else d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */ 1928*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d); 1929*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 1930*7b5038d7SDag-Erling Smørgrav return result; 1931*7b5038d7SDag-Erling Smørgrav } 1932*7b5038d7SDag-Erling Smørgrav #endif 1933*7b5038d7SDag-Erling Smørgrav 1934*7b5038d7SDag-Erling Smørgrav ldns_status 1935*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 1936*7b5038d7SDag-Erling Smørgrav ldns_buffer *key_buf, uint8_t algo) 1937*7b5038d7SDag-Erling Smørgrav { 1938*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_buffers_raw( 1939*7b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(rawsig_buf), 1940*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(rawsig_buf), 1941*7b5038d7SDag-Erling Smørgrav verify_buf, 1942*7b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(key_buf), 1943*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key_buf), algo); 1944*7b5038d7SDag-Erling Smørgrav } 1945*7b5038d7SDag-Erling Smørgrav 1946*7b5038d7SDag-Erling Smørgrav ldns_status 1947*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen, 1948*7b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf, unsigned char* key, size_t keylen, 1949*7b5038d7SDag-Erling Smørgrav uint8_t algo) 1950*7b5038d7SDag-Erling Smørgrav { 1951*7b5038d7SDag-Erling Smørgrav /* check for right key */ 1952*7b5038d7SDag-Erling Smørgrav switch(algo) { 1953*7b5038d7SDag-Erling Smørgrav case LDNS_DSA: 1954*7b5038d7SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 1955*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_dsa_raw(sig, 1956*7b5038d7SDag-Erling Smørgrav siglen, 1957*7b5038d7SDag-Erling Smørgrav verify_buf, 1958*7b5038d7SDag-Erling Smørgrav key, 1959*7b5038d7SDag-Erling Smørgrav keylen); 1960*7b5038d7SDag-Erling Smørgrav break; 1961*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1: 1962*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 1963*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha1_raw(sig, 1964*7b5038d7SDag-Erling Smørgrav siglen, 1965*7b5038d7SDag-Erling Smørgrav verify_buf, 1966*7b5038d7SDag-Erling Smørgrav key, 1967*7b5038d7SDag-Erling Smørgrav keylen); 1968*7b5038d7SDag-Erling Smørgrav break; 1969*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 1970*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA256: 1971*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha256_raw(sig, 1972*7b5038d7SDag-Erling Smørgrav siglen, 1973*7b5038d7SDag-Erling Smørgrav verify_buf, 1974*7b5038d7SDag-Erling Smørgrav key, 1975*7b5038d7SDag-Erling Smørgrav keylen); 1976*7b5038d7SDag-Erling Smørgrav break; 1977*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA512: 1978*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha512_raw(sig, 1979*7b5038d7SDag-Erling Smørgrav siglen, 1980*7b5038d7SDag-Erling Smørgrav verify_buf, 1981*7b5038d7SDag-Erling Smørgrav key, 1982*7b5038d7SDag-Erling Smørgrav keylen); 1983*7b5038d7SDag-Erling Smørgrav break; 1984*7b5038d7SDag-Erling Smørgrav #endif 1985*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1986*7b5038d7SDag-Erling Smørgrav case LDNS_ECC_GOST: 1987*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf, 1988*7b5038d7SDag-Erling Smørgrav key, keylen); 1989*7b5038d7SDag-Erling Smørgrav break; 1990*7b5038d7SDag-Erling Smørgrav #endif 1991*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1992*7b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 1993*7b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 1994*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf, 1995*7b5038d7SDag-Erling Smørgrav key, keylen, algo); 1996*7b5038d7SDag-Erling Smørgrav break; 1997*7b5038d7SDag-Erling Smørgrav #endif 1998*7b5038d7SDag-Erling Smørgrav case LDNS_RSAMD5: 1999*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsamd5_raw(sig, 2000*7b5038d7SDag-Erling Smørgrav siglen, 2001*7b5038d7SDag-Erling Smørgrav verify_buf, 2002*7b5038d7SDag-Erling Smørgrav key, 2003*7b5038d7SDag-Erling Smørgrav keylen); 2004*7b5038d7SDag-Erling Smørgrav break; 2005*7b5038d7SDag-Erling Smørgrav default: 2006*7b5038d7SDag-Erling Smørgrav /* do you know this alg?! */ 2007*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO; 2008*7b5038d7SDag-Erling Smørgrav } 2009*7b5038d7SDag-Erling Smørgrav } 2010*7b5038d7SDag-Erling Smørgrav 2011*7b5038d7SDag-Erling Smørgrav 2012*7b5038d7SDag-Erling Smørgrav /** 2013*7b5038d7SDag-Erling Smørgrav * Reset the ttl in the rrset with the orig_ttl from the sig 2014*7b5038d7SDag-Erling Smørgrav * and update owner name if it was wildcard 2015*7b5038d7SDag-Erling Smørgrav * Also canonicalizes the rrset. 2016*7b5038d7SDag-Erling Smørgrav * @param rrset: rrset to modify 2017*7b5038d7SDag-Erling Smørgrav * @param sig: signature to take TTL and wildcard values from 2018*7b5038d7SDag-Erling Smørgrav */ 2019*7b5038d7SDag-Erling Smørgrav static void 2020*7b5038d7SDag-Erling Smørgrav ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig) 2021*7b5038d7SDag-Erling Smørgrav { 2022*7b5038d7SDag-Erling Smørgrav uint32_t orig_ttl; 2023*7b5038d7SDag-Erling Smørgrav uint16_t i; 2024*7b5038d7SDag-Erling Smørgrav uint8_t label_count; 2025*7b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_name; 2026*7b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_chopped; 2027*7b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_chopped_tmp; 2028*7b5038d7SDag-Erling Smørgrav 2029*7b5038d7SDag-Erling Smørgrav if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) { 2030*7b5038d7SDag-Erling Smørgrav return; 2031*7b5038d7SDag-Erling Smørgrav } 2032*7b5038d7SDag-Erling Smørgrav 2033*7b5038d7SDag-Erling Smørgrav orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3)); 2034*7b5038d7SDag-Erling Smørgrav label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2)); 2035*7b5038d7SDag-Erling Smørgrav 2036*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) { 2037*7b5038d7SDag-Erling Smørgrav if (label_count < 2038*7b5038d7SDag-Erling Smørgrav ldns_dname_label_count( 2039*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) { 2040*7b5038d7SDag-Erling Smørgrav (void) ldns_str2rdf_dname(&wildcard_name, "*"); 2041*7b5038d7SDag-Erling Smørgrav wildcard_chopped = ldns_rdf_clone(ldns_rr_owner( 2042*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrset_clone, i))); 2043*7b5038d7SDag-Erling Smørgrav while (label_count < ldns_dname_label_count(wildcard_chopped)) { 2044*7b5038d7SDag-Erling Smørgrav wildcard_chopped_tmp = ldns_dname_left_chop( 2045*7b5038d7SDag-Erling Smørgrav wildcard_chopped); 2046*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_chopped); 2047*7b5038d7SDag-Erling Smørgrav wildcard_chopped = wildcard_chopped_tmp; 2048*7b5038d7SDag-Erling Smørgrav } 2049*7b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard_name, wildcard_chopped); 2050*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_chopped); 2051*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr( 2052*7b5038d7SDag-Erling Smørgrav rrset_clone, i))); 2053*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 2054*7b5038d7SDag-Erling Smørgrav wildcard_name); 2055*7b5038d7SDag-Erling Smørgrav } 2056*7b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl); 2057*7b5038d7SDag-Erling Smørgrav /* convert to lowercase */ 2058*7b5038d7SDag-Erling Smørgrav ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i)); 2059*7b5038d7SDag-Erling Smørgrav } 2060*7b5038d7SDag-Erling Smørgrav } 2061*7b5038d7SDag-Erling Smørgrav 2062*7b5038d7SDag-Erling Smørgrav /** 2063*7b5038d7SDag-Erling Smørgrav * Make raw signature buffer out of rrsig 2064*7b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer for result 2065*7b5038d7SDag-Erling Smørgrav * @param rrsig: signature to convert 2066*7b5038d7SDag-Erling Smørgrav * @return OK or more specific error. 2067*7b5038d7SDag-Erling Smørgrav */ 2068*7b5038d7SDag-Erling Smørgrav static ldns_status 2069*7b5038d7SDag-Erling Smørgrav ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig) 2070*7b5038d7SDag-Erling Smørgrav { 2071*7b5038d7SDag-Erling Smørgrav uint8_t sig_algo; 2072*7b5038d7SDag-Erling Smørgrav 2073*7b5038d7SDag-Erling Smørgrav if (rrsig == NULL) { 2074*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG; 2075*7b5038d7SDag-Erling Smørgrav } 2076*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 1) == NULL) { 2077*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG; 2078*7b5038d7SDag-Erling Smørgrav } 2079*7b5038d7SDag-Erling Smørgrav sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1)); 2080*7b5038d7SDag-Erling Smørgrav /* check for known and implemented algo's now (otherwise 2081*7b5038d7SDag-Erling Smørgrav * the function could return a wrong error 2082*7b5038d7SDag-Erling Smørgrav */ 2083*7b5038d7SDag-Erling Smørgrav /* create a buffer with signature rdata */ 2084*7b5038d7SDag-Erling Smørgrav /* for some algorithms we need other data than for others... */ 2085*7b5038d7SDag-Erling Smørgrav /* (the DSA API wants DER encoding for instance) */ 2086*7b5038d7SDag-Erling Smørgrav 2087*7b5038d7SDag-Erling Smørgrav switch(sig_algo) { 2088*7b5038d7SDag-Erling Smørgrav case LDNS_RSAMD5: 2089*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1: 2090*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 2091*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 2092*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA256: 2093*7b5038d7SDag-Erling Smørgrav case LDNS_RSASHA512: 2094*7b5038d7SDag-Erling Smørgrav #endif 2095*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 2096*7b5038d7SDag-Erling Smørgrav case LDNS_ECC_GOST: 2097*7b5038d7SDag-Erling Smørgrav #endif 2098*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) { 2099*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG; 2100*7b5038d7SDag-Erling Smørgrav } 2101*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8)) 2102*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2103*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2104*7b5038d7SDag-Erling Smørgrav } 2105*7b5038d7SDag-Erling Smørgrav break; 2106*7b5038d7SDag-Erling Smørgrav case LDNS_DSA: 2107*7b5038d7SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 2108*7b5038d7SDag-Erling Smørgrav /* EVP takes rfc2459 format, which is a tad longer than dns format */ 2109*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) { 2110*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG; 2111*7b5038d7SDag-Erling Smørgrav } 2112*7b5038d7SDag-Erling Smørgrav if (ldns_convert_dsa_rrsig_rdf2asn1( 2113*7b5038d7SDag-Erling Smørgrav rawsig_buf, ldns_rr_rdf(rrsig, 8)) 2114*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2115*7b5038d7SDag-Erling Smørgrav /* 2116*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(rawsig_buf, 2117*7b5038d7SDag-Erling Smørgrav ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) { 2118*7b5038d7SDag-Erling Smørgrav */ 2119*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2120*7b5038d7SDag-Erling Smørgrav } 2121*7b5038d7SDag-Erling Smørgrav break; 2122*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 2123*7b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 2124*7b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 2125*7b5038d7SDag-Erling Smørgrav /* EVP produces an ASN prefix on the signature, which is 2126*7b5038d7SDag-Erling Smørgrav * not used in the DNS */ 2127*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) { 2128*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG; 2129*7b5038d7SDag-Erling Smørgrav } 2130*7b5038d7SDag-Erling Smørgrav if (ldns_convert_ecdsa_rrsig_rdf2asn1( 2131*7b5038d7SDag-Erling Smørgrav rawsig_buf, ldns_rr_rdf(rrsig, 8)) 2132*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2133*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2134*7b5038d7SDag-Erling Smørgrav } 2135*7b5038d7SDag-Erling Smørgrav break; 2136*7b5038d7SDag-Erling Smørgrav #endif 2137*7b5038d7SDag-Erling Smørgrav case LDNS_DH: 2138*7b5038d7SDag-Erling Smørgrav case LDNS_ECC: 2139*7b5038d7SDag-Erling Smørgrav case LDNS_INDIRECT: 2140*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL; 2141*7b5038d7SDag-Erling Smørgrav default: 2142*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO; 2143*7b5038d7SDag-Erling Smørgrav } 2144*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2145*7b5038d7SDag-Erling Smørgrav } 2146*7b5038d7SDag-Erling Smørgrav 2147*7b5038d7SDag-Erling Smørgrav /** 2148*7b5038d7SDag-Erling Smørgrav * Check RRSIG timestamps against the given 'now' time. 2149*7b5038d7SDag-Erling Smørgrav * @param rrsig: signature to check. 2150*7b5038d7SDag-Erling Smørgrav * @param now: the current time in seconds epoch. 2151*7b5038d7SDag-Erling Smørgrav * @return status code LDNS_STATUS_OK if all is fine. 2152*7b5038d7SDag-Erling Smørgrav */ 2153*7b5038d7SDag-Erling Smørgrav static ldns_status 2154*7b5038d7SDag-Erling Smørgrav ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now) 2155*7b5038d7SDag-Erling Smørgrav { 2156*7b5038d7SDag-Erling Smørgrav int32_t inception, expiration; 2157*7b5038d7SDag-Erling Smørgrav 2158*7b5038d7SDag-Erling Smørgrav /* check the signature time stamps */ 2159*7b5038d7SDag-Erling Smørgrav inception = (int32_t)ldns_rdf2native_time_t( 2160*7b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_inception(rrsig)); 2161*7b5038d7SDag-Erling Smørgrav expiration = (int32_t)ldns_rdf2native_time_t( 2162*7b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_expiration(rrsig)); 2163*7b5038d7SDag-Erling Smørgrav 2164*7b5038d7SDag-Erling Smørgrav if (expiration - inception < 0) { 2165*7b5038d7SDag-Erling Smørgrav /* bad sig, expiration before inception?? Tsssg */ 2166*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION; 2167*7b5038d7SDag-Erling Smørgrav } 2168*7b5038d7SDag-Erling Smørgrav if (((int32_t) now) - inception < 0) { 2169*7b5038d7SDag-Erling Smørgrav /* bad sig, inception date has not yet come to pass */ 2170*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED; 2171*7b5038d7SDag-Erling Smørgrav } 2172*7b5038d7SDag-Erling Smørgrav if (expiration - ((int32_t) now) < 0) { 2173*7b5038d7SDag-Erling Smørgrav /* bad sig, expiration date has passed */ 2174*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_SIG_EXPIRED; 2175*7b5038d7SDag-Erling Smørgrav } 2176*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2177*7b5038d7SDag-Erling Smørgrav } 2178*7b5038d7SDag-Erling Smørgrav 2179*7b5038d7SDag-Erling Smørgrav /** 2180*7b5038d7SDag-Erling Smørgrav * Prepare for verification. 2181*7b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer made ready. 2182*7b5038d7SDag-Erling Smørgrav * @param verify_buf: data for verification buffer made ready. 2183*7b5038d7SDag-Erling Smørgrav * @param rrset_clone: made ready. 2184*7b5038d7SDag-Erling Smørgrav * @param rrsig: signature to prepare for. 2185*7b5038d7SDag-Erling Smørgrav * @return LDNS_STATUS_OK is all went well. Otherwise specific error. 2186*7b5038d7SDag-Erling Smørgrav */ 2187*7b5038d7SDag-Erling Smørgrav static ldns_status 2188*7b5038d7SDag-Erling Smørgrav ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 2189*7b5038d7SDag-Erling Smørgrav ldns_rr_list* rrset_clone, ldns_rr* rrsig) 2190*7b5038d7SDag-Erling Smørgrav { 2191*7b5038d7SDag-Erling Smørgrav ldns_status result; 2192*7b5038d7SDag-Erling Smørgrav 2193*7b5038d7SDag-Erling Smørgrav /* canonicalize the sig */ 2194*7b5038d7SDag-Erling Smørgrav ldns_dname2canonical(ldns_rr_owner(rrsig)); 2195*7b5038d7SDag-Erling Smørgrav 2196*7b5038d7SDag-Erling Smørgrav /* check if the typecovered is equal to the type checked */ 2197*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) != 2198*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0))) 2199*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR; 2200*7b5038d7SDag-Erling Smørgrav 2201*7b5038d7SDag-Erling Smørgrav /* create a buffer with b64 signature rdata */ 2202*7b5038d7SDag-Erling Smørgrav result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig); 2203*7b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) 2204*7b5038d7SDag-Erling Smørgrav return result; 2205*7b5038d7SDag-Erling Smørgrav 2206*7b5038d7SDag-Erling Smørgrav /* use TTL from signature. Use wildcard names for wildcards */ 2207*7b5038d7SDag-Erling Smørgrav /* also canonicalizes rrset_clone */ 2208*7b5038d7SDag-Erling Smørgrav ldns_rrset_use_signature_ttl(rrset_clone, rrsig); 2209*7b5038d7SDag-Erling Smørgrav 2210*7b5038d7SDag-Erling Smørgrav /* sort the rrset in canonical order */ 2211*7b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(rrset_clone); 2212*7b5038d7SDag-Erling Smørgrav 2213*7b5038d7SDag-Erling Smørgrav /* put the signature rr (without the b64) to the verify_buf */ 2214*7b5038d7SDag-Erling Smørgrav if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK) 2215*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2216*7b5038d7SDag-Erling Smørgrav 2217*7b5038d7SDag-Erling Smørgrav /* add the rrset in verify_buf */ 2218*7b5038d7SDag-Erling Smørgrav if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone) 2219*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) 2220*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2221*7b5038d7SDag-Erling Smørgrav 2222*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2223*7b5038d7SDag-Erling Smørgrav } 2224*7b5038d7SDag-Erling Smørgrav 2225*7b5038d7SDag-Erling Smørgrav /** 2226*7b5038d7SDag-Erling Smørgrav * Check if a key matches a signature. 2227*7b5038d7SDag-Erling Smørgrav * Checks keytag, sigalgo and signature. 2228*7b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer for verify 2229*7b5038d7SDag-Erling Smørgrav * @param verify_buf: raw data buffer for verify 2230*7b5038d7SDag-Erling Smørgrav * @param rrsig: the rrsig 2231*7b5038d7SDag-Erling Smørgrav * @param key: key to attempt. 2232*7b5038d7SDag-Erling Smørgrav * @return LDNS_STATUS_OK if OK, else some specific error. 2233*7b5038d7SDag-Erling Smørgrav */ 2234*7b5038d7SDag-Erling Smørgrav static ldns_status 2235*7b5038d7SDag-Erling Smørgrav ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 2236*7b5038d7SDag-Erling Smørgrav ldns_rr* rrsig, ldns_rr* key) 2237*7b5038d7SDag-Erling Smørgrav { 2238*7b5038d7SDag-Erling Smørgrav uint8_t sig_algo; 2239*7b5038d7SDag-Erling Smørgrav 2240*7b5038d7SDag-Erling Smørgrav if (rrsig == NULL) { 2241*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG; 2242*7b5038d7SDag-Erling Smørgrav } 2243*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 1) == NULL) { 2244*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG; 2245*7b5038d7SDag-Erling Smørgrav } 2246*7b5038d7SDag-Erling Smørgrav sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1)); 2247*7b5038d7SDag-Erling Smørgrav 2248*7b5038d7SDag-Erling Smørgrav /* before anything, check if the keytags match */ 2249*7b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(key) 2250*7b5038d7SDag-Erling Smørgrav == 2251*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig)) 2252*7b5038d7SDag-Erling Smørgrav ) { 2253*7b5038d7SDag-Erling Smørgrav ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2254*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_ERR; 2255*7b5038d7SDag-Erling Smørgrav 2256*7b5038d7SDag-Erling Smørgrav /* put the key-data in a buffer, that's the third rdf, with 2257*7b5038d7SDag-Erling Smørgrav * the base64 encoded key data */ 2258*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(key, 3) == NULL) { 2259*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf); 2260*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY; 2261*7b5038d7SDag-Erling Smørgrav } 2262*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3)) 2263*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2264*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf); 2265*7b5038d7SDag-Erling Smørgrav /* returning is bad might screw up 2266*7b5038d7SDag-Erling Smørgrav good keys later in the list 2267*7b5038d7SDag-Erling Smørgrav what to do? */ 2268*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 2269*7b5038d7SDag-Erling Smørgrav } 2270*7b5038d7SDag-Erling Smørgrav 2271*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(key, 2) == NULL) { 2272*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY; 2273*7b5038d7SDag-Erling Smørgrav } 2274*7b5038d7SDag-Erling Smørgrav else if (sig_algo == ldns_rdf2native_int8( 2275*7b5038d7SDag-Erling Smørgrav ldns_rr_rdf(key, 2))) { 2276*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_buffers(rawsig_buf, 2277*7b5038d7SDag-Erling Smørgrav verify_buf, key_buf, sig_algo); 2278*7b5038d7SDag-Erling Smørgrav } else { 2279*7b5038d7SDag-Erling Smørgrav /* No keys with the corresponding algorithm are found */ 2280*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY; 2281*7b5038d7SDag-Erling Smørgrav } 2282*7b5038d7SDag-Erling Smørgrav 2283*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf); 2284*7b5038d7SDag-Erling Smørgrav return result; 2285*7b5038d7SDag-Erling Smørgrav } 2286*7b5038d7SDag-Erling Smørgrav else { 2287*7b5038d7SDag-Erling Smørgrav /* No keys with the corresponding keytag are found */ 2288*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY; 2289*7b5038d7SDag-Erling Smørgrav } 2290*7b5038d7SDag-Erling Smørgrav } 2291*7b5038d7SDag-Erling Smørgrav 2292*7b5038d7SDag-Erling Smørgrav /* 2293*7b5038d7SDag-Erling Smørgrav * to verify: 2294*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 key rdata 2295*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sorted rrset 2296*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 sig rdata 2297*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sig without the b64 rdata 2298*7b5038d7SDag-Erling Smørgrav * - cat the sig data (without b64 rdata) to the rrset 2299*7b5038d7SDag-Erling Smørgrav * - verify the rrset+sig, with the b64 data and the b64 key data 2300*7b5038d7SDag-Erling Smørgrav */ 2301*7b5038d7SDag-Erling Smørgrav ldns_status 2302*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_keylist_time( 2303*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset, 2304*7b5038d7SDag-Erling Smørgrav ldns_rr *rrsig, 2305*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 2306*7b5038d7SDag-Erling Smørgrav time_t check_time, 2307*7b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys) 2308*7b5038d7SDag-Erling Smørgrav { 2309*7b5038d7SDag-Erling Smørgrav ldns_status result; 2310*7b5038d7SDag-Erling Smørgrav ldns_rr_list *valid = ldns_rr_list_new(); 2311*7b5038d7SDag-Erling Smørgrav if (!valid) 2312*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2313*7b5038d7SDag-Erling Smørgrav 2314*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid); 2315*7b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) { 2316*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid); 2317*7b5038d7SDag-Erling Smørgrav return result; 2318*7b5038d7SDag-Erling Smørgrav } 2319*7b5038d7SDag-Erling Smørgrav 2320*7b5038d7SDag-Erling Smørgrav /* check timestamps last; its OK except time */ 2321*7b5038d7SDag-Erling Smørgrav result = ldns_rrsig_check_timestamps(rrsig, check_time); 2322*7b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) { 2323*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid); 2324*7b5038d7SDag-Erling Smørgrav return result; 2325*7b5038d7SDag-Erling Smørgrav } 2326*7b5038d7SDag-Erling Smørgrav 2327*7b5038d7SDag-Erling Smørgrav ldns_rr_list_cat(good_keys, valid); 2328*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid); 2329*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2330*7b5038d7SDag-Erling Smørgrav } 2331*7b5038d7SDag-Erling Smørgrav 2332*7b5038d7SDag-Erling Smørgrav /* 2333*7b5038d7SDag-Erling Smørgrav * to verify: 2334*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 key rdata 2335*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sorted rrset 2336*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 sig rdata 2337*7b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sig without the b64 rdata 2338*7b5038d7SDag-Erling Smørgrav * - cat the sig data (without b64 rdata) to the rrset 2339*7b5038d7SDag-Erling Smørgrav * - verify the rrset+sig, with the b64 data and the b64 key data 2340*7b5038d7SDag-Erling Smørgrav */ 2341*7b5038d7SDag-Erling Smørgrav ldns_status 2342*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_keylist(ldns_rr_list *rrset, 2343*7b5038d7SDag-Erling Smørgrav ldns_rr *rrsig, 2344*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 2345*7b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys) 2346*7b5038d7SDag-Erling Smørgrav { 2347*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_keylist_time( 2348*7b5038d7SDag-Erling Smørgrav rrset, rrsig, keys, ldns_time(NULL), good_keys); 2349*7b5038d7SDag-Erling Smørgrav } 2350*7b5038d7SDag-Erling Smørgrav 2351*7b5038d7SDag-Erling Smørgrav ldns_status 2352*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset, 2353*7b5038d7SDag-Erling Smørgrav ldns_rr *rrsig, 2354*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, 2355*7b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys) 2356*7b5038d7SDag-Erling Smørgrav { 2357*7b5038d7SDag-Erling Smørgrav ldns_buffer *rawsig_buf; 2358*7b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf; 2359*7b5038d7SDag-Erling Smørgrav uint16_t i; 2360*7b5038d7SDag-Erling Smørgrav ldns_status result, status; 2361*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone; 2362*7b5038d7SDag-Erling Smørgrav ldns_rr_list *validkeys; 2363*7b5038d7SDag-Erling Smørgrav 2364*7b5038d7SDag-Erling Smørgrav if (!rrset) { 2365*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 2366*7b5038d7SDag-Erling Smørgrav } 2367*7b5038d7SDag-Erling Smørgrav 2368*7b5038d7SDag-Erling Smørgrav validkeys = ldns_rr_list_new(); 2369*7b5038d7SDag-Erling Smørgrav if (!validkeys) { 2370*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2371*7b5038d7SDag-Erling Smørgrav } 2372*7b5038d7SDag-Erling Smørgrav 2373*7b5038d7SDag-Erling Smørgrav /* clone the rrset so that we can fiddle with it */ 2374*7b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset); 2375*7b5038d7SDag-Erling Smørgrav 2376*7b5038d7SDag-Erling Smørgrav /* create the buffers which will certainly hold the raw data */ 2377*7b5038d7SDag-Erling Smørgrav rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2378*7b5038d7SDag-Erling Smørgrav verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2379*7b5038d7SDag-Erling Smørgrav 2380*7b5038d7SDag-Erling Smørgrav result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 2381*7b5038d7SDag-Erling Smørgrav rrset_clone, rrsig); 2382*7b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) { 2383*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf); 2384*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf); 2385*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2386*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys); 2387*7b5038d7SDag-Erling Smørgrav return result; 2388*7b5038d7SDag-Erling Smørgrav } 2389*7b5038d7SDag-Erling Smørgrav 2390*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY; 2391*7b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(keys); i++) { 2392*7b5038d7SDag-Erling Smørgrav status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 2393*7b5038d7SDag-Erling Smørgrav rrsig, ldns_rr_list_rr(keys, i)); 2394*7b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 2395*7b5038d7SDag-Erling Smørgrav /* one of the keys has matched, don't break 2396*7b5038d7SDag-Erling Smørgrav * here, instead put the 'winning' key in 2397*7b5038d7SDag-Erling Smørgrav * the validkey list and return the list 2398*7b5038d7SDag-Erling Smørgrav * later */ 2399*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(validkeys, 2400*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(keys,i))) { 2401*7b5038d7SDag-Erling Smørgrav /* couldn't push the key?? */ 2402*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf); 2403*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf); 2404*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2405*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys); 2406*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 2407*7b5038d7SDag-Erling Smørgrav } 2408*7b5038d7SDag-Erling Smørgrav 2409*7b5038d7SDag-Erling Smørgrav result = status; 2410*7b5038d7SDag-Erling Smørgrav } 2411*7b5038d7SDag-Erling Smørgrav 2412*7b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) { 2413*7b5038d7SDag-Erling Smørgrav result = status; 2414*7b5038d7SDag-Erling Smørgrav } 2415*7b5038d7SDag-Erling Smørgrav } 2416*7b5038d7SDag-Erling Smørgrav 2417*7b5038d7SDag-Erling Smørgrav /* no longer needed */ 2418*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2419*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf); 2420*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf); 2421*7b5038d7SDag-Erling Smørgrav 2422*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(validkeys) == 0) { 2423*7b5038d7SDag-Erling Smørgrav /* no keys were added, return last error */ 2424*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys); 2425*7b5038d7SDag-Erling Smørgrav return result; 2426*7b5038d7SDag-Erling Smørgrav } 2427*7b5038d7SDag-Erling Smørgrav 2428*7b5038d7SDag-Erling Smørgrav /* do not check timestamps */ 2429*7b5038d7SDag-Erling Smørgrav 2430*7b5038d7SDag-Erling Smørgrav ldns_rr_list_cat(good_keys, validkeys); 2431*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys); 2432*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2433*7b5038d7SDag-Erling Smørgrav } 2434*7b5038d7SDag-Erling Smørgrav 2435*7b5038d7SDag-Erling Smørgrav ldns_status 2436*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_time( 2437*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset, 2438*7b5038d7SDag-Erling Smørgrav ldns_rr *rrsig, 2439*7b5038d7SDag-Erling Smørgrav ldns_rr *key, 2440*7b5038d7SDag-Erling Smørgrav time_t check_time) 2441*7b5038d7SDag-Erling Smørgrav { 2442*7b5038d7SDag-Erling Smørgrav ldns_buffer *rawsig_buf; 2443*7b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf; 2444*7b5038d7SDag-Erling Smørgrav ldns_status result; 2445*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone; 2446*7b5038d7SDag-Erling Smørgrav 2447*7b5038d7SDag-Erling Smørgrav if (!rrset) { 2448*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NO_DATA; 2449*7b5038d7SDag-Erling Smørgrav } 2450*7b5038d7SDag-Erling Smørgrav /* clone the rrset so that we can fiddle with it */ 2451*7b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset); 2452*7b5038d7SDag-Erling Smørgrav /* create the buffers which will certainly hold the raw data */ 2453*7b5038d7SDag-Erling Smørgrav rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2454*7b5038d7SDag-Erling Smørgrav verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2455*7b5038d7SDag-Erling Smørgrav 2456*7b5038d7SDag-Erling Smørgrav result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 2457*7b5038d7SDag-Erling Smørgrav rrset_clone, rrsig); 2458*7b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) { 2459*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2460*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf); 2461*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf); 2462*7b5038d7SDag-Erling Smørgrav return result; 2463*7b5038d7SDag-Erling Smørgrav } 2464*7b5038d7SDag-Erling Smørgrav result = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 2465*7b5038d7SDag-Erling Smørgrav rrsig, key); 2466*7b5038d7SDag-Erling Smørgrav /* no longer needed */ 2467*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2468*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf); 2469*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf); 2470*7b5038d7SDag-Erling Smørgrav 2471*7b5038d7SDag-Erling Smørgrav /* check timestamp last, apart from time its OK */ 2472*7b5038d7SDag-Erling Smørgrav if(result == LDNS_STATUS_OK) 2473*7b5038d7SDag-Erling Smørgrav result = ldns_rrsig_check_timestamps(rrsig, check_time); 2474*7b5038d7SDag-Erling Smørgrav 2475*7b5038d7SDag-Erling Smørgrav return result; 2476*7b5038d7SDag-Erling Smørgrav } 2477*7b5038d7SDag-Erling Smørgrav 2478*7b5038d7SDag-Erling Smørgrav ldns_status 2479*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key) 2480*7b5038d7SDag-Erling Smørgrav { 2481*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL)); 2482*7b5038d7SDag-Erling Smørgrav } 2483*7b5038d7SDag-Erling Smørgrav 2484*7b5038d7SDag-Erling Smørgrav 2485*7b5038d7SDag-Erling Smørgrav ldns_status 2486*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_evp(ldns_buffer *sig, 2487*7b5038d7SDag-Erling Smørgrav ldns_buffer *rrset, 2488*7b5038d7SDag-Erling Smørgrav EVP_PKEY *key, 2489*7b5038d7SDag-Erling Smørgrav const EVP_MD *digest_type) 2490*7b5038d7SDag-Erling Smørgrav { 2491*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_evp_raw( 2492*7b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig), 2493*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig), 2494*7b5038d7SDag-Erling Smørgrav rrset, 2495*7b5038d7SDag-Erling Smørgrav key, 2496*7b5038d7SDag-Erling Smørgrav digest_type); 2497*7b5038d7SDag-Erling Smørgrav } 2498*7b5038d7SDag-Erling Smørgrav 2499*7b5038d7SDag-Erling Smørgrav ldns_status 2500*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 2501*7b5038d7SDag-Erling Smørgrav ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type) 2502*7b5038d7SDag-Erling Smørgrav { 2503*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX ctx; 2504*7b5038d7SDag-Erling Smørgrav int res; 2505*7b5038d7SDag-Erling Smørgrav 2506*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX_init(&ctx); 2507*7b5038d7SDag-Erling Smørgrav 2508*7b5038d7SDag-Erling Smørgrav EVP_VerifyInit(&ctx, digest_type); 2509*7b5038d7SDag-Erling Smørgrav EVP_VerifyUpdate(&ctx, 2510*7b5038d7SDag-Erling Smørgrav ldns_buffer_begin(rrset), 2511*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(rrset)); 2512*7b5038d7SDag-Erling Smørgrav res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key); 2513*7b5038d7SDag-Erling Smørgrav 2514*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX_cleanup(&ctx); 2515*7b5038d7SDag-Erling Smørgrav 2516*7b5038d7SDag-Erling Smørgrav if (res == 1) { 2517*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2518*7b5038d7SDag-Erling Smørgrav } else if (res == 0) { 2519*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS; 2520*7b5038d7SDag-Erling Smørgrav } 2521*7b5038d7SDag-Erling Smørgrav /* TODO how to communicate internal SSL error? 2522*7b5038d7SDag-Erling Smørgrav let caller use ssl's get_error() */ 2523*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SSL_ERR; 2524*7b5038d7SDag-Erling Smørgrav } 2525*7b5038d7SDag-Erling Smørgrav 2526*7b5038d7SDag-Erling Smørgrav ldns_status 2527*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key) 2528*7b5038d7SDag-Erling Smørgrav { 2529*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_dsa_raw( 2530*7b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(sig), 2531*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig), 2532*7b5038d7SDag-Erling Smørgrav rrset, 2533*7b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key), 2534*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key)); 2535*7b5038d7SDag-Erling Smørgrav } 2536*7b5038d7SDag-Erling Smørgrav 2537*7b5038d7SDag-Erling Smørgrav ldns_status 2538*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key) 2539*7b5038d7SDag-Erling Smørgrav { 2540*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha1_raw( 2541*7b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig), 2542*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig), 2543*7b5038d7SDag-Erling Smørgrav rrset, 2544*7b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key), 2545*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key)); 2546*7b5038d7SDag-Erling Smørgrav } 2547*7b5038d7SDag-Erling Smørgrav 2548*7b5038d7SDag-Erling Smørgrav ldns_status 2549*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key) 2550*7b5038d7SDag-Erling Smørgrav { 2551*7b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsamd5_raw( 2552*7b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig), 2553*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig), 2554*7b5038d7SDag-Erling Smørgrav rrset, 2555*7b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key), 2556*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key)); 2557*7b5038d7SDag-Erling Smørgrav } 2558*7b5038d7SDag-Erling Smørgrav 2559*7b5038d7SDag-Erling Smørgrav ldns_status 2560*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen, 2561*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen) 2562*7b5038d7SDag-Erling Smørgrav { 2563*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 2564*7b5038d7SDag-Erling Smørgrav ldns_status result; 2565*7b5038d7SDag-Erling Smørgrav 2566*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2567*7b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) { 2568*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, 2569*7b5038d7SDag-Erling Smørgrav siglen, 2570*7b5038d7SDag-Erling Smørgrav rrset, 2571*7b5038d7SDag-Erling Smørgrav evp_key, 2572*7b5038d7SDag-Erling Smørgrav EVP_dss1()); 2573*7b5038d7SDag-Erling Smørgrav } else { 2574*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR; 2575*7b5038d7SDag-Erling Smørgrav } 2576*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2577*7b5038d7SDag-Erling Smørgrav return result; 2578*7b5038d7SDag-Erling Smørgrav 2579*7b5038d7SDag-Erling Smørgrav } 2580*7b5038d7SDag-Erling Smørgrav 2581*7b5038d7SDag-Erling Smørgrav ldns_status 2582*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen, 2583*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen) 2584*7b5038d7SDag-Erling Smørgrav { 2585*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 2586*7b5038d7SDag-Erling Smørgrav ldns_status result; 2587*7b5038d7SDag-Erling Smørgrav 2588*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2589*7b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { 2590*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, 2591*7b5038d7SDag-Erling Smørgrav siglen, 2592*7b5038d7SDag-Erling Smørgrav rrset, 2593*7b5038d7SDag-Erling Smørgrav evp_key, 2594*7b5038d7SDag-Erling Smørgrav EVP_sha1()); 2595*7b5038d7SDag-Erling Smørgrav } else { 2596*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR; 2597*7b5038d7SDag-Erling Smørgrav } 2598*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2599*7b5038d7SDag-Erling Smørgrav 2600*7b5038d7SDag-Erling Smørgrav return result; 2601*7b5038d7SDag-Erling Smørgrav } 2602*7b5038d7SDag-Erling Smørgrav 2603*7b5038d7SDag-Erling Smørgrav ldns_status 2604*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha256_raw(unsigned char* sig, 2605*7b5038d7SDag-Erling Smørgrav size_t siglen, 2606*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, 2607*7b5038d7SDag-Erling Smørgrav unsigned char* key, 2608*7b5038d7SDag-Erling Smørgrav size_t keylen) 2609*7b5038d7SDag-Erling Smørgrav { 2610*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 2611*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 2612*7b5038d7SDag-Erling Smørgrav ldns_status result; 2613*7b5038d7SDag-Erling Smørgrav 2614*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2615*7b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { 2616*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, 2617*7b5038d7SDag-Erling Smørgrav siglen, 2618*7b5038d7SDag-Erling Smørgrav rrset, 2619*7b5038d7SDag-Erling Smørgrav evp_key, 2620*7b5038d7SDag-Erling Smørgrav EVP_sha256()); 2621*7b5038d7SDag-Erling Smørgrav } else { 2622*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR; 2623*7b5038d7SDag-Erling Smørgrav } 2624*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2625*7b5038d7SDag-Erling Smørgrav 2626*7b5038d7SDag-Erling Smørgrav return result; 2627*7b5038d7SDag-Erling Smørgrav #else 2628*7b5038d7SDag-Erling Smørgrav /* touch these to prevent compiler warnings */ 2629*7b5038d7SDag-Erling Smørgrav (void) sig; 2630*7b5038d7SDag-Erling Smørgrav (void) siglen; 2631*7b5038d7SDag-Erling Smørgrav (void) rrset; 2632*7b5038d7SDag-Erling Smørgrav (void) key; 2633*7b5038d7SDag-Erling Smørgrav (void) keylen; 2634*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO; 2635*7b5038d7SDag-Erling Smørgrav #endif 2636*7b5038d7SDag-Erling Smørgrav } 2637*7b5038d7SDag-Erling Smørgrav 2638*7b5038d7SDag-Erling Smørgrav ldns_status 2639*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha512_raw(unsigned char* sig, 2640*7b5038d7SDag-Erling Smørgrav size_t siglen, 2641*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, 2642*7b5038d7SDag-Erling Smørgrav unsigned char* key, 2643*7b5038d7SDag-Erling Smørgrav size_t keylen) 2644*7b5038d7SDag-Erling Smørgrav { 2645*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 2646*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 2647*7b5038d7SDag-Erling Smørgrav ldns_status result; 2648*7b5038d7SDag-Erling Smørgrav 2649*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2650*7b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { 2651*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, 2652*7b5038d7SDag-Erling Smørgrav siglen, 2653*7b5038d7SDag-Erling Smørgrav rrset, 2654*7b5038d7SDag-Erling Smørgrav evp_key, 2655*7b5038d7SDag-Erling Smørgrav EVP_sha512()); 2656*7b5038d7SDag-Erling Smørgrav } else { 2657*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR; 2658*7b5038d7SDag-Erling Smørgrav } 2659*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2660*7b5038d7SDag-Erling Smørgrav 2661*7b5038d7SDag-Erling Smørgrav return result; 2662*7b5038d7SDag-Erling Smørgrav #else 2663*7b5038d7SDag-Erling Smørgrav /* touch these to prevent compiler warnings */ 2664*7b5038d7SDag-Erling Smørgrav (void) sig; 2665*7b5038d7SDag-Erling Smørgrav (void) siglen; 2666*7b5038d7SDag-Erling Smørgrav (void) rrset; 2667*7b5038d7SDag-Erling Smørgrav (void) key; 2668*7b5038d7SDag-Erling Smørgrav (void) keylen; 2669*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO; 2670*7b5038d7SDag-Erling Smørgrav #endif 2671*7b5038d7SDag-Erling Smørgrav } 2672*7b5038d7SDag-Erling Smørgrav 2673*7b5038d7SDag-Erling Smørgrav 2674*7b5038d7SDag-Erling Smørgrav ldns_status 2675*7b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsamd5_raw(unsigned char* sig, 2676*7b5038d7SDag-Erling Smørgrav size_t siglen, 2677*7b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, 2678*7b5038d7SDag-Erling Smørgrav unsigned char* key, 2679*7b5038d7SDag-Erling Smørgrav size_t keylen) 2680*7b5038d7SDag-Erling Smørgrav { 2681*7b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key; 2682*7b5038d7SDag-Erling Smørgrav ldns_status result; 2683*7b5038d7SDag-Erling Smørgrav 2684*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2685*7b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { 2686*7b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, 2687*7b5038d7SDag-Erling Smørgrav siglen, 2688*7b5038d7SDag-Erling Smørgrav rrset, 2689*7b5038d7SDag-Erling Smørgrav evp_key, 2690*7b5038d7SDag-Erling Smørgrav EVP_md5()); 2691*7b5038d7SDag-Erling Smørgrav } else { 2692*7b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR; 2693*7b5038d7SDag-Erling Smørgrav } 2694*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2695*7b5038d7SDag-Erling Smørgrav 2696*7b5038d7SDag-Erling Smørgrav return result; 2697*7b5038d7SDag-Erling Smørgrav } 2698*7b5038d7SDag-Erling Smørgrav 2699*7b5038d7SDag-Erling Smørgrav #endif 2700