Home | History | Annotate | Line # | Download | only in generic
      1 /*	$NetBSD: nsec3param_51.c,v 1.11 2026/01/29 18:37:53 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 /*
     17  * Copyright (C) 2004  Nominet, Ltd.
     18  *
     19  * Permission to use, copy, modify, and distribute this software for any
     20  * purpose with or without fee is hereby granted, provided that the above
     21  * copyright notice and this permission notice appear in all copies.
     22  *
     23  * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
     24  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     25  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
     26  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     27  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     28  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     29  * PERFORMANCE OF THIS SOFTWARE.
     30  */
     31 
     32 /* RFC 5155 */
     33 
     34 #ifndef RDATA_GENERIC_NSEC3PARAM_51_C
     35 #define RDATA_GENERIC_NSEC3PARAM_51_C
     36 
     37 #include <isc/base32.h>
     38 #include <isc/iterated_hash.h>
     39 
     40 #define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
     41 
     42 static isc_result_t
     43 fromtext_nsec3param(ARGS_FROMTEXT) {
     44 	isc_token_t token;
     45 	unsigned int flags = 0;
     46 	unsigned char hashalg;
     47 
     48 	REQUIRE(type == dns_rdatatype_nsec3param);
     49 
     50 	UNUSED(type);
     51 	UNUSED(rdclass);
     52 	UNUSED(callbacks);
     53 	UNUSED(origin);
     54 	UNUSED(options);
     55 
     56 	/* Hash. */
     57 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     58 				      false));
     59 	RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
     60 	RETERR(uint8_tobuffer(hashalg, target));
     61 
     62 	/* Flags. */
     63 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     64 				      false));
     65 	flags = token.value.as_ulong;
     66 	if (flags > 255U) {
     67 		RETTOK(ISC_R_RANGE);
     68 	}
     69 	RETERR(uint8_tobuffer(flags, target));
     70 
     71 	/* Iterations. */
     72 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     73 				      false));
     74 	if (token.value.as_ulong > 0xffffU) {
     75 		RETTOK(ISC_R_RANGE);
     76 	}
     77 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
     78 
     79 	/* Salt. */
     80 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     81 				      false));
     82 	if (token.value.as_textregion.length > (255 * 2)) {
     83 		RETTOK(DNS_R_TEXTTOOLONG);
     84 	}
     85 	if (strcmp(DNS_AS_STR(token), "-") == 0) {
     86 		RETERR(uint8_tobuffer(0, target));
     87 	} else {
     88 		RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
     89 		RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
     90 	}
     91 
     92 	return ISC_R_SUCCESS;
     93 }
     94 
     95 static isc_result_t
     96 totext_nsec3param(ARGS_TOTEXT) {
     97 	isc_region_t sr;
     98 	unsigned int i, j;
     99 	unsigned char hash;
    100 	unsigned char flags;
    101 	char buf[sizeof("65535 ")];
    102 	uint32_t iterations;
    103 
    104 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    105 	REQUIRE(rdata->length != 0);
    106 
    107 	UNUSED(tctx);
    108 
    109 	dns_rdata_toregion(rdata, &sr);
    110 
    111 	hash = uint8_fromregion(&sr);
    112 	isc_region_consume(&sr, 1);
    113 
    114 	flags = uint8_fromregion(&sr);
    115 	isc_region_consume(&sr, 1);
    116 
    117 	iterations = uint16_fromregion(&sr);
    118 	isc_region_consume(&sr, 2);
    119 
    120 	snprintf(buf, sizeof(buf), "%u ", hash);
    121 	RETERR(str_totext(buf, target));
    122 
    123 	snprintf(buf, sizeof(buf), "%u ", flags);
    124 	RETERR(str_totext(buf, target));
    125 
    126 	snprintf(buf, sizeof(buf), "%u ", iterations);
    127 	RETERR(str_totext(buf, target));
    128 
    129 	j = uint8_fromregion(&sr);
    130 	isc_region_consume(&sr, 1);
    131 	INSIST(j <= sr.length);
    132 
    133 	if (j != 0) {
    134 		i = sr.length;
    135 		sr.length = j;
    136 		RETERR(isc_hex_totext(&sr, 1, "", target));
    137 		sr.length = i - j;
    138 	} else {
    139 		RETERR(str_totext("-", target));
    140 	}
    141 
    142 	return ISC_R_SUCCESS;
    143 }
    144 
    145 static isc_result_t
    146 fromwire_nsec3param(ARGS_FROMWIRE) {
    147 	isc_region_t sr, rr;
    148 	unsigned int saltlen;
    149 
    150 	REQUIRE(type == dns_rdatatype_nsec3param);
    151 
    152 	UNUSED(type);
    153 	UNUSED(rdclass);
    154 	UNUSED(dctx);
    155 
    156 	isc_buffer_activeregion(source, &sr);
    157 	rr = sr;
    158 
    159 	/* hash(1), flags(1), iterations(2), saltlen(1) */
    160 	if (sr.length < 5U) {
    161 		RETERR(DNS_R_FORMERR);
    162 	}
    163 	saltlen = sr.base[4];
    164 	isc_region_consume(&sr, 5);
    165 
    166 	if (sr.length != saltlen) {
    167 		RETERR(DNS_R_FORMERR);
    168 	}
    169 	isc_region_consume(&sr, saltlen);
    170 	RETERR(mem_tobuffer(target, rr.base, rr.length));
    171 	isc_buffer_forward(source, rr.length);
    172 	return ISC_R_SUCCESS;
    173 }
    174 
    175 static isc_result_t
    176 towire_nsec3param(ARGS_TOWIRE) {
    177 	isc_region_t sr;
    178 
    179 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    180 	REQUIRE(rdata->length != 0);
    181 
    182 	UNUSED(cctx);
    183 
    184 	dns_rdata_toregion(rdata, &sr);
    185 	return mem_tobuffer(target, sr.base, sr.length);
    186 }
    187 
    188 static int
    189 compare_nsec3param(ARGS_COMPARE) {
    190 	isc_region_t r1;
    191 	isc_region_t r2;
    192 
    193 	REQUIRE(rdata1->type == rdata2->type);
    194 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
    195 	REQUIRE(rdata1->type == dns_rdatatype_nsec3param);
    196 	REQUIRE(rdata1->length != 0);
    197 	REQUIRE(rdata2->length != 0);
    198 
    199 	dns_rdata_toregion(rdata1, &r1);
    200 	dns_rdata_toregion(rdata2, &r2);
    201 	return isc_region_compare(&r1, &r2);
    202 }
    203 
    204 static isc_result_t
    205 fromstruct_nsec3param(ARGS_FROMSTRUCT) {
    206 	dns_rdata_nsec3param_t *nsec3param = source;
    207 
    208 	REQUIRE(type == dns_rdatatype_nsec3param);
    209 	REQUIRE(nsec3param != NULL);
    210 	REQUIRE(nsec3param->common.rdtype == type);
    211 	REQUIRE(nsec3param->common.rdclass == rdclass);
    212 
    213 	UNUSED(type);
    214 	UNUSED(rdclass);
    215 
    216 	RETERR(uint8_tobuffer(nsec3param->hash, target));
    217 	RETERR(uint8_tobuffer(nsec3param->flags, target));
    218 	RETERR(uint16_tobuffer(nsec3param->iterations, target));
    219 	RETERR(uint8_tobuffer(nsec3param->salt_length, target));
    220 	RETERR(mem_tobuffer(target, nsec3param->salt, nsec3param->salt_length));
    221 	return ISC_R_SUCCESS;
    222 }
    223 
    224 static isc_result_t
    225 tostruct_nsec3param(ARGS_TOSTRUCT) {
    226 	isc_region_t region;
    227 	dns_rdata_nsec3param_t *nsec3param = target;
    228 
    229 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    230 	REQUIRE(nsec3param != NULL);
    231 	REQUIRE(rdata->length != 0);
    232 
    233 	DNS_RDATACOMMON_INIT(nsec3param, rdata->type, rdata->rdclass);
    234 
    235 	region.base = rdata->data;
    236 	region.length = rdata->length;
    237 	nsec3param->hash = uint8_consume_fromregion(&region);
    238 	nsec3param->flags = uint8_consume_fromregion(&region);
    239 	nsec3param->iterations = uint16_consume_fromregion(&region);
    240 
    241 	nsec3param->salt_length = uint8_consume_fromregion(&region);
    242 	INSIST(nsec3param->salt_length == region.length);
    243 	nsec3param->salt = mem_maybedup(mctx, region.base,
    244 					nsec3param->salt_length);
    245 	isc_region_consume(&region, nsec3param->salt_length);
    246 
    247 	nsec3param->mctx = mctx;
    248 	return ISC_R_SUCCESS;
    249 }
    250 
    251 static void
    252 freestruct_nsec3param(ARGS_FREESTRUCT) {
    253 	dns_rdata_nsec3param_t *nsec3param = source;
    254 
    255 	REQUIRE(nsec3param != NULL);
    256 	REQUIRE(nsec3param->common.rdtype == dns_rdatatype_nsec3param);
    257 
    258 	if (nsec3param->mctx == NULL) {
    259 		return;
    260 	}
    261 
    262 	if (nsec3param->salt != NULL) {
    263 		isc_mem_free(nsec3param->mctx, nsec3param->salt);
    264 	}
    265 	nsec3param->mctx = NULL;
    266 }
    267 
    268 static isc_result_t
    269 additionaldata_nsec3param(ARGS_ADDLDATA) {
    270 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    271 
    272 	UNUSED(rdata);
    273 	UNUSED(owner);
    274 	UNUSED(add);
    275 	UNUSED(arg);
    276 
    277 	return ISC_R_SUCCESS;
    278 }
    279 
    280 static isc_result_t
    281 digest_nsec3param(ARGS_DIGEST) {
    282 	isc_region_t r;
    283 
    284 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    285 
    286 	dns_rdata_toregion(rdata, &r);
    287 	return (digest)(arg, &r);
    288 }
    289 
    290 static bool
    291 checkowner_nsec3param(ARGS_CHECKOWNER) {
    292 	REQUIRE(type == dns_rdatatype_nsec3param);
    293 
    294 	UNUSED(name);
    295 	UNUSED(type);
    296 	UNUSED(rdclass);
    297 	UNUSED(wildcard);
    298 
    299 	return true;
    300 }
    301 
    302 static bool
    303 checknames_nsec3param(ARGS_CHECKNAMES) {
    304 	REQUIRE(rdata->type == dns_rdatatype_nsec3param);
    305 
    306 	UNUSED(rdata);
    307 	UNUSED(owner);
    308 	UNUSED(bad);
    309 
    310 	return true;
    311 }
    312 
    313 static int
    314 casecompare_nsec3param(ARGS_COMPARE) {
    315 	return compare_nsec3param(rdata1, rdata2);
    316 }
    317 
    318 #endif /* RDATA_GENERIC_NSEC3PARAM_51_C */
    319