dnssec_verify.c

Go to the documentation of this file.
00001 #include <ldns/config.h>
00002 
00003 #include <ldns/ldns.h>
00004 
00005 #include <strings.h>
00006 #include <time.h>
00007 
00008 #ifdef HAVE_SSL
00009 /* this entire file is rather useless when you don't have
00010  * crypto...
00011  */
00012 #include <openssl/ssl.h>
00013 #include <openssl/evp.h>
00014 #include <openssl/rand.h>
00015 #include <openssl/err.h>
00016 #include <openssl/md5.h>
00017 
00018 ldns_dnssec_data_chain *
00019 ldns_dnssec_data_chain_new()
00020 {
00021         ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
00022         if(!nc) return NULL;
00023         /* 
00024          * not needed anymore because CALLOC initalizes everything to zero.
00025 
00026         nc->rrset = NULL;
00027         nc->parent_type = 0;
00028         nc->parent = NULL;
00029         nc->signatures = NULL;
00030         nc->packet_rcode = 0;
00031         nc->packet_qtype = 0;
00032         nc->packet_nodata = false;
00033 
00034          */
00035         return nc;
00036 }
00037 
00038 void
00039 ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
00040 {
00041         LDNS_FREE(chain);
00042 }
00043 
00044 void
00045 ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
00046 {
00047         ldns_rr_list_deep_free(chain->rrset);
00048         ldns_rr_list_deep_free(chain->signatures);
00049         if (chain->parent) {
00050                 ldns_dnssec_data_chain_deep_free(chain->parent);
00051         }
00052         LDNS_FREE(chain);
00053 }
00054 
00055 void
00056 ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
00057                 const ldns_dnssec_data_chain *chain)
00058 {
00059         ldns_lookup_table *rcode;
00060         const ldns_rr_descriptor *rr_descriptor;
00061         if (chain) {
00062                 ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
00063                 if (ldns_rr_list_rr_count(chain->rrset) > 0) {
00064                         rcode = ldns_lookup_by_id(ldns_rcodes,
00065                                                                  (int) chain->packet_rcode);
00066                         if (rcode) {
00067                                 fprintf(out, ";; rcode: %s\n", rcode->name);
00068                         }
00069 
00070                         rr_descriptor = ldns_rr_descript(chain->packet_qtype);
00071                         if (rr_descriptor && rr_descriptor->_name) {
00072                                 fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
00073                         } else if (chain->packet_qtype != 0) {
00074                                 fprintf(out, "TYPE%u", 
00075                                            chain->packet_qtype);
00076                         }
00077                         if (chain->packet_nodata) {
00078                                 fprintf(out, ";; NODATA response\n");
00079                         }
00080                         fprintf(out, "rrset:\n");
00081                         ldns_rr_list_print_fmt(out, fmt, chain->rrset);
00082                         fprintf(out, "sigs:\n");
00083                         ldns_rr_list_print_fmt(out, fmt, chain->signatures);
00084                         fprintf(out, "---\n");
00085                 } else {
00086                         fprintf(out, "<no data>\n");
00087                 }
00088         }
00089 }
00090 void
00091 ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
00092 {
00093         ldns_dnssec_data_chain_print_fmt(
00094                         out, ldns_output_format_default, chain);
00095 }
00096 
00097 
00098 static void
00099 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
00100                                             uint16_t qflags,
00101                                             const ldns_pkt *pkt,
00102                                             ldns_rr_list *signatures,
00103                                                 ldns_dnssec_data_chain *new_chain,
00104                                                 ldns_rdf *key_name,
00105                                                 ldns_rr_class c) {
00106         ldns_rr_list *keys;
00107         ldns_pkt *my_pkt;
00108         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
00109                 new_chain->signatures = ldns_rr_list_clone(signatures);
00110                 new_chain->parent_type = 0;
00111 
00112                 keys = ldns_pkt_rr_list_by_name_and_type(
00113                                   pkt,
00114                                  key_name,
00115                                  LDNS_RR_TYPE_DNSKEY,
00116                                  LDNS_SECTION_ANY_NOQUESTION
00117                           );
00118                 if (!keys) {
00119                         my_pkt = ldns_resolver_query(res,
00120                                                                         key_name,
00121                                                                         LDNS_RR_TYPE_DNSKEY,
00122                                                                         c,
00123                                                                         qflags);
00124                         if (my_pkt) {
00125                         keys = ldns_pkt_rr_list_by_name_and_type(
00126                                           my_pkt,
00127                                          key_name,
00128                                          LDNS_RR_TYPE_DNSKEY,
00129                                          LDNS_SECTION_ANY_NOQUESTION
00130                                   );
00131                         new_chain->parent = ldns_dnssec_build_data_chain(res,
00132                                                                                                         qflags,
00133                                                                                                         keys,
00134                                                                                                         my_pkt,
00135                                                                                                         NULL);
00136                         new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
00137                         ldns_pkt_free(my_pkt);
00138                         }
00139                 } else {
00140                         new_chain->parent = ldns_dnssec_build_data_chain(res,
00141                                                                                                         qflags,
00142                                                                                                         keys,
00143                                                                                                         pkt,
00144                                                                                                         NULL);
00145                         new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
00146                 }
00147                 ldns_rr_list_deep_free(keys);
00148         }
00149 }
00150 
00151 static void
00152 ldns_dnssec_build_data_chain_other(ldns_resolver *res,
00153                                             uint16_t qflags,
00154                                                 ldns_dnssec_data_chain *new_chain,
00155                                                 ldns_rdf *key_name,
00156                                                 ldns_rr_class c,
00157                                                 ldns_rr_list *dss)
00158 {
00159         /* 'self-signed', parent is a DS */
00160         
00161         /* okay, either we have other keys signing the current one,
00162          * or the current
00163          * one should have a DS record in the parent zone.
00164          * How do we find this out? Try both?
00165          *
00166          * request DNSKEYS for current zone,
00167          * add all signatures to current level
00168          */
00169         ldns_pkt *my_pkt;
00170         ldns_rr_list *signatures2;
00171         
00172         new_chain->parent_type = 1;
00173 
00174         my_pkt = ldns_resolver_query(res,
00175                                                         key_name,
00176                                                         LDNS_RR_TYPE_DS,
00177                                                         c,
00178                                                         qflags);
00179         if (my_pkt) {
00180         dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
00181                                                                         key_name,
00182                                                                         LDNS_RR_TYPE_DS,
00183                                                                         LDNS_SECTION_ANY_NOQUESTION
00184                                                                         );
00185         if (dss) {
00186                 new_chain->parent = ldns_dnssec_build_data_chain(res,
00187                                                                                                 qflags,
00188                                                                                                 dss,
00189                                                                                                 my_pkt,
00190                                                                                                 NULL);
00191                 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
00192                 ldns_rr_list_deep_free(dss);
00193         }
00194         ldns_pkt_free(my_pkt);
00195         }
00196 
00197         my_pkt = ldns_resolver_query(res,
00198                                                         key_name,
00199                                                         LDNS_RR_TYPE_DNSKEY,
00200                                                         c,
00201                                                         qflags);
00202         if (my_pkt) {
00203         signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
00204                                                                                    key_name,
00205                                                                                    LDNS_RR_TYPE_RRSIG,
00206                                                                                    LDNS_SECTION_ANSWER);
00207         if (signatures2) {
00208                 if (new_chain->signatures) {
00209                         printf("There were already sigs!\n");
00210                         ldns_rr_list_deep_free(new_chain->signatures);
00211                         printf("replacing the old sigs\n");
00212                 }
00213                 new_chain->signatures = signatures2;
00214         }
00215         ldns_pkt_free(my_pkt);
00216         }
00217 }
00218 
00219 ldns_dnssec_data_chain *
00220 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
00221                                        uint16_t qflags,
00222                                        ldns_rr *orig_rr,
00223                                        const ldns_rr_list *rrset,
00224                                        ldns_dnssec_data_chain *new_chain)
00225 {
00226         ldns_rdf *possible_parent_name;
00227         ldns_pkt *my_pkt;
00228         /* apparently we were not able to find a signing key, so
00229            we assume the chain ends here
00230         */
00231         /* try parents for auth denial of DS */
00232         if (orig_rr) {
00233                 possible_parent_name = ldns_rr_owner(orig_rr);
00234         } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
00235                 possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
00236         } else {
00237                 /* no information to go on, give up */
00238                 return new_chain;
00239         }
00240 
00241         my_pkt = ldns_resolver_query(res,
00242                       possible_parent_name,
00243                       LDNS_RR_TYPE_DS,
00244                       LDNS_RR_CLASS_IN,
00245                       qflags);
00246         if (!my_pkt) {
00247                 return new_chain;
00248         }
00249 
00250         if (ldns_pkt_ancount(my_pkt) > 0) {
00251                 /* add error, no sigs but DS in parent */
00252                 /*ldns_pkt_print(stdout, my_pkt);*/
00253                 ldns_pkt_free(my_pkt);
00254         } else {
00255                 /* are there signatures? */
00256                 new_chain->parent =  ldns_dnssec_build_data_chain(res, 
00257                                           qflags, 
00258                                           NULL,
00259                                           my_pkt,
00260                                           NULL);
00261 
00262                 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
00263                 
00264         }
00265         return new_chain;
00266 }
00267 
00268 
00269 ldns_dnssec_data_chain *
00270 ldns_dnssec_build_data_chain(ldns_resolver *res,
00271                                             uint16_t qflags,
00272                                             const ldns_rr_list *rrset,
00273                                             const ldns_pkt *pkt,
00274                                             ldns_rr *orig_rr)
00275 {
00276         ldns_rr_list *signatures = NULL;
00277         ldns_rr_list *dss = NULL;
00278         
00279         ldns_rr_list *my_rrset;
00280 
00281         ldns_pkt *my_pkt;
00282 
00283         ldns_rdf *name = NULL, *key_name = NULL;
00284         ldns_rr_type type = 0;
00285         ldns_rr_class c = 0;
00286 
00287         bool other_rrset = false;
00288         
00289         ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
00290 
00291         if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
00292                 /* hmm. no dnssec data in the packet. go up to try and deny
00293                  * DS? */
00294                 return new_chain;
00295         }
00296 
00297         if (orig_rr) {
00298                 new_chain->rrset = ldns_rr_list_new();
00299                 ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
00300                 new_chain->parent = ldns_dnssec_build_data_chain(res,
00301                                                                                             qflags,
00302                                                                                             rrset,
00303                                                                                             pkt,
00304                                                                                             NULL);
00305                 new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
00306                 new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
00307                 if (ldns_pkt_ancount(pkt) == 0) {
00308                         new_chain->packet_nodata = true;
00309                 }
00310                 return new_chain;
00311         }
00312         
00313         if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
00314                 /* hmm, no data, do we have denial? only works if pkt was given,
00315                    otherwise caller has to do the check himself */
00316                 new_chain->packet_nodata = true;
00317                 if (pkt) {
00318                         my_rrset = ldns_pkt_rr_list_by_type(pkt,
00319                                                                                  LDNS_RR_TYPE_NSEC,
00320                                                                                  LDNS_SECTION_ANY_NOQUESTION
00321                                                                                  );
00322                         if (my_rrset) {
00323                                 if (ldns_rr_list_rr_count(my_rrset) > 0) {
00324                                         type = LDNS_RR_TYPE_NSEC;
00325                                         other_rrset = true;
00326                                 } else {
00327                                         ldns_rr_list_deep_free(my_rrset);
00328                                         my_rrset = NULL;
00329                                 }
00330                         } else {
00331                                 /* nothing, try nsec3 */
00332                                 my_rrset = ldns_pkt_rr_list_by_type(pkt,
00333                                                      LDNS_RR_TYPE_NSEC3,
00334                                                         LDNS_SECTION_ANY_NOQUESTION);
00335                                 if (my_rrset) {
00336                                         if (ldns_rr_list_rr_count(my_rrset) > 0) {
00337                                                 type = LDNS_RR_TYPE_NSEC3;
00338                                                 other_rrset = true;
00339                                         } else {
00340                                                 ldns_rr_list_deep_free(my_rrset);
00341                                                 my_rrset = NULL;
00342                                         }
00343                                 } else {
00344                                         /* nothing, stop */
00345                                         /* try parent zone? for denied insecure? */
00346                                         return new_chain;
00347                                 }
00348                         }
00349                 } else {
00350                         return new_chain;
00351                 }
00352         } else {
00353                 my_rrset = (ldns_rr_list *) rrset;
00354         }
00355         
00356         if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
00357                 new_chain->rrset = ldns_rr_list_clone(my_rrset);
00358                 name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
00359                 type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
00360                 c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
00361         }
00362         
00363         if (other_rrset) {
00364                 ldns_rr_list_deep_free(my_rrset);
00365         }
00366         
00367         /* normally there will only be 1 signature 'set'
00368            but there can be more than 1 denial (wildcards)
00369            so check for NSEC
00370         */
00371         if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
00372                 /* just throw in all signatures, the tree builder must sort
00373                    this out */
00374                 if (pkt) {
00375                         signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
00376                 } else {
00377                         my_pkt = ldns_resolver_query(res, name, type, c, qflags);
00378                         if (my_pkt) {
00379                         signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
00380                         ldns_pkt_free(my_pkt);
00381                         }
00382                 }
00383         } else {
00384                 if (pkt) {
00385                         signatures =
00386                                 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
00387                                                                                                         name,
00388                                                                                                         type);
00389                 }
00390                 if (!signatures) {
00391                         my_pkt = ldns_resolver_query(res, name, type, c, qflags);
00392                         if (my_pkt) {
00393                         signatures =
00394                                 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
00395                                                                                                         name,
00396                                                                                                         type);
00397                         ldns_pkt_free(my_pkt);
00398                         }
00399                 }
00400         }
00401 
00402         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
00403                 key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
00404         }
00405 
00406         if (!key_name) {
00407                 return ldns_dnssec_build_data_chain_nokeyname(res,
00408                                                               qflags,
00409                                                               orig_rr,
00410                                                               rrset,
00411                                                               new_chain);
00412         }
00413 
00414         if (type != LDNS_RR_TYPE_DNSKEY) {
00415                 ldns_dnssec_build_data_chain_dnskey(res,
00416                                                     qflags,
00417                                                     pkt,
00418                                                     signatures,
00419                                                     new_chain,
00420                                                     key_name,
00421                                                     c
00422                                                     );
00423         } else {
00424                 ldns_dnssec_build_data_chain_other(res,
00425                                                    qflags,
00426                                                    new_chain,
00427                                                    key_name,
00428                                                    c,
00429                                                    dss
00430                                                     
00431                                                     );
00432         }
00433         if (signatures) {
00434                 ldns_rr_list_deep_free(signatures);
00435         }
00436 
00437         return new_chain;
00438 }
00439 
00440 ldns_dnssec_trust_tree *
00441 ldns_dnssec_trust_tree_new()
00442 {
00443         ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
00444                                                                                    1);
00445         if(!new_tree) return NULL;
00446         new_tree->rr = NULL;
00447         new_tree->rrset = NULL;
00448         new_tree->parent_count = 0;
00449 
00450         return new_tree;
00451 }
00452 
00453 void
00454 ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
00455 {
00456         size_t i;
00457         if (tree) {
00458                 for (i = 0; i < tree->parent_count; i++) {
00459                         ldns_dnssec_trust_tree_free(tree->parents[i]);
00460                 }
00461         }
00462         LDNS_FREE(tree);
00463 }
00464 
00465 size_t
00466 ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
00467 {
00468         size_t result = 0;
00469         size_t parent = 0;
00470         size_t i;
00471         
00472         for (i = 0; i < tree->parent_count; i++) {
00473                 parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
00474                 if (parent > result) {
00475                         result = parent;
00476                 }
00477         }
00478         return 1 + result;
00479 }
00480 
00481 /* TODO ldns_ */
00482 static void
00483 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
00484 {
00485         size_t i;
00486         for (i = 0; i < nr; i++) {
00487                 if (i == nr - 1) {
00488                         fprintf(out, "|---");
00489                 } else if (map && i < treedepth && map[i] == 1) {
00490                         fprintf(out, "|   ");
00491                 } else {
00492                         fprintf(out, "    ");
00493                 }
00494         }
00495 }
00496 
00497 void
00498 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
00499                 const ldns_output_format *fmt,
00500                 ldns_dnssec_trust_tree *tree,
00501                 size_t tabs,
00502                 bool extended,
00503                 uint8_t *sibmap,
00504                 size_t treedepth)
00505 {
00506         size_t i;
00507         const ldns_rr_descriptor *descriptor;
00508         bool mapset = false;
00509         
00510         if (!sibmap) {
00511                 treedepth = ldns_dnssec_trust_tree_depth(tree);
00512                 sibmap = LDNS_XMALLOC(uint8_t, treedepth);
00513                 if(!sibmap)
00514                         return; /* mem err */
00515                 memset(sibmap, 0, treedepth);
00516                 mapset = true;
00517         }
00518         
00519         if (tree) {
00520                 if (tree->rr) {
00521                         print_tabs(out, tabs, sibmap, treedepth);
00522                         ldns_rdf_print(out, ldns_rr_owner(tree->rr));
00523                         descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
00524 
00525                         if (descriptor->_name) {
00526                                 fprintf(out, " (%s", descriptor->_name);
00527                         } else {
00528                                 fprintf(out, " (TYPE%d", 
00529                                            ldns_rr_get_type(tree->rr));
00530                         }
00531                         if (tabs > 0) {
00532                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
00533                                         fprintf(out, " keytag: %u",
00534                                                 (unsigned int) ldns_calc_keytag(tree->rr));
00535                                         fprintf(out, " alg: ");
00536                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
00537                                         fprintf(out, " flags: ");
00538                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
00539                                 } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
00540                                         fprintf(out, " keytag: ");
00541                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
00542                                         fprintf(out, " digest type: ");
00543                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
00544                                 }
00545                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
00546                                         fprintf(out, " ");
00547                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
00548                                         fprintf(out, " ");
00549                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
00550                                 }
00551                         }
00552                         
00553                         fprintf(out, ")\n");
00554                         for (i = 0; i < tree->parent_count; i++) {
00555                                 if (tree->parent_count > 1 && i < tree->parent_count - 1) {
00556                                         sibmap[tabs] = 1;
00557                                 } else {
00558                                         sibmap[tabs] = 0;
00559                                 }
00560                                 /* only print errors */
00561                                 if (ldns_rr_get_type(tree->parents[i]->rr) == 
00562                                     LDNS_RR_TYPE_NSEC ||
00563                                     ldns_rr_get_type(tree->parents[i]->rr) ==
00564                                     LDNS_RR_TYPE_NSEC3) {
00565                                         if (tree->parent_status[i] == LDNS_STATUS_OK) {
00566                                                 print_tabs(out, tabs + 1, sibmap, treedepth);
00567                                                 if (tabs == 0 &&
00568                                                     ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
00569                                                         ldns_rr_rd_count(tree->rr) > 0) {
00570                                                         fprintf(out, "Existence of DS is denied by:\n");
00571                                                 } else {
00572                                                         fprintf(out, "Existence is denied by:\n");
00573                                                 }
00574                                         } else {
00575                                                 /* NS records aren't signed */
00576                                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
00577                                                         fprintf(out, "Existence of DS is denied by:\n");
00578                                                 } else {
00579                                                         print_tabs(out, tabs + 1, sibmap, treedepth);
00580                                                         fprintf(out,
00581                                                                    "Error in denial of existence: %s\n",
00582                                                                    ldns_get_errorstr_by_id(
00583                                                                            tree->parent_status[i]));
00584                                                 }
00585                                         }
00586                                 } else
00587                                         if (tree->parent_status[i] != LDNS_STATUS_OK) {
00588                                                 print_tabs(out, tabs + 1, sibmap, treedepth);
00589                                                 fprintf(out,
00590                                                            "%s:\n",
00591                                                            ldns_get_errorstr_by_id(
00592                                                                tree->parent_status[i]));
00593                                                 if (tree->parent_status[i]
00594                                                     == LDNS_STATUS_SSL_ERR) {
00595                                                         printf("; SSL Error: ");
00596                                                         ERR_load_crypto_strings();
00597                                                         ERR_print_errors_fp(stdout);
00598                                                         printf("\n");
00599                                                 }
00600                                                 ldns_rr_print_fmt(out, fmt, 
00601                                                         tree->
00602                                                         parent_signature[i]);
00603                                                 printf("For RRset:\n");
00604                                                 ldns_rr_list_print_fmt(out, fmt,
00605                                                                 tree->rrset);
00606                                                 printf("With key:\n");
00607                                                 ldns_rr_print_fmt(out, fmt,
00608                                                         tree->parents[i]->rr);
00609                                         }
00610                                 ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
00611                                                 tree->parents[i],
00612                                                 tabs+1,
00613                                                 extended,
00614                                                 sibmap,
00615                                                 treedepth);
00616                         }
00617                 } else {
00618                         print_tabs(out, tabs, sibmap, treedepth);
00619                         fprintf(out, "<no data>\n");
00620                 }
00621         } else {
00622                 fprintf(out, "<null pointer>\n");
00623         }
00624         
00625         if (mapset) {
00626                 LDNS_FREE(sibmap);
00627         }
00628 }
00629 
00630 void
00631 ldns_dnssec_trust_tree_print_sm(FILE *out, 
00632                 ldns_dnssec_trust_tree *tree,
00633                 size_t tabs,
00634                 bool extended,
00635                 uint8_t *sibmap,
00636                 size_t treedepth)
00637 {
00638         ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default, 
00639                         tree, tabs, extended, sibmap, treedepth);
00640 }
00641 
00642 void
00643 ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
00644                 ldns_dnssec_trust_tree *tree,
00645                 size_t tabs,
00646                 bool extended)
00647 {
00648         ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 
00649                         tree, tabs, extended, NULL, 0);
00650 }
00651 
00652 void
00653 ldns_dnssec_trust_tree_print(FILE *out,
00654                 ldns_dnssec_trust_tree *tree,
00655                 size_t tabs,
00656                 bool extended)
00657 {
00658         ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default, 
00659                         tree, tabs, extended);
00660 }
00661 
00662 
00663 ldns_status
00664 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
00665                                   const ldns_dnssec_trust_tree *parent,
00666                                   const ldns_rr *signature,
00667                                   const ldns_status parent_status)
00668 {
00669         if (tree
00670             && parent
00671             && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
00672                 /*
00673                   printf("Add parent for: ");
00674                   ldns_rr_print(stdout, tree->rr);
00675                   printf("parent: ");
00676                   ldns_rr_print(stdout, parent->rr);
00677                 */
00678                 tree->parents[tree->parent_count] =
00679                         (ldns_dnssec_trust_tree *) parent;
00680                 tree->parent_status[tree->parent_count] = parent_status;
00681                 tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
00682                 tree->parent_count++;
00683                 return LDNS_STATUS_OK;
00684         } else {
00685                 return LDNS_STATUS_ERR;
00686         }
00687 }
00688 
00689 /* if rr is null, take the first from the rrset */
00690 ldns_dnssec_trust_tree *
00691 ldns_dnssec_derive_trust_tree_time(
00692                 ldns_dnssec_data_chain *data_chain, 
00693                 ldns_rr *rr, 
00694                 time_t check_time
00695                 )
00696 {
00697         ldns_rr_list *cur_rrset;
00698         ldns_rr_list *cur_sigs;
00699         ldns_rr *cur_rr = NULL;
00700         ldns_rr *cur_sig_rr;
00701         size_t i, j;
00702 
00703         ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
00704         if(!new_tree)
00705                 return NULL;
00706         
00707         if (data_chain && data_chain->rrset) {
00708                 cur_rrset = data_chain->rrset;
00709         
00710                 cur_sigs = data_chain->signatures;
00711 
00712                 if (rr) {
00713                         cur_rr = rr;
00714                 }
00715 
00716                 if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
00717                         cur_rr = ldns_rr_list_rr(cur_rrset, 0);
00718                 }
00719 
00720                 if (cur_rr) {
00721                         new_tree->rr = cur_rr;
00722                         new_tree->rrset = cur_rrset;
00723                         /* there are three possibilities:
00724                            1 - 'normal' rrset, signed by a key
00725                            2 - dnskey signed by other dnskey
00726                            3 - dnskey proven by higher level DS
00727                            (data denied by nsec is a special case that can
00728                            occur in multiple places)
00729                                    
00730                         */
00731                         if (cur_sigs) {
00732                                 for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
00733                                         /* find the appropriate key in the parent list */
00734                                         cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
00735 
00736                                         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
00737                                                 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
00738                                                                                    ldns_rr_owner(cur_rr)))
00739                                                         {
00740                                                                 /* find first that does match */
00741 
00742                                                                 for (j = 0;
00743                                                                      j < ldns_rr_list_rr_count(cur_rrset) && 
00744                                                                                 ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
00745                                                                      j++) {
00746                                                                         cur_rr = ldns_rr_list_rr(cur_rrset, j);
00747                                                                         
00748                                                                 }
00749                                                                 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 
00750                                                                                                    ldns_rr_owner(cur_rr)))
00751                                                                         {
00752                                                                                 break;
00753                                                                         }
00754                                                         }
00755                                                         
00756                                         }
00757                                         /* option 1 */
00758                                         if (data_chain->parent) {
00759                                                 ldns_dnssec_derive_trust_tree_normal_rrset_time(
00760                                                     new_tree,
00761                                                     data_chain,
00762                                                     cur_sig_rr,
00763                                                     check_time);
00764                                         }
00765 
00766                                         /* option 2 */
00767                                         ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
00768                                             new_tree,
00769                                             data_chain,
00770                                             cur_rr,
00771                                             cur_sig_rr,
00772                                             check_time);
00773                                 }
00774                                         
00775                                 ldns_dnssec_derive_trust_tree_ds_rrset_time(
00776                                                 new_tree, data_chain, 
00777                                                 cur_rr, check_time);
00778                         } else {
00779                                 /* no signatures? maybe it's nsec data */
00780                                         
00781                                 /* just add every rr from parent as new parent */
00782                                 ldns_dnssec_derive_trust_tree_no_sig_time(
00783                                         new_tree, data_chain, check_time);
00784                         }
00785                 }
00786         }
00787 
00788         return new_tree;
00789 }
00790 
00791 ldns_dnssec_trust_tree *
00792 ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
00793 {
00794         return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
00795 }
00796 
00797 void
00798 ldns_dnssec_derive_trust_tree_normal_rrset_time(
00799                 ldns_dnssec_trust_tree *new_tree, 
00800                 ldns_dnssec_data_chain *data_chain, 
00801                 ldns_rr *cur_sig_rr,
00802                 time_t check_time)
00803 {
00804         size_t i, j;
00805         ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset); 
00806         ldns_dnssec_trust_tree *cur_parent_tree;
00807         ldns_rr *cur_parent_rr;
00808         uint16_t cur_keytag;
00809         ldns_rr_list *tmp_rrset = NULL;
00810         ldns_status cur_status;
00811 
00812         cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
00813         
00814         for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
00815                 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
00816                 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
00817                         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
00818 
00819                                 /* TODO: check wildcard nsec too */
00820                                 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
00821                                         tmp_rrset = cur_rrset;
00822                                         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
00823                                             == LDNS_RR_TYPE_NSEC ||
00824                                             ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
00825                                             == LDNS_RR_TYPE_NSEC3) {
00826                                                 /* might contain different names! 
00827                                                    sort and split */
00828                                                 ldns_rr_list_sort(cur_rrset);
00829                                                 if (tmp_rrset && tmp_rrset != cur_rrset) {
00830                                                         ldns_rr_list_deep_free(tmp_rrset);
00831                                                         tmp_rrset = NULL;
00832                                                 }
00833                                                 tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
00834                                                 
00835                                                 /* with nsecs, this might be the wrong one */
00836                                                 while (tmp_rrset &&
00837                                                        ldns_rr_list_rr_count(cur_rrset) > 0 &&
00838                                                        ldns_dname_compare(
00839                                                                 ldns_rr_owner(ldns_rr_list_rr(
00840                                                                                         tmp_rrset, 0)),
00841                                                                 ldns_rr_owner(cur_sig_rr)) != 0) {
00842                                                         ldns_rr_list_deep_free(tmp_rrset);
00843                                                         tmp_rrset =
00844                                                                 ldns_rr_list_pop_rrset(cur_rrset);
00845                                                 }
00846                                         }
00847                                         cur_status = ldns_verify_rrsig_time(
00848                                                         tmp_rrset, 
00849                                                         cur_sig_rr, 
00850                                                         cur_parent_rr,
00851                                                         check_time);
00852                                         /* avoid dupes */
00853                                         for (i = 0; i < new_tree->parent_count; i++) {
00854                                                 if (cur_parent_rr == new_tree->parents[i]->rr) {
00855                                                         goto done;
00856                                                 }
00857                                         }
00858 
00859                                         cur_parent_tree =
00860                                                 ldns_dnssec_derive_trust_tree_time(
00861                                                                 data_chain->parent,
00862                                                                 cur_parent_rr,
00863                                                                 check_time);
00864                                         (void)ldns_dnssec_trust_tree_add_parent(new_tree,
00865                                                    cur_parent_tree,
00866                                                    cur_sig_rr,
00867                                                    cur_status);
00868                                 }
00869                         }
00870                 }
00871         }
00872  done:
00873         if (tmp_rrset && tmp_rrset != cur_rrset) {
00874                 ldns_rr_list_deep_free(tmp_rrset);
00875         }
00876         ldns_rr_list_deep_free(cur_rrset);
00877 }
00878 
00879 void
00880 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
00881                                            ldns_dnssec_data_chain *data_chain,
00882                                            ldns_rr *cur_sig_rr)
00883 {
00884         ldns_dnssec_derive_trust_tree_normal_rrset_time(
00885                         new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
00886 }
00887 
00888 void
00889 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
00890                 ldns_dnssec_trust_tree *new_tree, 
00891                 ldns_dnssec_data_chain *data_chain, 
00892                 ldns_rr *cur_rr, 
00893                 ldns_rr *cur_sig_rr,
00894                 time_t check_time)
00895 {
00896         size_t j;
00897         ldns_rr_list *cur_rrset = data_chain->rrset;
00898         ldns_dnssec_trust_tree *cur_parent_tree;
00899         ldns_rr *cur_parent_rr;
00900         uint16_t cur_keytag;
00901         ldns_status cur_status;
00902 
00903         cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
00904 
00905         for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
00906                 cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
00907                 if (cur_parent_rr != cur_rr &&
00908                     ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
00909                         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
00910                             ) {
00911                                 cur_parent_tree = ldns_dnssec_trust_tree_new();
00912                                 cur_parent_tree->rr = cur_parent_rr;
00913                                 cur_parent_tree->rrset = cur_rrset;
00914                                 cur_status = ldns_verify_rrsig_time(
00915                                                 cur_rrset, cur_sig_rr, 
00916                                                 cur_parent_rr, check_time);
00917                                 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
00918                                             cur_parent_tree, cur_sig_rr, cur_status);
00919                         }
00920                 }
00921         }
00922 }
00923 
00924 void
00925 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
00926                                            ldns_dnssec_data_chain *data_chain,
00927                                            ldns_rr *cur_rr,
00928                                            ldns_rr *cur_sig_rr)
00929 {
00930         ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
00931                         new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
00932 }
00933 
00934 void
00935 ldns_dnssec_derive_trust_tree_ds_rrset_time(
00936                 ldns_dnssec_trust_tree *new_tree,
00937                 ldns_dnssec_data_chain *data_chain, 
00938                 ldns_rr *cur_rr,
00939                 time_t check_time)
00940 {
00941         size_t j, h;
00942         ldns_rr_list *cur_rrset = data_chain->rrset;
00943         ldns_dnssec_trust_tree *cur_parent_tree;
00944         ldns_rr *cur_parent_rr;
00945 
00946         /* try the parent to see whether there are DSs there */
00947         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
00948             data_chain->parent &&
00949             data_chain->parent->rrset
00950             ) {
00951                 for (j = 0;
00952                         j < ldns_rr_list_rr_count(data_chain->parent->rrset);
00953                         j++) {
00954                         cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
00955                         if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
00956                                 for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
00957                                         cur_rr = ldns_rr_list_rr(cur_rrset, h);
00958                                         if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
00959                                                 cur_parent_tree =
00960                                                         ldns_dnssec_derive_trust_tree_time(
00961                                                             data_chain->parent, 
00962                                                             cur_parent_rr,
00963                                                             check_time);
00964                                                 (void) ldns_dnssec_trust_tree_add_parent(
00965                                                             new_tree,
00966                                                             cur_parent_tree,
00967                                                             NULL,
00968                                                             LDNS_STATUS_OK);
00969                                         } else {
00970                                                 /*ldns_rr_print(stdout, cur_parent_rr);*/
00971                                         }
00972                                 }
00973                         }
00974                 }
00975         }
00976 }
00977 
00978 void
00979 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
00980                                        ldns_dnssec_data_chain *data_chain,
00981                                        ldns_rr *cur_rr)
00982 {
00983         ldns_dnssec_derive_trust_tree_ds_rrset_time(
00984                         new_tree, data_chain, cur_rr, ldns_time(NULL));
00985 }
00986 
00987 void
00988 ldns_dnssec_derive_trust_tree_no_sig_time(
00989                 ldns_dnssec_trust_tree *new_tree, 
00990                 ldns_dnssec_data_chain *data_chain,
00991                 time_t check_time)
00992 {
00993         size_t i;
00994         ldns_rr_list *cur_rrset;
00995         ldns_rr *cur_parent_rr;
00996         ldns_dnssec_trust_tree *cur_parent_tree;
00997         ldns_status result;
00998         
00999         if (data_chain->parent && data_chain->parent->rrset) {
01000                 cur_rrset = data_chain->parent->rrset;
01001                 /* nsec? */
01002                 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
01003                         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
01004                             LDNS_RR_TYPE_NSEC3) {
01005                                 result = ldns_dnssec_verify_denial_nsec3(
01006                                                 new_tree->rr,
01007                                                    cur_rrset,
01008                                                    data_chain->parent->signatures,
01009                                                    data_chain->packet_rcode,
01010                                                    data_chain->packet_qtype,
01011                                                    data_chain->packet_nodata);
01012                         } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
01013                                          LDNS_RR_TYPE_NSEC) {
01014                                 result = ldns_dnssec_verify_denial(
01015                                                 new_tree->rr,
01016                                                    cur_rrset,
01017                                                    data_chain->parent->signatures);
01018                         } else {
01019                                 /* unsigned zone, unsigned parent */
01020                                 result = LDNS_STATUS_OK;
01021                         }
01022                 } else {
01023                         result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01024                 }
01025                 for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
01026                         cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
01027                         cur_parent_tree = 
01028                                 ldns_dnssec_derive_trust_tree_time(
01029                                                 data_chain->parent, 
01030                                                 cur_parent_rr,
01031                                                 check_time);
01032                         (void) ldns_dnssec_trust_tree_add_parent(new_tree,
01033                                     cur_parent_tree, NULL, result);
01034                 }
01035         }
01036 }
01037 
01038 void
01039 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
01040                                      ldns_dnssec_data_chain *data_chain)
01041 {
01042         ldns_dnssec_derive_trust_tree_no_sig_time(
01043                         new_tree, data_chain, ldns_time(NULL));
01044 }
01045 
01046 /*
01047  * returns OK if there is a path from tree to key with only OK
01048  * the (first) error in between otherwise
01049  * or NOT_FOUND if the key wasn't present at all
01050  */
01051 ldns_status
01052 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
01053                                                           ldns_rr_list *trusted_keys)
01054 {
01055         size_t i;
01056         ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
01057         bool equal;
01058         ldns_status parent_result;
01059         
01060         if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
01061                 { if (tree->rr) {
01062                                 for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
01063                                         equal = ldns_rr_compare_ds(
01064                                                           tree->rr,
01065                                                           ldns_rr_list_rr(trusted_keys, i));
01066                                         if (equal) {
01067                                                 result = LDNS_STATUS_OK;
01068                                                 return result;
01069                                         }
01070                                 }
01071                         }
01072                         for (i = 0; i < tree->parent_count; i++) {
01073                                 parent_result =
01074                                         ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
01075                                                                                                   trusted_keys);
01076                                 if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
01077                                         if (tree->parent_status[i] != LDNS_STATUS_OK) {
01078                                                 result = tree->parent_status[i];
01079                                         } else {
01080                                                 if (ldns_rr_get_type(tree->rr)
01081                                                     == LDNS_RR_TYPE_NSEC &&
01082                                                     parent_result == LDNS_STATUS_OK
01083                                                     ) {
01084                                                         result =
01085                                                                 LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
01086                                                 } else {
01087                                                         result = parent_result;
01088                                                 }
01089                                         }
01090                                 }
01091                         }
01092                 } else {
01093                 result = LDNS_STATUS_ERR;
01094         }
01095         
01096         return result;
01097 }
01098 
01099 ldns_status
01100 ldns_verify_time(
01101                 ldns_rr_list *rrset,
01102                 ldns_rr_list *rrsig, 
01103                 const ldns_rr_list *keys, 
01104                 time_t check_time,
01105                 ldns_rr_list *good_keys
01106                 )
01107 {
01108         uint16_t i;
01109         ldns_status verify_result = LDNS_STATUS_ERR;
01110 
01111         if (!rrset || !rrsig || !keys) {
01112                 return LDNS_STATUS_ERR;
01113         }
01114 
01115         if (ldns_rr_list_rr_count(rrset) < 1) {
01116                 return LDNS_STATUS_ERR;
01117         }
01118 
01119         if (ldns_rr_list_rr_count(rrsig) < 1) {
01120                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
01121         }
01122         
01123         if (ldns_rr_list_rr_count(keys) < 1) {
01124                 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
01125         } else {
01126                 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
01127                         ldns_status s = ldns_verify_rrsig_keylist_time(
01128                                         rrset, ldns_rr_list_rr(rrsig, i), 
01129                                         keys, check_time, good_keys);
01130                         /* try a little to get more descriptive error */
01131                         if(s == LDNS_STATUS_OK) {
01132                                 verify_result = LDNS_STATUS_OK;
01133                         } else if(verify_result == LDNS_STATUS_ERR)
01134                                 verify_result = s;
01135                         else if(s !=  LDNS_STATUS_ERR && verify_result ==
01136                                 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
01137                                 verify_result = s;
01138                 }
01139         }
01140         return verify_result;
01141 }
01142 
01143 ldns_status
01144 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, 
01145                   ldns_rr_list *good_keys)
01146 {
01147         return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
01148 }
01149 
01150 ldns_status
01151 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
01152         const ldns_rr_list *keys, ldns_rr_list *good_keys)
01153 {
01154         uint16_t i;
01155         ldns_status verify_result = LDNS_STATUS_ERR;
01156 
01157         if (!rrset || !rrsig || !keys) {
01158                 return LDNS_STATUS_ERR;
01159         }
01160 
01161         if (ldns_rr_list_rr_count(rrset) < 1) {
01162                 return LDNS_STATUS_ERR;
01163         }
01164 
01165         if (ldns_rr_list_rr_count(rrsig) < 1) {
01166                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
01167         }
01168 
01169         if (ldns_rr_list_rr_count(keys) < 1) {
01170                 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
01171         } else {
01172                 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
01173                         ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
01174                                 ldns_rr_list_rr(rrsig, i), keys, good_keys);
01175 
01176                         /* try a little to get more descriptive error */
01177                         if (s == LDNS_STATUS_OK) {
01178                                 verify_result = LDNS_STATUS_OK;
01179                         } else if (verify_result == LDNS_STATUS_ERR) {
01180                                 verify_result = s;
01181                         } else if (s !=  LDNS_STATUS_ERR && verify_result ==
01182                                 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
01183                                 verify_result = s;
01184                         }
01185                 }
01186         }
01187         return verify_result;
01188 }
01189 
01190 ldns_rr_list *
01191 ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
01192                              const ldns_rdf *domain,
01193                              const ldns_rr_list *keys,
01194                              time_t check_time,
01195                              ldns_status *status)
01196 {
01197         ldns_rr_list * trusted_keys = NULL;
01198         ldns_rr_list * ds_keys = NULL;
01199         ldns_rdf * prev_parent_domain;
01200         ldns_rdf *      parent_domain;
01201         ldns_rr_list * parent_keys = NULL;
01202 
01203         if (res && domain && keys) {
01204 
01205                 if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
01206                                          domain, keys, check_time))) {
01207                         *status = LDNS_STATUS_OK;
01208                 } else {
01209                         /* No trusted keys in this domain, we'll have to find some in the parent domain */
01210                         *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
01211 
01212                         parent_domain = ldns_dname_left_chop(domain);
01213                         while (ldns_rdf_size(parent_domain) > 0) {
01214                                 /* Fail if we are at the root */
01215         
01216                                 if ((parent_keys = 
01217                                         ldns_fetch_valid_domain_keys_time(res,
01218                                              parent_domain,
01219                                              keys,
01220                                              check_time,
01221                                              status))) {
01222                                         /* Check DS records */
01223                                         if ((ds_keys =
01224                                                 ldns_validate_domain_ds_time(res,
01225                                                      domain,
01226                                                      parent_keys,
01227                                                      check_time))) {
01228                                                 trusted_keys =
01229                                                 ldns_fetch_valid_domain_keys_time(
01230                                                                 res, 
01231                                                                 domain, 
01232                                                                 ds_keys, 
01233                                                                 check_time,
01234                                                                 status);
01235                                                 ldns_rr_list_deep_free(ds_keys);
01236                                         } else {
01237                                                 /* No valid DS at the parent -- fail */
01238                                                 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
01239                                         }
01240                                         ldns_rr_list_deep_free(parent_keys);
01241                                         break;
01242                                 } else {
01243                                         parent_domain = ldns_dname_left_chop((
01244                                                 prev_parent_domain 
01245                                                         = parent_domain
01246                                                 ));
01247                                         ldns_rdf_deep_free(prev_parent_domain);
01248                                 }
01249                         }
01250                         ldns_rdf_deep_free(parent_domain);
01251                 }
01252         }
01253         return trusted_keys;
01254 }
01255 
01256 ldns_rr_list *
01257 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
01258                              const ldns_rdf *domain,
01259                              const ldns_rr_list *keys,
01260                              ldns_status *status)
01261 {
01262         return ldns_fetch_valid_domain_keys_time(
01263                         res, domain, keys, ldns_time(NULL), status);
01264 }
01265 
01266 ldns_rr_list *
01267 ldns_validate_domain_dnskey_time(
01268                 const ldns_resolver * res,
01269                 const ldns_rdf * domain,
01270                 const ldns_rr_list * keys,
01271                 time_t check_time
01272                 )
01273 {
01274         ldns_pkt * keypkt;
01275         ldns_rr * cur_key;
01276         uint16_t key_i; uint16_t key_j; uint16_t key_k;
01277         uint16_t sig_i; ldns_rr * cur_sig;
01278 
01279         ldns_rr_list * domain_keys = NULL;
01280         ldns_rr_list * domain_sigs = NULL;
01281         ldns_rr_list * trusted_keys = NULL;
01282 
01283         /* Fetch keys for the domain */
01284         keypkt = ldns_resolver_query(res, domain,
01285                 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
01286         if (keypkt) {
01287                 domain_keys = ldns_pkt_rr_list_by_type(keypkt,
01288                                                                             LDNS_RR_TYPE_DNSKEY,
01289                                                                             LDNS_SECTION_ANSWER);
01290                 domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
01291                                                                             LDNS_RR_TYPE_RRSIG,
01292                                                                             LDNS_SECTION_ANSWER);
01293 
01294                 /* Try to validate the record using our keys */
01295                 for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
01296       
01297                         cur_key = ldns_rr_list_rr(domain_keys, key_i);
01298                         for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
01299                                 if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
01300                                                                    cur_key)) {
01301           
01302                                         /* Current key is trusted -- validate */
01303                                         trusted_keys = ldns_rr_list_new();
01304           
01305                                         for (sig_i=0;
01306                                                 sig_i<ldns_rr_list_rr_count(domain_sigs);
01307                                                 sig_i++) {
01308                                                 cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
01309                                                 /* Avoid non-matching sigs */
01310                                                 if (ldns_rdf2native_int16(
01311                                                            ldns_rr_rrsig_keytag(cur_sig))
01312                                                     == ldns_calc_keytag(cur_key)) {
01313                                                         if (ldns_verify_rrsig_time(
01314                                                                         domain_keys,
01315                                                                         cur_sig,
01316                                                                         cur_key,
01317                                                                         check_time)
01318                                                             == LDNS_STATUS_OK) {
01319                 
01320                                                                 /* Push the whole rrset 
01321                                                                    -- we can't do much more */
01322                                                                 for (key_k=0;
01323                                                                         key_k<ldns_rr_list_rr_count(
01324                                                                                         domain_keys);
01325                                                                         key_k++) {
01326                                                                         ldns_rr_list_push_rr(
01327                                                                             trusted_keys,
01328                                                                             ldns_rr_clone(
01329                                                                                    ldns_rr_list_rr(
01330                                                                                           domain_keys,
01331                                                                                           key_k)));
01332                                                                 }
01333                 
01334                                                                 ldns_rr_list_deep_free(domain_keys);
01335                                                                 ldns_rr_list_deep_free(domain_sigs);
01336                                                                 ldns_pkt_free(keypkt);
01337                                                                 return trusted_keys;
01338                                                         }
01339                                                 }
01340                                         }
01341           
01342                                         /* Only push our trusted key */
01343                                         ldns_rr_list_push_rr(trusted_keys,
01344                                                                          ldns_rr_clone(cur_key));
01345                                 }
01346                         }
01347                 }
01348 
01349                 ldns_rr_list_deep_free(domain_keys);
01350                 ldns_rr_list_deep_free(domain_sigs);
01351                 ldns_pkt_free(keypkt);
01352 
01353         } else {
01354                 /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
01355         }
01356     
01357         return trusted_keys;
01358 }
01359 
01360 ldns_rr_list *
01361 ldns_validate_domain_dnskey(const ldns_resolver * res,
01362                                            const ldns_rdf * domain,
01363                                            const ldns_rr_list * keys)
01364 {
01365         return ldns_validate_domain_dnskey_time(
01366                         res, domain, keys, ldns_time(NULL));
01367 }
01368 
01369 ldns_rr_list *
01370 ldns_validate_domain_ds_time(
01371                 const ldns_resolver *res, 
01372                 const ldns_rdf * domain,
01373                 const ldns_rr_list * keys,
01374                 time_t check_time)
01375 {
01376         ldns_pkt * dspkt;
01377         uint16_t key_i;
01378         ldns_rr_list * rrset = NULL;
01379         ldns_rr_list * sigs = NULL;
01380         ldns_rr_list * trusted_keys = NULL;
01381 
01382         /* Fetch DS for the domain */
01383         dspkt = ldns_resolver_query(res, domain,
01384                 LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
01385         if (dspkt) {
01386                 rrset = ldns_pkt_rr_list_by_type(dspkt,
01387                                                                    LDNS_RR_TYPE_DS,
01388                                                                    LDNS_SECTION_ANSWER);
01389                 sigs = ldns_pkt_rr_list_by_type(dspkt,
01390                                                                   LDNS_RR_TYPE_RRSIG,
01391                                                                   LDNS_SECTION_ANSWER);
01392 
01393                 /* Validate sigs */
01394                 if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
01395                                 == LDNS_STATUS_OK) {
01396                         trusted_keys = ldns_rr_list_new();
01397                         for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
01398                                 ldns_rr_list_push_rr(trusted_keys,
01399                                                                  ldns_rr_clone(ldns_rr_list_rr(rrset,
01400                                                                                                                  key_i)
01401                                                                                         )
01402                                                                  );
01403                         }
01404                 }
01405 
01406                 ldns_rr_list_deep_free(rrset);
01407                 ldns_rr_list_deep_free(sigs);
01408                 ldns_pkt_free(dspkt);
01409 
01410         } else {
01411                 /* LDNS_STATUS_CRYPTO_NO_DS */
01412         }
01413 
01414         return trusted_keys;
01415 }
01416 
01417 ldns_rr_list *
01418 ldns_validate_domain_ds(const ldns_resolver *res,
01419                                     const ldns_rdf * domain,
01420                                     const ldns_rr_list * keys)
01421 {
01422         return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
01423 }
01424 
01425 ldns_status
01426 ldns_verify_trusted_time(
01427                 ldns_resolver *res, 
01428                 ldns_rr_list *rrset, 
01429                 ldns_rr_list * rrsigs, 
01430                 time_t check_time,
01431                 ldns_rr_list * validating_keys
01432                 )
01433 {
01434         uint16_t sig_i; uint16_t key_i;
01435         ldns_rr * cur_sig; ldns_rr * cur_key;
01436         ldns_rr_list * trusted_keys = NULL;
01437         ldns_status result = LDNS_STATUS_ERR;
01438 
01439         if (!res || !rrset || !rrsigs) {
01440                 return LDNS_STATUS_ERR;
01441         }
01442 
01443         if (ldns_rr_list_rr_count(rrset) < 1) {
01444                 return LDNS_STATUS_ERR;
01445         }
01446 
01447         if (ldns_rr_list_rr_count(rrsigs) < 1) {
01448                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
01449         }
01450   
01451         /* Look at each sig */
01452         for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
01453 
01454                 cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
01455                 /* Get a valid signer key and validate the sig */
01456                 if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
01457                                         res, 
01458                                         ldns_rr_rrsig_signame(cur_sig), 
01459                                         ldns_resolver_dnssec_anchors(res), 
01460                                         check_time,
01461                                         &result))) {
01462 
01463                         for (key_i = 0;
01464                                 key_i < ldns_rr_list_rr_count(trusted_keys);
01465                                 key_i++) {
01466                                 cur_key = ldns_rr_list_rr(trusted_keys, key_i);
01467 
01468                                 if ((result = ldns_verify_rrsig_time(rrset,
01469                                                                 cur_sig, 
01470                                                                 cur_key,
01471                                                                 check_time))
01472                                     == LDNS_STATUS_OK) {
01473                                         if (validating_keys) {
01474                                                 ldns_rr_list_push_rr(validating_keys,
01475                                                                                  ldns_rr_clone(cur_key));
01476                                         }
01477                                         ldns_rr_list_deep_free(trusted_keys);
01478                                         return LDNS_STATUS_OK;
01479                                 } 
01480                         }
01481                 }
01482         }
01483 
01484         ldns_rr_list_deep_free(trusted_keys);
01485         return result;
01486 }
01487 
01488 ldns_status
01489 ldns_verify_trusted(
01490                 ldns_resolver *res,
01491                 ldns_rr_list *rrset, 
01492                 ldns_rr_list * rrsigs, 
01493                 ldns_rr_list * validating_keys)
01494 {
01495         return ldns_verify_trusted_time(
01496                         res, rrset, rrsigs, ldns_time(NULL), validating_keys);
01497 }
01498 
01499 
01500 ldns_status
01501 ldns_dnssec_verify_denial(ldns_rr *rr,
01502                           ldns_rr_list *nsecs,
01503                           ldns_rr_list *rrsigs)
01504 {
01505         ldns_rdf *rr_name;
01506         ldns_rdf *wildcard_name;
01507         ldns_rdf *chopped_dname;
01508         ldns_rr *cur_nsec;
01509         size_t i;
01510         ldns_status result;
01511         /* needed for wildcard check on exact match */
01512         ldns_rr *rrsig;
01513         bool name_covered = false;
01514         bool type_covered = false;
01515         bool wildcard_covered = false;
01516         bool wildcard_type_covered = false;
01517 
01518         wildcard_name = ldns_dname_new_frm_str("*");
01519         rr_name = ldns_rr_owner(rr);
01520         chopped_dname = ldns_dname_left_chop(rr_name);
01521         result = ldns_dname_cat(wildcard_name, chopped_dname);
01522         if (result != LDNS_STATUS_OK) {
01523                 return result;
01524         }
01525         
01526         ldns_rdf_deep_free(chopped_dname);
01527         
01528         for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01529                 cur_nsec = ldns_rr_list_rr(nsecs, i);
01530                 if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
01531                         /* see section 5.4 of RFC4035, if the label count of the NSEC's
01532                            RRSIG is equal, then it is proven that wildcard expansion 
01533                            could not have been used to match the request */
01534                         rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
01535                                           ldns_rr_owner(cur_nsec),
01536                                           ldns_rr_get_type(cur_nsec),
01537                                           rrsigs);
01538                         if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
01539                             == ldns_dname_label_count(rr_name)) {
01540                                 wildcard_covered = true;
01541                         }
01542                         
01543                         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
01544                                                                            ldns_rr_get_type(rr))) {
01545                                 type_covered = true;
01546                         }
01547                 }
01548                 if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
01549                         name_covered = true;
01550                 }
01551                 
01552                 if (ldns_dname_compare(wildcard_name,
01553                                                    ldns_rr_owner(cur_nsec)) == 0) {
01554                         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
01555                                                                            ldns_rr_get_type(rr))) {
01556                                 wildcard_type_covered = true;
01557                         }
01558                 }
01559                 
01560                 if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
01561                         wildcard_covered = true;
01562                 }
01563                 
01564         }
01565         
01566         ldns_rdf_deep_free(wildcard_name);
01567         
01568         if (type_covered || !name_covered) {
01569                 return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01570         }
01571         
01572         if (wildcard_type_covered || !wildcard_covered) {
01573                 return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
01574         }
01575 
01576         return LDNS_STATUS_OK;
01577 }
01578 
01579 #ifdef HAVE_SSL
01580 ldns_status
01581 ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
01582                                      , ldns_rr_list *nsecs
01583                                      , ATTR_UNUSED(ldns_rr_list *rrsigs)
01584                                      , ldns_pkt_rcode packet_rcode
01585                                      , ldns_rr_type packet_qtype
01586                                      , bool packet_nodata
01587                                      , ldns_rr **match
01588                                      )
01589 {
01590         ldns_rdf *closest_encloser;
01591         ldns_rdf *wildcard;
01592         ldns_rdf *hashed_wildcard_name;
01593         bool wildcard_covered = false;
01594         ldns_rdf *zone_name;
01595         ldns_rdf *hashed_name;
01596         /* self assignment to suppress uninitialized warning */
01597         ldns_rdf *next_closer = next_closer;
01598         ldns_rdf *hashed_next_closer;
01599         size_t i;
01600         ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01601 
01602         if (match) {
01603                 *match = NULL;
01604         }
01605 
01606         zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
01607 
01608         /* section 8.4 */
01609         if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
01610                 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
01611                                                    ldns_rr_owner(rr),
01612                                                    ldns_rr_get_type(rr),
01613                                                    nsecs);
01614                 if(!closest_encloser) {
01615                         result = LDNS_STATUS_NSEC3_ERR;
01616                         goto done;
01617                 }
01618 
01619                 wildcard = ldns_dname_new_frm_str("*");
01620                 (void) ldns_dname_cat(wildcard, closest_encloser);
01621 
01622                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01623                         hashed_wildcard_name =
01624                                 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
01625                                                                                  wildcard
01626                                                                                  );
01627                         (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
01628 
01629                         if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
01630                                                                  hashed_wildcard_name)) {
01631                                 wildcard_covered = true;
01632                                 if (match) {
01633                                         *match = ldns_rr_list_rr(nsecs, i);
01634                                 }
01635                         }
01636                         ldns_rdf_deep_free(hashed_wildcard_name);
01637                 }
01638 
01639                 ldns_rdf_deep_free(closest_encloser);
01640                 ldns_rdf_deep_free(wildcard);
01641 
01642                 if (!wildcard_covered) {
01643                         result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
01644                 } else if (closest_encloser && wildcard_covered) {
01645                         result = LDNS_STATUS_OK;
01646                 } else {
01647                         result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01648                 }
01649         } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
01650                 /* section 8.5 */
01651                 hashed_name = ldns_nsec3_hash_name_frm_nsec3(
01652                                    ldns_rr_list_rr(nsecs, 0),
01653                                    ldns_rr_owner(rr));
01654                 (void) ldns_dname_cat(hashed_name, zone_name);
01655                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01656                         if (ldns_dname_compare(hashed_name,
01657                                  ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
01658                             == 0) {
01659                                 if (!ldns_nsec_bitmap_covers_type(
01660                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01661                                             packet_qtype)
01662                                     &&
01663                                     !ldns_nsec_bitmap_covers_type(
01664                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01665                                             LDNS_RR_TYPE_CNAME)) {
01666                                         result = LDNS_STATUS_OK;
01667                                         if (match) {
01668                                                 *match = ldns_rr_list_rr(nsecs, i);
01669                                         }
01670                                         goto done;
01671                                 }
01672                         }
01673                 }
01674                 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01675                 /* wildcard no data? section 8.7 */
01676                 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
01677                                    ldns_rr_owner(rr),
01678                                    ldns_rr_get_type(rr),
01679                                    nsecs);
01680                 if(!closest_encloser) {
01681                         result = LDNS_STATUS_NSEC3_ERR;
01682                         goto done;
01683                 }
01684                 wildcard = ldns_dname_new_frm_str("*");
01685                 (void) ldns_dname_cat(wildcard, closest_encloser);
01686                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01687                         hashed_wildcard_name =
01688                                 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
01689                                          wildcard);
01690                         (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
01691 
01692                         if (ldns_dname_compare(hashed_wildcard_name,
01693                                  ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
01694                             == 0) {
01695                                 if (!ldns_nsec_bitmap_covers_type(
01696                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01697                                             packet_qtype)
01698                                     &&
01699                                     !ldns_nsec_bitmap_covers_type(
01700                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01701                                             LDNS_RR_TYPE_CNAME)) {
01702                                         result = LDNS_STATUS_OK;
01703                                         if (match) {
01704                                                 *match = ldns_rr_list_rr(nsecs, i);
01705                                         }
01706                                 }
01707                         }
01708                         ldns_rdf_deep_free(hashed_wildcard_name);
01709                         if (result == LDNS_STATUS_OK) {
01710                                 break;
01711                         }
01712                 }
01713                 ldns_rdf_deep_free(closest_encloser);
01714                 ldns_rdf_deep_free(wildcard);
01715         } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
01716                 /* section 8.6 */
01717                 /* note: up to XXX this is the same as for 8.5 */
01718                 hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
01719                                                                                                                  0),
01720                                                                                         ldns_rr_owner(rr)
01721                                                                                         );
01722                 (void) ldns_dname_cat(hashed_name, zone_name);
01723                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01724                         if (ldns_dname_compare(hashed_name,
01725                                                            ldns_rr_owner(ldns_rr_list_rr(nsecs,
01726                                                                                                            i)))
01727                             == 0) {
01728                                 if (!ldns_nsec_bitmap_covers_type(
01729                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01730                                             LDNS_RR_TYPE_DS)
01731                                     && 
01732                                     !ldns_nsec_bitmap_covers_type(
01733                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
01734                                             LDNS_RR_TYPE_CNAME)) {
01735                                         result = LDNS_STATUS_OK;
01736                                         if (match) {
01737                                                 *match = ldns_rr_list_rr(nsecs, i);
01738                                         }
01739                                         goto done;
01740                                 }
01741                         }
01742                 }
01743 
01744                 /* XXX see note above */
01745                 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
01746 
01747                 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
01748                                    ldns_rr_owner(rr),
01749                                    ldns_rr_get_type(rr),
01750                                    nsecs);
01751                 if(!closest_encloser) {
01752                         result = LDNS_STATUS_NSEC3_ERR;
01753                         goto done;
01754                 }
01755                 /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
01756 
01757                 if (ldns_dname_label_count(closest_encloser) + 1
01758                     >= ldns_dname_label_count(ldns_rr_owner(rr))) {
01759                         
01760                         /* Query name *is* the "next closer". */
01761                         hashed_next_closer = hashed_name;
01762                 } else {
01763 
01764                         /* "next closer" has less labels than the query name.
01765                          * Create the name and hash it.
01766                          */
01767                         next_closer = ldns_dname_clone_from(
01768                                         ldns_rr_owner(rr),
01769                                         ldns_dname_label_count(ldns_rr_owner(rr))
01770                                         - (ldns_dname_label_count(closest_encloser) + 1)
01771                                         );
01772                         hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
01773                                         ldns_rr_list_rr(nsecs, 0),
01774                                         next_closer
01775                                         );
01776                         (void) ldns_dname_cat(hashed_next_closer, zone_name);
01777                 }
01778                 /* Find the NSEC3 that covers the "next closer" */
01779                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
01780                         if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
01781                                                   hashed_next_closer) && 
01782                                 ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
01783 
01784                                 result = LDNS_STATUS_OK;
01785                                 if (match) {
01786                                         *match = ldns_rr_list_rr(nsecs, i);
01787                                 }
01788                                 break;
01789                         }
01790                 }
01791                 if (ldns_dname_label_count(closest_encloser) + 1
01792                     < ldns_dname_label_count(ldns_rr_owner(rr))) {
01793 
01794                         /* "next closer" has less labels than the query name.
01795                          * Dispose of the temporary variables that held that name.
01796                          */
01797                         ldns_rdf_deep_free(hashed_next_closer);
01798                         ldns_rdf_deep_free(next_closer);
01799                 }
01800                 ldns_rdf_deep_free(closest_encloser);
01801         }
01802 
01803  done:
01804         ldns_rdf_deep_free(zone_name);
01805         return result;
01806 }
01807 
01808 ldns_status
01809 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
01810                                                   ldns_rr_list *nsecs,
01811                                                   ldns_rr_list *rrsigs,
01812                                                   ldns_pkt_rcode packet_rcode,
01813                                                   ldns_rr_type packet_qtype,
01814                                                   bool packet_nodata)
01815 {
01816         return ldns_dnssec_verify_denial_nsec3_match(
01817                                 rr, nsecs, rrsigs, packet_rcode,
01818                                 packet_qtype, packet_nodata, NULL
01819                );
01820 }
01821 
01822 
01823 #endif /* HAVE_SSL */
01824 
01825 #ifdef USE_GOST
01826 EVP_PKEY*
01827 ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
01828 {
01829         /* prefix header for X509 encoding */
01830         uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
01831                 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
01832                 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
01833                 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
01834         unsigned char encoded[37+64];
01835         const unsigned char* pp;
01836         if(keylen != 64) {
01837                 /* key wrong size */
01838                 return NULL;
01839         }
01840 
01841         /* create evp_key */
01842         memmove(encoded, asn, 37);
01843         memmove(encoded+37, key, 64);
01844         pp = (unsigned char*)&encoded[0];
01845 
01846         return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
01847 }
01848 
01849 static ldns_status
01850 ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
01851         ldns_buffer* rrset, unsigned char* key, size_t keylen)
01852 {
01853         EVP_PKEY *evp_key;
01854         ldns_status result;
01855 
01856         (void) ldns_key_EVP_load_gost_id();
01857         evp_key = ldns_gost2pkey_raw(key, keylen);
01858         if(!evp_key) {
01859                 /* could not convert key */
01860                 return LDNS_STATUS_CRYPTO_BOGUS;
01861         }
01862 
01863         /* verify signature */
01864         result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, 
01865                 evp_key, EVP_get_digestbyname("md_gost94"));
01866         EVP_PKEY_free(evp_key);
01867 
01868         return result;
01869 }
01870 #endif
01871 
01872 #ifdef USE_ECDSA
01873 EVP_PKEY*
01874 ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
01875 {
01876         unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
01877         const unsigned char* pp = buf;
01878         EVP_PKEY *evp_key;
01879         EC_KEY *ec;
01880         /* check length, which uncompressed must be 2 bignums */
01881         if(algo == LDNS_ECDSAP256SHA256) {
01882                 if(keylen != 2*256/8) return NULL;
01883                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
01884         } else if(algo == LDNS_ECDSAP384SHA384) {
01885                 if(keylen != 2*384/8) return NULL;
01886                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
01887         } else    ec = NULL;
01888         if(!ec) return NULL;
01889         if(keylen+1 > sizeof(buf))
01890                 return NULL; /* sanity check */
01891         /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
01892          * of openssl) for uncompressed data */
01893         buf[0] = POINT_CONVERSION_UNCOMPRESSED;
01894         memmove(buf+1, key, keylen);
01895         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
01896                 EC_KEY_free(ec);
01897                 return NULL;
01898         }
01899         evp_key = EVP_PKEY_new();
01900         if(!evp_key) {
01901                 EC_KEY_free(ec);
01902                 return NULL;
01903         }
01904         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
01905                 EVP_PKEY_free(evp_key);
01906                 EC_KEY_free(ec);
01907                 return NULL;
01908         }
01909         return evp_key;
01910 }
01911 
01912 static ldns_status
01913 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen, 
01914         ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
01915 {
01916         EVP_PKEY *evp_key;
01917         ldns_status result;
01918         const EVP_MD *d;
01919 
01920         evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
01921         if(!evp_key) {
01922                 /* could not convert key */
01923                 return LDNS_STATUS_CRYPTO_BOGUS;
01924         }
01925         if(algo == LDNS_ECDSAP256SHA256)
01926                 d = EVP_sha256();
01927         else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
01928         result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
01929         EVP_PKEY_free(evp_key);
01930         return result;
01931 }
01932 #endif
01933 
01934 ldns_status
01935 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 
01936                                          ldns_buffer *key_buf, uint8_t algo)
01937 {
01938         return ldns_verify_rrsig_buffers_raw(
01939                          (unsigned char*)ldns_buffer_begin(rawsig_buf),
01940                          ldns_buffer_position(rawsig_buf),
01941                          verify_buf,
01942                          (unsigned char*)ldns_buffer_begin(key_buf), 
01943                          ldns_buffer_position(key_buf), algo);
01944 }
01945 
01946 ldns_status
01947 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
01948                                                 ldns_buffer *verify_buf, unsigned char* key, size_t keylen, 
01949                                                 uint8_t algo)
01950 {
01951         /* check for right key */
01952         switch(algo) {
01953         case LDNS_DSA:
01954         case LDNS_DSA_NSEC3:
01955                 return ldns_verify_rrsig_dsa_raw(sig,
01956                                                                    siglen,
01957                                                                    verify_buf,
01958                                                                    key,
01959                                                                    keylen);
01960                 break;
01961         case LDNS_RSASHA1:
01962         case LDNS_RSASHA1_NSEC3:
01963                 return ldns_verify_rrsig_rsasha1_raw(sig,
01964                                                                           siglen,
01965                                                                           verify_buf,
01966                                                                           key,
01967                                                                           keylen);
01968                 break;
01969 #ifdef USE_SHA2
01970         case LDNS_RSASHA256:
01971                 return ldns_verify_rrsig_rsasha256_raw(sig,
01972                                                                             siglen,
01973                                                                             verify_buf,
01974                                                                             key,
01975                                                                             keylen);
01976                 break;
01977         case LDNS_RSASHA512:
01978                 return ldns_verify_rrsig_rsasha512_raw(sig,
01979                                                                             siglen,
01980                                                                             verify_buf,
01981                                                                             key,
01982                                                                             keylen);
01983                 break;
01984 #endif
01985 #ifdef USE_GOST
01986         case LDNS_ECC_GOST:
01987                 return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
01988                         key, keylen);
01989                 break;
01990 #endif
01991 #ifdef USE_ECDSA
01992         case LDNS_ECDSAP256SHA256:
01993         case LDNS_ECDSAP384SHA384:
01994                 return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
01995                         key, keylen, algo);
01996                 break;
01997 #endif
01998         case LDNS_RSAMD5:
01999                 return ldns_verify_rrsig_rsamd5_raw(sig,
02000                                                                          siglen,
02001                                                                          verify_buf,
02002                                                                          key,
02003                                                                          keylen);
02004                 break;
02005         default:
02006                 /* do you know this alg?! */
02007                 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
02008         }
02009 }
02010 
02011 
02019 static void
02020 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
02021 {
02022         uint32_t orig_ttl;
02023         uint16_t i;
02024         uint8_t label_count;
02025         ldns_rdf *wildcard_name;
02026         ldns_rdf *wildcard_chopped;
02027         ldns_rdf *wildcard_chopped_tmp;
02028         
02029         if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
02030                 return;
02031         }
02032 
02033         orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
02034         label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
02035 
02036         for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
02037                 if (label_count < 
02038                     ldns_dname_label_count(
02039                            ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
02040                         (void) ldns_str2rdf_dname(&wildcard_name, "*");
02041                         wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
02042                                 ldns_rr_list_rr(rrset_clone, i)));
02043                         while (label_count < ldns_dname_label_count(wildcard_chopped)) {
02044                                 wildcard_chopped_tmp = ldns_dname_left_chop(
02045                                         wildcard_chopped);
02046                                 ldns_rdf_deep_free(wildcard_chopped);
02047                                 wildcard_chopped = wildcard_chopped_tmp;
02048                         }
02049                         (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
02050                         ldns_rdf_deep_free(wildcard_chopped);
02051                         ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
02052                                 rrset_clone, i)));
02053                         ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
02054                                 wildcard_name);
02055                 }
02056                 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
02057                 /* convert to lowercase */
02058                 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
02059         }
02060 }
02061 
02068 static ldns_status
02069 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
02070 {
02071         uint8_t sig_algo;
02072        
02073         if (rrsig == NULL) {
02074                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
02075         }
02076         if (ldns_rr_rdf(rrsig, 1) == NULL) {
02077                 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
02078         }
02079         sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
02080         /* check for known and implemented algo's now (otherwise 
02081          * the function could return a wrong error
02082          */
02083         /* create a buffer with signature rdata */
02084         /* for some algorithms we need other data than for others... */
02085         /* (the DSA API wants DER encoding for instance) */
02086 
02087         switch(sig_algo) {
02088         case LDNS_RSAMD5:
02089         case LDNS_RSASHA1:
02090         case LDNS_RSASHA1_NSEC3:
02091 #ifdef USE_SHA2
02092         case LDNS_RSASHA256:
02093         case LDNS_RSASHA512:
02094 #endif
02095 #ifdef USE_GOST
02096         case LDNS_ECC_GOST:
02097 #endif
02098                 if (ldns_rr_rdf(rrsig, 8) == NULL) {
02099                         return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
02100                 }
02101                 if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
02102                                 != LDNS_STATUS_OK) {
02103                         return LDNS_STATUS_MEM_ERR;
02104                 }
02105                 break;
02106         case LDNS_DSA:
02107         case LDNS_DSA_NSEC3:
02108                 /* EVP takes rfc2459 format, which is a tad longer than dns format */
02109                 if (ldns_rr_rdf(rrsig, 8) == NULL) {
02110                         return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
02111                 }
02112                 if (ldns_convert_dsa_rrsig_rdf2asn1(
02113                                         rawsig_buf, ldns_rr_rdf(rrsig, 8)) 
02114                                 != LDNS_STATUS_OK) {
02115                         /*
02116                           if (ldns_rdf2buffer_wire(rawsig_buf,
02117                           ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
02118                         */
02119                         return LDNS_STATUS_MEM_ERR;
02120                 }
02121                 break;
02122 #ifdef USE_ECDSA
02123         case LDNS_ECDSAP256SHA256:
02124         case LDNS_ECDSAP384SHA384:
02125                 /* EVP produces an ASN prefix on the signature, which is
02126                  * not used in the DNS */
02127                 if (ldns_rr_rdf(rrsig, 8) == NULL) {
02128                         return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
02129                 }
02130                 if (ldns_convert_ecdsa_rrsig_rdf2asn1(
02131                                         rawsig_buf, ldns_rr_rdf(rrsig, 8))
02132                                 != LDNS_STATUS_OK) {
02133                         return LDNS_STATUS_MEM_ERR;
02134                 }
02135                 break;
02136 #endif
02137         case LDNS_DH:
02138         case LDNS_ECC:
02139         case LDNS_INDIRECT:
02140                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
02141         default:
02142                 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
02143         }
02144         return LDNS_STATUS_OK;
02145 }
02146 
02153 static ldns_status
02154 ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
02155 {
02156         int32_t inception, expiration;
02157         
02158         /* check the signature time stamps */
02159         inception = (int32_t)ldns_rdf2native_time_t(
02160                 ldns_rr_rrsig_inception(rrsig));
02161         expiration = (int32_t)ldns_rdf2native_time_t(
02162                 ldns_rr_rrsig_expiration(rrsig));
02163 
02164         if (expiration - inception < 0) {
02165                 /* bad sig, expiration before inception?? Tsssg */
02166                 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
02167         }
02168         if (((int32_t) now) - inception < 0) {
02169                 /* bad sig, inception date has not yet come to pass */
02170                 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
02171         }
02172         if (expiration - ((int32_t) now) < 0) {
02173                 /* bad sig, expiration date has passed */
02174                 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
02175         }
02176         return LDNS_STATUS_OK;
02177 }
02178 
02187 static ldns_status
02188 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
02189         ldns_rr_list* rrset_clone, ldns_rr* rrsig)
02190 {
02191         ldns_status result;
02192 
02193         /* canonicalize the sig */
02194         ldns_dname2canonical(ldns_rr_owner(rrsig));
02195         
02196         /* check if the typecovered is equal to the type checked */
02197         if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
02198             ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
02199                 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
02200         
02201         /* create a buffer with b64 signature rdata */
02202         result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
02203         if(result != LDNS_STATUS_OK)
02204                 return result;
02205 
02206         /* use TTL from signature. Use wildcard names for wildcards */
02207         /* also canonicalizes rrset_clone */
02208         ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
02209 
02210         /* sort the rrset in canonical order  */
02211         ldns_rr_list_sort(rrset_clone);
02212 
02213         /* put the signature rr (without the b64) to the verify_buf */
02214         if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
02215                 return LDNS_STATUS_MEM_ERR;
02216 
02217         /* add the rrset in verify_buf */
02218         if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone) 
02219                 != LDNS_STATUS_OK)
02220                 return LDNS_STATUS_MEM_ERR;
02221 
02222         return LDNS_STATUS_OK;
02223 }
02224 
02234 static ldns_status
02235 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
02236         ldns_rr* rrsig, ldns_rr* key)
02237 {
02238         uint8_t sig_algo;
02239        
02240         if (rrsig == NULL) {
02241                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
02242         }
02243         if (ldns_rr_rdf(rrsig, 1) == NULL) {
02244                 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
02245         }
02246         sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
02247 
02248         /* before anything, check if the keytags match */
02249         if (ldns_calc_keytag(key)
02250             ==
02251             ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
02252             ) {
02253                 ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
02254                 ldns_status result = LDNS_STATUS_ERR;
02255 
02256                 /* put the key-data in a buffer, that's the third rdf, with
02257                  * the base64 encoded key data */
02258                 if (ldns_rr_rdf(key, 3) == NULL) {
02259                         ldns_buffer_free(key_buf);
02260                         return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
02261                 }
02262                 if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
02263                                 != LDNS_STATUS_OK) {
02264                         ldns_buffer_free(key_buf); 
02265                         /* returning is bad might screw up
02266                            good keys later in the list
02267                            what to do? */
02268                         return LDNS_STATUS_ERR;
02269                 }
02270 
02271                 if (ldns_rr_rdf(key, 2) == NULL) {
02272                         result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
02273                 }
02274                 else if (sig_algo == ldns_rdf2native_int8(
02275                                         ldns_rr_rdf(key, 2))) {
02276                         result = ldns_verify_rrsig_buffers(rawsig_buf, 
02277                                 verify_buf, key_buf, sig_algo);
02278                 } else {
02279                         /* No keys with the corresponding algorithm are found */
02280                         result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
02281                 }
02282 
02283                 ldns_buffer_free(key_buf); 
02284                 return result;
02285         }
02286         else {
02287                 /* No keys with the corresponding keytag are found */
02288                 return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
02289         }
02290 }
02291 
02292 /* 
02293  * to verify:
02294  * - create the wire fmt of the b64 key rdata
02295  * - create the wire fmt of the sorted rrset
02296  * - create the wire fmt of the b64 sig rdata
02297  * - create the wire fmt of the sig without the b64 rdata
02298  * - cat the sig data (without b64 rdata) to the rrset
02299  * - verify the rrset+sig, with the b64 data and the b64 key data
02300  */
02301 ldns_status
02302 ldns_verify_rrsig_keylist_time(
02303                 ldns_rr_list *rrset,
02304                 ldns_rr *rrsig,
02305                 const ldns_rr_list *keys, 
02306                 time_t check_time,
02307                 ldns_rr_list *good_keys)
02308 {
02309         ldns_status result;
02310         ldns_rr_list *valid = ldns_rr_list_new();
02311         if (!valid)
02312                 return LDNS_STATUS_MEM_ERR;
02313 
02314         result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
02315         if(result != LDNS_STATUS_OK) {
02316                 ldns_rr_list_free(valid); 
02317                 return result;
02318         }
02319 
02320         /* check timestamps last; its OK except time */
02321         result = ldns_rrsig_check_timestamps(rrsig, check_time);
02322         if(result != LDNS_STATUS_OK) {
02323                 ldns_rr_list_free(valid); 
02324                 return result;
02325         }
02326 
02327         ldns_rr_list_cat(good_keys, valid);
02328         ldns_rr_list_free(valid);
02329         return LDNS_STATUS_OK;
02330 }
02331 
02332 /* 
02333  * to verify:
02334  * - create the wire fmt of the b64 key rdata
02335  * - create the wire fmt of the sorted rrset
02336  * - create the wire fmt of the b64 sig rdata
02337  * - create the wire fmt of the sig without the b64 rdata
02338  * - cat the sig data (without b64 rdata) to the rrset
02339  * - verify the rrset+sig, with the b64 data and the b64 key data
02340  */
02341 ldns_status
02342 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
02343                                          ldns_rr *rrsig,
02344                                          const ldns_rr_list *keys, 
02345                                          ldns_rr_list *good_keys)
02346 {
02347         return ldns_verify_rrsig_keylist_time(
02348                         rrset, rrsig, keys, ldns_time(NULL), good_keys);
02349 }
02350 
02351 ldns_status
02352 ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
02353                                          ldns_rr *rrsig,
02354                                          const ldns_rr_list *keys, 
02355                                          ldns_rr_list *good_keys)
02356 {
02357         ldns_buffer *rawsig_buf;
02358         ldns_buffer *verify_buf;
02359         uint16_t i;
02360         ldns_status result, status;
02361         ldns_rr_list *rrset_clone;
02362         ldns_rr_list *validkeys;
02363 
02364         if (!rrset) {
02365                 return LDNS_STATUS_ERR;
02366         }
02367 
02368         validkeys = ldns_rr_list_new();
02369         if (!validkeys) {
02370                 return LDNS_STATUS_MEM_ERR;
02371         }
02372         
02373         /* clone the rrset so that we can fiddle with it */
02374         rrset_clone = ldns_rr_list_clone(rrset);
02375 
02376         /* create the buffers which will certainly hold the raw data */
02377         rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
02378         verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
02379 
02380         result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
02381                 rrset_clone, rrsig);
02382         if(result != LDNS_STATUS_OK) {
02383                 ldns_buffer_free(verify_buf);
02384                 ldns_buffer_free(rawsig_buf);
02385                 ldns_rr_list_deep_free(rrset_clone);
02386                 ldns_rr_list_free(validkeys);
02387                 return result;
02388         }
02389 
02390         result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
02391         for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
02392                 status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
02393                         rrsig, ldns_rr_list_rr(keys, i));
02394                 if (status == LDNS_STATUS_OK) {
02395                         /* one of the keys has matched, don't break
02396                          * here, instead put the 'winning' key in
02397                          * the validkey list and return the list 
02398                          * later */
02399                         if (!ldns_rr_list_push_rr(validkeys, 
02400                                 ldns_rr_list_rr(keys,i))) {
02401                                 /* couldn't push the key?? */
02402                                 ldns_buffer_free(rawsig_buf);
02403                                 ldns_buffer_free(verify_buf);
02404                                 ldns_rr_list_deep_free(rrset_clone);
02405                                 ldns_rr_list_free(validkeys);
02406                                 return LDNS_STATUS_MEM_ERR;
02407                         }
02408 
02409                         result = status;
02410                 }
02411 
02412                 if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
02413                         result = status;
02414                 }
02415         }
02416 
02417         /* no longer needed */
02418         ldns_rr_list_deep_free(rrset_clone);
02419         ldns_buffer_free(rawsig_buf);
02420         ldns_buffer_free(verify_buf);
02421 
02422         if (ldns_rr_list_rr_count(validkeys) == 0) {
02423                 /* no keys were added, return last error */
02424                 ldns_rr_list_free(validkeys); 
02425                 return result;
02426         }
02427 
02428         /* do not check timestamps */
02429 
02430         ldns_rr_list_cat(good_keys, validkeys);
02431         ldns_rr_list_free(validkeys);
02432         return LDNS_STATUS_OK;
02433 }
02434 
02435 ldns_status
02436 ldns_verify_rrsig_time(
02437                 ldns_rr_list *rrset, 
02438                 ldns_rr *rrsig, 
02439                 ldns_rr *key, 
02440                 time_t check_time)
02441 {
02442         ldns_buffer *rawsig_buf;
02443         ldns_buffer *verify_buf;
02444         ldns_status result;
02445         ldns_rr_list *rrset_clone;
02446 
02447         if (!rrset) {
02448                 return LDNS_STATUS_NO_DATA;
02449         }
02450         /* clone the rrset so that we can fiddle with it */
02451         rrset_clone = ldns_rr_list_clone(rrset);
02452         /* create the buffers which will certainly hold the raw data */
02453         rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
02454         verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
02455 
02456         result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
02457                 rrset_clone, rrsig);
02458         if(result != LDNS_STATUS_OK) {
02459                 ldns_rr_list_deep_free(rrset_clone);
02460                 ldns_buffer_free(rawsig_buf);
02461                 ldns_buffer_free(verify_buf);
02462                 return result;
02463         }
02464         result = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
02465                 rrsig, key);
02466         /* no longer needed */
02467         ldns_rr_list_deep_free(rrset_clone);
02468         ldns_buffer_free(rawsig_buf);
02469         ldns_buffer_free(verify_buf);
02470 
02471         /* check timestamp last, apart from time its OK */
02472         if(result == LDNS_STATUS_OK)
02473                 result = ldns_rrsig_check_timestamps(rrsig, check_time);
02474 
02475         return result;
02476 }
02477 
02478 ldns_status
02479 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
02480 {
02481         return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
02482 }
02483 
02484 
02485 ldns_status
02486 ldns_verify_rrsig_evp(ldns_buffer *sig,
02487                                   ldns_buffer *rrset,
02488                                   EVP_PKEY *key,
02489                                   const EVP_MD *digest_type)
02490 {
02491         return ldns_verify_rrsig_evp_raw(
02492                          (unsigned char*)ldns_buffer_begin(sig),
02493                          ldns_buffer_position(sig),
02494                          rrset,
02495                          key,
02496                          digest_type);
02497 }
02498 
02499 ldns_status
02500 ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
02501                                          ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
02502 {
02503         EVP_MD_CTX ctx;
02504         int res;
02505 
02506         EVP_MD_CTX_init(&ctx);
02507         
02508         EVP_VerifyInit(&ctx, digest_type);
02509         EVP_VerifyUpdate(&ctx,
02510                                   ldns_buffer_begin(rrset),
02511                                   ldns_buffer_position(rrset));
02512         res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
02513         
02514         EVP_MD_CTX_cleanup(&ctx);
02515         
02516         if (res == 1) {
02517                 return LDNS_STATUS_OK;
02518         } else if (res == 0) {
02519                 return LDNS_STATUS_CRYPTO_BOGUS;
02520         }
02521         /* TODO how to communicate internal SSL error?
02522            let caller use ssl's get_error() */
02523         return LDNS_STATUS_SSL_ERR;
02524 }
02525 
02526 ldns_status
02527 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
02528 {
02529         return ldns_verify_rrsig_dsa_raw(
02530                          (unsigned char*) ldns_buffer_begin(sig),
02531                          ldns_buffer_position(sig),
02532                          rrset,
02533                          (unsigned char*) ldns_buffer_begin(key),
02534                          ldns_buffer_position(key));
02535 }
02536 
02537 ldns_status
02538 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
02539 {
02540         return ldns_verify_rrsig_rsasha1_raw(
02541                          (unsigned char*)ldns_buffer_begin(sig),
02542                          ldns_buffer_position(sig),
02543                          rrset,
02544                          (unsigned char*) ldns_buffer_begin(key),
02545                          ldns_buffer_position(key));
02546 }
02547 
02548 ldns_status
02549 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
02550 {
02551         return ldns_verify_rrsig_rsamd5_raw(
02552                          (unsigned char*)ldns_buffer_begin(sig),
02553                          ldns_buffer_position(sig),
02554                          rrset,
02555                          (unsigned char*) ldns_buffer_begin(key),
02556                          ldns_buffer_position(key));
02557 }
02558 
02559 ldns_status
02560 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
02561                                          ldns_buffer* rrset, unsigned char* key, size_t keylen)
02562 {
02563         EVP_PKEY *evp_key;
02564         ldns_status result;
02565 
02566         evp_key = EVP_PKEY_new();
02567         if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
02568                 result = ldns_verify_rrsig_evp_raw(sig,
02569                                                                 siglen,
02570                                                                 rrset,
02571                                                                 evp_key,
02572                                                                 EVP_dss1());
02573         } else {
02574                 result = LDNS_STATUS_SSL_ERR;
02575         }
02576         EVP_PKEY_free(evp_key);
02577         return result;
02578 
02579 }
02580 
02581 ldns_status
02582 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
02583                                                 ldns_buffer* rrset, unsigned char* key, size_t keylen)
02584 {
02585         EVP_PKEY *evp_key;
02586         ldns_status result;
02587 
02588         evp_key = EVP_PKEY_new();
02589         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
02590                 result = ldns_verify_rrsig_evp_raw(sig,
02591                                                                 siglen,
02592                                                                 rrset,
02593                                                                 evp_key,
02594                                                                 EVP_sha1());
02595         } else {
02596                 result = LDNS_STATUS_SSL_ERR;
02597         }
02598         EVP_PKEY_free(evp_key);
02599 
02600         return result;
02601 }
02602 
02603 ldns_status
02604 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
02605                                                   size_t siglen,
02606                                                   ldns_buffer* rrset,
02607                                                   unsigned char* key,
02608                                                   size_t keylen)
02609 {
02610 #ifdef USE_SHA2
02611         EVP_PKEY *evp_key;
02612         ldns_status result;
02613 
02614         evp_key = EVP_PKEY_new();
02615         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
02616                 result = ldns_verify_rrsig_evp_raw(sig,
02617                                                                 siglen,
02618                                                                 rrset,
02619                                                                 evp_key,
02620                                                                 EVP_sha256());
02621         } else {
02622                 result = LDNS_STATUS_SSL_ERR;
02623         }
02624         EVP_PKEY_free(evp_key);
02625 
02626         return result;
02627 #else
02628         /* touch these to prevent compiler warnings */
02629         (void) sig;
02630         (void) siglen;
02631         (void) rrset;
02632         (void) key;
02633         (void) keylen;
02634         return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
02635 #endif
02636 }
02637 
02638 ldns_status
02639 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
02640                                                   size_t siglen,
02641                                                   ldns_buffer* rrset,
02642                                                   unsigned char* key,
02643                                                   size_t keylen)
02644 {
02645 #ifdef USE_SHA2
02646         EVP_PKEY *evp_key;
02647         ldns_status result;
02648 
02649         evp_key = EVP_PKEY_new();
02650         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
02651                 result = ldns_verify_rrsig_evp_raw(sig,
02652                                                                 siglen,
02653                                                                 rrset,
02654                                                                 evp_key,
02655                                                                 EVP_sha512());
02656         } else {
02657                 result = LDNS_STATUS_SSL_ERR;
02658         }
02659         EVP_PKEY_free(evp_key);
02660 
02661         return result;
02662 #else
02663         /* touch these to prevent compiler warnings */
02664         (void) sig;
02665         (void) siglen;
02666         (void) rrset;
02667         (void) key;
02668         (void) keylen;
02669         return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
02670 #endif
02671 }
02672 
02673 
02674 ldns_status
02675 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
02676                                             size_t siglen,
02677                                             ldns_buffer* rrset,
02678                                             unsigned char* key,
02679                                             size_t keylen)
02680 {
02681         EVP_PKEY *evp_key;
02682         ldns_status result;
02683 
02684         evp_key = EVP_PKEY_new();
02685         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
02686                 result = ldns_verify_rrsig_evp_raw(sig,
02687                                                                 siglen,
02688                                                                 rrset,
02689                                                                 evp_key,
02690                                                                 EVP_md5());
02691         } else {
02692                 result = LDNS_STATUS_SSL_ERR;
02693         }
02694         EVP_PKEY_free(evp_key);
02695 
02696         return result;
02697 }
02698 
02699 #endif

Generated on Fri Jun 8 17:07:46 2012 for ldns by  doxygen 1.4.7