1 /* $NetBSD: keydata_65533.c,v 1.6 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 #ifndef GENERIC_KEYDATA_65533_C 15 #define GENERIC_KEYDATA_65533_C 1 16 17 #include <isc/stdtime.h> 18 #include <isc/time.h> 19 20 #include <dst/dst.h> 21 22 #define RRTYPE_KEYDATA_ATTRIBUTES (0) 23 24 static inline isc_result_t 25 fromtext_keydata(ARGS_FROMTEXT) { 26 isc_token_t token; 27 dns_secalg_t alg; 28 dns_secproto_t proto; 29 dns_keyflags_t flags; 30 uint32_t refresh, addhd, removehd; 31 32 REQUIRE(type == dns_rdatatype_keydata); 33 34 UNUSED(type); 35 UNUSED(rdclass); 36 UNUSED(origin); 37 UNUSED(options); 38 UNUSED(callbacks); 39 40 /* refresh timer */ 41 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 42 false)); 43 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); 44 RETERR(uint32_tobuffer(refresh, target)); 45 46 /* add hold-down */ 47 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 48 false)); 49 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); 50 RETERR(uint32_tobuffer(addhd, target)); 51 52 /* remove hold-down */ 53 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 54 false)); 55 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); 56 RETERR(uint32_tobuffer(removehd, target)); 57 58 /* flags */ 59 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 60 false)); 61 RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); 62 RETERR(uint16_tobuffer(flags, target)); 63 64 /* protocol */ 65 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 66 false)); 67 RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); 68 RETERR(mem_tobuffer(target, &proto, 1)); 69 70 /* algorithm */ 71 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 72 false)); 73 RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); 74 RETERR(mem_tobuffer(target, &alg, 1)); 75 76 /* No Key? */ 77 if ((flags & 0xc000) == 0xc000) { 78 return (ISC_R_SUCCESS); 79 } 80 81 return (isc_base64_tobuffer(lexer, target, -2)); 82 } 83 84 static inline isc_result_t 85 totext_keydata(ARGS_TOTEXT) { 86 isc_region_t sr; 87 char buf[sizeof("64000")]; 88 unsigned int flags; 89 unsigned char algorithm; 90 unsigned long refresh, add, deltime; 91 char algbuf[DNS_NAME_FORMATSIZE]; 92 const char *keyinfo; 93 94 REQUIRE(rdata->type == dns_rdatatype_keydata); 95 96 if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) { 97 return (unknown_totext(rdata, tctx, target)); 98 } 99 100 dns_rdata_toregion(rdata, &sr); 101 102 /* refresh timer */ 103 refresh = uint32_fromregion(&sr); 104 isc_region_consume(&sr, 4); 105 RETERR(dns_time32_totext(refresh, target)); 106 RETERR(str_totext(" ", target)); 107 108 /* add hold-down */ 109 add = uint32_fromregion(&sr); 110 isc_region_consume(&sr, 4); 111 RETERR(dns_time32_totext(add, target)); 112 RETERR(str_totext(" ", target)); 113 114 /* remove hold-down */ 115 deltime = uint32_fromregion(&sr); 116 isc_region_consume(&sr, 4); 117 RETERR(dns_time32_totext(deltime, target)); 118 RETERR(str_totext(" ", target)); 119 120 /* flags */ 121 flags = uint16_fromregion(&sr); 122 isc_region_consume(&sr, 2); 123 snprintf(buf, sizeof(buf), "%u", flags); 124 RETERR(str_totext(buf, target)); 125 RETERR(str_totext(" ", target)); 126 if ((flags & DNS_KEYFLAG_KSK) != 0) { 127 if ((flags & DNS_KEYFLAG_REVOKE) != 0) { 128 keyinfo = "revoked KSK"; 129 } else { 130 keyinfo = "KSK"; 131 } 132 } else { 133 keyinfo = "ZSK"; 134 } 135 136 /* protocol */ 137 snprintf(buf, sizeof(buf), "%u", sr.base[0]); 138 isc_region_consume(&sr, 1); 139 RETERR(str_totext(buf, target)); 140 RETERR(str_totext(" ", target)); 141 142 /* algorithm */ 143 algorithm = sr.base[0]; 144 snprintf(buf, sizeof(buf), "%u", algorithm); 145 isc_region_consume(&sr, 1); 146 RETERR(str_totext(buf, target)); 147 148 /* No Key? */ 149 if ((flags & 0xc000) == 0xc000) { 150 return (ISC_R_SUCCESS); 151 } 152 153 /* key */ 154 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 155 RETERR(str_totext(" (", target)); 156 } 157 RETERR(str_totext(tctx->linebreak, target)); 158 if (tctx->width == 0) { /* No splitting */ 159 RETERR(isc_base64_totext(&sr, 60, "", target)); 160 } else { 161 RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, 162 target)); 163 } 164 165 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { 166 RETERR(str_totext(tctx->linebreak, target)); 167 } else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 168 RETERR(str_totext(" ", target)); 169 } 170 171 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 172 RETERR(str_totext(")", target)); 173 } 174 175 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { 176 isc_region_t tmpr; 177 char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; 178 char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; 179 char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; 180 isc_time_t t; 181 182 RETERR(str_totext(" ; ", target)); 183 RETERR(str_totext(keyinfo, target)); 184 dns_secalg_format((dns_secalg_t)algorithm, algbuf, 185 sizeof(algbuf)); 186 RETERR(str_totext("; alg = ", target)); 187 RETERR(str_totext(algbuf, target)); 188 RETERR(str_totext("; key id = ", target)); 189 dns_rdata_toregion(rdata, &tmpr); 190 /* Skip over refresh, addhd, and removehd */ 191 isc_region_consume(&tmpr, 12); 192 snprintf(buf, sizeof(buf), "%u", dst_region_computeid(&tmpr)); 193 RETERR(str_totext(buf, target)); 194 195 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 196 isc_stdtime_t now; 197 198 isc_stdtime_get(&now); 199 200 RETERR(str_totext(tctx->linebreak, target)); 201 RETERR(str_totext("; next refresh: ", target)); 202 isc_time_set(&t, refresh, 0); 203 isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf)); 204 RETERR(str_totext(rbuf, target)); 205 206 if (add == 0U) { 207 RETERR(str_totext(tctx->linebreak, target)); 208 RETERR(str_totext("; no trust", target)); 209 } else { 210 RETERR(str_totext(tctx->linebreak, target)); 211 if (add < now) { 212 RETERR(str_totext("; trusted since: ", 213 target)); 214 } else { 215 RETERR(str_totext("; trust pending: ", 216 target)); 217 } 218 isc_time_set(&t, add, 0); 219 isc_time_formathttptimestamp(&t, abuf, 220 sizeof(abuf)); 221 RETERR(str_totext(abuf, target)); 222 } 223 224 if (deltime != 0U) { 225 RETERR(str_totext(tctx->linebreak, target)); 226 RETERR(str_totext("; removal pending: ", 227 target)); 228 isc_time_set(&t, deltime, 0); 229 isc_time_formathttptimestamp(&t, dbuf, 230 sizeof(dbuf)); 231 RETERR(str_totext(dbuf, target)); 232 } 233 } 234 } 235 return (ISC_R_SUCCESS); 236 } 237 238 static inline isc_result_t 239 fromwire_keydata(ARGS_FROMWIRE) { 240 isc_region_t sr; 241 242 REQUIRE(type == dns_rdatatype_keydata); 243 244 UNUSED(type); 245 UNUSED(rdclass); 246 UNUSED(dctx); 247 UNUSED(options); 248 249 isc_buffer_activeregion(source, &sr); 250 isc_buffer_forward(source, sr.length); 251 return (mem_tobuffer(target, sr.base, sr.length)); 252 } 253 254 static inline isc_result_t 255 towire_keydata(ARGS_TOWIRE) { 256 isc_region_t sr; 257 258 REQUIRE(rdata->type == dns_rdatatype_keydata); 259 260 UNUSED(cctx); 261 262 dns_rdata_toregion(rdata, &sr); 263 return (mem_tobuffer(target, sr.base, sr.length)); 264 } 265 266 static inline int 267 compare_keydata(ARGS_COMPARE) { 268 isc_region_t r1; 269 isc_region_t r2; 270 271 REQUIRE(rdata1->type == rdata2->type); 272 REQUIRE(rdata1->rdclass == rdata2->rdclass); 273 REQUIRE(rdata1->type == dns_rdatatype_keydata); 274 275 dns_rdata_toregion(rdata1, &r1); 276 dns_rdata_toregion(rdata2, &r2); 277 return (isc_region_compare(&r1, &r2)); 278 } 279 280 static inline isc_result_t 281 fromstruct_keydata(ARGS_FROMSTRUCT) { 282 dns_rdata_keydata_t *keydata = source; 283 284 REQUIRE(type == dns_rdatatype_keydata); 285 REQUIRE(keydata != NULL); 286 REQUIRE(keydata->common.rdtype == type); 287 REQUIRE(keydata->common.rdclass == rdclass); 288 289 UNUSED(type); 290 UNUSED(rdclass); 291 292 /* Refresh timer */ 293 RETERR(uint32_tobuffer(keydata->refresh, target)); 294 295 /* Add hold-down */ 296 RETERR(uint32_tobuffer(keydata->addhd, target)); 297 298 /* Remove hold-down */ 299 RETERR(uint32_tobuffer(keydata->removehd, target)); 300 301 /* Flags */ 302 RETERR(uint16_tobuffer(keydata->flags, target)); 303 304 /* Protocol */ 305 RETERR(uint8_tobuffer(keydata->protocol, target)); 306 307 /* Algorithm */ 308 RETERR(uint8_tobuffer(keydata->algorithm, target)); 309 310 /* Data */ 311 return (mem_tobuffer(target, keydata->data, keydata->datalen)); 312 } 313 314 static inline isc_result_t 315 tostruct_keydata(ARGS_TOSTRUCT) { 316 dns_rdata_keydata_t *keydata = target; 317 isc_region_t sr; 318 319 REQUIRE(rdata->type == dns_rdatatype_keydata); 320 REQUIRE(keydata != NULL); 321 322 keydata->common.rdclass = rdata->rdclass; 323 keydata->common.rdtype = rdata->type; 324 ISC_LINK_INIT(&keydata->common, link); 325 326 dns_rdata_toregion(rdata, &sr); 327 328 /* Refresh timer */ 329 if (sr.length < 4) { 330 return (ISC_R_UNEXPECTEDEND); 331 } 332 keydata->refresh = uint32_fromregion(&sr); 333 isc_region_consume(&sr, 4); 334 335 /* Add hold-down */ 336 if (sr.length < 4) { 337 return (ISC_R_UNEXPECTEDEND); 338 } 339 keydata->addhd = uint32_fromregion(&sr); 340 isc_region_consume(&sr, 4); 341 342 /* Remove hold-down */ 343 if (sr.length < 4) { 344 return (ISC_R_UNEXPECTEDEND); 345 } 346 keydata->removehd = uint32_fromregion(&sr); 347 isc_region_consume(&sr, 4); 348 349 /* Flags */ 350 if (sr.length < 2) { 351 return (ISC_R_UNEXPECTEDEND); 352 } 353 keydata->flags = uint16_fromregion(&sr); 354 isc_region_consume(&sr, 2); 355 356 /* Protocol */ 357 if (sr.length < 1) { 358 return (ISC_R_UNEXPECTEDEND); 359 } 360 keydata->protocol = uint8_fromregion(&sr); 361 isc_region_consume(&sr, 1); 362 363 /* Algorithm */ 364 if (sr.length < 1) { 365 return (ISC_R_UNEXPECTEDEND); 366 } 367 keydata->algorithm = uint8_fromregion(&sr); 368 isc_region_consume(&sr, 1); 369 370 /* Data */ 371 keydata->datalen = sr.length; 372 keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); 373 if (keydata->data == NULL) { 374 return (ISC_R_NOMEMORY); 375 } 376 377 keydata->mctx = mctx; 378 return (ISC_R_SUCCESS); 379 } 380 381 static inline void 382 freestruct_keydata(ARGS_FREESTRUCT) { 383 dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *)source; 384 385 REQUIRE(keydata != NULL); 386 REQUIRE(keydata->common.rdtype == dns_rdatatype_keydata); 387 388 if (keydata->mctx == NULL) { 389 return; 390 } 391 392 if (keydata->data != NULL) { 393 isc_mem_free(keydata->mctx, keydata->data); 394 } 395 keydata->mctx = NULL; 396 } 397 398 static inline isc_result_t 399 additionaldata_keydata(ARGS_ADDLDATA) { 400 REQUIRE(rdata->type == dns_rdatatype_keydata); 401 402 UNUSED(rdata); 403 UNUSED(add); 404 UNUSED(arg); 405 406 return (ISC_R_SUCCESS); 407 } 408 409 static inline isc_result_t 410 digest_keydata(ARGS_DIGEST) { 411 isc_region_t r; 412 413 REQUIRE(rdata->type == dns_rdatatype_keydata); 414 415 dns_rdata_toregion(rdata, &r); 416 417 return ((digest)(arg, &r)); 418 } 419 420 static inline bool 421 checkowner_keydata(ARGS_CHECKOWNER) { 422 REQUIRE(type == dns_rdatatype_keydata); 423 424 UNUSED(name); 425 UNUSED(type); 426 UNUSED(rdclass); 427 UNUSED(wildcard); 428 429 return (true); 430 } 431 432 static inline bool 433 checknames_keydata(ARGS_CHECKNAMES) { 434 REQUIRE(rdata->type == dns_rdatatype_keydata); 435 436 UNUSED(rdata); 437 UNUSED(owner); 438 UNUSED(bad); 439 440 return (true); 441 } 442 443 static inline int 444 casecompare_keydata(ARGS_COMPARE) { 445 return (compare_keydata(rdata1, rdata2)); 446 } 447 448 #endif /* GENERIC_KEYDATA_65533_C */ 449