"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/dns/rdata/generic/nsec3_50.c" (4 Sep 2020, 10407 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nsec3_50.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 9.17.4_vs_9.17.5.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*
   13  * Copyright (C) 2004  Nominet, Ltd.
   14  *
   15  * Permission to use, copy, modify, and distribute this software for any
   16  * purpose with or without fee is hereby granted, provided that the above
   17  * copyright notice and this permission notice appear in all copies.
   18  *
   19  * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
   20  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
   21  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
   22  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   23  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
   24  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   25  * PERFORMANCE OF THIS SOFTWARE.
   26  */
   27 
   28 /* RFC 5155 */
   29 
   30 #ifndef RDATA_GENERIC_NSEC3_50_C
   31 #define RDATA_GENERIC_NSEC3_50_C
   32 
   33 #include <isc/base32.h>
   34 #include <isc/iterated_hash.h>
   35 
   36 #define RRTYPE_NSEC3_ATTRIBUTES DNS_RDATATYPEATTR_DNSSEC
   37 
   38 static inline isc_result_t
   39 fromtext_nsec3(ARGS_FROMTEXT) {
   40     isc_token_t token;
   41     unsigned int flags;
   42     unsigned char hashalg;
   43     isc_buffer_t b;
   44     unsigned char buf[256];
   45 
   46     REQUIRE(type == dns_rdatatype_nsec3);
   47 
   48     UNUSED(type);
   49     UNUSED(rdclass);
   50     UNUSED(callbacks);
   51     UNUSED(origin);
   52     UNUSED(options);
   53 
   54     /* Hash. */
   55     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
   56                       false));
   57     RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
   58     RETERR(uint8_tobuffer(hashalg, target));
   59 
   60     /* Flags. */
   61     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
   62                       false));
   63     flags = token.value.as_ulong;
   64     if (flags > 255U) {
   65         RETTOK(ISC_R_RANGE);
   66     }
   67     RETERR(uint8_tobuffer(flags, target));
   68 
   69     /* Iterations. */
   70     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
   71                       false));
   72     if (token.value.as_ulong > 0xffffU) {
   73         RETTOK(ISC_R_RANGE);
   74     }
   75     RETERR(uint16_tobuffer(token.value.as_ulong, target));
   76 
   77     /* salt */
   78     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
   79                       false));
   80     if (token.value.as_textregion.length > (255 * 2)) {
   81         RETTOK(DNS_R_TEXTTOOLONG);
   82     }
   83     if (strcmp(DNS_AS_STR(token), "-") == 0) {
   84         RETERR(uint8_tobuffer(0, target));
   85     } else {
   86         RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
   87         RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
   88     }
   89 
   90     /*
   91      * Next hash a single base32hex word.
   92      */
   93     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
   94                       false));
   95     isc_buffer_init(&b, buf, sizeof(buf));
   96     RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b));
   97     if (isc_buffer_usedlength(&b) > 0xffU) {
   98         RETTOK(ISC_R_RANGE);
   99     }
  100     RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target));
  101     RETERR(mem_tobuffer(target, &buf, isc_buffer_usedlength(&b)));
  102 
  103     return (typemap_fromtext(lexer, target, true));
  104 }
  105 
  106 static inline isc_result_t
  107 totext_nsec3(ARGS_TOTEXT) {
  108     isc_region_t sr;
  109     unsigned int i, j;
  110     unsigned char hash;
  111     unsigned char flags;
  112     char buf[sizeof("TYPE65535")];
  113     uint32_t iterations;
  114 
  115     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  116     REQUIRE(rdata->length != 0);
  117 
  118     dns_rdata_toregion(rdata, &sr);
  119 
  120     /* Hash */
  121     hash = uint8_fromregion(&sr);
  122     isc_region_consume(&sr, 1);
  123     snprintf(buf, sizeof(buf), "%u ", hash);
  124     RETERR(str_totext(buf, target));
  125 
  126     /* Flags */
  127     flags = uint8_fromregion(&sr);
  128     isc_region_consume(&sr, 1);
  129     snprintf(buf, sizeof(buf), "%u ", flags);
  130     RETERR(str_totext(buf, target));
  131 
  132     /* Iterations */
  133     iterations = uint16_fromregion(&sr);
  134     isc_region_consume(&sr, 2);
  135     snprintf(buf, sizeof(buf), "%u ", iterations);
  136     RETERR(str_totext(buf, target));
  137 
  138     /* Salt */
  139     j = uint8_fromregion(&sr);
  140     isc_region_consume(&sr, 1);
  141     INSIST(j <= sr.length);
  142 
  143     if (j != 0) {
  144         i = sr.length;
  145         sr.length = j;
  146         RETERR(isc_hex_totext(&sr, 1, "", target));
  147         sr.length = i - j;
  148     } else {
  149         RETERR(str_totext("-", target));
  150     }
  151 
  152     if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
  153         RETERR(str_totext(" (", target));
  154     }
  155     RETERR(str_totext(tctx->linebreak, target));
  156 
  157     /* Next hash */
  158     j = uint8_fromregion(&sr);
  159     isc_region_consume(&sr, 1);
  160     INSIST(j <= sr.length);
  161 
  162     i = sr.length;
  163     sr.length = j;
  164     RETERR(isc_base32hexnp_totext(&sr, 1, "", target));
  165     sr.length = i - j;
  166 
  167     /*
  168      * Don't leave a trailing space when there's no typemap present.
  169      */
  170     if (((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) && (sr.length > 0)) {
  171         RETERR(str_totext(" ", target));
  172     }
  173     RETERR(typemap_totext(&sr, tctx, target));
  174 
  175     if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
  176         RETERR(str_totext(" )", target));
  177     }
  178 
  179     return (ISC_R_SUCCESS);
  180 }
  181 
  182 static inline isc_result_t
  183 fromwire_nsec3(ARGS_FROMWIRE) {
  184     isc_region_t sr, rr;
  185     unsigned int saltlen, hashlen;
  186 
  187     REQUIRE(type == dns_rdatatype_nsec3);
  188 
  189     UNUSED(type);
  190     UNUSED(rdclass);
  191     UNUSED(options);
  192     UNUSED(dctx);
  193 
  194     isc_buffer_activeregion(source, &sr);
  195     rr = sr;
  196 
  197     /* hash(1), flags(1), iteration(2), saltlen(1) */
  198     if (sr.length < 5U) {
  199         RETERR(DNS_R_FORMERR);
  200     }
  201     saltlen = sr.base[4];
  202     isc_region_consume(&sr, 5);
  203 
  204     if (sr.length < saltlen) {
  205         RETERR(DNS_R_FORMERR);
  206     }
  207     isc_region_consume(&sr, saltlen);
  208 
  209     if (sr.length < 1U) {
  210         RETERR(DNS_R_FORMERR);
  211     }
  212     hashlen = sr.base[0];
  213     isc_region_consume(&sr, 1);
  214 
  215     if (hashlen < 1 || sr.length < hashlen) {
  216         RETERR(DNS_R_FORMERR);
  217     }
  218     isc_region_consume(&sr, hashlen);
  219 
  220     RETERR(typemap_test(&sr, true));
  221 
  222     RETERR(mem_tobuffer(target, rr.base, rr.length));
  223     isc_buffer_forward(source, rr.length);
  224     return (ISC_R_SUCCESS);
  225 }
  226 
  227 static inline isc_result_t
  228 towire_nsec3(ARGS_TOWIRE) {
  229     isc_region_t sr;
  230 
  231     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  232     REQUIRE(rdata->length != 0);
  233 
  234     UNUSED(cctx);
  235 
  236     dns_rdata_toregion(rdata, &sr);
  237     return (mem_tobuffer(target, sr.base, sr.length));
  238 }
  239 
  240 static inline int
  241 compare_nsec3(ARGS_COMPARE) {
  242     isc_region_t r1;
  243     isc_region_t r2;
  244 
  245     REQUIRE(rdata1->type == rdata2->type);
  246     REQUIRE(rdata1->rdclass == rdata2->rdclass);
  247     REQUIRE(rdata1->type == dns_rdatatype_nsec3);
  248     REQUIRE(rdata1->length != 0);
  249     REQUIRE(rdata2->length != 0);
  250 
  251     dns_rdata_toregion(rdata1, &r1);
  252     dns_rdata_toregion(rdata2, &r2);
  253     return (isc_region_compare(&r1, &r2));
  254 }
  255 
  256 static inline isc_result_t
  257 fromstruct_nsec3(ARGS_FROMSTRUCT) {
  258     dns_rdata_nsec3_t *nsec3 = source;
  259     isc_region_t region;
  260 
  261     REQUIRE(type == dns_rdatatype_nsec3);
  262     REQUIRE(nsec3 != NULL);
  263     REQUIRE(nsec3->common.rdtype == type);
  264     REQUIRE(nsec3->common.rdclass == rdclass);
  265     REQUIRE(nsec3->typebits != NULL || nsec3->len == 0);
  266     REQUIRE(nsec3->hash == dns_hash_sha1);
  267 
  268     UNUSED(type);
  269     UNUSED(rdclass);
  270 
  271     RETERR(uint8_tobuffer(nsec3->hash, target));
  272     RETERR(uint8_tobuffer(nsec3->flags, target));
  273     RETERR(uint16_tobuffer(nsec3->iterations, target));
  274     RETERR(uint8_tobuffer(nsec3->salt_length, target));
  275     RETERR(mem_tobuffer(target, nsec3->salt, nsec3->salt_length));
  276     RETERR(uint8_tobuffer(nsec3->next_length, target));
  277     RETERR(mem_tobuffer(target, nsec3->next, nsec3->next_length));
  278 
  279     region.base = nsec3->typebits;
  280     region.length = nsec3->len;
  281     RETERR(typemap_test(&region, true));
  282     return (mem_tobuffer(target, nsec3->typebits, nsec3->len));
  283 }
  284 
  285 static inline isc_result_t
  286 tostruct_nsec3(ARGS_TOSTRUCT) {
  287     isc_region_t region;
  288     dns_rdata_nsec3_t *nsec3 = target;
  289 
  290     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  291     REQUIRE(nsec3 != NULL);
  292     REQUIRE(rdata->length != 0);
  293 
  294     nsec3->common.rdclass = rdata->rdclass;
  295     nsec3->common.rdtype = rdata->type;
  296     ISC_LINK_INIT(&nsec3->common, link);
  297 
  298     region.base = rdata->data;
  299     region.length = rdata->length;
  300     nsec3->hash = uint8_consume_fromregion(&region);
  301     nsec3->flags = uint8_consume_fromregion(&region);
  302     nsec3->iterations = uint16_consume_fromregion(&region);
  303 
  304     nsec3->salt_length = uint8_consume_fromregion(&region);
  305     nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length);
  306     if (nsec3->salt == NULL) {
  307         return (ISC_R_NOMEMORY);
  308     }
  309     isc_region_consume(&region, nsec3->salt_length);
  310 
  311     nsec3->next_length = uint8_consume_fromregion(&region);
  312     nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length);
  313     if (nsec3->next == NULL) {
  314         goto cleanup;
  315     }
  316     isc_region_consume(&region, nsec3->next_length);
  317 
  318     nsec3->len = region.length;
  319     nsec3->typebits = mem_maybedup(mctx, region.base, region.length);
  320     if (nsec3->typebits == NULL) {
  321         goto cleanup;
  322     }
  323 
  324     nsec3->mctx = mctx;
  325     return (ISC_R_SUCCESS);
  326 
  327 cleanup:
  328     if (nsec3->next != NULL) {
  329         isc_mem_free(mctx, nsec3->next);
  330     }
  331     isc_mem_free(mctx, nsec3->salt);
  332     return (ISC_R_NOMEMORY);
  333 }
  334 
  335 static inline void
  336 freestruct_nsec3(ARGS_FREESTRUCT) {
  337     dns_rdata_nsec3_t *nsec3 = source;
  338 
  339     REQUIRE(nsec3 != NULL);
  340     REQUIRE(nsec3->common.rdtype == dns_rdatatype_nsec3);
  341 
  342     if (nsec3->mctx == NULL) {
  343         return;
  344     }
  345 
  346     if (nsec3->salt != NULL) {
  347         isc_mem_free(nsec3->mctx, nsec3->salt);
  348     }
  349     if (nsec3->next != NULL) {
  350         isc_mem_free(nsec3->mctx, nsec3->next);
  351     }
  352     if (nsec3->typebits != NULL) {
  353         isc_mem_free(nsec3->mctx, nsec3->typebits);
  354     }
  355     nsec3->mctx = NULL;
  356 }
  357 
  358 static inline isc_result_t
  359 additionaldata_nsec3(ARGS_ADDLDATA) {
  360     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  361 
  362     UNUSED(rdata);
  363     UNUSED(add);
  364     UNUSED(arg);
  365 
  366     return (ISC_R_SUCCESS);
  367 }
  368 
  369 static inline isc_result_t
  370 digest_nsec3(ARGS_DIGEST) {
  371     isc_region_t r;
  372 
  373     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  374 
  375     dns_rdata_toregion(rdata, &r);
  376     return ((digest)(arg, &r));
  377 }
  378 
  379 static inline bool
  380 checkowner_nsec3(ARGS_CHECKOWNER) {
  381     unsigned char owner[NSEC3_MAX_HASH_LENGTH];
  382     isc_buffer_t buffer;
  383     dns_label_t label;
  384 
  385     REQUIRE(type == dns_rdatatype_nsec3);
  386 
  387     UNUSED(type);
  388     UNUSED(rdclass);
  389     UNUSED(wildcard);
  390 
  391     /*
  392      * First label is a base32hex string without padding.
  393      */
  394     dns_name_getlabel(name, 0, &label);
  395     isc_region_consume(&label, 1);
  396     isc_buffer_init(&buffer, owner, sizeof(owner));
  397     if (isc_base32hexnp_decoderegion(&label, &buffer) == ISC_R_SUCCESS) {
  398         return (true);
  399     }
  400 
  401     return (false);
  402 }
  403 
  404 static inline bool
  405 checknames_nsec3(ARGS_CHECKNAMES) {
  406     REQUIRE(rdata->type == dns_rdatatype_nsec3);
  407 
  408     UNUSED(rdata);
  409     UNUSED(owner);
  410     UNUSED(bad);
  411 
  412     return (true);
  413 }
  414 
  415 static inline int
  416 casecompare_nsec3(ARGS_COMPARE) {
  417     return (compare_nsec3(rdata1, rdata2));
  418 }
  419 
  420 #endif /* RDATA_GENERIC_NSEC3_50_C */