dnssec_verify.c

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

Generated on Thu Apr 5 23:03:54 2012 for ldns by  doxygen 1.4.7