1/* 2 * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id: nsec3param_51.c,v 1.7 2009/12/04 21:09:34 marka Exp $ */ 18 19/* 20 * Copyright (C) 2004 Nominet, Ltd. 21 * 22 * Permission to use, copy, modify, and distribute this software for any 23 * purpose with or without fee is hereby granted, provided that the above 24 * copyright notice and this permission notice appear in all copies. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH 27 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 28 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 29 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 30 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 31 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 32 * PERFORMANCE OF THIS SOFTWARE. 33 */ 34 35/* RFC 5155 */ 36 37#ifndef RDATA_GENERIC_NSEC3PARAM_51_C 38#define RDATA_GENERIC_NSEC3PARAM_51_C 39 40#include <isc/iterated_hash.h> 41#include <isc/base32.h> 42 43#define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) 44 45static inline isc_result_t 46fromtext_nsec3param(ARGS_FROMTEXT) { 47 isc_token_t token; 48 unsigned int flags = 0; 49 unsigned char hashalg; 50 51 REQUIRE(type == 51); 52 53 UNUSED(type); 54 UNUSED(rdclass); 55 UNUSED(callbacks); 56 UNUSED(origin); 57 UNUSED(options); 58 59 /* Hash. */ 60 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 61 ISC_FALSE)); 62 RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); 63 RETERR(uint8_tobuffer(hashalg, target)); 64 65 /* Flags. */ 66 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 67 ISC_FALSE)); 68 flags = token.value.as_ulong; 69 if (flags > 255U) 70 RETTOK(ISC_R_RANGE); 71 RETERR(uint8_tobuffer(flags, target)); 72 73 /* Iterations. */ 74 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 75 ISC_FALSE)); 76 if (token.value.as_ulong > 0xffffU) 77 RETTOK(ISC_R_RANGE); 78 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 79 80 /* Salt. */ 81 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 82 ISC_FALSE)); 83 if (token.value.as_textregion.length > (255*2)) 84 RETTOK(DNS_R_TEXTTOOLONG); 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 inline 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 isc_uint32_t iterations; 103 104 REQUIRE(rdata->type == 51); 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 sprintf(buf, "%u ", hash); 121 RETERR(str_totext(buf, target)); 122 123 sprintf(buf, "%u ", flags); 124 RETERR(str_totext(buf, target)); 125 126 sprintf(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 return (ISC_R_SUCCESS); 142} 143 144static inline isc_result_t 145fromwire_nsec3param(ARGS_FROMWIRE) { 146 isc_region_t sr, rr; 147 unsigned int saltlen; 148 149 REQUIRE(type == 51); 150 151 UNUSED(type); 152 UNUSED(rdclass); 153 UNUSED(options); 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 saltlen = sr.base[4]; 163 isc_region_consume(&sr, 5); 164 165 if (sr.length < saltlen) 166 RETERR(DNS_R_FORMERR); 167 isc_region_consume(&sr, saltlen); 168 RETERR(mem_tobuffer(target, rr.base, rr.length)); 169 isc_buffer_forward(source, rr.length); 170 return (ISC_R_SUCCESS); 171} 172 173static inline isc_result_t 174towire_nsec3param(ARGS_TOWIRE) { 175 isc_region_t sr; 176 177 REQUIRE(rdata->type == 51); 178 REQUIRE(rdata->length != 0); 179 180 UNUSED(cctx); 181 182 dns_rdata_toregion(rdata, &sr); 183 return (mem_tobuffer(target, sr.base, sr.length)); 184} 185 186static inline int 187compare_nsec3param(ARGS_COMPARE) { 188 isc_region_t r1; 189 isc_region_t r2; 190 191 REQUIRE(rdata1->type == rdata2->type); 192 REQUIRE(rdata1->rdclass == rdata2->rdclass); 193 REQUIRE(rdata1->type == 51); 194 REQUIRE(rdata1->length != 0); 195 REQUIRE(rdata2->length != 0); 196 197 dns_rdata_toregion(rdata1, &r1); 198 dns_rdata_toregion(rdata2, &r2); 199 return (isc_region_compare(&r1, &r2)); 200} 201 202static inline isc_result_t 203fromstruct_nsec3param(ARGS_FROMSTRUCT) { 204 dns_rdata_nsec3param_t *nsec3param = source; 205 206 REQUIRE(type == 51); 207 REQUIRE(source != NULL); 208 REQUIRE(nsec3param->common.rdtype == type); 209 REQUIRE(nsec3param->common.rdclass == rdclass); 210 211 UNUSED(type); 212 UNUSED(rdclass); 213 214 RETERR(uint8_tobuffer(nsec3param->hash, target)); 215 RETERR(uint8_tobuffer(nsec3param->flags, target)); 216 RETERR(uint16_tobuffer(nsec3param->iterations, target)); 217 RETERR(uint8_tobuffer(nsec3param->salt_length, target)); 218 RETERR(mem_tobuffer(target, nsec3param->salt, 219 nsec3param->salt_length)); 220 return (ISC_R_SUCCESS); 221} 222 223static inline isc_result_t 224tostruct_nsec3param(ARGS_TOSTRUCT) { 225 isc_region_t region; 226 dns_rdata_nsec3param_t *nsec3param = target; 227 228 REQUIRE(rdata->type == 51); 229 REQUIRE(target != 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 isc_region_consume(®ion, nsec3param->salt_length); 248 249 nsec3param->mctx = mctx; 250 return (ISC_R_SUCCESS); 251} 252 253static inline void 254freestruct_nsec3param(ARGS_FREESTRUCT) { 255 dns_rdata_nsec3param_t *nsec3param = source; 256 257 REQUIRE(source != NULL); 258 REQUIRE(nsec3param->common.rdtype == 51); 259 260 if (nsec3param->mctx == NULL) 261 return; 262 263 if (nsec3param->salt != NULL) 264 isc_mem_free(nsec3param->mctx, nsec3param->salt); 265 nsec3param->mctx = NULL; 266} 267 268static inline isc_result_t 269additionaldata_nsec3param(ARGS_ADDLDATA) { 270 REQUIRE(rdata->type == 51); 271 272 UNUSED(rdata); 273 UNUSED(add); 274 UNUSED(arg); 275 276 return (ISC_R_SUCCESS); 277} 278 279static inline isc_result_t 280digest_nsec3param(ARGS_DIGEST) { 281 isc_region_t r; 282 283 REQUIRE(rdata->type == 51); 284 285 dns_rdata_toregion(rdata, &r); 286 return ((digest)(arg, &r)); 287} 288 289static inline isc_boolean_t 290checkowner_nsec3param(ARGS_CHECKOWNER) { 291 292 REQUIRE(type == 51); 293 294 UNUSED(name); 295 UNUSED(type); 296 UNUSED(rdclass); 297 UNUSED(wildcard); 298 299 return (ISC_TRUE); 300} 301 302static inline isc_boolean_t 303checknames_nsec3param(ARGS_CHECKNAMES) { 304 305 REQUIRE(rdata->type == 51); 306 307 UNUSED(rdata); 308 UNUSED(owner); 309 UNUSED(bad); 310 311 return (ISC_TRUE); 312} 313 314static inline int 315casecompare_nsec3param(ARGS_COMPARE) { 316 return (compare_nsec3param(rdata1, rdata2)); 317} 318 319#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */ 320