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