1/* $NetBSD: nsec3param_51.c,v 1.1 2024/02/18 20:57:43 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 42static isc_result_t 43fromtext_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 95static isc_result_t 96totext_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 145static isc_result_t 146fromwire_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(options); 155 UNUSED(dctx); 156 157 isc_buffer_activeregion(source, &sr); 158 rr = sr; 159 160 /* hash(1), flags(1), iterations(2), saltlen(1) */ 161 if (sr.length < 5U) { 162 RETERR(DNS_R_FORMERR); 163 } 164 saltlen = sr.base[4]; 165 isc_region_consume(&sr, 5); 166 167 if (sr.length != saltlen) { 168 RETERR(DNS_R_FORMERR); 169 } 170 isc_region_consume(&sr, saltlen); 171 RETERR(mem_tobuffer(target, rr.base, rr.length)); 172 isc_buffer_forward(source, rr.length); 173 return (ISC_R_SUCCESS); 174} 175 176static isc_result_t 177towire_nsec3param(ARGS_TOWIRE) { 178 isc_region_t sr; 179 180 REQUIRE(rdata->type == dns_rdatatype_nsec3param); 181 REQUIRE(rdata->length != 0); 182 183 UNUSED(cctx); 184 185 dns_rdata_toregion(rdata, &sr); 186 return (mem_tobuffer(target, sr.base, sr.length)); 187} 188 189static int 190compare_nsec3param(ARGS_COMPARE) { 191 isc_region_t r1; 192 isc_region_t r2; 193 194 REQUIRE(rdata1->type == rdata2->type); 195 REQUIRE(rdata1->rdclass == rdata2->rdclass); 196 REQUIRE(rdata1->type == dns_rdatatype_nsec3param); 197 REQUIRE(rdata1->length != 0); 198 REQUIRE(rdata2->length != 0); 199 200 dns_rdata_toregion(rdata1, &r1); 201 dns_rdata_toregion(rdata2, &r2); 202 return (isc_region_compare(&r1, &r2)); 203} 204 205static isc_result_t 206fromstruct_nsec3param(ARGS_FROMSTRUCT) { 207 dns_rdata_nsec3param_t *nsec3param = source; 208 209 REQUIRE(type == dns_rdatatype_nsec3param); 210 REQUIRE(nsec3param != NULL); 211 REQUIRE(nsec3param->common.rdtype == type); 212 REQUIRE(nsec3param->common.rdclass == rdclass); 213 214 UNUSED(type); 215 UNUSED(rdclass); 216 217 RETERR(uint8_tobuffer(nsec3param->hash, target)); 218 RETERR(uint8_tobuffer(nsec3param->flags, target)); 219 RETERR(uint16_tobuffer(nsec3param->iterations, target)); 220 RETERR(uint8_tobuffer(nsec3param->salt_length, target)); 221 RETERR(mem_tobuffer(target, nsec3param->salt, nsec3param->salt_length)); 222 return (ISC_R_SUCCESS); 223} 224 225static isc_result_t 226tostruct_nsec3param(ARGS_TOSTRUCT) { 227 isc_region_t region; 228 dns_rdata_nsec3param_t *nsec3param = target; 229 230 REQUIRE(rdata->type == dns_rdatatype_nsec3param); 231 REQUIRE(nsec3param != NULL); 232 REQUIRE(rdata->length != 0); 233 234 nsec3param->common.rdclass = rdata->rdclass; 235 nsec3param->common.rdtype = rdata->type; 236 ISC_LINK_INIT(&nsec3param->common, link); 237 238 region.base = rdata->data; 239 region.length = rdata->length; 240 nsec3param->hash = uint8_consume_fromregion(®ion); 241 nsec3param->flags = uint8_consume_fromregion(®ion); 242 nsec3param->iterations = uint16_consume_fromregion(®ion); 243 244 nsec3param->salt_length = uint8_consume_fromregion(®ion); 245 INSIST(nsec3param->salt_length == region.length); 246 nsec3param->salt = mem_maybedup(mctx, region.base, 247 nsec3param->salt_length); 248 if (nsec3param->salt == NULL) { 249 return (ISC_R_NOMEMORY); 250 } 251 isc_region_consume(®ion, nsec3param->salt_length); 252 253 nsec3param->mctx = mctx; 254 return (ISC_R_SUCCESS); 255} 256 257static void 258freestruct_nsec3param(ARGS_FREESTRUCT) { 259 dns_rdata_nsec3param_t *nsec3param = source; 260 261 REQUIRE(nsec3param != NULL); 262 REQUIRE(nsec3param->common.rdtype == dns_rdatatype_nsec3param); 263 264 if (nsec3param->mctx == NULL) { 265 return; 266 } 267 268 if (nsec3param->salt != NULL) { 269 isc_mem_free(nsec3param->mctx, nsec3param->salt); 270 } 271 nsec3param->mctx = NULL; 272} 273 274static isc_result_t 275additionaldata_nsec3param(ARGS_ADDLDATA) { 276 REQUIRE(rdata->type == dns_rdatatype_nsec3param); 277 278 UNUSED(rdata); 279 UNUSED(add); 280 UNUSED(arg); 281 282 return (ISC_R_SUCCESS); 283} 284 285static isc_result_t 286digest_nsec3param(ARGS_DIGEST) { 287 isc_region_t r; 288 289 REQUIRE(rdata->type == dns_rdatatype_nsec3param); 290 291 dns_rdata_toregion(rdata, &r); 292 return ((digest)(arg, &r)); 293} 294 295static bool 296checkowner_nsec3param(ARGS_CHECKOWNER) { 297 REQUIRE(type == dns_rdatatype_nsec3param); 298 299 UNUSED(name); 300 UNUSED(type); 301 UNUSED(rdclass); 302 UNUSED(wildcard); 303 304 return (true); 305} 306 307static bool 308checknames_nsec3param(ARGS_CHECKNAMES) { 309 REQUIRE(rdata->type == dns_rdatatype_nsec3param); 310 311 UNUSED(rdata); 312 UNUSED(owner); 313 UNUSED(bad); 314 315 return (true); 316} 317 318static int 319casecompare_nsec3param(ARGS_COMPARE) { 320 return (compare_nsec3param(rdata1, rdata2)); 321} 322 323#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */ 324