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