"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/dns/rdata/generic/nsec3_50.c" (7 Sep 2020, 10561 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


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.11.22_vs_9.11.23.

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