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