1249259Sdim/* $NetBSD: keydata_65533.c,v 1.3.4.1 2012/06/05 21:15:11 bouyer Exp $ */ 2249259Sdim 3249259Sdim/* 4249259Sdim * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 5249259Sdim * 6249259Sdim * Permission to use, copy, modify, and/or distribute this software for any 7249259Sdim * purpose with or without fee is hereby granted, provided that the above 8249259Sdim * copyright notice and this permission notice appear in all copies. 9249259Sdim * 10249259Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11249259Sdim * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12249259Sdim * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13249259Sdim * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14249259Sdim * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15249259Sdim * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16249259Sdim * PERFORMANCE OF THIS SOFTWARE. 17249259Sdim */ 18249259Sdim 19249259Sdim/* Id */ 20249259Sdim 21249259Sdim#ifndef GENERIC_KEYDATA_65533_C 22249259Sdim#define GENERIC_KEYDATA_65533_C 1 23249259Sdim 24249259Sdim#include <dst/dst.h> 25249259Sdim 26249259Sdim#define RRTYPE_KEYDATA_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) 27249259Sdim 28249259Sdimstatic inline isc_result_t 29249259Sdimfromtext_keydata(ARGS_FROMTEXT) { 30249259Sdim isc_token_t token; 31249259Sdim dns_secalg_t alg; 32249259Sdim dns_secproto_t proto; 33249259Sdim dns_keyflags_t flags; 34249259Sdim isc_uint32_t refresh, addhd, removehd; 35249259Sdim 36249259Sdim REQUIRE(type == 65533); 37249259Sdim 38249259Sdim UNUSED(type); 39249259Sdim UNUSED(rdclass); 40249259Sdim UNUSED(origin); 41249259Sdim UNUSED(options); 42249259Sdim UNUSED(callbacks); 43249259Sdim 44249259Sdim /* refresh timer */ 45249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 46249259Sdim ISC_FALSE)); 47249259Sdim RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); 48249259Sdim RETERR(uint32_tobuffer(refresh, target)); 49249259Sdim 50249259Sdim /* add hold-down */ 51249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 52249259Sdim ISC_FALSE)); 53249259Sdim RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); 54249259Sdim RETERR(uint32_tobuffer(addhd, target)); 55249259Sdim 56249259Sdim /* remove hold-down */ 57249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 58249259Sdim ISC_FALSE)); 59249259Sdim RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); 60249259Sdim RETERR(uint32_tobuffer(removehd, target)); 61249259Sdim 62249259Sdim /* flags */ 63249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 64249259Sdim ISC_FALSE)); 65249259Sdim RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); 66249259Sdim RETERR(uint16_tobuffer(flags, target)); 67249259Sdim 68249259Sdim /* protocol */ 69249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 70249259Sdim ISC_FALSE)); 71249259Sdim RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); 72249259Sdim RETERR(mem_tobuffer(target, &proto, 1)); 73249259Sdim 74249259Sdim /* algorithm */ 75249259Sdim RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 76249259Sdim ISC_FALSE)); 77249259Sdim RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); 78249259Sdim RETERR(mem_tobuffer(target, &alg, 1)); 79249259Sdim 80249259Sdim /* No Key? */ 81249259Sdim if ((flags & 0xc000) == 0xc000) 82249259Sdim return (ISC_R_SUCCESS); 83249259Sdim 84249259Sdim return (isc_base64_tobuffer(lexer, target, -1)); 85249259Sdim} 86249259Sdim 87249259Sdimstatic inline isc_result_t 88249259Sdimtotext_keydata(ARGS_TOTEXT) { 89249259Sdim isc_region_t sr; 90249259Sdim char buf[sizeof("64000")]; 91249259Sdim unsigned int flags; 92249259Sdim unsigned char algorithm; 93249259Sdim unsigned long when; 94249259Sdim char algbuf[DNS_NAME_FORMATSIZE]; 95249259Sdim const char *keyinfo; 96249259Sdim 97249259Sdim REQUIRE(rdata->type == 65533); 98249259Sdim REQUIRE(rdata->length != 0); 99249259Sdim 100249259Sdim dns_rdata_toregion(rdata, &sr); 101249259Sdim 102249259Sdim /* refresh timer */ 103249259Sdim when = uint32_fromregion(&sr); 104249259Sdim isc_region_consume(&sr, 4); 105249259Sdim RETERR(dns_time32_totext(when, target)); 106249259Sdim RETERR(str_totext(" ", target)); 107249259Sdim 108249259Sdim /* add hold-down */ 109249259Sdim when = uint32_fromregion(&sr); 110249259Sdim isc_region_consume(&sr, 4); 111249259Sdim RETERR(dns_time32_totext(when, target)); 112249259Sdim RETERR(str_totext(" ", target)); 113249259Sdim 114249259Sdim /* remove hold-down */ 115249259Sdim when = uint32_fromregion(&sr); 116249259Sdim isc_region_consume(&sr, 4); 117249259Sdim RETERR(dns_time32_totext(when, target)); 118249259Sdim RETERR(str_totext(" ", target)); 119249259Sdim 120249259Sdim /* flags */ 121249259Sdim flags = uint16_fromregion(&sr); 122249259Sdim isc_region_consume(&sr, 2); 123249259Sdim sprintf(buf, "%u", flags); 124249259Sdim RETERR(str_totext(buf, target)); 125249259Sdim RETERR(str_totext(" ", target)); 126249259Sdim if ((flags & DNS_KEYFLAG_KSK) != 0) { 127249259Sdim if (flags & DNS_KEYFLAG_REVOKE) 128249259Sdim keyinfo = "revoked KSK"; 129249259Sdim else 130249259Sdim keyinfo = "KSK"; 131249259Sdim } else 132249259Sdim keyinfo = "ZSK"; 133249259Sdim 134249259Sdim /* protocol */ 135249259Sdim sprintf(buf, "%u", sr.base[0]); 136249259Sdim isc_region_consume(&sr, 1); 137249259Sdim RETERR(str_totext(buf, target)); 138249259Sdim RETERR(str_totext(" ", target)); 139249259Sdim 140249259Sdim /* algorithm */ 141249259Sdim algorithm = sr.base[0]; 142249259Sdim sprintf(buf, "%u", algorithm); 143249259Sdim isc_region_consume(&sr, 1); 144249259Sdim RETERR(str_totext(buf, target)); 145249259Sdim 146249259Sdim /* No Key? */ 147249259Sdim if ((flags & 0xc000) == 0xc000) 148249259Sdim return (ISC_R_SUCCESS); 149249259Sdim 150249259Sdim /* key */ 151249259Sdim if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 152249259Sdim RETERR(str_totext(" (", target)); 153249259Sdim RETERR(str_totext(tctx->linebreak, target)); 154249259Sdim if (tctx->width == 0) /* No splitting */ 155249259Sdim RETERR(isc_base64_totext(&sr, 60, "", target)); 156249259Sdim else 157249259Sdim RETERR(isc_base64_totext(&sr, tctx->width - 2, 158249259Sdim tctx->linebreak, target)); 159249259Sdim 160249259Sdim if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) 161249259Sdim RETERR(str_totext(tctx->linebreak, target)); 162249259Sdim else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 163249259Sdim RETERR(str_totext(" ", target)); 164249259Sdim 165249259Sdim if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 166249259Sdim RETERR(str_totext(")", target)); 167249259Sdim 168249259Sdim if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { 169249259Sdim isc_region_t tmpr; 170249259Sdim 171249259Sdim RETERR(str_totext(" ; ", target)); 172249259Sdim RETERR(str_totext(keyinfo, target)); 173249259Sdim dns_secalg_format((dns_secalg_t) algorithm, algbuf, 174249259Sdim sizeof(algbuf)); 175249259Sdim RETERR(str_totext("; alg = ", target)); 176249259Sdim RETERR(str_totext(algbuf, target)); 177249259Sdim RETERR(str_totext("; key id = ", target)); 178249259Sdim dns_rdata_toregion(rdata, &tmpr); 179249259Sdim /* Skip over refresh, addhd, and removehd */ 180249259Sdim isc_region_consume(&tmpr, 12); 181249259Sdim sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); 182249259Sdim RETERR(str_totext(buf, target)); 183249259Sdim } 184249259Sdim return (ISC_R_SUCCESS); 185249259Sdim} 186249259Sdim 187249259Sdimstatic inline isc_result_t 188249259Sdimfromwire_keydata(ARGS_FROMWIRE) { 189249259Sdim isc_region_t sr; 190249259Sdim 191249259Sdim REQUIRE(type == 65533); 192249259Sdim 193249259Sdim UNUSED(type); 194249259Sdim UNUSED(rdclass); 195249259Sdim UNUSED(dctx); 196249259Sdim UNUSED(options); 197249259Sdim 198249259Sdim isc_buffer_activeregion(source, &sr); 199249259Sdim if (sr.length < 16) 200249259Sdim return (ISC_R_UNEXPECTEDEND); 201249259Sdim 202249259Sdim isc_buffer_forward(source, sr.length); 203249259Sdim return (mem_tobuffer(target, sr.base, sr.length)); 204249259Sdim} 205249259Sdim 206249259Sdimstatic inline isc_result_t 207249259Sdimtowire_keydata(ARGS_TOWIRE) { 208249259Sdim isc_region_t sr; 209249259Sdim 210249259Sdim REQUIRE(rdata->type == 65533); 211249259Sdim REQUIRE(rdata->length != 0); 212249259Sdim 213249259Sdim UNUSED(cctx); 214249259Sdim 215249259Sdim dns_rdata_toregion(rdata, &sr); 216249259Sdim return (mem_tobuffer(target, sr.base, sr.length)); 217249259Sdim} 218249259Sdim 219249259Sdimstatic inline int 220249259Sdimcompare_keydata(ARGS_COMPARE) { 221249259Sdim isc_region_t r1; 222249259Sdim isc_region_t r2; 223249259Sdim 224249259Sdim REQUIRE(rdata1->type == rdata2->type); 225249259Sdim REQUIRE(rdata1->rdclass == rdata2->rdclass); 226249259Sdim REQUIRE(rdata1->type == 65533); 227249259Sdim REQUIRE(rdata1->length != 0); 228249259Sdim REQUIRE(rdata2->length != 0); 229249259Sdim 230249259Sdim dns_rdata_toregion(rdata1, &r1); 231249259Sdim dns_rdata_toregion(rdata2, &r2); 232249259Sdim return (isc_region_compare(&r1, &r2)); 233249259Sdim} 234249259Sdim 235249259Sdimstatic inline isc_result_t 236249259Sdimfromstruct_keydata(ARGS_FROMSTRUCT) { 237249259Sdim dns_rdata_keydata_t *keydata = source; 238249259Sdim 239249259Sdim REQUIRE(type == 65533); 240249259Sdim REQUIRE(source != NULL); 241249259Sdim REQUIRE(keydata->common.rdtype == type); 242249259Sdim REQUIRE(keydata->common.rdclass == rdclass); 243249259Sdim 244249259Sdim UNUSED(type); 245249259Sdim UNUSED(rdclass); 246249259Sdim 247249259Sdim /* Refresh timer */ 248249259Sdim RETERR(uint32_tobuffer(keydata->refresh, target)); 249249259Sdim 250249259Sdim /* Add hold-down */ 251249259Sdim RETERR(uint32_tobuffer(keydata->addhd, target)); 252249259Sdim 253249259Sdim /* Remove hold-down */ 254249259Sdim RETERR(uint32_tobuffer(keydata->removehd, target)); 255249259Sdim 256249259Sdim /* Flags */ 257249259Sdim RETERR(uint16_tobuffer(keydata->flags, target)); 258249259Sdim 259249259Sdim /* Protocol */ 260249259Sdim RETERR(uint8_tobuffer(keydata->protocol, target)); 261249259Sdim 262249259Sdim /* Algorithm */ 263249259Sdim RETERR(uint8_tobuffer(keydata->algorithm, target)); 264249259Sdim 265249259Sdim /* Data */ 266249259Sdim return (mem_tobuffer(target, keydata->data, keydata->datalen)); 267249259Sdim} 268249259Sdim 269249259Sdimstatic inline isc_result_t 270249259Sdimtostruct_keydata(ARGS_TOSTRUCT) { 271249259Sdim dns_rdata_keydata_t *keydata = target; 272249259Sdim isc_region_t sr; 273249259Sdim 274249259Sdim REQUIRE(rdata->type == 65533); 275249259Sdim REQUIRE(target != NULL); 276249259Sdim REQUIRE(rdata->length != 0); 277249259Sdim 278249259Sdim keydata->common.rdclass = rdata->rdclass; 279249259Sdim keydata->common.rdtype = rdata->type; 280249259Sdim ISC_LINK_INIT(&keydata->common, link); 281249259Sdim 282249259Sdim dns_rdata_toregion(rdata, &sr); 283249259Sdim 284249259Sdim /* Refresh timer */ 285249259Sdim if (sr.length < 4) 286249259Sdim return (ISC_R_UNEXPECTEDEND); 287249259Sdim keydata->refresh = uint32_fromregion(&sr); 288249259Sdim isc_region_consume(&sr, 4); 289249259Sdim 290249259Sdim /* Add hold-down */ 291249259Sdim if (sr.length < 4) 292249259Sdim return (ISC_R_UNEXPECTEDEND); 293249259Sdim keydata->addhd = uint32_fromregion(&sr); 294249259Sdim isc_region_consume(&sr, 4); 295249259Sdim 296249259Sdim /* Remove hold-down */ 297249259Sdim if (sr.length < 4) 298249259Sdim return (ISC_R_UNEXPECTEDEND); 299249259Sdim keydata->removehd = uint32_fromregion(&sr); 300249259Sdim isc_region_consume(&sr, 4); 301249259Sdim 302249259Sdim /* Flags */ 303249259Sdim if (sr.length < 2) 304249259Sdim return (ISC_R_UNEXPECTEDEND); 305249259Sdim keydata->flags = uint16_fromregion(&sr); 306249259Sdim isc_region_consume(&sr, 2); 307249259Sdim 308249259Sdim /* Protocol */ 309249259Sdim if (sr.length < 1) 310249259Sdim return (ISC_R_UNEXPECTEDEND); 311249259Sdim keydata->protocol = uint8_fromregion(&sr); 312249259Sdim isc_region_consume(&sr, 1); 313249259Sdim 314249259Sdim /* Algorithm */ 315249259Sdim if (sr.length < 1) 316249259Sdim return (ISC_R_UNEXPECTEDEND); 317249259Sdim keydata->algorithm = uint8_fromregion(&sr); 318249259Sdim isc_region_consume(&sr, 1); 319249259Sdim 320249259Sdim /* Data */ 321249259Sdim keydata->datalen = sr.length; 322249259Sdim keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); 323249259Sdim if (keydata->data == NULL) 324249259Sdim return (ISC_R_NOMEMORY); 325249259Sdim 326249259Sdim keydata->mctx = mctx; 327249259Sdim return (ISC_R_SUCCESS); 328249259Sdim} 329249259Sdim 330249259Sdimstatic inline void 331249259Sdimfreestruct_keydata(ARGS_FREESTRUCT) { 332249259Sdim dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *) source; 333249259Sdim 334249259Sdim REQUIRE(source != NULL); 335249259Sdim REQUIRE(keydata->common.rdtype == 65533); 336249259Sdim 337251662Sdim if (keydata->mctx == NULL) 338251662Sdim return; 339251662Sdim 340251662Sdim if (keydata->data != NULL) 341251662Sdim isc_mem_free(keydata->mctx, keydata->data); 342251662Sdim keydata->mctx = NULL; 343251662Sdim} 344251662Sdim 345251662Sdimstatic inline isc_result_t 346251662Sdimadditionaldata_keydata(ARGS_ADDLDATA) { 347251662Sdim REQUIRE(rdata->type == 65533); 348251662Sdim 349251662Sdim UNUSED(rdata); 350251662Sdim UNUSED(add); 351251662Sdim UNUSED(arg); 352251662Sdim 353251662Sdim return (ISC_R_SUCCESS); 354251662Sdim} 355251662Sdim 356251662Sdimstatic inline isc_result_t 357251662Sdimdigest_keydata(ARGS_DIGEST) { 358251662Sdim isc_region_t r; 359251662Sdim 360251662Sdim REQUIRE(rdata->type == 65533); 361251662Sdim 362251662Sdim dns_rdata_toregion(rdata, &r); 363251662Sdim 364251662Sdim return ((digest)(arg, &r)); 365251662Sdim} 366251662Sdim 367251662Sdimstatic inline isc_boolean_t 368251662Sdimcheckowner_keydata(ARGS_CHECKOWNER) { 369251662Sdim 370251662Sdim REQUIRE(type == 65533); 371249259Sdim 372249259Sdim UNUSED(name); 373249259Sdim UNUSED(type); 374251662Sdim UNUSED(rdclass); 375249259Sdim UNUSED(wildcard); 376249259Sdim 377249259Sdim return (ISC_TRUE); 378249259Sdim} 379249259Sdim 380249259Sdimstatic inline isc_boolean_t 381249259Sdimchecknames_keydata(ARGS_CHECKNAMES) { 382249259Sdim 383249259Sdim REQUIRE(rdata->type == 65533); 384249259Sdim 385249259Sdim UNUSED(rdata); 386249259Sdim UNUSED(owner); 387249259Sdim UNUSED(bad); 388249259Sdim 389249259Sdim return (ISC_TRUE); 390249259Sdim} 391249259Sdim 392249259Sdimstatic inline int 393249259Sdimcasecompare_keydata(ARGS_COMPARE) { 394249259Sdim return (compare_keydata(rdata1, rdata2)); 395249259Sdim} 396249259Sdim 397249259Sdim#endif /* GENERIC_KEYDATA_65533_C */ 398249259Sdim