1/* 2 * Copyright (C) 2012 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$ */ 18 19/* draft-ietf-dane-protocol-19.txt */ 20 21#ifndef RDATA_GENERIC_TLSA_52_C 22#define RDATA_GENERIC_TLSA_52_C 23 24#define RRTYPE_TLSA_ATTRIBUTES 0 25 26static inline isc_result_t 27fromtext_tlsa(ARGS_FROMTEXT) { 28 isc_token_t token; 29 30 REQUIRE(type == 52); 31 32 UNUSED(type); 33 UNUSED(rdclass); 34 UNUSED(origin); 35 UNUSED(options); 36 UNUSED(callbacks); 37 38 /* 39 * Certificate Usage. 40 */ 41 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 42 ISC_FALSE)); 43 if (token.value.as_ulong > 0xffU) 44 RETTOK(ISC_R_RANGE); 45 RETERR(uint8_tobuffer(token.value.as_ulong, target)); 46 47 /* 48 * Selector. 49 */ 50 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 51 ISC_FALSE)); 52 if (token.value.as_ulong > 0xffU) 53 RETTOK(ISC_R_RANGE); 54 RETERR(uint8_tobuffer(token.value.as_ulong, target)); 55 56 /* 57 * Matching type. 58 */ 59 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 60 ISC_FALSE)); 61 if (token.value.as_ulong > 0xffU) 62 RETTOK(ISC_R_RANGE); 63 RETERR(uint8_tobuffer(token.value.as_ulong, target)); 64 65 /* 66 * Certificate Association Data. 67 */ 68 return (isc_hex_tobuffer(lexer, target, -1)); 69} 70 71static inline isc_result_t 72totext_tlsa(ARGS_TOTEXT) { 73 isc_region_t sr; 74 char buf[sizeof("64000 ")]; 75 unsigned int n; 76 77 REQUIRE(rdata->type == 52); 78 REQUIRE(rdata->length != 0); 79 80 UNUSED(tctx); 81 82 dns_rdata_toregion(rdata, &sr); 83 84 /* 85 * Certificate Usage. 86 */ 87 n = uint8_fromregion(&sr); 88 isc_region_consume(&sr, 1); 89 sprintf(buf, "%u ", n); 90 RETERR(str_totext(buf, target)); 91 92 /* 93 * Selector. 94 */ 95 n = uint8_fromregion(&sr); 96 isc_region_consume(&sr, 1); 97 sprintf(buf, "%u ", n); 98 RETERR(str_totext(buf, target)); 99 100 /* 101 * Matching type. 102 */ 103 n = uint8_fromregion(&sr); 104 isc_region_consume(&sr, 1); 105 sprintf(buf, "%u", n); 106 RETERR(str_totext(buf, target)); 107 108 /* 109 * Certificate Association Data. 110 */ 111 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 112 RETERR(str_totext(" (", target)); 113 RETERR(str_totext(tctx->linebreak, target)); 114 if (tctx->width == 0) /* No splitting */ 115 RETERR(isc_hex_totext(&sr, 0, "", target)); 116 else 117 RETERR(isc_hex_totext(&sr, tctx->width - 2, 118 tctx->linebreak, target)); 119 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 120 RETERR(str_totext(" )", target)); 121 return (ISC_R_SUCCESS); 122} 123 124static inline isc_result_t 125fromwire_tlsa(ARGS_FROMWIRE) { 126 isc_region_t sr; 127 128 REQUIRE(type == 52); 129 130 UNUSED(type); 131 UNUSED(rdclass); 132 UNUSED(dctx); 133 UNUSED(options); 134 135 isc_buffer_activeregion(source, &sr); 136 137 if (sr.length < 3) 138 return (ISC_R_UNEXPECTEDEND); 139 140 isc_buffer_forward(source, sr.length); 141 return (mem_tobuffer(target, sr.base, sr.length)); 142} 143 144static inline isc_result_t 145towire_tlsa(ARGS_TOWIRE) { 146 isc_region_t sr; 147 148 REQUIRE(rdata->type == 52); 149 REQUIRE(rdata->length != 0); 150 151 UNUSED(cctx); 152 153 dns_rdata_toregion(rdata, &sr); 154 return (mem_tobuffer(target, sr.base, sr.length)); 155} 156 157static inline int 158compare_tlsa(ARGS_COMPARE) { 159 isc_region_t r1; 160 isc_region_t r2; 161 162 REQUIRE(rdata1->type == rdata2->type); 163 REQUIRE(rdata1->rdclass == rdata2->rdclass); 164 REQUIRE(rdata1->type == 52); 165 REQUIRE(rdata1->length != 0); 166 REQUIRE(rdata2->length != 0); 167 168 dns_rdata_toregion(rdata1, &r1); 169 dns_rdata_toregion(rdata2, &r2); 170 return (isc_region_compare(&r1, &r2)); 171} 172 173static inline isc_result_t 174fromstruct_tlsa(ARGS_FROMSTRUCT) { 175 dns_rdata_tlsa_t *tlsa = source; 176 177 REQUIRE(type == 52); 178 REQUIRE(source != NULL); 179 REQUIRE(tlsa->common.rdtype == type); 180 REQUIRE(tlsa->common.rdclass == rdclass); 181 182 UNUSED(type); 183 UNUSED(rdclass); 184 185 RETERR(uint8_tobuffer(tlsa->usage, target)); 186 RETERR(uint8_tobuffer(tlsa->selector, target)); 187 RETERR(uint8_tobuffer(tlsa->match, target)); 188 189 return (mem_tobuffer(target, tlsa->data, tlsa->length)); 190} 191 192static inline isc_result_t 193tostruct_tlsa(ARGS_TOSTRUCT) { 194 dns_rdata_tlsa_t *tlsa = target; 195 isc_region_t region; 196 197 REQUIRE(rdata->type == 52); 198 REQUIRE(target != NULL); 199 REQUIRE(rdata->length != 0); 200 201 tlsa->common.rdclass = rdata->rdclass; 202 tlsa->common.rdtype = rdata->type; 203 ISC_LINK_INIT(&tlsa->common, link); 204 205 dns_rdata_toregion(rdata, ®ion); 206 207 tlsa->usage = uint8_fromregion(®ion); 208 isc_region_consume(®ion, 1); 209 tlsa->selector = uint8_fromregion(®ion); 210 isc_region_consume(®ion, 1); 211 tlsa->match = uint8_fromregion(®ion); 212 isc_region_consume(®ion, 1); 213 tlsa->length = region.length; 214 215 tlsa->data = mem_maybedup(mctx, region.base, region.length); 216 if (tlsa->data == NULL) 217 return (ISC_R_NOMEMORY); 218 219 tlsa->mctx = mctx; 220 return (ISC_R_SUCCESS); 221} 222 223static inline void 224freestruct_tlsa(ARGS_FREESTRUCT) { 225 dns_rdata_tlsa_t *tlsa = source; 226 227 REQUIRE(tlsa != NULL); 228 REQUIRE(tlsa->common.rdtype == 52); 229 230 if (tlsa->mctx == NULL) 231 return; 232 233 if (tlsa->data != NULL) 234 isc_mem_free(tlsa->mctx, tlsa->data); 235 tlsa->mctx = NULL; 236} 237 238static inline isc_result_t 239additionaldata_tlsa(ARGS_ADDLDATA) { 240 REQUIRE(rdata->type == 52); 241 242 UNUSED(rdata); 243 UNUSED(add); 244 UNUSED(arg); 245 246 return (ISC_R_SUCCESS); 247} 248 249static inline isc_result_t 250digest_tlsa(ARGS_DIGEST) { 251 isc_region_t r; 252 253 REQUIRE(rdata->type == 52); 254 255 dns_rdata_toregion(rdata, &r); 256 257 return ((digest)(arg, &r)); 258} 259 260static inline isc_boolean_t 261checkowner_tlsa(ARGS_CHECKOWNER) { 262 263 REQUIRE(type == 52); 264 265 UNUSED(name); 266 UNUSED(type); 267 UNUSED(rdclass); 268 UNUSED(wildcard); 269 270 return (ISC_TRUE); 271} 272 273static inline isc_boolean_t 274checknames_tlsa(ARGS_CHECKNAMES) { 275 276 REQUIRE(rdata->type == 52); 277 278 UNUSED(rdata); 279 UNUSED(owner); 280 UNUSED(bad); 281 282 return (ISC_TRUE); 283} 284 285static inline int 286casecompare_tlsa(ARGS_COMPARE) { 287 return (compare_tlsa(rdata1, rdata2)); 288} 289 290#endif /* RDATA_GENERIC_TLSA_52_C */ 291