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